В версии 6.1.4 появилась возможность пользователям сайта входить на сайты HostCMS через протокол OAuth. В данной теме будет доступно обновление XSL и типовой личного кабинета без которого данный функционал не будет доступен после стандартного обновления системы HostCMS.
XSL "ЛичныйКабинетПользователя" был изменен, полный код нового шаблона:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:hostcms="http://www.hostcms.ru/"
exclude-result-prefixes="hostcms">
<xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" encoding="utf-8" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml"/>
<xsl:template match="/siteuser">
<xsl:choose>
<!-- Авторизованный пользователь -->
<xsl:when test="@id > 0">
<h1>Пользователь <xsl:value-of select="login" /></h1>
<!-- Выводим меню -->
<ul class="users">
<xsl:apply-templates select="item"/>
</ul>
</xsl:when>
<!-- Неавторизованный пользователь -->
<xsl:otherwise>
<div class="authorization">
<h1>Личный кабинет</h1>
<!-- Выводим ошибку, если она была передана через внешний параметр -->
<xsl:if test="error/node()">
<div id="error">
<xsl:value-of select="error"/>
</div>
</xsl:if>
<form action="/users/" method="post">
<p>Пользователь:
<br /><input name="login" type="text" size="30" class="large" />
</p>
<p>Пароль:
<br /><input name="password" type="password" size="30" class="large" />
</p>
<p>
<label><input name="remember" type="checkbox" /> Запомнить меня на сайте.</label>
</p>
<input name="apply" type="submit" value="Войти" class="button" />
<!-- Страница редиректа после авторизации -->
<xsl:if test="location/node()">
<input name="location" type="hidden" value="{location}" />
</xsl:if>
</form>
<p>Первый раз на сайте? — <a href="/users/registration/">Зарегистрируйтесь</a>!</p>
<p>Забыли пароль? Мы можем его <a href="/users/restore_password/">восстановить</a>.</p>
</div>
<xsl:if test="count(site/siteuser_identity_provider)">
<div class="authorization">
<xsl:if test="count(site/siteuser_identity_provider[type = 1])">
<h1>OAuth</h1>
<xsl:for-each select="site/siteuser_identity_provider[image != '' and type = 1]">
<xsl:element name="a">
<xsl:attribute name="href">
?oauth_provider=<xsl:value-of select="@id"/>
</xsl:attribute>
<img src="{dir}{image}" alt="{name}"/>
</xsl:element> 
</xsl:for-each>
</xsl:if>
<h1>OpenID</h1>
<!-- Выводим ошибку, если она была передана через внешний параметр -->
<xsl:if test="provider_error/node()">
<div id="error">
<xsl:value-of select="provider_error"/>
</div>
</xsl:if>
<xsl:if test="count(site/siteuser_identity_provider[type = 0])">
<form action="/users/" method="post">
<p>Войти с помощью:</p>
<xsl:for-each select="site/siteuser_identity_provider[image != '' and type = 0]">
<label>
<input type="radio" name="identity_provider" value="{@id}">
<xsl:if test="position() = 1">
<xsl:attribute name="checked">checked</xsl:attribute>
</xsl:if>
</input> <img src="{dir}{image}" alt="{name}" title="{name}" />
</label>
</xsl:for-each>
<p>Логин в выбранном сервисе:
<br /><input name="openid_login" type="text" size="30" class="large" />
</p>
<input name="applyOpenIDLogin" type="submit" value="Войти" class="button" />
</form>
<form action="/users/" method="post">
<p>или введите OpenID вручную:
<br /><input name="openid" type="text" size="30" class="large" />
</p>
<input name="applyOpenID" type="submit" value="Войти" class="button" />
</form>
</xsl:if>
</div>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="item">
<li style="background: url('{image}') no-repeat 11px 5px">
<a href="{path}">
<xsl:value-of select="name"/>
</a>
</li>
</xsl:template>
</xsl:stylesheet>
Настройки типовой динамической "Пользователи сайта" были изменены:
// Авторизация OAuth
if(!is_null($oauth_provider = Core_Array::getGet('oauth_provider')))
{
try
{
Core_Session::start();
Core_Array::set($_SESSION, 'oauth_provider', $oauth_provider);
$oSiteuser_Oauth_Controller = Siteuser_Oauth_Controller::factory($oauth_provider);
if(is_null($oSiteuser_Oauth_Controller))
{
throw new Exception('Class does not exist');
}
Core_Array::set($_SESSION, 'oauth_data', $oSiteuser_Oauth_Controller->execute());
die();
}
catch (Exception $e){}
}
$bTwitter = !is_null($oauth_token = Core_Array::getGet('oauth_token')) && !is_null($oauth_verifier = Core_Array::getGet('oauth_verifier'));
// Встречаем ответ Вконтакте/Facebook/Одноклассники/Google+/Яндекс/Mail.ru/Twitter
if(!is_null($code = Core_Array::getGet('code')) || $bTwitter)
{
$oauth_provider = Core_Array::get($_SESSION, 'oauth_provider');
$oSiteuser_Oauth_Controller = Siteuser_Oauth_Controller::factory($oauth_provider);
if(is_null($oSiteuser_Oauth_Controller))
{
throw new Exception('Class does not exist');
}
if ($bTwitter)
{
$oSiteuser_Oauth_Controller->oauth_token_secret = Core_Array::get($_SESSION, 'oauth_data');
$oSiteuser_Oauth_Controller->oauth_token = $oauth_token;
$oSiteuser_Oauth_Controller->oauth_verifier = $oauth_verifier;
}
else
{
$oSiteuser_Oauth_Controller->code = $code;
}
$aResult = $oSiteuser_Oauth_Controller->execute();
if(is_null(Core_Array::get($aResult, 'error')))
{
if (!is_null($user_id = Core_Array::get($aResult, 'user_id')))
{
$oCurrentSiteuser = NULL;
$oSiteuser_Identity = Core_Entity::factory('Siteuser_Identity');
$oSiteuser_Identity->queryBuilder()
->where('siteuser_identity_provider_id', '=', $oauth_provider)
->where('identity', '=', $user_id)
->limit(1);
$aSiteuser_Identities = $oSiteuser_Identity->findAll(FALSE);
if (!count($aSiteuser_Identities))
{
$oSite = Core_Entity::factory('Site', CURRENT_SITE);
if(!is_null($user_login = Core_Array::get($aResult, 'login')))
{
$oSiteuser = $oSite->Siteusers->getByLogin($user_login, FALSE);
$sUserLogin = is_null($oSiteuser)
? $user_login
: '';
}
else
{
$sUserLogin = '';
}
if(!is_null($user_email = Core_Array::get($aResult, 'email')))
{
$oSiteuser = $oSite->Siteusers->getByEmail($user_email, FALSE);
$sUserEmail = !is_null($oSiteuser)
? $user_email
: '';
}
else
{
$sUserEmail = '';
}
// Create new siteuser
$oSiteuser = Core_Entity::factory('Siteuser');
$oSiteuser->login = $sUserLogin;
$oSiteuser->password = Core_Hash::instance()->hash(Core_Password::get(12));
$oSiteuser->email = $sUserEmail;
$oSiteuser->name = Core_Array::get($aResult, 'name', '');
$oSiteuser->surname = Core_Array::get($aResult, 'surname', '');
$oSiteuser->company = Core_Array::get($aResult, 'company', '');
$oSiteuser->save();
if (!is_null($sPicture = Core_Array::get($aResult, 'picture')) && $sPicture != '')
{
// Ищем свойство аватара
$oSiteuser_Property_List = Core_Entity::factory('Siteuser_Property_List', CURRENT_SITE);
$oProperty = $oSiteuser_Property_List->Properties->getByname('Аватар', FALSE);
if(!is_null($oProperty))
{
// Папка назначения
$sDestinationFolder = $oSiteuser->getDirPath();
// Файл-источник
$sSourceFile = $sPicture;
// Создаем папку назначения
$oSiteuser->createDir();
// Файл из WEB'а, создаем временный файл
$sTempFileName = tempnam(CMS_FOLDER . TMP_DIR, "CMS");
// Копируем содержимое WEB-файла в локальный временный файл
file_put_contents($sTempFileName, file_get_contents($sSourceFile));
// Файл-источник равен временному файлу
$sSourceFile = $sTempFileName;
switch(Core_Image::exifImagetype($sSourceFile))
{
case 1:
$sExt = 'gif';
break;
case 2:
$sExt = 'jpeg';
break;
case 3:
$sExt = 'png';
break;
default:
$sExt = 'jpeg';
break;
}
$sTargetFileName = "property_{$oProperty->id}.{$sExt}";
// Создаем массив параметров для загрузки картинок элементу
$aPicturesParam = array();
$aPicturesParam['large_image_isset'] = TRUE;
$aPicturesParam['large_image_source'] = $sSourceFile;
$aPicturesParam['large_image_name'] = "avatar.{$sExt}";
$aPicturesParam['large_image_target'] = $sDestinationFolder . $sTargetFileName;
$aPicturesParam['large_image_preserve_aspect_ratio'] = TRUE;
$aPicturesParam['large_image_max_width'] = $oProperty->image_large_max_width;
$aPicturesParam['large_image_max_height'] = $oProperty->image_large_max_height;
$aPicturesParam['large_image_watermark'] = FALSE;
$aPicturesParam['create_small_image_from_large'] = FALSE;
$aPropertyValues = $oProperty->getValues($oSiteuser->id, FALSE);
$oProperty_Value = count($aPropertyValues)
? $aPropertyValues[0]
: $oProperty->createNewValue($oSiteuser->id);
// Удаляем старое большое изображение
if ($oProperty_Value->file != '')
{
try
{
Core_File::delete($sDestinationFolder . $oProperty_Value->file);
} catch (Exception $e) {}
}
try
{
$aResult = Core_File::adminUpload($aPicturesParam);
}
catch (Exception $exc)
{
Core_Message::show($exc->getMessage(), 'error');
$aResult = array('large_image' => FALSE);
}
if ($aResult['large_image'])
{
$oProperty_Value->file = $sTargetFileName;
$oProperty_Value->file_name = '';
}
$oProperty_Value->save();
// Файл временный, подлежит удалению
try
{
Core_File::delete($sSourceFile);
} catch (Exception $e) {}
}
}
if($sUserLogin == '')
{
$oSiteuser->login = 'id' . $oSiteuser->id;
$oSiteuser->save();
}
// Add siteuser's identity
$oSiteuser_Identity = Core_Entity::factory('Siteuser_Identity');
$oSiteuser_Identity->siteuser_identity_provider_id = $oauth_provider;
$oSiteuser_Identity->identity = $user_id;
$oSiteuser->add($oSiteuser_Identity);
// Add into default group
$oSiteuser_Group = $oSiteuser->Site->Siteuser_Groups->getDefault();
if (!is_null($oSiteuser_Group))
{
$oSiteuser_Group->add($oSiteuser);
}
$oSiteuser->activate();
}
else
{
$oSiteuser = $aSiteuser_Identities[0]->Siteuser;
}
$oSiteuser->setCurrent();
$Siteuser_Controller_Show->setEntity($oSiteuser);
}
else
{
throw new Exception("Can't detect siteuser id!");
}
}
else
{
$error = Core_Array::get($aResult, 'error');
$error_description = Core_Array::get($aResult, 'error_description');
throw new Exception("Error: {$error} - {$error_description}");
}
}
вставлять после строки
$Siteuser_Controller_Show = new Siteuser_Controller_Show(
$oSiteuser
);