253 lines
8.2 KiB
PHP
253 lines
8.2 KiB
PHP
<?php
|
|
|
|
namespace IPS\Login;
|
|
|
|
class _Vkontakte extends LoginAbstract
|
|
{
|
|
/**
|
|
* @brief Icon
|
|
*/
|
|
public static $icon = 'vk';
|
|
|
|
/**
|
|
* Get Form
|
|
*
|
|
* @param \IPS\Http\Url $url The URL for the login page
|
|
* @return string
|
|
*/
|
|
public function loginForm( $url, $ucp=FALSE )
|
|
{
|
|
$url = \IPS\Http\Url::internal( 'applications/core/interface/vkontakte/auth.php', 'none' );
|
|
|
|
if ( $ucp )
|
|
{
|
|
$state = "ucp-" . \IPS\Session::i()->csrfKey;
|
|
}
|
|
else
|
|
{
|
|
$state = \IPS\Dispatcher::i()->controllerLocation . "-" . \IPS\Session::i()->csrfKey;
|
|
}
|
|
|
|
return \IPS\Theme::i()->getTemplate( 'login', 'core', 'global' )->vkontakte( "https://oauth.vk.com/authorize?client_id={$this->settings['app_id']}&scope=email&redirect_uri=".urlencode( $url ) . "&state={$state}&response_type=code" );
|
|
|
|
}
|
|
|
|
/**
|
|
* Authenticate
|
|
*
|
|
* @param string $url The URL for the login page
|
|
* @param \IPS\Member $member If we want to integrate this login method with an existing member, provide the member object
|
|
* @return \IPS\Member
|
|
* @throws \IPS\Login\Exception
|
|
*/
|
|
public function authenticate( $url, $member=NULL )
|
|
{
|
|
$url = $url->setQueryString( 'loginProcess', 'vkontakte' );
|
|
|
|
try
|
|
{
|
|
|
|
/* Get a token */
|
|
try
|
|
{
|
|
$response = \IPS\Http\Url::external( "https://oauth.vk.com/access_token?client_id={$this->settings['app_id']}&redirect_uri=".(string) \IPS\Http\Url::internal( 'applications/core/interface/vkontakte/auth.php', 'none' )."&client_secret={$this->settings['app_secret']}&code=".\IPS\Request::i()->code
|
|
)->request()->get()->decodeJson();
|
|
}
|
|
catch( \RuntimeException $e )
|
|
{
|
|
throw new \IPS\Login\Exception( 'generic_error', \IPS\Login\Exception::INTERNAL_ERROR );
|
|
}
|
|
|
|
/* Get the user data */
|
|
$userData = $response;
|
|
if(!isset($userData['email'])) throw new \IPS\Login\Exception( 'В вашем аккаунте ВК отсутствует email, укажите его!', \IPS\Login\Exception::INTERNAL_ERROR );
|
|
/* Find or create member */
|
|
$newMember = FALSE;
|
|
if ( $member === NULL )
|
|
{
|
|
$member = \IPS\Member::load( $userData['email'], 'email' );
|
|
if ( !$member->member_id )
|
|
{
|
|
|
|
$member = new \IPS\Member;
|
|
if ( \IPS\Settings::i()->reg_auth_type == 'admin' or \IPS\Settings::i()->reg_auth_type == 'admin_user' )
|
|
{
|
|
$member->members_bitoptions['validating'] = TRUE;
|
|
}
|
|
$member->member_group_id = \IPS\Settings::i()->member_group;
|
|
$member->email = $userData['email'];
|
|
$member->profilesync = json_encode( array( 'vkontakte' => array( 'photo' => TRUE, 'cover' => FALSE, 'status' => TRUE ) ) );
|
|
$newMember = TRUE;
|
|
|
|
$name1 = \IPS\Http\Url::external( "https://api.vk.com/method/users.get?user_id={$userData['user_id']}&v=5.29&access_token={$response['access_token']}&fields=first_name,last_name,screen_name,bdate,nickname" )->request()->get()->decodeJson();
|
|
|
|
$member->name = $name1['response'][0]['nickname'];
|
|
|
|
if ( empty($member->name) AND $this->settings['real_name'] )
|
|
{
|
|
$name = $name1['response'][0]['first_name'].' '.$name1['response'][0]['last_name'];
|
|
$existingUsername = \IPS\Member::load( $name, 'name' );
|
|
|
|
if ( !$existingUsername->member_id )
|
|
{
|
|
$member->name = $name;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
$member->vk_uid = $userData['user_id'];
|
|
$member->vk_token = $response['access_token'];
|
|
$member->save();
|
|
|
|
/* Sync */
|
|
if ( $newMember )
|
|
{
|
|
if ( \IPS\Settings::i()->reg_auth_type == 'admin_user' )
|
|
{
|
|
\IPS\Db::i()->update( 'core_validating', array( 'user_verified' => 1 ), array( 'member_id=?', $member->member_id ) );
|
|
}
|
|
|
|
$sync = new \IPS\core\ProfileSync\VK( $member );
|
|
|
|
$sync->sync();
|
|
}
|
|
|
|
/* Return */
|
|
return $member;
|
|
}
|
|
catch ( \IPS\Http\Request\Exception $e )
|
|
{
|
|
throw new \IPS\Login\Exception( 'generic_error', \IPS\Login\Exception::INTERNAL_ERROR );
|
|
}
|
|
}
|
|
|
|
public static function link( \IPS\Member $member, $details )
|
|
{
|
|
try {
|
|
$userData = \IPS\Http\Url::external( "https://api.vk.com/method/users.get?uid={$details[1]}&access_token={$details[0]}&fields=first_name,last_name,screen_name,bdate,nickname" )->request()->get()->decodeJson();
|
|
$userData = $userData['response'][0];
|
|
$member->vk_id = $details[1];
|
|
$member->vk_token = $details[0];
|
|
$member->save();
|
|
}catch(\Exception $e) {}
|
|
}
|
|
|
|
/**
|
|
* ACP Settings Form
|
|
*
|
|
* @param string $url URL to redirect user to after successful submission
|
|
* @return array List of settings to save - settings will be stored to core_login_handlers.login_settings DB field
|
|
* @code
|
|
return array( 'savekey' => new \IPS\Helpers\Form\[Type]( ... ), ... );
|
|
* @endcode
|
|
*/
|
|
public function acpForm()
|
|
{
|
|
$where = array( array( 'template_group=?', 'login' ) );
|
|
|
|
$where[] = array( 'template_app=?', 'core' );
|
|
|
|
$where[] = array( 'template_location=?', 'global' );
|
|
|
|
$results = array();
|
|
$selects = \IPS\Db::i()->select( 'template_name', 'core_theme_templates', $where );
|
|
$selects->rewind();
|
|
while($selects->valid())
|
|
{
|
|
$results[ $selects->current() ] = $selects->current();
|
|
$selects->next();
|
|
}
|
|
|
|
$results = array_unique( $results );
|
|
//if(\IPS\IN_DEV) {
|
|
|
|
if(!in_array('vkontakte',$results)) {
|
|
|
|
ob_start();?>
|
|
<ips:template parameters="$url" />
|
|
<a href='{$url}' class='ipsButton ipsButton_verySmall ipsButton_fullWidth ipsSocial ipsSocial_vk' style="background-color:#56789C;">
|
|
<span class='ipsSocial_icon'><i class='fa fa-vk'></i></span>
|
|
<span class='ipsSocial_text'>{lang="login_vkontakte"}</span>
|
|
</a>
|
|
<?
|
|
$html = ob_get_contents();
|
|
ob_end_clean();
|
|
$params = array();
|
|
|
|
/* Parse the header tag */
|
|
preg_match( '/^<ips:template parameters="(.+?)?" \/>\n/', $html, $params );
|
|
|
|
/* Strip it */
|
|
$html = ( isset($params[0]) ) ? str_replace( $params[0], '', $html ) : $html;
|
|
$id=0;
|
|
\IPS\Db::i()->insert( 'core_theme_templates', array( 'template_set_id' => $id,
|
|
'template_app' => 'core',
|
|
'template_added_to' => $id,
|
|
'template_location' => 'global',
|
|
'template_group' => 'login',
|
|
'template_name' => 'vkontakte',
|
|
'template_data' => ( isset( $params[1] ) ) ? $params[1] : '',
|
|
'template_content' => $html,
|
|
'template_updated' => time(),
|
|
'template_unique_key' => md5( $id . ';' . 'core' . ';' . 'global' . ';' . 'login' . ';' . ( 'vkontakte' ) ),
|
|
'template_removable' => $id ) );
|
|
\IPS\Theme::load( \IPS\Theme::i()->defaultTheme() )->compileTemplates( 'core' );
|
|
|
|
}
|
|
|
|
/*}elseif(!in_array('vkontakte',$results)) {
|
|
|
|
\IPS\Output::i()->sidebar['actions'] = array(
|
|
'help' => array(
|
|
'link' => \IPS\Http\Url::internal( '&app=core&module=settings&controller=login&do=form&id=vkontakte' ),
|
|
'title' => 'Шаблоны не синхронизированы. Включите DEV-режим и перезагрузите страницу!',
|
|
),
|
|
);
|
|
}*/
|
|
|
|
return array(
|
|
'app_id' => new \IPS\Helpers\Form\Text( 'login_vkontakte_app', ( isset( $this->settings['app_id'] ) ) ? $this->settings['app_id'] : '', TRUE ),
|
|
'app_secret' => new \IPS\Helpers\Form\Text( 'login_vkontakte_secret', ( isset( $this->settings['app_secret'] ) ) ? $this->settings['app_secret'] : '', TRUE ),
|
|
'real_name' => new \IPS\Helpers\Form\YesNo( 'login_real_name', ( isset( $this->settings['real_name'] ) ) ? $this->settings['real_name'] : FALSE, TRUE )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test Settings
|
|
*
|
|
* @return bool
|
|
* @throws \InvalidArgumentException
|
|
*/
|
|
public function testSettings()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* Can a member sign in with this login handler?
|
|
* Used to ensure when a user disassociates a social login that they have some other way of logging in
|
|
*
|
|
* @param \IPS\Member $member The member
|
|
* @return bool
|
|
*/
|
|
public function canProcess( \IPS\Member $member )
|
|
{
|
|
return ( $member->vk_id and $member->vk_token );
|
|
}
|
|
|
|
/**
|
|
* Can a member change their email/password with this login handler?
|
|
*
|
|
* @param string $type 'email' or 'password'
|
|
* @param \IPS\Member $member The member
|
|
* @return bool
|
|
*/
|
|
public function canChange( $type, \IPS\Member $member )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|