Выбор группы пользователем из выпадающего списка при регистрации — различия между версиями
| Williwaw (обсуждение | вклад)  (Новая страница: «'''Актуально для версии 2.9.5'''  == Задача ==  Предположим, необходимо дать пользователю при рег…») | Williwaw (обсуждение | вклад)  | ||
| (не показано 6 промежуточных версий этого же участника) | |||
| Строка 1: | Строка 1: | ||
| '''Актуально для версии 2.9.5''' | '''Актуально для версии 2.9.5''' | ||
| + | |||
| + | Данное решение рассмотрено на примере интернет-магазина "Современный", шаблон demodizzy.  | ||
| == Задача == | == Задача == | ||
| Строка 29: | Строка 31: | ||
| 	return def_module::parseTemplate($itemsTemplate, $items); | 	return def_module::parseTemplate($itemsTemplate, $items); | ||
| } | } | ||
| + | </source> | ||
| + | |||
| + | Теперь,идем в шаблон, по которому выводится форма регистрации(templates/demodizzy/xslt/modules/users/registration.xsl) и добавим туда вызов макроса: | ||
| + | |||
| + | <source lang="xml"> | ||
| + | |||
| + | <div> | ||
| + |      <label class="required"> | ||
| + |          <span> | ||
| + | 	      <xsl:text>группа:</xsl:text> | ||
| + | 	</span> | ||
| + | 	<xsl:apply-templates select="document('udata://users/selected_groups/')/udata" /> | ||
| + |      </label> | ||
| + | </div>  | ||
| + | </source> | ||
| + | |||
| + | и шаблон обработки результатов, который будет выводить выбранные группы в выпадающем списке: | ||
| + | |||
| + | <source lang="xml"> | ||
| + | |||
| + | <xsl:template match="udata[@module = 'users'][@method = 'selected_groups']"> | ||
| + | 	<select name = 'group' id = 'group'> | ||
| + | 		<xsl:for-each select = "./items/item"> | ||
| + | 			<option value = "{./@id}"> | ||
| + | 			         <xsl:value-of select = "./@name"/> | ||
| + | 			</option> | ||
| + | 		</xsl:for-each> | ||
| + | 	</select> | ||
| + | </xsl:template> | ||
| </source> | </source> | ||
| − | + | Теперь нам нужно написать метод, который обработает введенные пользователем данные и запишет его в выбранную им же группу. | |
| − | Переименуем его, например, в  | + | Для этого можно воспользоваться стандартным методом registrate_do, немного его изменив. Идем в  /classes/modules/users/_register.php, | 
| + | полностью копируем оттуда метод registrate_do и вставляем в файл __custom.php, в этой же директории.   | ||
| + | Переименуем его, например, в registrate_do_custom. | ||
| Начальный код метода: | Начальный код метода: | ||
| <source lang="php"> | <source lang="php"> | ||
| − | public function  | + | public function registrate_do_custom($template = "default") { | 
| + | 	if ($this->is_auth()) { | ||
| + | 	$this->redirect($this->pre_lang . "/"); | ||
| + | 	} | ||
| + | 	if(!($template = getRequest('template'))) { | ||
| + | 		$template = 'default'; | ||
| + | 	} | ||
| + | 	$objectTypes = umiObjectTypesCollection::getInstance(); | ||
| + | 	$regedit = regedit::getInstance(); | ||
| + | |||
| + | 	$refererUrl = getServer('HTTP_REFERER'); | ||
| + | 	$without_act = (bool) $regedit->getVal("//modules/users/without_act"); | ||
| − | + | 	$objectTypeId = $objectTypes->getBaseType("users", "user"); | |
| − | + | 	if ($customObjectTypeId = getRequest('type-id')) { | |
| − | + | 		$childClasses = $objectTypes->getChildClasses($objectTypeId); | |
| − | + | 		if (in_array($customObjectTypeId, $childClasses)) { | |
| − | + | 			$objectTypeId = $customObjectTypeId; | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | 			$ | ||
| 		} | 		} | ||
| + | 	} | ||
| + | |||
| + | 	$objectType = $objectTypes->getType($objectTypeId); | ||
| + | |||
| + | 	$this->errorSetErrorPage($refererUrl); | ||
| + | |||
| + | 	$login = $this->validateLogin(getRequest('login'), false, true); | ||
| + | 	$password = $this->validatePassword(getRequest('password'), getRequest('password_confirm'), getRequest('login'), true); | ||
| + | 	$email = $this->validateEmail(getRequest('email'), false, !$without_act); | ||
| + | |||
| + | 	//Captcha validation | ||
| + | 	if (isset($_REQUEST['captcha'])) { | ||
| + | 		$_SESSION['user_captcha'] = md5((int) getRequest('captcha')); | ||
| + | 	} | ||
| + | |||
| + | 	if (!umiCaptcha::checkCaptcha()) { | ||
| + | 		$this->errorAddErrors('errors_wrong_captcha'); | ||
| + | 	} | ||
| + | |||
| + | 	$this->errorThrow('public'); | ||
| + | |||
| + | 	$oEventPoint = new umiEventPoint("users_registrate"); | ||
| + | 	$oEventPoint->setMode("before"); | ||
| + | 	$oEventPoint->setParam("login", $login); | ||
| + | 	$oEventPoint->addRef("password", $password); | ||
| + | 	$oEventPoint->addRef("email", $email); | ||
| + | 	$this->setEventPoint($oEventPoint); | ||
| + | |||
| + | 	//Creating user... | ||
| + | 	$objectId = umiObjectsCollection::getInstance()->addObject($login, $objectTypeId); | ||
| + | 	$activationCode = md5($login . time()); | ||
| + | |||
| + | 	$object = umiObjectsCollection::getInstance()->getObject($objectId); | ||
| + | |||
| + | 	$object->setValue("login", $login); | ||
| + | 	$object->setValue("password", md5($password)); | ||
| + | 	$object->setValue("e-mail", $email); | ||
| + | |||
| + | 	$object->setValue("is_activated", $without_act); | ||
| + | 	$object->setValue("activate_code", $activationCode); | ||
| + | 	$object->setValue("referer", urldecode(getSession("http_referer"))); | ||
| + | 	$object->setValue("target", urldecode(getSession("http_target"))); | ||
| + | 	$object->setValue("register_date", umiDate::getCurrentTimeStamp()); | ||
| + | 	$object->setOwnerId($objectId); | ||
| + | |||
| + | 	if ($without_act) { | ||
| + | 		$_SESSION['cms_login'] = $login; | ||
| + | 		$_SESSION['cms_pass'] = md5($password); | ||
| + | 		$_SESSION['user_id'] = $objectId; | ||
| + | |||
| + | 		session_commit(); | ||
| + | 	} | ||
| + | |||
| + | 	$group_id = regedit::getInstance()->getVal("//modules/users/def_group"); | ||
| + | 	$object->setValue("groups", Array($group_id)); | ||
| + | |||
| + | 	cmsController::getInstance()->getModule('data'); | ||
| + | 	$data_module = cmsController::getInstance()->getModule('data'); | ||
| + | 	$data_module->saveEditedObjectWithIgnorePermissions($objectId, true, true); | ||
| − | + | 	$object->commit(); | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | 	if ($eshop_module = cmsController::getInstance()->getModule('eshop')) { | |
| − | + | 		$eshop_module->discountCardSave($objectId); | |
| − | + | 	} | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | 		$ | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | 	//Forming mail... | |
| − | + | 	list($template_mail, $template_mail_subject, $template_mail_noactivation, $template_mail_subject_noactivation) = def_module::loadTemplatesForMail("users/register/".$template,"mail_registrated", "mail_registrated_subject","mail_registrated_noactivation", "mail_registrated_subject_noactivation"); | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | 	if ($without_act && $template_mail_noactivation && $template_mail_subject_noactivation) { | |
| − | + | 		$template_mail = $template_mail_noactivation; | |
| − | + | 		$template_mail_subject = $template_mail_subject_noactivation; | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | 		$ | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| 	} | 	} | ||
| − | |||
| − | |||
| − | + | 	$mailData = array( | |
| − | $ | + | 		'user_id' => $objectId, | 
| − | + | 		'domain' => $domain = cmsController::getInstance()->getCurrentDomain()->getCurrentHostName(), | |
| + | 		'activate_link' => "http://" . $domain . $this->pre_lang . "/users/activate/" . $activationCode . "/", | ||
| + | 		'login' => $login, | ||
| + | 		'password' => $password, | ||
| + | 		'lname' => $object->getValue("lname"), | ||
| + | 		'fname' => $object->getValue("fname"), | ||
| + | 		'father_name' => $object->getValue("father_name"), | ||
| + | 	); | ||
| + | |||
| + | 	$mailContent = def_module::parseTemplateForMail($template_mail, $mailData, false, $objectId); | ||
| + | 	$mailSubject = def_module::parseTemplateForMail($template_mail_subject, $mailData, false, $objectId); | ||
| + | |||
| + | 	$fio = $object->getValue("lname") . " " . $object->getValue("fname") . " " . $object->getValue("father_name"); | ||
| + | |||
| + | 	$email_from = regedit::getInstance()->getVal("//settings/email_from"); | ||
| + | 	$fio_from = regedit::getInstance()->getVal("//settings/fio_from"); | ||
| + | |||
| + | |||
| + | 	$registrationMail = new umiMail(); | ||
| + | 	$registrationMail->addRecipient($email, $fio); | ||
| + | 	$registrationMail->setFrom($email_from, $fio_from); | ||
| + | 	$registrationMail->setSubject($mailSubject); | ||
| + | 	$registrationMail->setContent($mailContent); | ||
| + | 	$registrationMail->commit(); | ||
| + | 	$registrationMail->send(); | ||
| + | |||
| + | 	$oEventPoint = new umiEventPoint("users_registrate"); | ||
| + | 	$oEventPoint->setMode("after"); | ||
| + | 	$oEventPoint->setParam("user_id", $objectId); | ||
| + | 	$oEventPoint->setParam("login", $login); | ||
| + | 	$this->setEventPoint($oEventPoint); | ||
| − | + | 	if ($without_act) { | |
| − | + | 		$this->redirect($this->pre_lang . "/users/registrate_done/?result=without_activation"); | |
| + | 	}  | ||
| + |         else { | ||
| + | 		$this->redirect($this->pre_lang . "/users/registrate_done/"); | ||
| + | 	} | ||
| − | + | }	 | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| </source> | </source> | ||
| − | + | Чтобы не дать возможности пользователю зарегистрировать каким-либо образом в качестве супервайзера, перед тем как записывать пользователя в базу добавим проверку на то, не является ли переданный id группы id группы супервайзеров. Если пользователь попытался зарегистрироваться супервайзером, его будет редиректить на главную страницу, а ,на указанную при регистрации почту, будет выслано письмо с предупреждением. Находим в коде строку комментария //Creating user... и после нее вставляем следующий код: | |
| <source lang="php"> | <source lang="php"> | ||
| − | + | $igroup = getRequest('group'); | |
| − | + | $objects = umiObjectsCollection::getInstance(); | |
| − | + | $SupervisorGroupId = $objects->getObjectIdByGUID('users-users-15'); | |
| − | + | if ($igroup != $SupervisorGroupId){  | |
| − | + |      $group_id = $igroup; | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| }   | }   | ||
| − | + | else { | |
| + |      $name = 'admin'; | ||
| + |      $email = 'admin@adress.com'; | ||
| + |      $recipient = $email; | ||
| + |      $mail_body = 'Зарегистрироваться супервайзером нельзя.'; | ||
| + |      $subject = 'Даже не пытайтесь.'; | ||
| + |      $header = "From: ". $name . " <" . $email . ">\r\n"; | ||
| + |      mail($recipient, $subject, $mail_body, $header); | ||
| + |      $this->redirect('/'); | ||
| + |      exit(); | ||
| + | } | ||
| </source> | </source> | ||
| − | + | Теперь находим следующие строки: | |
| <source lang="php"> | <source lang="php"> | ||
| − | $ | + | $group_id = regedit::getInstance()->getVal("//modules/users/def_group"); | 
| + | $object->setValue("groups", Array($group_id)); | ||
| </source> | </source> | ||
| − | + | Первую строку удаляем, а вторую вырезаем и вставляем после этих строк: | |
| + | |||
| <source lang="php"> | <source lang="php"> | ||
| − | + | $object->setValue("register_date", umiDate::getCurrentTimeStamp()); | |
| − | + | $object->setOwnerId($objectId); | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| </source> | </source> | ||
| − | |||
| − | [[Категория:Написание кастомных макросов]][[Категория:Модуль  | + | Теперь, осталось только изменить в шаблоне  формы регистрации  action на "%pre_lang%/users/registrate_do_custom/ и добавить permissions.custom.php в директорию класса users | 
| + | |||
| + | [[Категория:Написание кастомных макросов]][[Категория:Модуль Пользователи]] | ||
Текущая версия на 15:04, 31 января 2014
Актуально для версии 2.9.5
Данное решение рассмотрено на примере интернет-магазина "Современный", шаблон demodizzy.
Задача
Предположим, необходимо дать пользователю при регистрации возможность выбрать группу. Например, пользователь может зарегистрироваться как оптовый покупатель или розничный покупатель.
Решение
В первую очередь, необходимо написать кастомный макрос, который будет выбирать определенные группы пользователей для вывода их в выпадающем списке, так, чтобы в выборку не были включены группы "зарегистрированные пользователи" и "супервайзеры". Добавим в модуле шаблоны данных для типа "группы пользователей" поле типа чекбокс с названием, например, "для регистрации" и отметим в модуле пользователи этот чекбокс у необходимых групп.
Открываем файл /classes/modules/users/_custom.php и вставляем туда следующий метод:
public function selected_groups($template = 'default'){
		
	$groups = new selector('objects');
	$groups->types('object-type')->id('36');
	$groups->where('for_registration')->equals('1');
			
	list($itemsTemplate, $itemTemplate) = def_module::loadTemplates("users/{$template}", "items", "item");	
	$item = array();
	$items = array();
	foreach($groups as $group){
		$item['attribute:id'] = $group->getId();
		$item['attribute:name'] =  $group->getValue('nazvanie');
		$items[] = def_module::parseTemplate($itemTemplate, $item);
	}
	$items = array('subnodes:items' => $items);
	return def_module::parseTemplate($itemsTemplate, $items);
}
Теперь,идем в шаблон, по которому выводится форма регистрации(templates/demodizzy/xslt/modules/users/registration.xsl) и добавим туда вызов макроса:
<div>
     <label class="required">
         <span>
	      <xsl:text>группа:</xsl:text>
	</span>
	<xsl:apply-templates select="document('udata://users/selected_groups/')/udata" />
     </label>
</div>
и шаблон обработки результатов, который будет выводить выбранные группы в выпадающем списке:
<xsl:template match="udata[@module = 'users'][@method = 'selected_groups']">
	<select name = 'group' id = 'group'>
		<xsl:for-each select = "./items/item">
			<option value = "{./@id}">
			         <xsl:value-of select = "./@name"/>
			</option>
		</xsl:for-each>
	</select>
</xsl:template>
Теперь нам нужно написать метод, который обработает введенные пользователем данные и запишет его в выбранную им же группу.
Для этого можно воспользоваться стандартным методом registrate_do, немного его изменив. Идем в  /classes/modules/users/_register.php,
полностью копируем оттуда метод registrate_do и вставляем в файл __custom.php, в этой же директории. 
Переименуем его, например, в registrate_do_custom.
Начальный код метода:
public function registrate_do_custom($template = "default") {
	if ($this->is_auth()) {
	$this->redirect($this->pre_lang . "/");
	}
	if(!($template = getRequest('template'))) {
		$template = 'default';
	}
	$objectTypes = umiObjectTypesCollection::getInstance();
	$regedit = regedit::getInstance();
	$refererUrl = getServer('HTTP_REFERER');
	$without_act = (bool) $regedit->getVal("//modules/users/without_act");
	$objectTypeId = $objectTypes->getBaseType("users", "user");
	if ($customObjectTypeId = getRequest('type-id')) {
		$childClasses = $objectTypes->getChildClasses($objectTypeId);
		if (in_array($customObjectTypeId, $childClasses)) {
			$objectTypeId = $customObjectTypeId;
		}
	}
	$objectType = $objectTypes->getType($objectTypeId);
	$this->errorSetErrorPage($refererUrl);
	$login = $this->validateLogin(getRequest('login'), false, true);
	$password = $this->validatePassword(getRequest('password'), getRequest('password_confirm'), getRequest('login'), true);
	$email = $this->validateEmail(getRequest('email'), false, !$without_act);
	//Captcha validation
	if (isset($_REQUEST['captcha'])) {
		$_SESSION['user_captcha'] = md5((int) getRequest('captcha'));
	}
	if (!umiCaptcha::checkCaptcha()) {
		$this->errorAddErrors('errors_wrong_captcha');
	}
	$this->errorThrow('public');
	$oEventPoint = new umiEventPoint("users_registrate");
	$oEventPoint->setMode("before");
	$oEventPoint->setParam("login", $login);
	$oEventPoint->addRef("password", $password);
	$oEventPoint->addRef("email", $email);
	$this->setEventPoint($oEventPoint);
	//Creating user...
	$objectId = umiObjectsCollection::getInstance()->addObject($login, $objectTypeId);
	$activationCode = md5($login . time());
	$object = umiObjectsCollection::getInstance()->getObject($objectId);
	$object->setValue("login", $login);
	$object->setValue("password", md5($password));
	$object->setValue("e-mail", $email);
	$object->setValue("is_activated", $without_act);
	$object->setValue("activate_code", $activationCode);
	$object->setValue("referer", urldecode(getSession("http_referer")));
	$object->setValue("target", urldecode(getSession("http_target")));
	$object->setValue("register_date", umiDate::getCurrentTimeStamp());
	$object->setOwnerId($objectId);
	if ($without_act) {
		$_SESSION['cms_login'] = $login;
		$_SESSION['cms_pass'] = md5($password);
		$_SESSION['user_id'] = $objectId;
		session_commit();
	}
	$group_id = regedit::getInstance()->getVal("//modules/users/def_group");
	$object->setValue("groups", Array($group_id));
	cmsController::getInstance()->getModule('data');
	$data_module = cmsController::getInstance()->getModule('data');
	$data_module->saveEditedObjectWithIgnorePermissions($objectId, true, true);
	$object->commit();
	if ($eshop_module = cmsController::getInstance()->getModule('eshop')) {
		$eshop_module->discountCardSave($objectId);
	}
	//Forming mail...
	list($template_mail, $template_mail_subject, $template_mail_noactivation, $template_mail_subject_noactivation) = def_module::loadTemplatesForMail("users/register/".$template,"mail_registrated", "mail_registrated_subject","mail_registrated_noactivation", "mail_registrated_subject_noactivation");
	if ($without_act && $template_mail_noactivation && $template_mail_subject_noactivation) {
		$template_mail = $template_mail_noactivation;
		$template_mail_subject = $template_mail_subject_noactivation;
	}
	$mailData = array(
		'user_id' => $objectId,
		'domain' => $domain = cmsController::getInstance()->getCurrentDomain()->getCurrentHostName(),
		'activate_link' => "http://" . $domain . $this->pre_lang . "/users/activate/" . $activationCode . "/",
		'login' => $login,
		'password' => $password,
		'lname' => $object->getValue("lname"),
		'fname' => $object->getValue("fname"),
		'father_name' => $object->getValue("father_name"),
	);
	$mailContent = def_module::parseTemplateForMail($template_mail, $mailData, false, $objectId);
	$mailSubject = def_module::parseTemplateForMail($template_mail_subject, $mailData, false, $objectId);
	$fio = $object->getValue("lname") . " " . $object->getValue("fname") . " " . $object->getValue("father_name");
	$email_from = regedit::getInstance()->getVal("//settings/email_from");
	$fio_from = regedit::getInstance()->getVal("//settings/fio_from");
	$registrationMail = new umiMail();
	$registrationMail->addRecipient($email, $fio);
	$registrationMail->setFrom($email_from, $fio_from);
	$registrationMail->setSubject($mailSubject);
	$registrationMail->setContent($mailContent);
	$registrationMail->commit();
	$registrationMail->send();
	$oEventPoint = new umiEventPoint("users_registrate");
	$oEventPoint->setMode("after");
	$oEventPoint->setParam("user_id", $objectId);
	$oEventPoint->setParam("login", $login);
	$this->setEventPoint($oEventPoint);
	if ($without_act) {
		$this->redirect($this->pre_lang . "/users/registrate_done/?result=without_activation");
	} 
        else {
		$this->redirect($this->pre_lang . "/users/registrate_done/");
	}
}
Чтобы не дать возможности пользователю зарегистрировать каким-либо образом в качестве супервайзера, перед тем как записывать пользователя в базу добавим проверку на то, не является ли переданный id группы id группы супервайзеров. Если пользователь попытался зарегистрироваться супервайзером, его будет редиректить на главную страницу, а ,на указанную при регистрации почту, будет выслано письмо с предупреждением. Находим в коде строку комментария //Creating user... и после нее вставляем следующий код:
$igroup = getRequest('group');
$objects = umiObjectsCollection::getInstance();
$SupervisorGroupId = $objects->getObjectIdByGUID('users-users-15');
if ($igroup != $SupervisorGroupId){ 
     $group_id = $igroup;
} 
else {
     $name = 'admin';
     $email = 'admin@adress.com';
     $recipient = $email;
     $mail_body = 'Зарегистрироваться супервайзером нельзя.';
     $subject = 'Даже не пытайтесь.';
     $header = "From: ". $name . " <" . $email . ">\r\n";
     mail($recipient, $subject, $mail_body, $header);
     $this->redirect('/');
     exit();
}
Теперь находим следующие строки:
$group_id = regedit::getInstance()->getVal("//modules/users/def_group");
$object->setValue("groups", Array($group_id));
Первую строку удаляем, а вторую вырезаем и вставляем после этих строк:
$object->setValue("register_date", umiDate::getCurrentTimeStamp());
$object->setOwnerId($objectId);
Теперь, осталось только изменить в шаблоне  формы регистрации  action на "%pre_lang%/users/registrate_do_custom/ и добавить permissions.custom.php в директорию класса users
