Index: branches/5.2.x/core/units/users/users_event_handler.php =================================================================== diff -u -N -r14585 -r14596 --- branches/5.2.x/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 14585) +++ branches/5.2.x/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 14596) @@ -1,6 +1,6 @@ Special == 'forgot') { + $object =& $event->getObject(); + /* @var $object kDBItem */ + + if ( $event->Special == 'forgot' || $object->getFormName() == 'registration' ) { $this->_makePasswordRequired($event); } } @@ -70,8 +73,11 @@ * Shows only admins when required * * @param kEvent $event + * @return void + * @access protected + * @see kDBEventHandler::OnListBuild() */ - function SetCustomQuery(&$event) + protected function SetCustomQuery(&$event) { $object =& $event->getObject(); /* @var $object kDBList */ @@ -110,44 +116,47 @@ } /** - * 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 ($event->Name == 'OnLogin' || $event->Name == 'OnLogout') { + if ( $event->Name == 'OnLogin' || $event->Name == 'OnLogout' ) { // permission is checked in OnLogin event directly return true; } - if (!$this->Application->isAdminUser) { + if ( !$this->Application->isAdminUser ) { $user_id = $this->Application->RecallVar('user_id'); $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); - if ($event->Name == 'OnCreate' && $user_id == USER_GUEST) { + if ( $event->Name == 'OnCreate' && $user_id == USER_GUEST ) { // "Guest" can create new users return true; } - if ($event->Name == 'OnUpdate' && $user_id > 0) { - $user_dummy =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true)); + if ( $event->Name == 'OnUpdate' && $user_id > 0 ) { + $user_dummy =& $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true)); + /* @var $user_dummy UsersItem */ foreach ($items_info as $id => $field_values) { - if ($id != $user_id) { + if ( $id != $user_id ) { // registered users can update their record only return false; } $user_dummy->Load($id); $status_field = array_shift($this->Application->getUnitOption($event->Prefix, 'StatusField')); - if ($user_dummy->GetDBField($status_field) != STATUS_ACTIVE) { + if ( $user_dummy->GetDBField($status_field) != STATUS_ACTIVE ) { // not active user is not allowed to update his record (he could not activate himself manually) return false; } - if (isset($field_values[$status_field]) && $user_dummy->GetDBField($status_field) != $field_values[$status_field]) { + if ( isset($field_values[$status_field]) && $user_dummy->GetDBField($status_field) != $field_values[$status_field] ) { // user can't change status by himself return false; } @@ -158,10 +167,10 @@ if ( $event->Name == 'OnResetLostPassword' && $event->Special == 'forgot' && $user_id == USER_GUEST ) { // non-logged in users can reset their password, when reset code is valid - return is_numeric( $this->getPassedID($event) ); + return is_numeric($this->getPassedID($event)); } - if ($event->Name == 'OnUpdate' && $user_id <= 0) { + if ( $event->Name == 'OnUpdate' && $user_id <= 0 ) { // guests are not allowed to update their record, because they don't have it :) return false; } @@ -232,7 +241,7 @@ */ function OnLogin(&$event) { - $object =& $event->getObject(); + $object =& $event->getObject( Array ('form_name' => 'login') ); /* @var $object kDBItem */ $object->SetFieldsFromHash( $this->getSubmittedFields($event) ); @@ -279,6 +288,8 @@ function OnInpLogin(&$event) { $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), Array ('InPortalSyncronize')); + /* @var $sync_manager UsersSyncronizeManager */ + $sync_manager->performAction('LoginUser', $event->getEventParam('user'), $event->getEventParam('pass') ); if ($event->redirect && is_string($event->redirect)) { @@ -295,6 +306,8 @@ function OnInpLogout(&$event) { $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), Array ('InPortalSyncronize')); + /* @var $sync_manager UsersSyncronizeManager */ + $sync_manager->performAction('LogoutUser'); } @@ -308,232 +321,143 @@ } /** - * Redirects user after succesfull registration to confirmation template (on Front only) + * Redirects user after successful registration to confirmation template (on Front only) * * @param kEvent $event + * @return void + * @access protected */ - function OnAfterItemCreate(&$event) + protected function OnAfterItemCreate(&$event) { parent::OnAfterItemCreate($event); $this->afterItemChanged($event); - $object =& $event->getObject(); - /* @var $object kDBItem */ - - $primary_group_id = $object->GetDBField('PrimaryGroupId'); - - if ($primary_group_id) { - $ug_table = TABLE_PREFIX . 'UserGroup'; - - if ( $object->IsTempTable() ) { - $ug_table = $this->Application->GetTempName($ug_table, 'prefix:' . $event->Prefix); - } - - $fields_hash = Array ( - 'PortalUserId' => $object->GetID(), - 'GroupId' => $primary_group_id, - ); - - $this->Conn->doInsert($fields_hash, $ug_table, 'REPLACE'); - } + $this->assignToPrimaryGroup($event); } /** - * Login user if possible, if not then redirect to corresponding template + * Performs user registration * * @param kEvent $event */ - function autoLoginUser(&$event) + function OnCreate(&$event) { - $object =& $event->getObject(); - $this->Application->SetVar('u.current_id', $object->GetID()); + if ( $this->Application->isAdmin ) { + parent::OnCreate($event); - if ( $object->GetDBField('Status') == STATUS_ACTIVE ) { - $user_helper =& $this->Application->recallObject('UserHelper'); - /* @var $user_helper UserHelper */ - - if ( $user_helper->checkLoginPermission() ) { - $user_helper->loginUserById( $object->GetID() ); - } + return ; } - } + $object =& $event->getObject( Array('form_name' => 'registration') ); + /* @var $object UsersItem */ - /** - * When creating user & user with such email exists then force to use OnUpdate insted of ? - * - * @param kEvent $event - */ - function OnSubstituteSubscriber(&$event) - { - $ret = false; - $object =& $event->getObject( Array('skip_autoload' => true) ); + $field_values = $this->getSubmittedFields($event); + $user_email = getArrayValue($field_values, 'Email'); + $subscriber_id = $user_email ? $this->getSubscriberByEmail($user_email) : false; - $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); - - if ($items_info) { - list($id, $field_values) = each($items_info); - $user_email = isset($field_values['Email']) ? $field_values['Email'] : false; - - if ($user_email) { - // check if is subscriber - $verify_user =& $this->Application->recallObject('u.verify', null, Array('skip_autoload' => true) ); - $verify_user->Load($user_email, 'Email'); - - if ( $verify_user->isLoaded() && $verify_user->isSubscriberOnly() ) { - $items_info = Array( $verify_user->GetDBField('PortalUserId') => $field_values ); - $this->Application->SetVar($event->getPrefixSpecial(true), $items_info); - $ret = true; - } - } + if ( $subscriber_id ) { + // update existing subscriber + $object->Load($subscriber_id); + $object->SetDBField('PrimaryGroupId', $this->Application->ConfigValue('User_NewGroup')); + $this->Application->SetVar($event->getPrefixSpecial(true), Array ($object->GetID() => $field_values)); } - if ( isset($event->MasterEvent) ) { - $event->MasterEvent->setEventParam('is_subscriber_only', $ret); - } - else { - $event->setEventParam('is_subscriber_only', $ret); - } - } + $object->SetFieldsFromHash($field_values); + $status = $object->isLoaded() ? $object->Update() : $object->Create(); - /** - * Enter description here... - * - * @param kEvent $event - * @param bool $dry_run - * @return bool - */ - function isSubscriberOnly(&$event, $dry_run = false) - { - $event->CallSubEvent('OnSubstituteSubscriber'); - $is_subscriber = $event->getEventParam('is_subscriber_only'); - - if ($dry_run) { - return $is_subscriber; + if ( !$status ) { + $event->status = kEvent::erFAIL; + $event->redirect = false; + $object->setID( (int)$object->GetID() ); } - if ($is_subscriber) { - $object =& $event->getObject( Array('skip_autoload' => true) ); - $this->OnUpdate($event); + $this->setNextTemplate($event, true); - if ($event->status == kEvent::erSUCCESS) { - $this->OnAfterItemCreate($event); - $object->SendEmailEvents(); + if ( ($event->status == kEvent::erSUCCESS) && $event->redirect ) { + $this->assignToPrimaryGroup($event); - if (!$this->Application->isAdmin && $event->redirect) { - $this->autoLoginUser($event); - } - } + $object->SendEmailEvents(); + $this->autoLoginUser($event); } - - return $is_subscriber; } /** - * Creates new user + * Returns subscribed user ID by given e-mail address * - * @param kEvent $event + * @param string $email */ - function OnCreate(&$event) + function getSubscriberByEmail($email) { - if (!$this->Application->isAdminUser) { - $this->setUserStatus($event); - } + $verify_user =& $this->Application->recallObject('u.verify', null, Array ('skip_autoload' => true)); + /* @var $verify_user UsersItem */ - if ( !$this->isSubscriberOnly($event) ) { - $object =& $event->getObject( Array('skip_autoload' => true) ); - /* @var $object UsersItem */ + $verify_user->Load($email, 'Email'); - if ( $this->Application->ConfigValue('User_Password_Auto') ) { - $password = $object->generatePassword( rand(5, 8) ); - $this->Application->SetVar('user_password', $password); - } - - parent::OnCreate($event); - - $this->Application->SetVar('u.current_id', $object->getID()); // for affil:OnRegisterAffiliate after hook - - $this->setNextTemplate($event); - - if (!$this->Application->isAdmin && ($event->status == kEvent::erSUCCESS) && $event->redirect) { - $object->SendEmailEvents(); - $this->autoLoginUser($event); - } - } + return $verify_user->isLoaded() && $verify_user->isSubscriberOnly() ? $verify_user->GetID() : false; } /** - * Set's new user status based on config options + * Login user if possible, if not then redirect to corresponding template * * @param kEvent $event */ - function setUserStatus(&$event) + function autoLoginUser(&$event) { - $object =& $event->getObject( Array('skip_autoload' => true) ); + $object =& $event->getObject(); + $this->Application->SetVar('u.current_id', $object->GetID()); - $new_users_allowed = $this->Application->ConfigValue('User_Allow_New'); + if ( $object->GetDBField('Status') == STATUS_ACTIVE ) { + $user_helper =& $this->Application->recallObject('UserHelper'); + /* @var $user_helper UserHelper */ - switch ($new_users_allowed) { - case 1: // Immediate - $object->SetDBField('Status', STATUS_ACTIVE); - $next_template = $this->Application->GetVar('registration_confirm_template'); - if ($next_template) { - $event->redirect = $next_template; - } - break; - - case 3: // Upon Approval - case 4: // Email Activation - $next_template = $this->Application->GetVar('registration_confirm_pending_template'); - if ($next_template) { - $event->redirect = $next_template; - } - $object->SetDBField('Status', STATUS_PENDING); - break; - - case 2: // Not Allowed - $object->SetDBField('Status', STATUS_DISABLED); - break; + if ( $user_helper->checkLoginPermission() ) { + $user_helper->loginUserById( $object->GetID() ); + } } } /** * Set's new unique resource id to user * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemCreate(&$event) + protected function OnBeforeItemCreate(&$event) { parent::OnBeforeItemCreate($event); + $this->beforeItemChanged($event); + $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ - if ( !$this->isSubscriberOnly($event, true) ) { + $object =& $event->getObject(); + /* @var $object UsersItem */ + + if ( !$object->isSubscriberOnly() ) { + // don't checck state-to-country relations for subscribers $cs_helper->CheckStateField($event, 'State', 'Country'); } $this->_makePasswordRequired($event); $cs_helper->PopulateStates($event, 'State', 'Country'); - $object =& $event->getObject(); - /* @var $object UsersItem */ - if ( $this->Application->ConfigValue('Email_As_Login') ) { - $field_options = $object->GetFieldOptions('Email'); - $field_options['error_msgs']['unique'] = $this->Application->Phrase('lu_user_and_email_already_exist'); - $object->SetFieldOptions('Email', $field_options); + $error_msgs = $object->GetFieldOption('Email', 'error_msgs'); + $error_msgs['unique'] = '!lu_user_and_email_already_exist!'; + $object->SetFieldOption('Email', 'error_msgs', $error_msgs); } $this->setUserGroup($object); $user_helper =& $this->Application->recallObject('UserHelper'); /* @var $user_helper UserHelper */ - if (!$user_helper->checkBanRules($object)) { + if ( !$user_helper->checkBanRules($object) ) { $object->SetError('Login', 'banned'); } } @@ -571,6 +495,34 @@ } /** + * Assigns a user to it's primary group + * + * @param kEvent $event + */ + protected function assignToPrimaryGroup(&$event) + { + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $primary_group_id = $object->GetDBField('PrimaryGroupId'); + + if ($primary_group_id) { + $ug_table = TABLE_PREFIX . 'UserGroup'; + + if ( $object->IsTempTable() ) { + $ug_table = $this->Application->GetTempName($ug_table, 'prefix:' . $event->Prefix); + } + + $fields_hash = Array ( + 'PortalUserId' => $object->GetID(), + 'GroupId' => $primary_group_id, + ); + + $this->Conn->doInsert($fields_hash, $ug_table, 'REPLACE'); + } + } + + /** * Set's new unique resource id to user * * @param kEvent $event @@ -595,10 +547,9 @@ */ function OnRecommend(&$event) { - $object =& $event->getObject(); + $object =& $event->getObject( Array ('form_name' => 'recommend') ); /* @var $object kDBItem */ - $object->setRequired('RecommendEmail'); $object->SetFieldsFromHash( $this->getSubmittedFields($event) ); if ( !$object->ValidateField('RecommendEmail') ) { @@ -633,13 +584,15 @@ */ function OnUpdateAddress(&$event) { - $object =& $event->getObject( Array('skip_autoload' => true) ); + $object =& $event->getObject(Array ('skip_autoload' => true)); + /* @var $object kDBItem */ - $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); + $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); - if ($items_info) { + if ( $items_info ) { list ($id, $field_values) = each($items_info); - if ($id > 0) { + + if ( $id > 0 ) { $object->Load($id); } @@ -663,35 +616,29 @@ */ function OnSubscribeQuery(&$event) { - $user_email = $this->Application->GetVar('subscriber_email'); + $object =& $event->getObject( Array ('form_name' => 'subscription') ); + /* @var $object UsersItem */ - if ( preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $user_email) ) { - $object =& $this->Application->recallObject($this->Prefix . '.subscriber', null, Array('skip_autoload' => true)); - /* @var $object UsersItem */ + $object->SetFieldsFromHash( $this->getSubmittedFields($event) ); - $object->Load($user_email, 'Email'); - $event->SetRedirectParam('subscriber_email', $user_email); + if ( !$object->ValidateField('SubscriberEmail') ) { + $event->status = kEvent::erFAIL; - if ( $object->isLoaded() ) { - if ( $this->isSubscribed($object) ) { - $event->redirect = $this->Application->GetVar('unsubscribe_template'); - } - else { - $event->redirect = $this->Application->GetVar('subscribe_template'); - } - } - else { - $event->redirect = $this->Application->GetVar('subscribe_template'); - } + return ; } - else { - // used for error reporting only -> rewrite code + theme (by Alex) - $object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too - /* @var $object UsersItem */ - $object->SetError('SubscribeEmail', 'invalid_email', 'lu_InvalidEmail'); - $event->status = kEvent::erFAIL; + $user_email = $object->GetDBField('SubscriberEmail'); + $object->Load($user_email, 'Email'); + $event->SetRedirectParam('subscriber_email', $user_email); + + if ( $object->isLoaded() && $object->isSubscribed() ) { + $event->redirect = $this->Application->GetVar('unsubscribe_template'); } + else { + $event->redirect = $this->Application->GetVar('subscribe_template'); + } + + $event->SetRedirectParam('pass', 'm'); } /** @@ -701,50 +648,59 @@ */ function OnSubscribeUser(&$event) { - $object = &$this->Application->recallObject($this->Prefix . '.subscriber', null, Array('skip_autoload' => true)); + $object =& $event->getObject( Array ('form_name' => 'subscription') ); /* @var $object UsersItem */ $user_email = $this->Application->GetVar('subscriber_email'); + $object->SetDBField('SubscriberEmail', $user_email); - if ( preg_match('/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', $user_email) ) { - $this->RemoveRequiredFields($object); - $object->Load($user_email, 'Email'); + if ( !$object->ValidateField('SubscriberEmail') ) { + $event->status = kEvent::erFAIL; - if ( $object->isLoaded() ) { - if ( $this->isSubscribed($object) ) { - if ( $event->getEventParam('no_unsubscribe') ) { - // for customization code from FormsEventHandler - return ; - } + return ; + } - if ( $object->isSubscriberOnly() ) { - $this->Application->SetVar($object->getPrefixSpecial(true) . '_id', $object->GetID()); - $delete_event = new kEvent($object->getPrefixSpecial() . ':OnDelete'); - $this->Application->HandleEvent($delete_event); - } - else { - $this->RemoveSubscriberGroup( $object->GetID() ); - } + $this->RemoveRequiredFields($object); + $object->Load($user_email, 'Email'); - $event->redirect = $this->Application->GetVar('unsubscribe_ok_template'); + if ( $object->isLoaded() ) { + if ( $object->isSubscribed() ) { + if ( $event->getEventParam('no_unsubscribe') ) { + // for customization code from FormsEventHandler + return ; } + + if ( $object->isSubscriberOnly() ) { + $temp_handler =& $this->Application->recallObject($event->Prefix . '_TempHandler', 'kTempTablesHandler'); + /* @var $temp_handler kTempTablesHandler */ + + $temp_handler->DeleteItems($event->Prefix, '', Array($object->GetID())); + } else { - $this->AddSubscriberGroup($object); - $event->redirect = $this->Application->GetVar('subscribe_ok_template'); + $this->RemoveSubscriberGroup( $object->GetID() ); } + + $event->redirect = $this->Application->GetVar('unsubscribe_ok_template'); } else { - $object->generatePassword(); + $this->AddSubscriberGroup($object); + $event->redirect = $this->Application->GetVar('subscribe_ok_template'); + } + } + else { + $object->generatePassword(); + $object->SetDBField('Email', $user_email); - $object->SetDBField('Email', $user_email); + if ( $object->isRequired('Login') ) { $object->SetDBField('Login', $user_email); - $object->SetDBField('Status', STATUS_ACTIVE); // make user subscriber Active by default - $object->SetDBField('ip', $_SERVER['REMOTE_ADDR']); + } - if ( $object->Create() ) { - $this->AddSubscriberGroup($object); - $event->redirect = $this->Application->GetVar('subscribe_ok_template'); - } + $object->SetDBField('Status', STATUS_ACTIVE); // make user subscriber Active by default + $object->SetDBField('ip', $_SERVER['REMOTE_ADDR']); + + if ( $object->Create() ) { + $this->AddSubscriberGroup($object); + $event->redirect = $this->Application->GetVar('subscribe_ok_template'); } } } @@ -787,30 +743,14 @@ } /** - * Checks user subscription status - * - * @param kDBItem $object - * @return bool - */ - function isSubscribed(&$object) - { - $group_id = $this->Application->ConfigValue('User_SubscriberGroup'); - - $sql = 'SELECT GroupId - FROM ' . TABLE_PREFIX . 'UserGroup - WHERE (PortalUserId = ' . $object->GetID() . ') AND (GroupId = ' . $group_id . ')'; - - return $this->Conn->GetOne($sql); - } - - /** - * Checks, that user can reset his password - * + * Validates forgot password form and sends password reset confirmation e-mail + * * @param kEvent $event + * @return void */ function OnForgotPassword(&$event) { - $object =& $event->getObject(); + $object =& $event->getObject( Array ('form_name' => 'forgot_password') ); /* @var $object kDBItem */ $object->SetFieldsFromHash( $this->getSubmittedFields($event) ); @@ -873,28 +813,34 @@ { parent::OnUpdate($event); - $this->setNextTemplate($event); + if ( !$this->Application->isAdmin ) { + $this->setNextTemplate($event); + } } /** * Checks state against country * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemUpdate(&$event) + protected function OnBeforeItemUpdate(&$event) { parent::OnBeforeItemUpdate($event); + $this->beforeItemChanged($event); + $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ $cs_helper->CheckStateField($event, 'State', 'Country'); $cs_helper->PopulateStates($event, 'State', 'Country'); - if ($event->Special == 'forgot') { - $object =& $event->getObject(); - /* @var $object kDBItem */ + $object =& $event->getObject(); + /* @var $object kDBItem */ + if ($event->Special == 'forgot') { $object->SetDBField('PwResetConfirm', ''); $object->SetDBField('PwRequestTime_date', NULL); $object->SetDBField('PwRequestTime_time', NULL); @@ -909,26 +855,72 @@ } /** - * Enter description here... + * Occurs before item is changed * * @param kEvent $event */ - function setNextTemplate(&$event) + function beforeItemChanged(&$event) { - if ($this->Application->isAdmin) { - return ; + $object =& $event->getObject(); + /* @var $object UsersItem */ + + if ( !$this->Application->isAdmin && $object->getFormName() == 'registration' ) { + // sets new user's status based on config options + $status_map = Array (1 => STATUS_ACTIVE, 2 => STATUS_DISABLED, 3 => STATUS_PENDING, 4 => STATUS_PENDING); + $object->SetDBField('Status', $status_map[ $this->Application->ConfigValue('User_Allow_New') ]); + + if ( $this->Application->ConfigValue('User_Password_Auto') ) { + $object->generatePassword( rand(5, 8) ); + } + + if ( $this->Application->ConfigValue('RegistrationCaptcha') ) { + $captcha_helper =& $this->Application->recallObject('CaptchaHelper'); + /* @var $captcha_helper kCaptchaHelper */ + + $captcha_helper->validateCode($event, false); + } + + if ( $event->Name == 'OnBeforeItemUpdate' ) { + // when a subscriber-only users performs normal registration, then assign him to Member group + $this->setUserGroup($object); + } } + } + /** + * Sets redirect template based on user status & user request contents + * + * @param kEvent $event + * @param bool $for_registration + */ + function setNextTemplate(&$event, $for_registration = false) + { $event->SetRedirectParam('opener', 's'); + $object =& $event->getObject(); + /* @var $object UsersItem */ - if ($object->GetDBField('Status') == STATUS_ACTIVE) { + $next_template = false; + + if ( $object->GetDBField('Status') == STATUS_ACTIVE && $this->Application->GetVar('next_template') ) { $next_template = $this->Application->GetVar('next_template'); + } + elseif ( $for_registration ) { + switch ( $this->Application->ConfigValue('User_Allow_New') ) { + case 1: // Immediate + $next_template = $this->Application->GetVar('registration_confirm_template'); + break; - if ($next_template) { - $event->redirect = $next_template; + case 3: // Upon Approval + case 4: // Email Activation + $next_template = $this->Application->GetVar('registration_confirm_pending_template'); + break; } } + + if ($next_template) { + $event->redirect = $next_template; + } } /** @@ -982,17 +974,21 @@ } /** - * Enter description here... + * Used to keep user registration form data, while showing affiliate registration form fields * * @param kEvent $event + * @return void + * @access protected */ - function OnRefreshForm(&$event) + protected function OnRefreshForm(&$event) { $event->redirect = false; - $item_info = $this->Application->GetVar($event->getPrefixSpecial()); + $item_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); list($id, $fields) = each($item_info); - $object =& $event->getObject( Array('skip_autoload' => true) ); + $object =& $event->getObject( Array ('skip_autoload' => true) ); + /* @var $object kDBItem */ + $object->setID($id); $object->IgnoreValidation = true; $object->SetFieldsFromHash($fields); @@ -1075,36 +1071,42 @@ * Allows to change root password * * @param kEvent $event + * @return void + * @access protected */ - function OnUpdatePassword(&$event) + protected function OnUpdatePassword(&$event) { - $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); - if (!$items_info) return ; + $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); + if ( !$items_info ) { + return; + } + list ($id, $field_values) = each($items_info); $user_id = $this->Application->RecallVar('user_id'); - if ($id == $user_id && ($user_id > 0 || $user_id == USER_ROOT)) { - $user_dummy =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true)); + + if ( $id == $user_id && ($user_id > 0 || $user_id == USER_ROOT) ) { + $user_dummy =& $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true)); /* @var $user_dummy kDBItem */ $user_dummy->Load($id); - $status_field = array_shift($this->Application->getUnitOption($event->Prefix, 'StatusField')); + $status_field = array_shift( $this->Application->getUnitOption($event->Prefix, 'StatusField') ); - if ($user_dummy->GetDBField($status_field) != STATUS_ACTIVE) { + if ( $user_dummy->GetDBField($status_field) != STATUS_ACTIVE ) { // not active user is not allowed to update his record (he could not activate himself manually) - return false; + return ; } } - if ($user_id == USER_ROOT) { - $object =& $event->getObject( Array('skip_autoload' => true) ); + if ( $user_id == USER_ROOT ) { + $object =& $event->getObject(Array ('skip_autoload' => true)); /* @var $object UsersItem */ // put salt to user's config $field_options = $object->GetFieldOptions('RootPassword'); $field_options['salt'] = 'b38'; // this is internal hack to allow root/root passwords for dev - if ($this->Application->isDebugMode() && $field_values['RootPassword'] == 'root') { + if ( $this->Application->isDebugMode() && $field_values['RootPassword'] == 'root' ) { $field_options['min_length'] = 4; } @@ -1116,65 +1118,35 @@ $this->RemoveRequiredFields($object); $object->SetDBField('RootPassword', $this->Application->ConfigValue('RootPass')); - $object->SetFieldsFromHash($field_values); - $object->setID(-1); - $status = $object->Validate(); - if ($status) { + $object->SetFieldsFromHash($field_values); + $object->setID(-1); + + if ( $object->Validate() ) { // validation on, password match too - $fields_hash = Array ( - 'VariableValue' => $object->GetDBField('RootPassword') - ); + $fields_hash = Array ('VariableValue' => $object->GetDBField('RootPassword')); $conf_table = $this->Application->getUnitOption('conf', 'TableName'); $this->Conn->doUpdate($fields_hash, $conf_table, 'VariableName = "RootPass"'); $event->SetRedirectParam('opener', 'u'); } else { $event->status = kEvent::erFAIL; $event->redirect = false; - return; + return ; } } else { $object =& $event->getObject(); $object->SetFieldsFromHash($field_values); - if (!$object->Update()) { + if ( !$object->Update() ) { $event->status = kEvent::erFAIL; $event->redirect = false; } } $event->SetRedirectParam('opener', 'u'); - $event->redirect == true; } - /** - * Apply custom processing to item - * - * @param kEvent $event - */ - function customProcessing(&$event, $type) - { - if ($event->Name == 'OnCreate' && $type == 'before') { - $object =& $event->getObject(); - /* @var $object kDBItem */ - - // if auto password has not been set already - store real one - to be used in email events - if (!$this->Application->GetVar('user_password')) { - $this->Application->SetVar('user_password', $object->GetDirtyField('Password')); - $object->SetDBField('Password_plain', $object->GetDirtyField('Password')); - } - - // validate here, because subscribing procedure should not validate captcha code - if ($this->Application->ConfigValue('RegistrationCaptcha')) { - $captcha_helper =& $this->Application->recallObject('CaptchaHelper'); - /* @var $captcha_helper kCaptchaHelper */ - - $captcha_helper->validateCode($event, false); - } - } - } - function OnMassResetSettings(&$event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { @@ -1243,7 +1215,7 @@ * * @param kEvent $event */ - function afterItemChanged(&$event) + protected function afterItemChanged(&$event) { $this->saveUserImages($event); @@ -1263,16 +1235,17 @@ * Stores user's original Status before overwriting with data from temp table * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeDeleteFromLive(&$event) + protected function OnBeforeDeleteFromLive(&$event) { - $user_status = $this->Application->GetVar('user_status'); - if (!$user_status) { - $user_status = Array (); - } + parent::OnBeforeDeleteFromLive($event); $user_id = $event->getEventParam('id'); - if ($user_id > 0) { + $user_status = $this->Application->GetVar('user_status', Array ()); + + if ( $user_id > 0 ) { $user_status[$user_id] = $this->getUserStatus($user_id); $this->Application->SetVar('user_status', $user_status); } @@ -1375,7 +1348,8 @@ { parent::OnAfterConfigRead($event); - $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); + $forms = $this->Application->getUnitOption($event->Prefix, 'Forms'); + $form_fields =& $forms['default']['Fields']; // 1. arrange user registration countries $site_helper =& $this->Application->recallObject('SiteHelper'); @@ -1389,15 +1363,15 @@ if ($first_country) { // update user country dropdown sql - $fields['Country']['options_sql'] = preg_replace('/ORDER BY (.*)/', 'ORDER BY IF (CountryStateId = '.$first_country.', 1, 0) DESC, \\1', $fields['Country']['options_sql']); + $form_fields['Country']['options_sql'] = preg_replace('/ORDER BY (.*)/', 'ORDER BY IF (CountryStateId = '.$first_country.', 1, 0) DESC, \\1', $form_fields['Country']['options_sql']); } $max_username = $this->Application->ConfigValue('MaxUserName'); $fields['Login']['min_len'] = $this->Application->ConfigValue('Min_UserName'); $fields['Login']['max_len'] = $max_username ? $max_username : 255; // 2. set default user registration group - $fields['PrimaryGroupId']['default'] = $this->Application->ConfigValue('User_NewGroup'); + $form_fields['PrimaryGroupId']['default'] = $this->Application->ConfigValue('User_NewGroup'); // 3. allow avatar upload on Front-End $file_helper =& $this->Application->recallObject('FileHelper'); @@ -1407,7 +1381,7 @@ if ($this->Application->isAdminUser) { // 4. when in administrative console, then create all users with Active status - $fields['Status']['default'] = STATUS_ACTIVE; + $form_fields['Status']['default'] = STATUS_ACTIVE; // 5. remove groups tab on editing forms when AdvancedUserManagement config variable not set if (!$this->Application->ConfigValue('AdvancedUserManagement')) { @@ -1430,10 +1404,10 @@ if ( !$this->Application->ConfigValue('Email_As_Login') ) { // Login becomes required only, when it's used in registration process - $fields['Login']['required'] = 1; + $form_fields['Login']['required'] = 1; } - $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); + $this->Application->setUnitOption($event->Prefix, 'Forms', $forms); } /** @@ -1460,9 +1434,13 @@ * When cloning users, reset password (set random) * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeClone(&$event) + protected function OnBeforeClone(&$event) { + parent::OnBeforeClone($event); + $object =& $event->getObject(); /* @var $object UsersItem */ @@ -1539,8 +1517,10 @@ * Loads user images * * @param kEvent $event + * @return void + * @access protected */ - function OnAfterItemLoad(&$event) + protected function OnAfterItemLoad(&$event) { parent::OnAfterItemLoad($event); @@ -1582,21 +1562,23 @@ * Makes password required for new users * * @param kEvent $event + * @return void + * @access protected */ function OnPreCreate(&$event) { parent::OnPreCreate($event); - if ($event->status != kEvent::erSUCCESS) { - return ; + if ( $event->status != kEvent::erSUCCESS ) { + return; } $object =& $event->getObject(); /* @var $object kDBItem */ $user_type = $this->Application->GetVar('user_type'); - if ($user_type) { + if ( $user_type ) { $object->SetDBField('UserType', $user_type); if ( $user_type == UserType::ADMIN ) { @@ -1616,41 +1598,27 @@ * * @param kEvent $event */ - function OnNew(&$event) - { - parent::OnNew($event); - - if ($event->status == kEvent::erSUCCESS) { - $this->_makePasswordRequired($event); - } - } - - /** - * Makes password required for new users - * - * @param kEvent $event - */ function _makePasswordRequired(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $required_fields = Array ('Password', 'Password_plain', 'VerifyPassword', 'VerifyPassword_plain'); - foreach ($required_fields as $required_field) { - $object->setRequired($required_field); - } + $object->setRequired($required_fields); } /** * 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 < 0) { + if ( $id < 0 ) { // when root, guest and so on $object =& $event->getObject(); Index: branches/5.2.x/core/kernel/kbase.php =================================================================== diff -u -N -r14244 -r14596 --- branches/5.2.x/core/kernel/kbase.php (.../kbase.php) (revision 14244) +++ branches/5.2.x/core/kernel/kbase.php (.../kbase.php) (revision 14596) @@ -1,6 +1,6 @@ populateMultiLangFields = $populate_ml_fields; @@ -420,6 +435,7 @@ $this->IDField = $this->Application->getUnitOption($this->Prefix, 'IDField'); $this->TableName = $this->Application->getUnitOption($this->Prefix, 'TableName'); + $this->initForm($form_name); $this->defineFields(); $this->ApplyFieldModifiers(); // should be called only after all fields definitions been set @@ -432,26 +448,78 @@ } /** + * Adjusts object accoding to given form name + * + */ + protected function initForm($form_name = null) + { + $forms = $this->Application->getUnitOption($this->Prefix, 'Forms', Array ()); + + $this->formName = $form_name; + $this->formConfig = isset($forms['default']) ? $forms['default'] : Array (); + + if ( !$this->formName ) { + return ; + } + + if ( !isset($forms[$this->formName]) ) { + trigger_error('Form "' . $this->formName . '" isn\'t declared in "' . $this->Prefix . '" unit config.', E_USER_NOTICE); + } + else { + $this->formConfig = kUtil::array_merge_recursive($this->formConfig, $forms[$this->formName]); + } + } + + /** * Add field definitions from all possible sources * Used field sources: database fields, custom fields, virtual fields, calculated fields, aggregated calculated fields * * @access protected */ protected function defineFields() { - $this->Fields = $this->Application->getUnitOption($this->Prefix, 'Fields', Array ()); - $this->customFields = $this->Application->getUnitOption($this->Prefix, 'CustomFields', Array()); + $this->Fields = $this->getFormOption('Fields', Array ()); + $this->customFields = $this->getFormOption('CustomFields', Array()); - $this->setVirtualFields( $this->Application->getUnitOption($this->Prefix, 'VirtualFields', Array ()) ); + $this->setVirtualFields( $this->getFormOption('VirtualFields', Array ()) ); - $calculated_fields = $this->Application->getUnitOption($this->Prefix, 'CalculatedFields', Array()); + $calculated_fields = $this->getFormOption('CalculatedFields', Array()); $this->CalculatedFields = $this->getFieldsBySpecial($calculated_fields); - $aggregated_calculated_fields = $this->Application->getUnitOption($this->Prefix, 'AggregatedCalculatedFields', Array()); + $aggregated_calculated_fields = $this->getFormOption('AggregatedCalculatedFields', Array()); $this->AggregatedCalculatedFields = $this->getFieldsBySpecial($aggregated_calculated_fields); } /** + * Returns form name, used for validation + * + * @return string + */ + public function getFormName() + { + return $this->formName; + } + + /** + * Reads unit (specified by $prefix) option specified by $option and applies form change to it + * + * @param string $option + * @param mixed $default + * @return string + * @access public + */ + public function getFormOption($option, $default = false) + { + $ret = $this->Application->getUnitOption($this->Prefix, $option, $default); + + if ( isset($this->formConfig[$option]) ) { + $ret = kUtil::array_merge_recursive($ret, $this->formConfig[$option]); + } + + return $ret; + } + + /** * Only exteracts fields, that match current object Special * * @param Array $fields @@ -537,38 +605,41 @@ /** * Override field options with ones defined in submit via "field_modfiers" array (common for all prefixes) * - * @author Alex + * @param Array $field_modifiers + * @return void * @access public + * @author Alex */ public function ApplyFieldModifiers($field_modifiers = null) { - $allowed_modifiers = Array('required', 'multiple'); + $allowed_modifiers = Array ('required', 'multiple'); - if ($this->Application->isAdminUser) { + if ( $this->Application->isAdminUser ) { // can change upload dir on the fly (admin only!) $allowed_modifiers[] = 'upload_dir'; } - if (!isset($field_modifiers)) { + if ( !isset($field_modifiers) ) { $field_modifiers = $this->Application->GetVar('field_modifiers'); - if (!$field_modifiers) { + if ( !$field_modifiers ) { // no field modifiers - return false; + return ; } $field_modifiers = getArrayValue($field_modifiers, $this->getPrefixSpecial()); } - if (!$field_modifiers) { + if ( !$field_modifiers ) { // no field modifiers for current prefix_special - return false; + return ; } - foreach ($field_modifiers as $field => $field_options) - { - foreach ($field_options as $option_name => $option_value) - { - if ( !in_array(strtolower($option_name), $allowed_modifiers) ) continue; + foreach ($field_modifiers as $field => $field_options) { + foreach ($field_options as $option_name => $option_value) { + if ( !in_array(strtolower($option_name), $allowed_modifiers) ) { + continue; + } + $this->Fields[$field][$option_name] = $option_value; } } @@ -722,13 +793,14 @@ */ public function GetField($name, $format = null) { - $options = $this->GetFieldOptions($name); + $formatter_class = $this->GetFieldOption($name, 'formatter'); - if (array_key_exists('formatter', $options)) { - $formatter_class = $options['formatter']; + if ( $formatter_class ) { $value = ($formatter_class == 'kMultiLanguage') && !preg_match('/^l[0-9]+_/', $name) ? '' : $this->GetDBField($name); $formatter =& $this->Application->recallObject($formatter_class); + /* @var $formatter kFormatter */ + return $formatter->Format($value, $name, $this, $format); } @@ -766,16 +838,19 @@ * * @param Array $fields * @access public - * @todo maybe should not be publically accessable + * @todo Maybe should not be publicly accessible */ public function UpdateFormattersSubFields($fields = null) { - if (!is_array($fields)) { + if ( !is_array($fields) ) { $fields = array_keys($this->Fields); } + foreach ($fields as $field) { if ( isset($this->Fields[$field]['formatter']) ) { $formatter =& $this->Application->recallObject($this->Fields[$field]['formatter']); + /* @var $formatter kFormatter */ + $formatter->UpdateSubFields($field, $this->GetDBField($field), $this->Fields[$field], $this); } } Index: branches/5.2.x/core/kernel/utility/formatters/date_formatter.php =================================================================== diff -u -N -r14572 -r14596 --- branches/5.2.x/core/kernel/utility/formatters/date_formatter.php (.../date_formatter.php) (revision 14572) +++ branches/5.2.x/core/kernel/utility/formatters/date_formatter.php (.../date_formatter.php) (revision 14596) @@ -1,6 +1,6 @@ $field_name, 'formatter' => 'kDateFormatter', 'format' => $display_format['date'], 'input_format' => $input_format['date']); - $copy_options = Array ('default', 'required', 'use_timezone', 'error_msgs'); + $copy_options = Array ('type', 'default', 'required', 'use_timezone', 'error_msgs'); foreach ($copy_options as $copy_option) { if (array_key_exists($copy_option, $field_options) ) { $opts[$copy_option] = $field_options[$copy_option]; @@ -157,15 +157,27 @@ $object->setVirtualFields($add_fields); } - function UpdateSubFields($field, $value, &$options, &$object) + /** + * Used for split fields like timestamp -> date, time + * Called from DBItem to update sub fields values after loading item + * + * @param string $field + * @param string $value + * @param Array $options + * @param kDBItem $object + * @return void + * @access public + */ + public function UpdateSubFields($field, $value, &$options, &$object) { - if ( $sub_fields = getArrayValue($options, 'sub_fields') ) { - if( isset($value) && $value ) - { - $object->SetDBField( $sub_fields['date'], $value ); - $object->SetDBField( $sub_fields['time'], $value ); - } + $sub_fields = getArrayValue($options, 'sub_fields'); + + if ( !$sub_fields || !isset($value) || !$value ) { + return ; } + + $object->SetDBField($sub_fields['date'], $value); + $object->SetDBField($sub_fields['time'], $value); } /** @@ -210,7 +222,15 @@ } } -//function Format($value, $options, &$errors) + /** + * Formats value of a given field + * + * @param string $value + * @param string $field_name + * @param kDBItem|kDBList $object + * @param string $format + * @return string + */ function Format($value, $field_name, &$object, $format=null) { if ( is_null($value) ) return ''; @@ -331,9 +351,10 @@ * @param mixed $value * @param string $field_name * @param kDBItem $object - * @return string + * @return mixed + * @access public */ - function Parse($value, $field_name, &$object) + public function Parse($value, $field_name, &$object) { $options = $object->GetFieldOptions($field_name); Index: branches/5.2.x/core/kernel/db/db_tag_processor.php =================================================================== diff -u -N -r14585 -r14596 --- branches/5.2.x/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 14585) +++ branches/5.2.x/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 14596) @@ -1,6 +1,6 @@ getCurrentRecord(); } - function MoreLink($params) + /** + * Renders given block name, when there there is more data in list, then are displayed right now + * + * @param Array $params + * @return string + * @access protected + */ + protected function MoreLink($params) { $per_page = $this->SelectParam($params, 'per_page,max_items'); - if ($per_page !== false) { + if ( $per_page !== false ) { $params['per_page'] = $per_page; } @@ -620,13 +629,13 @@ $has_next_page = $list->GetPerPage() < $list->GetRecordsCount(); } - if ($has_next_page) { - $block_params = Array ( - 'name' => $this->SelectParam($params, 'render_as,block'), - ); + if ( $has_next_page ) { + $block_params = Array ('name' => $this->SelectParam($params, 'render_as,block')); return $this->Application->ParseBlock($block_params); } + + return ''; } function PageLink($params) @@ -755,12 +764,19 @@ return $iso; } + /** + * Convert primary currency to selected (if they are the same, converter will just return) + * + * @param float $value + * @param string $iso + * @return float + */ function ConvertCurrency($value, $iso) { $converter =& $this->Application->recallObject('kCurrencyRates'); - // convery primary currency to selected (if they are the same, converter will just return) - $value = $converter->Convert($value, 'PRIMARY', $iso); - return $value; + /* @var $converter kCurrencyRates */ + + return $converter->Convert($value, 'PRIMARY', $iso); } function AddCurrencySymbol($value, $iso) @@ -973,10 +989,14 @@ // $object =& $this->getObject($params); - $dst_field = $this->SelectParam($params, 'name,field'); + /* @var $object kDBItem */ + $dst_field = $this->SelectParam($params, 'name,field'); list($prefix_special, $src_field) = explode(':', $params['src']); + $src_object =& $this->Application->recallObject($prefix_special); + /* @var $src_object kDBItem */ + $object->SetDBField($dst_field, $src_object->GetDBField($src_field)); } @@ -996,61 +1016,77 @@ function Error($params) { - $field = $this->SelectParam($params, 'name,field'); $object =& $this->getObject($params); - $msg = $object->GetErrorMsg($field, false); - return $msg; + /* @var $object kDBItem */ + + $field = $this->SelectParam($params, 'name,field'); + + return $object->GetErrorMsg($field, false); } function HasError($params) { - if ($params['field'] == 'any') - { + if ($params['field'] == 'any') { $object =& $this->getObject($params); + /* @var $object kDBItem */ $skip_fields = array_key_exists('except', $params) ? $params['except'] : false; $skip_fields = $skip_fields ? explode(',', $skip_fields) : Array(); return $object->HasErrors($skip_fields); } - else - { - $fields = $this->SelectParam($params, 'field,fields'); - $fields = explode(',', $fields); + else { $res = false; - foreach($fields as $field) - { + $fields = explode(',', $this->SelectParam($params, 'field,fields')); + + foreach ($fields as $field) { + // call kDBTagProcessor::Error instead of kDBItem::GetErrorPseudo to have ability to override Error tag $params['field'] = $field; $res = $res || ($this->Error($params) != ''); } + return $res; } } - function ErrorWarning($params) + /** + * Renders error message block, when there are errors on a form + * + * @param Array $params + * @return string + * @access protected + */ + protected function ErrorWarning($params) { - if (!isset($params['field'])) { + if ( !isset($params['field']) ) { $params['field'] = 'any'; } - if ($this->HasError($params)) { + + if ( $this->HasError($params) ) { $params['prefix'] = $this->getPrefixSpecial(); + return $this->Application->ParseBlock($params); } + + return ''; } function IsRequired($params) { - $field = $params['field']; $object =& $this->getObject($params); + /* @var $object kDBItem */ + $field = $params['field']; $formatter_class = $object->GetFieldOption($field, 'formatter'); - if ($formatter_class == 'kMultiLanguage') - { + + if ( $formatter_class == 'kMultiLanguage' ) { $formatter =& $this->Application->recallObject($formatter_class); + /* @var $formatter kMultiLanguage */ + $field = $formatter->LangFieldName($field); } - return $object->GetFieldOption($field, 'required'); + return $object->isRequired($field); } function FieldOption($params) @@ -1062,10 +1098,18 @@ return $ret; } - function PredefinedOptions($params) + /** + * Prints list a all possible field options + * + * @param Array $params + * @return string + * @access protected + */ + protected function PredefinedOptions($params) { $object =& $this->getObject($params); - + /* @var $object kDBList */ + $field = $params['field']; $value = array_key_exists('value', $params) ? $params['value'] : $object->GetDBField($field); $field_options = $object->GetFieldOptions($field); @@ -1151,21 +1195,23 @@ $object =& $this->getObject($params); $options = $object->GetFieldOptions($field); - - $format = $options[ $this->SelectParam($params, 'input_format') ? 'input_format' : 'format' ]; - + $format = $options[$this->SelectParam($params, 'input_format') ? 'input_format' : 'format']; $formatter_class = array_key_exists('formatter', $options) ? $options['formatter'] : false; - if ($formatter_class) { + if ( $formatter_class ) { $formatter =& $this->Application->recallObject($formatter_class); + /* @var $formatter kFormatter */ + $human_format = array_key_exists('human', $params) ? $params['human'] : false; $edit_size = array_key_exists('edit_size', $params) ? $params['edit_size'] : false; $sample = array_key_exists('sample', $params) ? $params['sample'] : false; - if ($sample) { + + if ( $sample ) { return $formatter->GetSample($field, $options, $object); } - elseif ($human_format || $edit_size) { + elseif ( $human_format || $edit_size ) { $format = $formatter->HumanFormat($format); + return $edit_size ? strlen($format) : $format; } } @@ -1380,7 +1426,7 @@ { $object =& $this->getObject($params); /* @var $object kDBItem */ - + $field = $this->SelectParam($params, 'name,field'); $formatter_class = $object->GetFieldOption($field, 'formatter'); @@ -1518,38 +1564,53 @@ } /** - * Get's information of sorting field at "pos" position, + * Gets information of sorting field at "pos" position, * like sorting field name (type="field") or sorting direction (type="direction") * * @param Array $params - * @return mixed + * @return string + * @access protected */ - function OrderInfo($params) + protected function OrderInfo($params) { $user_sorting_start = $this->getUserSortIndex() + --$params['pos']; $list =& $this->GetList($params); - if($params['type'] == 'field') return $list->GetOrderField($user_sorting_start); - if($params['type'] == 'direction') return $list->GetOrderDirection($user_sorting_start); + if ( $params['type'] == 'field' ) { + return $list->GetOrderField($user_sorting_start); + } + + if ( $params['type'] == 'direction' ) { + return $list->GetOrderDirection($user_sorting_start); + } + + return ''; } /** * Checks if sorting field/direction matches passed field/direction parameter * * @param Array $params * @return bool + * @access protected */ - function IsOrder($params) + protected function IsOrder($params) { $params['type'] = isset($params['field']) ? 'field' : 'direction'; $value = $this->OrderInfo($params); - if( isset($params['field']) ) return $params['field'] == $value; - if( isset($params['direction']) ) return $params['direction'] == $value; + if ( isset($params['field']) ) { + return $params['field'] == $value; + } + elseif ( isset($params['direction']) ) { + return $params['direction'] == $value; + } + + return false; } /** - * Returns list perpage + * Returns list per-page * * @param Array $params * @return int @@ -1693,20 +1754,22 @@ $grids = $this->Application->getUnitOption($this->Prefix, 'Grids'); $grid = $grids[ $params['grid'] ]; - if (!array_key_exists('Icons', $grid)) { + if ( !isset($grid['Icons']) ) { return ''; } $icons = $grid['Icons']; - if (array_key_exists('name', $params)) { + if ( isset($params['name']) ) { $icon_name = $params['name']; - return array_key_exists($icon_name, $icons) ? $icons[$icon_name] : ''; + + return isset($icons[$icon_name]) ? $icons[$icon_name] : ''; } - $status_fields = $this->Application->getUnitOption($this->Prefix, 'StatusField'); + $status_fields = $this->Application->getUnitOption($this->Prefix, 'StatusField', Array ()); + /* @var $status_fields Array */ - if (!$status_fields) { + if ( !$status_fields ) { return $icons['default']; } @@ -1721,7 +1784,7 @@ $icon = rtrim($icon, '_'); - return array_key_exists($icon, $icons) ? $icons[$icon] : $icons['default']; + return isset($icons[$icon]) ? $icons[$icon] : $icons['default']; } /** @@ -1758,9 +1821,10 @@ $prefixes = array_key_exists('prefixes', $title_info) ? $title_info['prefixes'] : false; $all_tag_params = array_key_exists('tag_params', $title_info) ? $title_info['tag_params'] : false; - + /* @var $prefixes Array */ + if ($prefixes) { - // extract tag_perams passed directly to SectionTitle tag for specific prefix + // extract tag_params passed directly to SectionTitle tag for specific prefix foreach ($params as $tp_name => $tp_value) { if (preg_match('/(.*)\[(.*)\]/', $tp_name, $regs)) { $all_tag_params[ $regs[1] ][ $regs[2] ] = $tp_value; @@ -1845,24 +1909,33 @@ return $title; } - function getInfo(&$object, $info_type) + /** + * Returns information about list + * + * @param kDBList $object + * @param string $info_type + * @return string + * @access protected + */ + protected function getInfo(&$object, $info_type) { - switch ($info_type) - { + switch ( $info_type ) { case 'titlefield': - $field = $this->Application->getUnitOption($object->Prefix,'TitleField'); + $field = $this->Application->getUnitOption($object->Prefix, 'TitleField'); return $field !== false ? $object->GetField($field) : 'TitleField Missing'; break; case 'recordcount': - $of_phrase = $this->Application->Phrase('la_of'); - return $object->GetRecordsCount(false) != $object->GetRecordsCount() ? $object->GetRecordsCount().' '.$of_phrase.' '.$object->GetRecordsCount(false) : $object->GetRecordsCount(); + if ( $object->GetRecordsCount(false) != $object->GetRecordsCount() ) { + $of_phrase = $this->Application->Phrase('la_of'); + return $object->GetRecordsCount() . ' ' . $of_phrase . ' ' . $object->GetRecordsCount(false); + } + + return $object->GetRecordsCount(); break; - - default: - return $object->GetField($info_type); - break; } + + return $object->GetField($info_type); } function GridInfo($params) @@ -2013,34 +2086,35 @@ } /** - * If data was modfied & is in TempTables mode, then parse block with name passed; + * If data was modified & is in TempTables mode, then parse block with name passed; * remove modification mark if not in TempTables mode * * @param Array $params * @return string - * @access public - * @author Alexey + * @access protected */ - function SaveWarning($params) + protected function SaveWarning($params) { $main_prefix = array_key_exists('main_prefix', $params) ? $params['main_prefix'] : false; - if ($main_prefix) { + + if ( $main_prefix ) { $top_prefix = $main_prefix; } else { $top_prefix = $this->Application->GetTopmostPrefix($this->Prefix); } - $temp_tables = substr($this->Application->GetVar($top_prefix.'_mode'), 0, 1) == 't'; - $modified = $this->Application->RecallVar($top_prefix.'_modified'); + $temp_tables = substr($this->Application->GetVar($top_prefix . '_mode'), 0, 1) == 't'; + $modified = $this->Application->RecallVar($top_prefix . '_modified'); - if ($temp_tables && $modified) { + if ( $temp_tables && $modified ) { $block_params = $this->prepareTagParams($params); $block_params['name'] = $this->SelectParam($params, 'render_as,name'); $block_params['edit_mode'] = $temp_tables ? 1 : 0; return $this->Application->ParseBlock($block_params); } - $this->Application->RemoveVar($top_prefix.'_modified'); + + $this->Application->RemoveVar($top_prefix . '_modified'); return ''; } @@ -2081,36 +2155,35 @@ * * @param Array $params * @return string + * @access protected */ - function SearchField($params) // RangeValue + protected function SearchField($params) // RangeValue { $field = $this->SelectParam($params, 'field,name'); - $view_name = $this->Application->RecallVar($this->getPrefixSpecial().'_current_view'); - $custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial().'_custom_filter.'.$view_name/*, ALLOW_DEFAULT_SETTINGS*/); - $custom_filter = $custom_filter ? unserialize($custom_filter) : Array(); + $view_name = $this->Application->RecallVar($this->getPrefixSpecial() . '_current_view'); + $custom_filter = $this->Application->RecallPersistentVar($this->getPrefixSpecial() . '_custom_filter.' . $view_name /*, ALLOW_DEFAULT_SETTINGS*/); + $custom_filter = $custom_filter ? unserialize($custom_filter) : Array (); - if (isset($custom_filter[ $params['grid'] ][$field])) { - $ret = $custom_filter[ $params['grid'] ][$field][ $params['filter_type'] ]['submit_value']; - if (isset($params['type'])) { - $ret = $ret[ $params['type'] ]; + if ( isset($custom_filter[$params['grid']][$field]) ) { + $ret = $custom_filter[$params['grid']][$field][$params['filter_type']]['submit_value']; + if ( isset($params['type']) ) { + $ret = $ret[$params['type']]; } - if (array_key_exists('formatted', $params) && $params['formatted']) { + if ( array_key_exists('formatted', $params) && $params['formatted'] ) { $object =& $this->GetList($params); - $field_options = $object->GetFieldOptions($field); + $formatter_class = $object->GetFieldOption($field, 'formatter'); - if (array_key_exists('formatter', $field_options)) { - $formatter_class = $field_options['formatter']; - + if ( $formatter_class ) { $formatter =& $this->Application->recallObject($formatter_class); /* @var $formatter kFormatter */ $ret = $formatter->Format($ret, $field, $object); } } - if (!array_key_exists('no_special', $params) || !$params['no_special']) { + if ( !array_key_exists('no_special', $params) || !$params['no_special'] ) { $ret = htmlspecialchars($ret); } @@ -2151,6 +2224,8 @@ if ($formatter_class) { $formatter =& $this->Application->recallObject($formatter_class); + /* @var $formatter kFormatter */ + $human_format = array_key_exists('human', $params) ? $params['human'] : false; $edit_size = array_key_exists('edit_size', $params) ? $params['edit_size'] : false; $sample = array_key_exists('sample', $params) ? $params['sample'] : false; @@ -2170,20 +2245,21 @@ /** * Returns error of range field * - * @param unknown_type $params - * @return unknown + * @param Array $params + * @return string + * @access protected */ - function SearchError($params) + protected function SearchError($params) { $field = $this->SelectParam($params, 'field,name'); - $error_var_name = $this->getPrefixSpecial().'_'.$field.'_error'; + $error_var_name = $this->getPrefixSpecial() . '_' . $field . '_error'; $pseudo = $this->Application->RecallVar($error_var_name); - if ($pseudo) { + if ( $pseudo ) { $this->Application->RemoveVar($error_var_name); } - $object =& $this->Application->recallObject($this->Prefix.'.'.$this->Special.'-item', null, Array('skip_autoload' => true)); + $object =& $this->Application->recallObject($this->Prefix . '.' . $this->Special . '-item', null, Array ('skip_autoload' => true)); /* @var $object kDBItem */ $object->SetError($field, $pseudo); @@ -2253,7 +2329,8 @@ function ExportStatus($params) { $export_object =& $this->Application->recallObject('CatItemExportHelper'); - + /* @var $export_object kCatDBItemExportHelper */ + $event = new kEvent($this->getPrefixSpecial().':OnDummy'); $action_method = 'perform'.ucfirst($this->Special); @@ -2283,16 +2360,19 @@ * Returns path where exported category items should be saved * * @param Array $params + * @return string + * @access protected */ - function ExportPath($params) + protected function ExportPath($params) { - $export_options = unserialize($this->Application->RecallVar($this->getPrefixSpecial().'_options')); + $export_options = unserialize($this->Application->RecallVar($this->getPrefixSpecial() . '_options')); $extension = $export_options['ExportFormat'] == 1 ? 'csv' : 'xml'; $filename = preg_replace('/(.*)\.' . $extension . '$/', '\1', $export_options['ExportFilename']) . '.' . $extension; $path = EXPORT_PATH . '/'; - if (array_key_exists('as_url', $params) && $params['as_url']) { - $path = str_replace( FULL_PATH . '/', $this->Application->BaseURL(), $path); + + if ( array_key_exists('as_url', $params) && $params['as_url'] ) { + $path = str_replace(FULL_PATH . '/', $this->Application->BaseURL(), $path); } return $path . $filename; @@ -2444,19 +2524,20 @@ * * @param Array $params * @return string + * @access protected */ - function ItemLink($params) + protected function ItemLink($params) { $object =& $this->getObject($params); + /* @var $object kDBItem */ - if (!isset($params['pass'])) { + if ( !isset($params['pass']) ) { $params['pass'] = 'm'; } - $params[$object->getPrefixSpecial().'_id'] = $object->GetID(); + $params[ $object->getPrefixSpecial() . '_id' ] = $object->GetID(); - $m =& $this->Application->recallObject('m_TagProcessor'); - return $m->t($params); + return $this->Application->ProcessParsedTag('m', 'T', $params); } /** @@ -2467,8 +2548,8 @@ function PresetFormFields($params) { $prefix = $this->getPrefixSpecial(); - if (!$this->Application->GetVar($prefix.'_event')) { - $this->Application->HandleEvent(new kEvent($prefix.':OnNew')); + if ( !$this->Application->GetVar($prefix . '_event') ) { + $this->Application->HandleEvent(new kEvent($prefix . ':OnNew')); } } @@ -2574,12 +2655,13 @@ * * @param Array $params * @return string + * @access protected */ - function PrintEditTabs($params) + protected function PrintEditTabs($params) { $edit_tabs = $this->getEditTabs($params['preset_name']); - if (!$edit_tabs) { - return ; + if ( !$edit_tabs ) { + return ''; } usort($edit_tabs, Array (&$this, 'sortEditTabs')); @@ -2766,4 +2848,40 @@ return $value; } + + /** + * Returns/sets form name for current object + * + * @param Array $params + * @return string + */ + function FormName($params) + { + $form_name = $this->SelectParam($params, 'name,form,form_name'); + + if ( $form_name ) { + $prefix = $this->getPrefixSpecial(); + + if ( $this->Application->hasObject( $this->getPrefixSpecial() ) ) { + $object =& $this->getObject($params); + /* @var $object kDBItem */ + + if ( $object->getFormName() != $form_name ) { + trigger_error('Setting form to "' . $form_name . '" failed, since object "' . $this->getPrefixSpecial() . '" is created before FormName tag (e.g. in event or another tag).', E_USER_WARNING); + } + } + else { + $forms = $this->Application->GetVar('forms', Array ()); + $forms[ $this->getPrefixSpecial() ] = $form_name; + $this->Application->SetVar('forms', $forms); + } + + return ''; + } + + $object =& $this->getObject($params); + /* @var $object kDBItem */ + + return $object->getFormName(); + } } \ No newline at end of file Index: branches/5.2.x/core/units/phrases/phrases_event_handler.php =================================================================== diff -u -N -r14585 -r14596 --- branches/5.2.x/core/units/phrases/phrases_event_handler.php (.../phrases_event_handler.php) (revision 14585) +++ branches/5.2.x/core/units/phrases/phrases_event_handler.php (.../phrases_event_handler.php) (revision 14596) @@ -1,6 +1,6 @@ Special == 'import' || $event->Special == 'export') { $this->RemoveRequiredFields($object); - $object->setRequired('LangFile'); - $object->setRequired('PhraseType'); - $object->setRequired('Module'); + $object->setRequired( Array ('LangFile', 'PhraseType', 'Module') ); // allow multiple phrase types to be selected during import/export - $field_options = $object->GetFieldOptions('PhraseType'); - $field_options['type'] = 'string'; - $object->SetFieldOptions('PhraseType', $field_options); + $object->SetFieldOption('PhraseType', 'type', 'string'); } } /** * Allow to create phrases from front end in debug mode with DBG_PHRASES constant set * * @param kEvent $event + * @return bool + * @access public */ - function CheckPermission(&$event) + public function CheckPermission(&$event) { if (!$this->Application->isAdmin && $this->Application->isDebugMode(false) && kUtil::constOn('DBG_PHRASES')) { $allow_events = Array ('OnCreate', 'OnUpdate'); @@ -217,8 +216,10 @@ * Set last change info, when phrase is created * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemCreate(&$event) + protected function OnBeforeItemCreate(&$event) { parent::OnBeforeItemCreate($event); @@ -227,15 +228,15 @@ $primary_language_id = $this->Application->GetDefaultLanguageId(); - if (!$object->GetDBField('l' . $primary_language_id . '_Translation')) { + if ( !$object->GetDBField('l' . $primary_language_id . '_Translation') ) { // no translation on primary language -> try to copy from other language $src_languages = Array ('lang_id', 'm_lang'); // editable language, theme language foreach ($src_languages as $src_language) { $src_language = $this->Application->GetVar($src_language); $src_value = $src_language ? $object->GetDBField('l' . $src_language . '_Translation') : false; - if ($src_value) { + if ( $src_value ) { $object->SetDBField('l' . $primary_language_id . '_Translation', $src_value); break; } @@ -249,8 +250,10 @@ * Update last change info, when phrase is updated * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemUpdate(&$event) + protected function OnBeforeItemUpdate(&$event) { parent::OnBeforeItemUpdate($event); Index: branches/5.2.x/core/units/configuration/configuration_tag_processor.php =================================================================== diff -u -N -r14244 -r14596 --- branches/5.2.x/core/units/configuration/configuration_tag_processor.php (.../configuration_tag_processor.php) (revision 14244) +++ branches/5.2.x/core/units/configuration/configuration_tag_processor.php (.../configuration_tag_processor.php) (revision 14596) @@ -1,6 +1,6 @@ GetDBField('Validation'); $field_options = $field_options ? unserialize($field_options) : Array (); - return array_key_exists('required', $field_options) && $field_options['required']; + return isset($field_options['required']) && $field_options['required']; } function Error($params) Index: branches/5.2.x/core/kernel/db/dbitem.php =================================================================== diff -u -N -r14585 -r14596 --- branches/5.2.x/core/kernel/db/dbitem.php (.../dbitem.php) (revision 14585) +++ branches/5.2.x/core/kernel/db/dbitem.php (.../dbitem.php) (revision 14596) @@ -1,6 +1,6 @@ validator) ) { + $validator_class = $this->Application->getUnitOption($this->Prefix, 'ValidatorClass', 'kValidator'); - $this->ErrorMsgs['required'] = '!la_err_required!'; //'Field is required'; - $this->ErrorMsgs['unique'] = '!la_err_unique!'; //'Field value must be unique'; - $this->ErrorMsgs['value_out_of_range'] = '!la_err_value_out_of_range!'; //'Field is out of range, possible values from %s to %s'; - $this->ErrorMsgs['length_out_of_range'] = '!la_err_length_out_of_range!'; //'Field is out of range'; - $this->ErrorMsgs['bad_type'] = '!la_err_bad_type!'; //'Incorrect data format, please use %s'; - $this->ErrorMsgs['invalid_format'] = '!la_err_invalid_format!'; //'Incorrect data format, please use %s'; - $this->ErrorMsgs['bad_date_format'] = '!la_err_bad_date_format!'; //'Incorrect date format, please use (%s) ex. (%s)'; - $this->ErrorMsgs['primary_lang_required'] = '!la_err_primary_lang_required!'; + $this->validator =& $this->Application->makeClass($validator_class); + } + + $this->validator->setDataSource($this); } public function SetDirtyField($field_name, $field_value) @@ -131,14 +123,16 @@ return $value; } - $options = $this->GetFieldOptions($field_name); $res = $value; - if (array_key_exists('formatter', $options)) { - $formatter =& $this->Application->recallObject($options['formatter']); + $formatter = $this->GetFieldOption($field_name, 'formatter'); + + if ( $formatter ) { + $formatter =& $this->Application->recallObject($formatter); /* @var $formatter kFormatter */ $res = $formatter->Format($value, $field_name, $this, $format); } + return $res; } @@ -191,6 +185,8 @@ // kFormatter is always used, to make sure, that numeric value is converted to normal representation // according to regional format, even when formatter is not set (try seting format to 1.234,56 to understand why) $formatter =& $this->Application->recallObject(isset($options['formatter']) ? $options['formatter'] : 'kFormatter'); + /* @var $formatter kFormatter */ + $parsed = $formatter->Parse($value, $name, $this); $this->SetDBField($name,$parsed); @@ -208,48 +204,25 @@ public function SetDBField($name,$value) { $this->FieldValues[$name] = $value; - /*if (isset($this->Fields[$name]['formatter'])) { - $formatter =& $this->Application->recallObject($this->Fields[$name]['formatter']); - $formatter->UpdateSubFields($name, $value, $this->Fields[$name], $this); - }*/ } /** * Set's field error, if pseudo passed not found then create it with message text supplied. - * Don't owerrite existing pseudo translation. + * Don't overwrite existing pseudo translation. * * @param string $field * @param string $pseudo * @param string $error_label + * @param Array $error_params * * @return bool + * @access public */ public function SetError($field, $pseudo, $error_label = null, $error_params = null) { - $error_field = isset($this->Fields[$field]['error_field']) ? $this->Fields[$field]['error_field'] : $field; - if (isset($this->FieldErrors[$error_field]['pseudo'])) { - // don't set more then one error on field - return false; - } + $this->initValidator(); - $this->FieldErrors[$error_field]['pseudo'] = $pseudo; - - if (isset($error_params)) { - if (array_key_exists('value', $error_params)) { - $this->FieldErrors[$error_field]['value'] = $error_params['value']; - unset($error_params['value']); - } - - // additional params, that helps to determine error sources - $this->FieldErrors[$error_field]['params'] = $error_params; - } - - if (isset($error_label) && !isset($this->ErrorMsgs[$pseudo])) { - // label for error (only when not already set) - $this->ErrorMsgs[$pseudo] = (substr($error_label, 0, 1) == '+') ? substr($error_label, 1) : '!'.$error_label.'!'; - } - - return true; + return $this->validator->SetError($field, $pseudo, $error_label, $error_params); } /** @@ -260,7 +233,11 @@ */ public function RemoveError($field) { - unset( $this->FieldErrors[$field] ); + if ( !is_object($this->validator) ) { + return ; + } + + $this->validator->RemoveError($field); } /** @@ -271,11 +248,11 @@ */ public function GetErrorPseudo($field) { - if ( !array_key_exists($field, $this->FieldErrors) ) { + if ( !is_object($this->validator) ) { return ''; } - return array_key_exists('pseudo', $this->FieldErrors[$field]) ? $this->FieldErrors[$field]['pseudo'] : ''; + return $this->validator->GetErrorPseudo($field); } /** @@ -306,81 +283,76 @@ } /** - * Sets item' fields corresponding to elements in passed $hash values. - * - * The function sets current item fields to values passed in $hash, by matching $hash keys with field names - * of current item. If current item' fields are unknown {@link kDBItem::PrepareFields()} is called before acutally setting the fields - * - * @param Array $hash - * @param Array $set_fields Optional param, field names in target object to set, other fields will be skipped - * @access public - */ - public function SetFieldsFromHash($hash, $set_fields = null) + * Sets item' fields corresponding to elements in passed $hash values. + * + * The function sets current item fields to values passed in $hash, by matching $hash keys with field names + * of current item. If current item' fields are unknown {@link kDBItem::PrepareFields()} is called before actually setting the fields + * + * @param Array $hash + * @param Array $set_fields Optional param, field names in target object to set, other fields will be skipped + * @return void + * @access public + */ + public function SetFieldsFromHash($hash, $set_fields = Array ()) { - // used in formatter which work with multiple fields together - foreach($hash as $field_name => $field_value) { - if (is_numeric($field_name) || !array_key_exists($field_name, $this->Fields)) { - continue; - } + if ( !$set_fields ) { + $set_fields = array_keys($hash); + } - if (is_array($set_fields) && !in_array($field_name, $set_fields)) { - continue; - } + $set_fields = array_intersect($set_fields, array_keys($this->Fields)); - $this->SetDirtyField($field_name, $field_value); + // used in formatter which work with multiple fields together + foreach ($set_fields as $field_name) { + $this->SetDirtyField($field_name, $hash[$field_name]); } // formats all fields using associated formatters - foreach ($hash as $field_name => $field_value) - { - if (is_numeric($field_name) || !array_key_exists($field_name, $this->Fields)) { - continue; - } - - if (is_array($set_fields) && !in_array($field_name, $set_fields)) { - continue; - } - - $this->SetField($field_name,$field_value); + foreach ($set_fields as $field_name) { + $this->SetField($field_name, $hash[$field_name]); } } - public function SetDBFieldsFromHash($hash, $set_fields = null) + /** + * Sets object fields from $hash arrat + * @param Array $hash + * @param Array|null $set_fields + * @return void + * @access public + */ + public function SetDBFieldsFromHash($hash, $set_fields = Array ()) { - foreach ($hash as $field_name => $field_value) { - if (is_numeric($field_name) || !array_key_exists($field_name, $this->Fields)) { - continue; - } + if ( !$set_fields ) { + $set_fields = array_keys($hash); + } - if (is_array($set_fields) && !in_array($field_name, $set_fields)) { - continue; - } + $set_fields = array_intersect($set_fields, array_keys($this->Fields)); - $this->SetDBField($field_name, $field_value); + foreach ($set_fields as $field_name) { + $this->SetDBField($field_name, $hash[$field_name]); } } /** - * Returns part of SQL WHERE clause identifing the record, ex. id = 25 - * - * @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method - * @param Array $keys_hash alternative, then item id, keys hash to load item by - * @return void - * @see kDBItem::Load() - * @see kDBItem::Update() - * @see kDBItem::Delete() - * @access protected - */ - protected function GetKeyClause($method=null, $keys_hash = null) + * Returns part of SQL WHERE clause identifying the record, ex. id = 25 + * + * @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method + * @param Array $keys_hash alternative, then item id, keys hash to load item by + * @see kDBItem::Load() + * @see kDBItem::Update() + * @see kDBItem::Delete() + * @return string + * @access protected + */ + protected function GetKeyClause($method = null, $keys_hash = null) { - if (!isset($keys_hash)) { + if ( !isset($keys_hash) ) { $keys_hash = Array ($this->IDField => $this->ID); } $ret = ''; foreach ($keys_hash as $field => $value) { - if (!preg_match('/\./', $field)) { + if ( !preg_match('/\./', $field) ) { $ret .= '(`' . $this->TableName . '`.' . $field . ' = ' . $this->Conn->qstr($value) . ') AND '; } else { @@ -534,9 +506,13 @@ public function UpdateFormattersMasterFields() { + $this->initValidator(); // used, when called not from kValidator::Validate method + foreach ($this->Fields as $field => $options) { - if (isset($options['formatter'])) { + if ( isset($options['formatter']) ) { $formatter =& $this->Application->recallObject($options['formatter']); + /* @var $formatter kFormatter */ + $formatter->UpdateMasterFields($field, $this->GetDBField($field), $options, $this); } } @@ -576,101 +552,96 @@ } /** - * Updates previously loaded record with current item' values - * - * @access public - * @param int Primery Key Id to update - * @return bool - */ + * Updates previously loaded record with current item' values + * + * @access public + * @param int $id Primary Key Id to update + * @param bool $system_update + * @return bool + * @access public + */ public function Update($id = null, $system_update = false) { - if (isset($id)) { + if ( isset($id) ) { $this->setID($id); } - if (!$this->raiseEvent('OnBeforeItemUpdate')) { + if ( !$this->raiseEvent('OnBeforeItemUpdate') ) { return false; } - if (!isset($this->ID)) { + if ( !isset($this->ID) ) { // ID could be set inside OnBeforeItemUpdate event, so don't combine this check with previous one return false; } // validate before updating - if (!$this->Validate()) { + if ( !$this->Validate() ) { return false; } - if (!$this->FieldValues) { - // nothing to update - return true; - } + if ( !$this->FieldValues ) { + // nothing to update + return true; + } - $sql = ''; + $sql = ''; - foreach ($this->FieldValues as $field_name => $field_value) { - if ($this->skipField($field_name)) { - continue; - } + foreach ($this->FieldValues as $field_name => $field_value) { + if ( $this->skipField($field_name) ) { + continue; + } - if ( is_null($field_value) ) { - if (array_key_exists('not_null', $this->Fields[$field_name]) && $this->Fields[$field_name]['not_null']) { - // "kFormatter::Parse" methods converts empty values to NULL and for - // not-null fields they are replaced with default value here - $field_value = $this->Fields[$field_name]['default']; - } - } + if ( is_null($field_value) ) { + if ( array_key_exists('not_null', $this->Fields[$field_name]) && $this->Fields[$field_name]['not_null'] ) { + // "kFormatter::Parse" methods converts empty values to NULL and for + // not-null fields they are replaced with default value here + $field_value = $this->Fields[$field_name]['default']; + } + } - $sql .= '`' . $field_name . '` = ' . $this->Conn->qstr($field_value) . ', '; - } + $sql .= '`' . $field_name . '` = ' . $this->Conn->qstr($field_value) . ', '; + } - $sql = 'UPDATE ' . $this->TableName . ' - SET ' . substr($sql, 0, -2) . ' - WHERE ' . $this->GetKeyClause('update'); + $sql = 'UPDATE ' . $this->TableName . ' + SET ' . substr($sql, 0, -2) . ' + WHERE ' . $this->GetKeyClause('update'); - if ($this->Conn->ChangeQuery($sql) === false) { - // there was and sql error - return false; - } + if ( $this->Conn->ChangeQuery($sql) === false ) { + // there was and sql error + return false; + } $affected_rows = $this->Conn->getAffectedRows(); - if (!$system_update && ($affected_rows > 0)) { + if ( !$system_update && ($affected_rows > 0) ) { $this->setModifiedFlag(ChangeLog::UPDATE); } $this->saveCustomFields(); - $this->raiseEvent('OnAfterItemUpdate'); - $this->OriginalFieldValues = $this->FieldValues; - $this->Loaded = true; + $this->raiseEvent('OnAfterItemUpdate'); + $this->OriginalFieldValues = $this->FieldValues; + $this->Loaded = true; - if (!$this->IsTempTable()) { + if ( !$this->IsTempTable() ) { $this->Application->resetCounters($this->TableName); } return true; } + /** + * Validates given field + * + * @param string $field + * @return bool + * @access public + */ public function ValidateField($field) { - $options = $this->Fields[$field]; + $this->initValidator(); - /*if (isset($options['formatter'])) { - $formatter =& $this->Application->recallObject($options['formatter']); - $formatter->UpdateMasterFields($field, $this->GetDBField($field), $options, $this); - }*/ - - $error_field = isset($options['error_field']) ? $options['error_field'] : $field; - $res = !isset($this->FieldErrors[$error_field]['pseudo']) || !$this->FieldErrors[$error_field]['pseudo']; - - $res = $res && $this->ValidateRequired($field, $options); - $res = $res && $this->ValidateType($field, $options); - $res = $res && $this->ValidateRange($field, $options); - $res = $res && $this->ValidateUnique($field, $options); - $res = $res && $this->CustomValidation($field, $options); - - return $res; + return $this->validator->ValidateField($field); } /** @@ -683,101 +654,38 @@ */ public function Validate() { - $this->UpdateFormattersMasterFields(); //order is critical - should be called BEFORE checking errors - - if ($this->IgnoreValidation) { + if ( $this->IgnoreValidation ) { return true; } + $this->initValidator(); + // will apply any custom validation to the item $this->raiseEvent('OnBeforeItemValidate'); - $global_res = true; - foreach ($this->Fields as $field => $params) { - $res = $this->ValidateField($field); - - - $global_res = $global_res && $res; - } - - if (!$global_res && $this->Application->isDebugMode()) { - $error_msg = ' Validation failed in prefix '.$this->Prefix.', - FieldErrors follow (look at items with "pseudo" key set)
- You may ignore this notice if submitted data really has a validation error'; - trigger_error(trim($error_msg), E_USER_NOTICE); - $this->Application->Debugger->dumpVars($this->FieldErrors); - } - - if ($global_res) { + if ( $this->validator->Validate() ) { // no validation errors $this->raiseEvent('OnAfterItemValidate'); + + return true; } - return $global_res; + return false; } /** - * Check field value by user-defined alghoritm - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - */ - protected function CustomValidation($field, $params) - { - return true; - } - - /** * Check if item has errors * * @param Array $skip_fields fields to skip during error checking * @return bool */ public function HasErrors($skip_fields = Array ()) { - $global_res = false; - - foreach ($this->Fields as $field => $field_params) { - // If Formatter has set some error messages during values parsing - if ( !( in_array($field, $skip_fields) ) && - isset($this->FieldErrors[$field]['pseudo']) && $this->FieldErrors[$field] != '') { - $global_res = true; - } + if ( !is_object($this->validator) ) { + return false; } - return $global_res; - } - /** - * Check if value in field matches field type specified in config - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - */ - protected function ValidateType($field, $params) - { - $res = true; - $val = $this->FieldValues[$field]; - if ( $val != '' && - isset($params['type']) && - preg_match("#int|integer|double|float|real|numeric|string#", $params['type']) - ) { - if ($params['type'] == 'numeric') { - trigger_error('Invalid field type '.$params['type'].' (in ValidateType method), please use float instead', E_USER_NOTICE); - $params['type'] = 'float'; - } - $res = is_numeric($val); - if ($params['type']=='string' || $res) { - $f = 'is_'.$params['type']; - settype($val, $params['type']); - $res = $f($val) && ($val == $this->FieldValues[$field]); - } - if (!$res) { - $this->SetError($field, 'bad_type', null, Array ($params['type'])); - } - } - return $res; + return $this->validator->HasErrors($skip_fields); } /** @@ -787,125 +695,14 @@ * @param Array $params field options from config * @return bool * @access public + * @todo Find a way to get rid of direct call from kMultiLanguage::UpdateMasterFields method */ public function ValidateRequired($field, $params) { - $res = true; - if (isset($params['required']) && $params['required']) { - $check_value = $this->FieldValues[$field]; - if ($this->Application->ConfigValue('TrimRequiredFields')) { - $check_value = trim($check_value); - } - $res = ((string)$check_value != ''); - } - - if (!$res) { - $this->SetError($field, 'required'); - } - - return $res; + return $this->validator->ValidateRequired($field, $params); } /** - * Validates that current record has unique field combination among other table records - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - * @access private - */ - protected function ValidateUnique($field, $params) - { - $res = true; - $unique_fields = getArrayValue($params,'unique'); - if($unique_fields !== false) - { - $where = Array(); - array_push($unique_fields,$field); - foreach($unique_fields as $unique_field) - { - // if field is not empty or if it is required - we add where condition - if ((string)$this->GetDBField($unique_field) != '' || (isset($this->Fields[$unique_field]['required']) && $this->Fields[$unique_field]['required'])) { - $where[] = '`'.$unique_field.'` = '.$this->Conn->qstr( $this->GetDBField($unique_field) ); - } - else { - // not good if we check by less fields than indicated - return true; - } - } - // This can ONLY happen if all unique fields are empty and not required. - // In such case we return true, because if unique field is not required there may be numerous empty values -// if (!$where) return true; - - $sql = 'SELECT COUNT(*) FROM %s WHERE ('.implode(') AND (',$where).') AND ('.$this->IDField.' <> '.(int)$this->ID.')'; - - $res_temp = $this->Conn->GetOne( str_replace('%s', $this->TableName, $sql) ); - - $current_table_only = getArrayValue($params, 'current_table_only'); // check unique record only in current table - $res_live = $current_table_only ? 0 : $this->Conn->GetOne( str_replace('%s', $this->Application->GetLiveName($this->TableName), $sql) ); - - $res = ($res_temp == 0) && ($res_live == 0); - - if (!$res) { - $this->SetError($field, 'unique'); - } - } - return $res; - } - - /** - * Check if field value is in range specified in config - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - * @access private - */ - protected function ValidateRange($field, $params) - { - $res = true; - $val = $this->FieldValues[$field]; - - if ( isset($params['type']) && preg_match("#int|integer|double|float|real#", $params['type']) && strlen($val) > 0 ) { - if ( isset($params['max_value_inc'])) { - $res = $res && $val <= $params['max_value_inc']; - $max_val = $params['max_value_inc'].' (inclusive)'; - } - if ( isset($params['min_value_inc'])) { - $res = $res && $val >= $params['min_value_inc']; - $min_val = $params['min_value_inc'].' (inclusive)'; - } - if ( isset($params['max_value_exc'])) { - $res = $res && $val < $params['max_value_exc']; - $max_val = $params['max_value_exc'].' (exclusive)'; - } - if ( isset($params['min_value_exc'])) { - $res = $res && $val > $params['min_value_exc']; - $min_val = $params['min_value_exc'].' (exclusive)'; - } - } - if (!$res) { - if ( !isset($min_val) ) $min_val = '-∞'; - if ( !isset($max_val) ) $max_val = '∞'; - - $this->SetError($field, 'value_out_of_range', null, Array ($min_val, $max_val)); - return $res; - } - if ( isset($params['max_len'])) { - $res = $res && mb_strlen($val) <= $params['max_len']; - } - if ( isset($params['min_len'])) { - $res = $res && mb_strlen($val) >= $params['min_len']; - } - if (!$res) { - $error_params = Array (getArrayValue($params, 'min_len'), getArrayValue($params, 'max_len'), mb_strlen($val)); - $this->SetError($field, 'length_out_of_range', null, $error_params); - return $res; - } - return $res; - } - - /** * Return error message for field * * @param string $field @@ -914,33 +711,11 @@ */ public function GetErrorMsg($field, $force_escape = null) { - $err = $this->GetErrorPseudo($field); - - if (!$err) { + if ( !is_object($this->validator) ) { return ''; } - // if special error msg defined in config - if( isset($this->Fields[$field]['error_msgs'][$err]) ) - { - $msg = $this->Fields[$field]['error_msgs'][$err]; - } - else //fall back to defaults - { - if( !isset($this->ErrorMsgs[$err]) ) { - trigger_error('No user message is defined for pseudo error '.$err.'
', E_USER_WARNING); - return $err; //return the pseudo itself - } - $msg = $this->ErrorMsgs[$err]; - } - $msg = $this->Application->ReplaceLanguageTags($msg, $force_escape); - - if ( isset($this->FieldErrors[$field]['params']) ) - { - return vsprintf($msg, $this->FieldErrors[$field]['params']); - } - - return $msg; + return $this->validator->GetErrorMsg($field, $force_escape); } /** @@ -951,16 +726,21 @@ */ public function GetFieldErrors() { - return $this->FieldErrors; + if ( !is_object($this->validator) ) { + return Array (); + } + + return $this->validator->GetFieldErrors(); } /** - * Creates a record in the database table with current item' values - * - * @param mixed $force_id Set to TRUE to force creating of item's own ID or to value to force creating of passed id. Do not pass 1 for true, pass exactly TRUE! - * @access public - * @return bool - */ + * Creates a record in the database table with current item' values + * + * @param mixed $force_id Set to TRUE to force creating of item's own ID or to value to force creating of passed id. Do not pass 1 for true, pass exactly TRUE! + * @param bool $system_create + * @return bool + * @access public + */ public function Create($force_id = false, $system_create = false) { if (!$this->raiseEvent('OnBeforeItemCreate')) { @@ -989,7 +769,7 @@ if (is_null($field_value)) { if (array_key_exists('not_null', $this->Fields[$field_name]) && $this->Fields[$field_name]['not_null']) { // "kFormatter::Parse" methods converts empty values to NULL and for - // not-null fields they are replaced with default value here + // not-null fields they are replaced with default value here $values_sql .= $this->Conn->qstr($this->Fields[$field_name]['default']); } else { @@ -1048,18 +828,19 @@ } /** - * Deletes the record from databse - * - * @access public - * @return bool - */ + * Deletes the record from database + * + * @param int $id + * @return bool + * @access public + */ public function Delete($id = null) { - if (isset($id)) { + if ( isset($id) ) { $this->setID($id); } - if (!$this->raiseEvent('OnBeforeItemDelete')) { + if ( !$this->raiseEvent('OnBeforeItemDelete') ) { return false; } @@ -1069,14 +850,14 @@ $ret = $this->Conn->ChangeQuery($sql); $affected_rows = $this->Conn->getAffectedRows(); - if ($affected_rows > 0) { + if ( $affected_rows > 0 ) { $this->setModifiedFlag(ChangeLog::DELETE); // will change affected rows, so get it before this line // something was actually deleted $this->raiseEvent('OnAfterItemDelete'); } - if (!$this->IsTempTable()) { + if ( !$this->IsTempTable() ) { $this->Application->resetCounters($this->TableName); } @@ -1089,10 +870,10 @@ // master field is set only for CURRENT language $formatter = array_key_exists('formatter', $options) ? $options['formatter'] : false; - if (($formatter == 'kMultiLanguage') && array_key_exists('master_field', $options) && array_key_exists('error_field', $options)) { + if ( ($formatter == 'kMultiLanguage') && isset($options['master_field']) && isset($options['error_field']) ) { // MuliLanguage formatter sets error_field to master_field, but in PopulateMlFields mode, - // we display ML fields directly so we set it back to itself, otherwise error will not be displayed - unset($this->Fields[$field]['error_field']); + // we display ML fields directly so we set it back to itself, otherwise error won't be displayed + unset( $this->Fields[$field]['error_field'] ); } } } @@ -1279,7 +1060,7 @@ protected function LogChanges($main_prefix, $mode) { - if (!$mode) { + if ( !$mode ) { return ; } @@ -1295,7 +1076,7 @@ 'Action' => $mode, ); - if ($this->Prefix == $main_prefix) { + if ( $this->Prefix == $main_prefix ) { // main item $fields_hash['MasterId'] = $this->GetID(); $fields_hash['ParentPrefix'] = Array ($main_prefix); @@ -1304,10 +1085,11 @@ else { // sub item // collect foreign key values (for serial reset) - $foreign_keys = $this->Application->getUnitOption($this->Prefix, 'ForeignKey'); + $foreign_keys = $this->Application->getUnitOption($this->Prefix, 'ForeignKey', Array ()); $dependent_fields = $fields_hash['ParentId'] = $fields_hash['ParentPrefix'] = Array (); + /* @var $foreign_keys Array */ - if (is_array($foreign_keys)) { + if ( is_array($foreign_keys) ) { foreach ($foreign_keys as $prefix => $field_name) { $dependent_fields[$field_name] = $this->GetDBField($field_name); $fields_hash['ParentPrefix'][] = $prefix; @@ -1323,18 +1105,18 @@ $fields_hash['DependentFields'] = $dependent_fields; - // works only, when main item is present in url, when subitem is changed + // works only, when main item is present in url, when sub-item is changed $master_id = $this->Application->GetVar($main_prefix . '_id'); - if ($master_id === false) { - // works in case of we are not editing topmost item, when subitem is created/updated/deleted + if ( $master_id === false ) { + // works in case of we are not editing topmost item, when sub-item is created/updated/deleted $master_id = $this->getParentId('auto', true); } $fields_hash['MasterId'] = $master_id; } - switch ($mode) { + switch ( $mode ) { case ChangeLog::UPDATE: $to_save = array_merge($this->GetTitleField(), $this->GetChangedFields()); break; @@ -1346,6 +1128,10 @@ case ChangeLog::DELETE: $to_save = array_merge($this->GetTitleField(), $this->GetRealFields()); break; + + default: + $to_save = Array (); + break; } $fields_hash['Changes'] = serialize($to_save); @@ -1453,22 +1239,7 @@ */ public function GetRealFields() { - if (function_exists('array_diff_key')) { - $db_fields = array_diff_key($this->FieldValues, $this->VirtualFields, $this->CalculatedFields); - } - else { - $db_fields = Array(); - - foreach ($this->FieldValues as $key => $value) { - if (array_key_exists($key, $this->VirtualFields) || array_key_exists($key, $this->CalculatedFields)) { - continue; - } - - $db_fields[$key] = $value; - } - } - - return $db_fields; + return array_diff_key($this->FieldValues, $this->VirtualFields, $this->CalculatedFields); } /** @@ -1542,22 +1313,37 @@ /** * Sets new required flag to field * - * @param string $field + * @param mixed $fields * @param bool $is_required */ - public function setRequired($field, $is_required = true) + public function setRequired($fields, $is_required = true) { - $this->Fields[$field]['required'] = $is_required; + if ( !is_array($fields) ) { + $fields = explode(',', $fields); + } + + foreach ($fields as $field) { + $this->Fields[$field]['required'] = $is_required; + } } + /** + * Removes all data from an object + * + * @param int $new_id + * @return bool + * @access public + */ public function Clear($new_id = null) { $this->Loaded = false; - $this->FieldValues = Array(); - $this->OriginalFieldValues = Array (); + $this->FieldValues = $this->OriginalFieldValues = Array (); $this->SetDefaultValues(); // will wear off kDBItem::setID effect, so set it later - $this->FieldErrors = Array(); + if ( is_object($this->validator) ) { + $this->validator->reset(); + } + $this->setID($new_id); return $this->Loaded; @@ -1570,13 +1356,13 @@ protected function saveCustomFields() { - if (!$this->customFields || $this->inCloning) { + if ( !$this->customFields || $this->inCloning ) { return true; } $cdata_key = rtrim($this->Prefix . '-cdata.' . $this->Special, '.'); - $cdata =& $this->Application->recallObject($cdata_key, null, Array('skip_autoload' => true)); + $cdata =& $this->Application->recallObject($cdata_key, null, Array ('skip_autoload' => true, 'populate_ml_fields' => true)); /* @var $cdata kDBItem */ $resource_id = $this->GetDBField('ResourceId'); @@ -1586,25 +1372,9 @@ $ml_formatter =& $this->Application->recallObject('kMultiLanguage'); /* @var $ml_formatter kMultiLanguage */ - $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); - /* @var $ml_helper kMultiLanguageHelper */ - foreach ($this->customFields as $custom_id => $custom_name) { - $field_options = $cdata->GetFieldOptions('cust_' . $custom_id); - $force_primary = isset($field_options['force_primary']) && $field_options['force_primary']; - - if ($force_primary) { - $cdata->SetDBField($ml_formatter->LangFieldName('cust_' . $custom_id, true), $this->GetDBField('cust_' . $custom_name)); - } - else { - for ($language_id = 1; $language_id <= $ml_helper->languageCount; $language_id++) { - if (!$ml_helper->LanguageFound($language_id)) { - continue; - } - - $cdata->SetDBField('l' . $language_id . '_cust_' . $custom_id, $this->GetDBField('l' . $language_id . '_cust_' . $custom_name)); - } - } + $force_primary = $cdata->GetFieldOption('cust_' . $custom_id, 'force_primary'); + $cdata->SetDBField($ml_formatter->LangFieldName('cust_' . $custom_id, $force_primary), $this->GetDBField('cust_' . $custom_name)); } return $cdata->isLoaded() ? $cdata->Update() : $cdata->Create(); Index: branches/5.2.x/core/units/users/users_item.php =================================================================== diff -u -N -r14447 -r14596 --- branches/5.2.x/core/units/users/users_item.php (.../users_item.php) (revision 14447) +++ branches/5.2.x/core/units/users/users_item.php (.../users_item.php) (revision 14596) @@ -1,6 +1,6 @@ GetDBField('Status')) { + switch ( $this->GetDBField('Status') ) { case STATUS_ACTIVE: $event_name = $this->Application->ConfigValue('User_Password_Auto') ? 'USER.VALIDATE' : 'USER.ADD'; $this->Application->EmailEventAdmin($event_name); @@ -62,45 +62,87 @@ * * @return bool */ - function isSubscriberOnly() + public function isSubscriberOnly() { return $this->GetDBField('PrimaryGroupId') == $this->Application->ConfigValue('User_SubscriberGroup'); } - function Create($force_id=false, $system_create=false) + /** + * Checks that user is subscribed + * + * @return bool + */ + public function isSubscribed() { + $group_id = $this->Application->ConfigValue('User_SubscriberGroup'); + + $sql = 'SELECT GroupId + FROM ' . TABLE_PREFIX . 'UserGroup + WHERE (PortalUserId = ' . $this->GetID() . ') AND (GroupId = ' . $group_id . ')'; + + return $this->Conn->GetOne($sql); + } + + /** + * Creates a record in the database table with current item' values + * + * @param mixed $force_id Set to TRUE to force creating of item's own ID or to value to force creating of passed id. Do not pass 1 for true, pass exactly TRUE! + * @param bool $system_create + * @return bool + * @access public + */ + public function Create($force_id = false, $system_create = false) + { $ret = parent::Create($force_id, $system_create); - if ($ret) { - // find out how to syncronize user only when it's copied to live table - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), Array ('InPortalSyncronize')); + if ( $ret ) { + // find out how to synchronize user only when it's copied to live table + $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array (), Array ('InPortalSyncronize')); + /* @var $sync_manager UsersSyncronizeManager */ + $sync_manager->performAction('createUser', $this->FieldValues); } return $ret; } - - function Update($id=null, $system_update=false) + /** + * Updates previously loaded record with current item' values + * + * @access public + * @param int $id Primary Key Id to update + * @param bool $system_update + * @return bool + * @access public + */ + public function Update($id = null, $system_update = false) { $ret = parent::Update($id, $system_update); - if ($ret) { - // find out how to syncronize user only when it's copied to live table - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), Array ('InPortalSyncronize')); + + if ( $ret ) { + // find out how to synchronize user only when it's copied to live table + $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array (), Array ('InPortalSyncronize')); + /* @var $sync_manager UsersSyncronizeManager */ + $sync_manager->performAction('updateUser', $this->FieldValues); } + return $ret; } /** - * Deletes the record from databse - * - * @access public - * @return bool - */ - function Delete($id = null) + * Deletes the record from database + * + * @param int $id + * @return bool + * @access public + */ + public function Delete($id = null) { $ret = parent::Delete($id); - if ($ret) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), Array ('InPortalSyncronize')); + + if ( $ret ) { + $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array (), Array ('InPortalSyncronize')); + /* @var $sync_manager UsersSyncronizeManager */ + $sync_manager->performAction('deleteUser', $this->FieldValues); } Index: branches/5.2.x/core/units/users/users_tag_processor.php =================================================================== diff -u -N -r14585 -r14596 --- branches/5.2.x/core/units/users/users_tag_processor.php (.../users_tag_processor.php) (revision 14585) +++ branches/5.2.x/core/units/users/users_tag_processor.php (.../users_tag_processor.php) (revision 14596) @@ -1,6 +1,6 @@ Application->ConfigValue('Smtp_AdminMailFrom'); } - function AffiliatePaymentTypeChecked($params) - { - static $checked = false; - - if( $this->Application->GetVar('PaymentTypeId') ) - { - $apt_object =& $this->Application->recallObject('apt.active'); - if( $this->Application->GetVar('PaymentTypeId') == $apt_object->GetDBField('PaymentTypeId') ) - { - return 1; - } - else - { - return 0; - } - } - - if(!$checked) - { - $checked = true; - return 1; - } - else - { - return 0; - } - } - - function HasError($params) - { - $res = parent::HasError($params); - if($this->SelectParam($params,'field,fields') == 'any') - { - $res = $res || $this->Application->GetVar('MustAgreeToTerms'); // need to do it not put module fields into kernel ! (noticed by Alex) - $res = $res || $this->Application->GetVar('SSNRequiredError'); - } - return $res; - } - /** * Returns login name of user * Index: branches/5.2.x/core/units/forms/forms/forms_eh.php =================================================================== diff -u -N -r14244 -r14596 --- branches/5.2.x/core/units/forms/forms/forms_eh.php (.../forms_eh.php) (revision 14244) +++ branches/5.2.x/core/units/forms/forms/forms_eh.php (.../forms_eh.php) (revision 14596) @@ -1,6 +1,6 @@ status == kEvent::erSUCCESS) { + if ( $event->status == kEvent::erSUCCESS ) { $this->OnCreateFormFields($event); - $this->_deleteSectionCache(); } } - function OnMassDelete(&$event) + /** + * 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 + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnMassDelete(&$event) { parent::OnMassDelete($event); - if ($event->status == kEvent::erSUCCESS) { + if ( $event->status == kEvent::erSUCCESS ) { $this->_deleteSectionCache(); } } @@ -116,7 +132,7 @@ } /** - * Dynamically fills customdata config + * Dynamically fills custom data config * * @param kEvent $event */ @@ -157,41 +173,47 @@ * Enter description here... * * @param kEvent $event + * @return void + * @access protected */ - function OnFormSubmit(&$event) + protected function OnFormSubmit(&$event) { - $object =& $event->GetObject(); + $object =& $event->getObject(); + /* @var $object kDBItem */ $fields = explode(',',$this->Application->GetVar('fields')); $required_fields = explode(',', $this->Application->GetVar('required_fields')); $fields_params = $this->Application->GetVar('fields_params'); + $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields'); + foreach ($fields as $field) { - $virt_fields[$field] = Array(); - if (in_array($field, $required_fields)) { - $virt_fields[$field]['required'] = 1; + $virtual_fields[$field] = Array (); + + if ( in_array($field, $required_fields) ) { + $virtual_fields[$field]['required'] = 1; } + $params = getArrayValue($fields_params, $field); - if ($params !== false) { - if (getArrayValue($params, 'Type') == 'email') { - //'formatter'=>'kFormatter', 'regexp'=>'/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', 'error_msgs' => Array('invalid_format'=>'!la_invalid_email!') - $virt_fields[$field]['formatter'] = 'kFormatter'; - $virt_fields[$field]['regexp'] = '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i'; - $virt_fields[$field]['error_msgs'] = Array('invalid_format'=>'!la_invalid_email!'); + + if ( $params !== false ) { + if ( getArrayValue($params, 'Type') == 'email' ) { + $virtual_fields[$field]['formatter'] = 'kFormatter'; + $virtual_fields[$field]['regexp'] = '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i'; + $virtual_fields[$field]['error_msgs'] = Array ('invalid_format' => '!la_invalid_email!'); } - if (getArrayValue($params, 'Type') == 'file') { - $virt_fields[$field]['formatter'] = 'kUploadFormatter'; - $virt_fields[$field]['upload_dir'] = '/uploads/sketches/'; + + if ( getArrayValue($params, 'Type') == 'file' ) { + $virtual_fields[$field]['formatter'] = 'kUploadFormatter'; + $virtual_fields[$field]['upload_dir'] = '/uploads/sketches/'; } } } - $object->SetVirtualFields($virt_fields); + $object->SetVirtualFields($virtual_fields); $field_values = $this->getSubmittedFields($event); + $checkboxes = explode(',', $this->Application->GetVar('checkbox_fields')); // MailingList,In-Link,In-Newz,In-Bulletin - - $checkboxes = Array('MailingList', 'In-Link', 'In-Newz', 'In-Bulletin'); - $checkboxes = explode(',', $this->Application->GetVar('checkbox_fields')); foreach ($checkboxes as $checkbox) { if (isset($field_values[$checkbox])) { $field_values[$checkbox] = 1; @@ -202,16 +224,21 @@ } $object->SetFieldsFromHash($field_values); - if ($object->Validate()) { + + if ( $object->Validate() ) { $event->redirect = $this->Application->GetVar('success_template'); $this->Application->EmailEventAdmin($this->Application->GetVar('email_event')); - $this->Application->EmailEventUser($this->Application->GetVar('email_event'), null, - Array('to_email' => $field_values[$this->Application->GetVar('email_field')], - 'to_name' => $field_values[$this->Application->GetVar('name_field')])); - if ($field_values['MailingList']) { + $send_params = Array ( + 'to_email' => $field_values[$this->Application->GetVar('email_field')], + 'to_name' => $field_values[$this->Application->GetVar('name_field')] + ); + + $this->Application->EmailEventUser($this->Application->GetVar('email_event'), null, $send_params); + + if ( $field_values['MailingList'] ) { $this->Application->StoreVar('SubscriberEmail', $field_values['Email']); - $this->Application->HandleEvent($sub_event, 'u:OnSubscribeUser', Array('no_unsubscribe' => 1)); + $this->Application->HandleEvent($sub_event, 'u:OnSubscribeUser', Array ('no_unsubscribe' => 1)); } } else { @@ -223,25 +250,37 @@ * Don't use security image, when form requires login * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemCreate(&$event) + protected function OnBeforeItemCreate(&$event) { parent::OnBeforeItemCreate($event); - $this->_validatePopSettings($event); - $this->_disableSecurityImage($event); - $this->_setRequired($event); + $this->itemChanged($event); } /** * Don't use security image, when form requires login * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemUpdate(&$event) + protected function OnBeforeItemUpdate(&$event) { parent::OnBeforeItemUpdate($event); + $this->itemChanged($event); + } + + /** + * Occurs before item is changed + * + * @param kEvent $event + */ + function itemChanged(&$event) + { $this->_validatePopSettings($event); $this->_disableSecurityImage($event); $this->_setRequired($event); @@ -327,9 +366,7 @@ $fields = array_merge($fields, $bounce_fields); } - foreach ($fields as $field) { - $object->setRequired($field, $required); - } + $object->setRequired($fields, $required); } /** Index: branches/5.2.x/core/kernel/db/cat_dbitem.php =================================================================== diff -u -N -r14585 -r14596 --- branches/5.2.x/core/kernel/db/cat_dbitem.php (.../cat_dbitem.php) (revision 14585) +++ branches/5.2.x/core/kernel/db/cat_dbitem.php (.../cat_dbitem.php) (revision 14596) @@ -1,6 +1,6 @@ usePendingEditing = $this->Application->getUnitOption($this->Prefix, 'UsePendingEditing'); } - function Create($force_id = false, $system_create = false) + /** + * Creates a record in the database table with current item' values + * + * @param mixed $force_id Set to TRUE to force creating of item's own ID or to value to force creating of passed id. Do not pass 1 for true, pass exactly TRUE! + * @param bool $system_create + * @return bool + * @access public + */ + public function Create($force_id = false, $system_create = false) { $ret = parent::Create($force_id, $system_create); @@ -84,33 +92,43 @@ $this->assignToCategory($this->GetDBField('CategoryId'), true); } - function Update($id=null, $system_update=false) + /** + * Updates previously loaded record with current item' values + * + * @access public + * @param int $id Primary Key Id to update + * @param bool $system_update + * @return bool + * @access public + */ + public function Update($id = null, $system_update = false) { - $this->VirtualFields['ResourceId'] = Array(); + $this->VirtualFields['ResourceId'] = Array (); - if ($this->GetChangedFields()) { + if ( $this->GetChangedFields() ) { $now = adodb_mktime(); $this->SetDBField('Modified_date', $now); $this->SetDBField('Modified_time', $now); $this->SetDBField('ModifiedById', $this->Application->RecallVar('user_id')); } - if ($this->useFilenames) { + if ( $this->useFilenames ) { $this->checkFilename(); $this->generateFilename(); } $ret = parent::Update($id, $system_update); - if ($ret) { + if ( $ret ) { $filename = $this->useFilenames ? (string)$this->GetDBField('Filename') : ''; - $sql = 'UPDATE '.$this->CategoryItemsTable().' - SET Filename = '.$this->Conn->qstr($filename).' - WHERE ItemResourceId = '.$this->GetDBField('ResourceId'); + $sql = 'UPDATE ' . $this->CategoryItemsTable() . ' + SET Filename = ' . $this->Conn->qstr($filename) . ' + WHERE ItemResourceId = ' . $this->GetDBField('ResourceId'); $this->Conn->Query($sql); } unset($this->VirtualFields['ResourceId']); + return $ret; } @@ -228,18 +246,19 @@ * * @param int $id * @return bool + * @access public */ - function Delete($id = null) + public function Delete($id = null) { - if( isset($id) ) { + if ( isset($id) ) { $this->setID($id); } $this->Load($this->GetID()); $ret = parent::Delete(); - if ($ret) { + if ( $ret ) { // TODO: move to OnAfterItemDelete method $query = ' DELETE FROM ' . $this->CategoryItemsTable() . ' WHERE ItemResourceId = ' . $this->GetDBField('ResourceId'); @@ -259,32 +278,43 @@ { $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); // because item was loaded before by ResourceId - $ci_table = $this->Application->getUnitOption($this->Prefix.'-ci', 'TableName'); + $ci_table = $this->Application->getUnitOption($this->Prefix . '-ci', 'TableName'); $resource_id = $this->GetDBField('ResourceId'); - $item_cats_sql = 'SELECT CategoryId FROM %s WHERE ItemResourceId = %s'; - $delete_category_items_sql = 'DELETE FROM %s WHERE ItemResourceId = %s AND CategoryId IN (%s)'; + $item_cats_sql = ' SELECT CategoryId + FROM %s + WHERE ItemResourceId = %s'; + $delete_category_items_sql = ' DELETE FROM %s + WHERE ItemResourceId = %s AND CategoryId IN (%s)'; + $category_ids = $this->Conn->GetCol( sprintf($item_cats_sql, $ci_table, $resource_id) ); $cats_left = array_diff($category_ids, $delete_category_ids); - if(!$cats_left) - { - $sql = 'SELECT %s FROM %s WHERE ResourceId = %s'; - $ids = $this->Conn->GetCol( sprintf($sql, $id_field, $this->TableName, $resource_id) ); - $temp =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); - $temp->DeleteItems($this->Prefix, $this->Special, $ids); + if ( !$cats_left ) { + $sql = 'SELECT %s + FROM %s + WHERE ResourceId = %s'; + $ids = $this->Conn->GetCol(sprintf($sql, $id_field, $this->TableName, $resource_id)); + + $temp_handler =& $this->Application->recallObject($this->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler'); + /* @var $temp_handler kTempTablesHandler */ + + $temp_handler->DeleteItems($this->Prefix, $this->Special, $ids); } - else - { - $this->Conn->Query( sprintf($delete_category_items_sql, $ci_table, $resource_id, implode(',', $delete_category_ids) ) ); + else { + $this->Conn->Query( sprintf($delete_category_items_sql, $ci_table, $resource_id, implode(',', $delete_category_ids)) ); - $sql = 'SELECT CategoryId FROM %s WHERE PrimaryCat = 1 AND ItemResourceId = %s'; - $primary_cat_id = $this->Conn->GetCol( sprintf($sql, $ci_table, $resource_id) ); - if( count($primary_cat_id) == 0 ) - { - $sql = 'UPDATE %s SET PrimaryCat = 1 WHERE (CategoryId = %s) AND (ItemResourceId = %s)'; - $this->Conn->Query( sprintf($sql, $ci_table, reset($cats_left), $resource_id ) ); + $sql = 'SELECT CategoryId + FROM %s + WHERE PrimaryCat = 1 AND ItemResourceId = %s'; + $primary_cat_id = $this->Conn->GetCol(sprintf($sql, $ci_table, $resource_id)); + + if ( count($primary_cat_id) == 0 ) { + $sql = 'UPDATE %s + SET PrimaryCat = 1 + WHERE (CategoryId = %s) AND (ItemResourceId = %s)'; + $this->Conn->Query( sprintf($sql, $ci_table, reset($cats_left), $resource_id) ); } } } @@ -298,6 +328,8 @@ function stripDisallowed($filename) { $filenames_helper =& $this->Application->recallObject('FilenamesHelper'); + /* @var $filenames_helper kFilenamesHelper */ + $table = $this->IsTempTable() ? $this->Application->GetTempName(TABLE_PREFIX.'CategoryItems', 'prefix:'.$this->Prefix) : TABLE_PREFIX.'CategoryItems'; return $filenames_helper->stripDisallowed($table, 'ItemResourceId', $this->GetDBField('ResourceId'), $filename); @@ -314,85 +346,80 @@ /** * Generate item's filename based on it's title field value * - * @return string + * @return void + * @access protected */ - function generateFilename() + protected function generateFilename() { - if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) return false; + if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) { + return ; + } $title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField'); - if (preg_match('/l([\d]+)_(.*)/', $title_field, $regs)) { + + if ( preg_match('/l([\d]+)_(.*)/', $title_field, $regs) ) { // if title field is multilingual, then use it's name from primary language - $title_field = 'l'.$this->Application->GetDefaultLanguageId().'_'.$regs[2]; + $title_field = 'l' . $this->Application->GetDefaultLanguageId() . '_' . $regs[2]; } + $name = $this->stripDisallowed( $this->GetDBField($title_field) ); - if ( $name != $this->GetDBField('Filename') ) $this->SetDBField('Filename', $name); - } - - /** - * Check if value is set for required field - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - * @access private - */ - function ValidateRequired($field, $params) - { - $res = true; - if (getArrayValue($params, 'required')) { - $res = ( (string) $this->FieldValues[$field] != ''); + if ( $name != $this->GetDBField('Filename') ) { + $this->SetDBField('Filename', $name); } - if (!$res) { - $this->SetError($field, 'required'); - } - return $res; } /** * Adds item to other category * * @param int $category_id * @param bool $is_primary + * @return void + * @access public */ - function assignToCategory($category_id, $is_primary = false) + public function assignToCategory($category_id, $is_primary = false) { $table = $this->CategoryItemsTable(); - $key_clause = '(ItemResourceId = '.$this->GetDBField('ResourceId').')'; + $key_clause = '(ItemResourceId = ' . $this->GetDBField('ResourceId') . ')'; - // get all cateories, where item is in - $sql = 'SELECT PrimaryCat, CategoryId FROM '.$table.' WHERE '.$key_clause; + // get all categories, where item is in + $sql = 'SELECT PrimaryCat, CategoryId + FROM ' . $table . ' + WHERE ' . $key_clause; $item_categories = $this->Conn->GetCol($sql, 'CategoryId'); - if (!$item_categories) { - $item_categories = Array(); - $primary_found = false; - } - // find primary category - foreach ($item_categories as $item_category_id => $primary_found) { - if ($primary_found) { - break; + $primary_found = $item_category_id = false; + + if ( $item_categories ) { + // find primary category + foreach ($item_categories as $item_category_id => $primary_found) { + if ( $primary_found ) { + break; + } } } - if ($primary_found && ($item_category_id == $category_id) && !$is_primary) { + if ( $primary_found && ($item_category_id == $category_id) && !$is_primary ) { // want to make primary category as non-primary :( - return true; + return; } - else if (!$primary_found) { + elseif ( !$primary_found ) { $is_primary = true; } - if ($is_primary && $item_categories) { + if ( $is_primary && $item_categories ) { // reset primary mark from all other categories - $sql = 'UPDATE '.$table.' SET PrimaryCat = 0 WHERE '.$key_clause; + $sql = 'UPDATE ' . $table . ' + SET PrimaryCat = 0 + WHERE ' . $key_clause; $this->Conn->Query($sql); } // UPDATE & INSERT instead of REPLACE because CategoryItems table has no primary key defined in database - if (isset($item_categories[$category_id])) { - $sql = 'UPDATE '.$table.' SET PrimaryCat = '.($is_primary ? 1 : 0).' WHERE '.$key_clause.' AND (CategoryId = '.$category_id.')'; + if ( isset($item_categories[$category_id]) ) { + $sql = 'UPDATE ' . $table . ' + SET PrimaryCat = ' . ($is_primary ? 1 : 0) . ' + WHERE ' . $key_clause . ' AND (CategoryId = ' . $category_id . ')'; $this->Conn->Query($sql); } else { @@ -403,8 +430,10 @@ 'ItemPrefix' => $this->Prefix, 'Filename' => $this->useFilenames ? (string)$this->GetDBField('Filename') : '', // because some prefixes does not use filenames, ); + $this->Conn->doInsert($fields_hash, $table); } + // to ensure filename update after adding to another category // this is critical since there may be an item with same filename in newly added category! $this->Update(); @@ -493,16 +522,18 @@ { $original_id = $this->GetDBField('OrgId'); - if (!($this->usePendingEditing && $original_id)) { + if ( !($this->usePendingEditing && $original_id) ) { // non-pending copy of original link return $this->ChangeStatus(STATUS_ACTIVE); } - if ($this->raiseEvent('OnBeforeDeleteOriginal', null, Array('original_id' => $original_id))) { + if ( $this->raiseEvent('OnBeforeDeleteOriginal', null, Array ('original_id' => $original_id)) ) { // delete original item, because changes made in pending copy (this item) got to be approved in this method - $temp_handler =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); - $temp_handler->DeleteItems($this->Prefix, $this->Special, Array($original_id)); + $temp_handler =& $this->Application->recallObject($this->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler'); + /* @var $temp_handler kTempTablesHandler */ + $temp_handler->DeleteItems($this->Prefix, $this->Special, Array ($original_id)); + $this->SetDBField('OrgId', 0); return $this->ChangeStatus(STATUS_ACTIVE, true); } @@ -519,14 +550,16 @@ { $original_id = $this->GetDBField('OrgId'); - if (!($this->usePendingEditing && $original_id)) { + if ( !($this->usePendingEditing && $original_id) ) { // non-pending copy of original link return $this->ChangeStatus(STATUS_DISABLED); } // delete this item, because changes made in pending copy (this item) will be declined in this method - $temp_handler =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); - $temp_handler->DeleteItems($this->Prefix, $this->Special, Array($this->GetID())); + $temp_handler =& $this->Application->recallObject($this->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler'); + /* @var $temp_handler kTempTablesHandler */ + + $temp_handler->DeleteItems($this->Prefix, $this->Special, Array ($this->GetID())); $this->sendEmailEvents(STATUS_DISABLED, true); // original item is not changed here, because it is already enabled (thrus pending copy is visible to item's owner or admin with permission) @@ -566,17 +599,17 @@ } /** - * Returns part of SQL WHERE clause identifing the record, ex. id = 25 - * - * @access public - * @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method - * @param Array $keys_hash alternative, then item id, keys hash to load item by - * @return void - * @see kDBItem::Load() - * @see kDBItem::Update() - * @see kDBItem::Delete() - */ - function GetKeyClause($method = null, $keys_hash = null) + * Returns part of SQL WHERE clause identifying the record, ex. id = 25 + * + * @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method + * @param Array $keys_hash alternative, then item id, keys hash to load item by + * @see kDBItem::Load() + * @see kDBItem::Update() + * @see kDBItem::Delete() + * @return string + * @access protected + */ + protected function GetKeyClause($method = null, $keys_hash = null) { if ($method == 'load') { // for item with many categories makes primary to load Index: branches/5.2.x/core/kernel/utility/formatters/formatter.php =================================================================== diff -u -N -r14244 -r14596 --- branches/5.2.x/core/kernel/utility/formatters/formatter.php (.../formatter.php) (revision 14244) +++ branches/5.2.x/core/kernel/utility/formatters/formatter.php (.../formatter.php) (revision 14596) @@ -1,6 +1,6 @@ '.$field_type.' (in TypeCast method), please use float instead', E_USER_NOTICE); + trigger_error('Invalid field type ' . $field_type . ' (in TypeCast method), please use float instead', E_USER_NOTICE); $field_type = 'float'; } - $type_ok = preg_match('#int|integer|double|float|real|numeric|string#', $field_type); - if ($field_type == 'string') { - if (!$this->Application->isAdmin && isset($options['allow_html']) && $options['allow_html']) { + elseif ( $field_type == 'string' ) { + if ( !$this->Application->isAdmin && isset($options['allow_html']) && $options['allow_html'] ) { // this allows to revert htmlspecialchars call for each field submitted on front-end $value = kUtil::unhtmlentities($value); } + return $value; } - static $comma = null; - static $thousands = null; - if (is_null($comma) || is_null($thousands)) { - $lang =& $this->Application->recallObject('lang.current'); - $comma = $lang->GetDBField('DecimalPoint'); - $thousands = $lang->GetDBField('ThousandSep'); - } + $value = $this->formatNumber($value); + $type_ok = preg_match('#int|integer|double|float|real|numeric|string#', $field_type); - $value = str_replace($thousands, '', $value); - $value = str_replace($comma, '.', $value); - - if ($value != '' && $type_ok) - { + if ( $value != '' && $type_ok ) { $ret = is_numeric($value); - if($ret) - { - $f = 'is_'.$field_type; + + if ($ret) { + $f = 'is_' . $field_type; settype($value, $field_type); $ret = $f($value); } @@ -104,21 +96,62 @@ return $ret ? $value : false; } - function TypeCastArray($src, &$object) + /** + * Formats number, according to regional settings + * + * @param string $number + * @return float + */ + function formatNumber($number) { - $dst = array(); + static $comma = null, $thousands = null; + + if ( !isset($comma) || !isset($thousands) ) { + $lang =& $this->Application->recallObject('lang.current'); + /* @var $lang LanguagesItem */ + + $comma = $lang->GetDBField('DecimalPoint'); + $thousands = $lang->GetDBField('ThousandSep'); + } + + $number = str_replace($thousands, '', $number); + $number = str_replace($comma, '.', $number); + + return $number; + } + + /** + * Applies type casting on each array element + * @param Array $src + * @param kDBItem|kDBList|kDBBase $object + * @return Array + * @access public + */ + public function TypeCastArray($src, &$object) + { + $dst = array (); + foreach ($src as $id => $row) { - $tmp_row = array(); + $tmp_row = array (); foreach ($row as $fld => $value) { $field_options = $object->GetFieldOptions($fld); $tmp_row[$fld] = $this->TypeCast($value, $field_options); } $dst[$id] = $tmp_row; } + return $dst; } -//function Format($value, $options, &$errors) + /** + * Formats value of a given field + * + * @param string $value + * @param string $field_name + * @param kDBItem|kDBList|kDBBase $object + * @param string $format + * @return string + */ function Format($value, $field_name, &$object, $format = null) { if ( is_null($value) ) { @@ -148,6 +181,8 @@ if (preg_match('#int|integer|double|float|real|numeric#', $options['type'])) { $lang =& $this->Application->recallObject('lang.current'); + /* @var $lang LanguagesItem */ + return $lang->formatNumber($value); } elseif ($options['type'] == 'string') { @@ -162,17 +197,19 @@ * * @param mixed $value * @param string $field_name - * @param kDBItem $object + * @param kDBItem|kDBList|kDBBase $object * @return mixed + * @access public */ - function Parse($value, $field_name, &$object) + public function Parse($value, $field_name, &$object) { if ($value == '') { return NULL; } $options = $object->GetFieldOptions($field_name); - $tc_value = $this->TypeCast($value,$options); + $tc_value = $this->TypeCast($value, $options); + if ($tc_value === false) { return $value; // for leaving badly formatted date on the form } @@ -216,12 +253,14 @@ * Used for split fields like timestamp -> date, time * Called from DBItem to update sub fields values after loading item * - * @param unknown_type $field - * @param unknown_type $value - * @param unknown_type $options - * @param unknown_type $object + * @param string $field + * @param string $value + * @param Array $options + * @param kDBItem|kDBList|kDBBase $object + * @return void + * @access public */ - function UpdateSubFields($field, $value, &$options, &$object) + public function UpdateSubFields($field, $value, &$options, &$object) { } @@ -233,26 +272,25 @@ * @param string $field * @param mixed $value * @param Array $options - * @param kDBItem $object + * @param kDBItem|kDBList|kDBBase $object */ function UpdateMasterFields($field, $value, &$options, &$object) { } -/* function GetErrorMsg($pseudo_error, $options) + /** + * Return sample value, that can be entered in this field + * + * @param string $field + * @param Array $options + * @param kDBItem|kDBList|kDBBase $object + * @return string + * @access public + */ + public function GetSample($field, &$options, &$object) { - if ( isset($options['error_msgs'][$pseudo_error]) ) { - return $options['error_msgs'][$pseudo_error]; - } - else { - return $this->ErrorMsgs[$pseudo_error]; - } - }*/ - - function GetSample($field, &$options, &$object) - { - if (isset($options['sample_value'])) return $options['sample_value']; + return isset($options['sample_value']) ? $options['sample_value'] : ''; } } \ No newline at end of file Index: branches/5.2.x/core/admin_templates/login.tpl =================================================================== diff -u -N -r14502 -r14596 --- branches/5.2.x/core/admin_templates/login.tpl (.../login.tpl) (revision 14502) +++ branches/5.2.x/core/admin_templates/login.tpl (.../login.tpl) (revision 14596) @@ -124,6 +124,8 @@
+ +