Сейчас мы с вами реализуем личный кабинет покупателя. Согласитесь, что это очень полезная фишка для реализации систем лояльности. В данном курсе мы, правда, ограничимся только профилем пользователя и историей его заказов.
В данном уроке нам понадобится пара платных компонентов из репозитория modstore.pro:
Создадим с вами группу пользователей Users, для этого перейдем в Контроль доступа->Новая группа ресурсов:
Кроме того, я поставил галочку на опции “Создать параллельную группу ресурсов”, с помощью которой мы с вами будем скрывать от анонимных пользователей страницы личного кабинета. Теперь, чтобы настроить нашу группу пользователей, нам необходимо кликнуть по ней правой кнопкой мыши и нажать на “Редактирование”. Нас интересует вкладка “Права доступа”. На вкладке “Доступ к контекстам” у контекста web необходимо выставить политику доступа “Load, List and View”:
Аналогично действуем с группой ресурсов “Users” на вкладке “Доступ к группам ресурсов” и после не забываем нажать “Сохранить”:
Так как MODx по умолчанию выставляет некорректные права доступа для групп пользователей, нам необходимо отредактировать группу пользователей “аноним”. Нас интересует вкладка “Доступ к группам ресурсов”, где нужно выставить группе ресурсов “users” политику доступа “Load Only”. Не забудьте нажать кнопку “Сохранить”.
Мы с вами настроили наши права, теперь нам необходимо создать страницы авторизации и личного кабинета. Я создал шаблон для страницы авторизации и выглядит он следующим образом:
{extends 'file:templates/index.tpl'} {block 'content'} {include 'file:chunks/breadcrumbs.tpl'} <!-- CONTENT --> <section class="def-section content"> <div class="container"> <h1>{$_modx->resource.longtitle ?: $_modx->resource.pagetitle}</h1> {$_modx->resource.content} {$_modx->runSnippet(“!officeAuth”,[ 'groups' => 'Users', 'loginResourceId' => '23', 'HybridAuth' => '0' ])} </div> </section> <!-- / CONTENT --> {/block}
Так как я адаптировал под себя стандартный чанк Office, то я не буду указывать в парметрах чанки. Параметр loginResourceId отвечает за переадресацию после успешной авторизации. У меня это страница со списком заказов:
Если все настроили корректно, то у вас выведется форма авторизации и регистрации, которые вы можете проверить. А мы тем временем перейдем с вами к нашему личному кабинету. У всех страниц я оставил шаблон текстовой страницы. Предлагаю вам реализовать страницу редактирования профиля:
Я снял галочки с опций “Доступен для поиска” и “Использовать HTML-редактор” (это же необходимо сделать со страницей истории заказов) и разместил поле “Содержимое ресурса” вызов сниппета officeProfile:
{$_modx->runSnippet("!officeProfile", [ "tplProfile" => "@FILE chunks/office_profile.tpl" ])}
Чанк office_profile.tpl (его вид может быть лучше, можете сами настроить его с помощью Bootstrap 4):
<form action="" method="post" class="form-horizontal well" id="office-profile-form" enctype="multipart/form-data"> <div class="header"> <small>{'office_profile_header' | lexicon}</small> </div> <div class="form-group avatar"> {$_modx->runSnippet("!uaAvatar")} </div> <div class="form-group"> <label class="col-sm-2 control-label">{'office_profile_username' | lexicon}<sup class="red">*</sup></label> <div class="col-sm-10"> <input type="text" name="username" value="{$username}" placeholder="{'office_profile_username' | lexicon}" class="form-control"/> <p class="help-block message">{$error_username}</p> <p class="help-block desc">{'office_profile_username_desc' | lexicon}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">{'office_profile_fullname' | lexicon}<sup class="red">*</sup></label> <div class="col-sm-10"> <input type="text" name="fullname" value="{$fullname}" placeholder="{'office_profile_fullname' | lexicon}" class="form-control"/> <p class="help-block message">{$error_fullname}</p> <p class="help-block desc">{'office_profile_fullname_desc' | lexicon}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">{'office_profile_email' | lexicon}<sup class="red">*</sup></label> <div class="col-sm-10"> <input type="text" name="email" value="{$email}" placeholder="{'office_profile_email' | lexicon}" class="form-control"/> <p class="help-block message">{$error_email}</p> <p class="help-block desc">{'office_profile_email_desc' | lexicon}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label"> {'office_profile_phone' | lexicon}{if $_modx->config.office_auth_mode == 'phone'} <span class="red">*</span>{/if} </label> <div class="col-md-10"> <input type="text" name="mobilephone" placeholder="" value="{$mobilephone}" class="form-control"/> <p class="help-block message">{$error_mobilephone}</p> <p class="help-block desc">{'office_profile_phone_desc' | lexicon}</p> </div> </div> <div class="form-group hidden"> <label class="col-sm-2 control-label">{'office_auth_register_phone_code' | lexicon}</label> <div class="col-md-10"> <input type="text" name="phone_code" value="" class="form-control"/> <p class="help-block message">{$error_phone_code}</p> <p class="help-block desc">{'office_profile_phone_code_desc' | lexicon}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">{'office_profile_password' | lexicon}</label> <div class="col-sm-10"> <input type="password" name="specifiedpassword" value="" placeholder="********" class="form-control"/> <p class="help-block message">{$error_specifiedpassword}</p> <p class="help-block desc">{'office_profile_specifiedpassword_desc' | lexicon}</p> <input type="password" name="confirmpassword" value="" placeholder="********" class="form-control"/> <p class="help-block message">{$error_confirmpassword}</p> <p class="help-block desc">{'office_profile_confirmpassword_desc' | lexicon}</p> </div> </div> {if $providers?} <div class="form-group"> <label class="col-sm-2 control-label">{'ha.providers_available' | lexicon}</label> <div class="col-sm-10"> {$providers} </div> </div> {/if} <hr/> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-primary">{'office_profile_save' | lexicon}</button> <a class="btn btn-danger" href="{$_modx->resource.id | url : [] : ['action' => 'auth/logout']}">{'office_profile_logout' | lexicon}</a> </div> </div> </form>
Со страницей истории заказов нам достаточно разместить следующий вызов сниппета Office в поле “Содержимое ресурса”:
{$_modx->runSnippet("!Office", [ "action" => "miniShop2" ])}
Сейчас перейдем в “Содержимое”->”Группы ресурсов” и перетащим созданные нами страницы в группу ресурсов “Users”:
Для того, чтобюы нам настроить 403 страницу, необходимо зайти в системные настройки и для настройки “unauthorized_page” указать ID страницы с формой авторизации:
Отлично! Теперь выведем меню для авторизованных пользователей в чанке header:
{if $_modx->user.id > 0} <div class="dropdown"> <a href="{44 | url}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {if $_modx->user.id | user : 'photo'} <img src="{$_modx->getPlaceholder('+nophoto') | phpthumbon : 'w=20&h=20&zc=1&q=99'}" alt="{$_modx->user.id | user : 'username' | htmlent}" /> {else} <img src="{$_modx->user.id | user : 'photo' | phpthumbon : 'w=20&h=20&zc=1&q=99'}" alt="{$_modx->user.id | user : 'username' | htmlent}"> {/if} {$_modx->user.id | user : 'username'} <i class="fa fa-angle-down"></i> </a> {$_modx->runSnippet('pdoMenu', [ 'parents' => '21', 'limit' => 0, 'outerClass' => 'dropdown-menu', 'tplOuter' => '@INLINE <ul[[+classes]]>[[+wrapper]]<li><a href="{24 | url : [\'scheme\' => \'full\'] : [\'action\' => \'auth/logout\']}">Выйти</a></li></ul>' ])} </div> {else} <a href="{24 | url}"> Вход/Регистрация </a> {/if}
Вот и реализован наш личный кабинет покупателя, который в дальнейшем мы сможем расширить.