mirror of
https://github.com/e107inc/e107.git
synced 2025-01-17 20:58:30 +01:00
Merge pull request #4099 from Deltik/fix-3492
New 3rd-party PHP dependency manager for e107 core and HybridAuth upgrade.
This commit is contained in:
commit
35e2e3b4aa
14
.gitignore
vendored
14
.gitignore
vendored
@ -1,11 +1,21 @@
|
||||
# Ignore PhpStorm IDE files
|
||||
# Ignore IDE files
|
||||
.idea
|
||||
.project
|
||||
composer.phar
|
||||
|
||||
# Ignore third-party files
|
||||
phpDocumentor.phar
|
||||
# Uncomment the following line for e107 v3. See ./e107_handlers/vendor/README.md for details.
|
||||
#e107_handlers/vendor/
|
||||
|
||||
# Ignore user files
|
||||
.htaccess
|
||||
e107.htaccess
|
||||
e107_config.php
|
||||
e107_config_*.php
|
||||
e107_media/*
|
||||
e107_system/*
|
||||
e107InstallLog.log
|
||||
/.settings
|
||||
e107_core/override
|
||||
test/*
|
||||
@ -15,5 +25,3 @@ phpunit/
|
||||
# Ignore Vim swap files
|
||||
*.swp
|
||||
*.swo
|
||||
e107.htaccess
|
||||
e107InstallLog.log
|
||||
|
26
composer.json
Normal file
26
composer.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "e107inc/e107",
|
||||
"description": "e107 is a free (open-source) content management system which allows you to easily manage and publish your content online. Developers can save time in building websites and powerful online applications. Users can avoid programming completely! Blogs, Websites, Intranets - e107 does it all.",
|
||||
"type": "project",
|
||||
"keywords": ["e107", "cms"],
|
||||
"homepage": "https://e107.org/",
|
||||
"readme": "README.md",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"support": {
|
||||
"issues": "https://github.com/e107inc/e107/issues",
|
||||
"forum": "https://e107help.org/",
|
||||
"wiki": "https://github.com/e107inc/e107/wiki",
|
||||
"irc": "https://gitter.im/e107inc/e107",
|
||||
"source": "https://github.com/e107inc/e107"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "5.6"
|
||||
},
|
||||
"vendor-dir": "e107_handlers/vendor"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6",
|
||||
"hybridauth/hybridauth": "^3.1.1"
|
||||
}
|
||||
}
|
80
composer.lock
generated
Normal file
80
composer.lock
generated
Normal file
@ -0,0 +1,80 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2b9cc480eb532146a79c7735c57e9d56",
|
||||
"packages": [
|
||||
{
|
||||
"name": "hybridauth/hybridauth",
|
||||
"version": "v3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hybridauth/hybridauth.git",
|
||||
"reference": "020be6991e7ae9f1ffaabae6586245d2a9626273"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/020be6991e7ae9f1ffaabae6586245d2a9626273",
|
||||
"reference": "020be6991e7ae9f1ffaabae6586245d2a9626273",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"phpunit/phpunit": "~4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hybridauth\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Miled",
|
||||
"email": "hybridauth@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP Social Authentication Library",
|
||||
"homepage": "https://hybridauth.github.io",
|
||||
"keywords": [
|
||||
"Authentication",
|
||||
"OpenId",
|
||||
"api",
|
||||
"authorization",
|
||||
"facebook",
|
||||
"google",
|
||||
"oauth",
|
||||
"social",
|
||||
"twitter"
|
||||
],
|
||||
"time": "2019-12-27T09:26:40+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
"php": "5.6"
|
||||
}
|
||||
}
|
@ -338,84 +338,7 @@ $core_image = array (
|
||||
),
|
||||
$coredir['handlers'] =>
|
||||
array (
|
||||
'hybridauth' =>
|
||||
array (
|
||||
'Hybrid' =>
|
||||
array (
|
||||
'Providers' =>
|
||||
array (
|
||||
'AOL.php' => '363b16cae1ffd55db3ac5cc2f7e4733e',
|
||||
'Facebook.php' => '4aee3d317fe69953e01bb46725d43f94',
|
||||
'Foursquare.php' => '397589be7475ebaad8970ca4b6eb60fd',
|
||||
'Github.php' => '2e2d5834cc8a82235c16e40aa00ce541',
|
||||
'Google.php' => 'be4864960167e6b37de048b946c0d379',
|
||||
'GoogleOpenID.php' => 'bb90e3e12d87f0726ff58c1f5569bc4e',
|
||||
'LinkedIn.php' => '5523c4f074fe4e1861df527d73e49da4',
|
||||
'Live.php' => '995b6de787eae81944909613e070bb4c',
|
||||
'MySpace.php' => '0a0064690cfff91854cd21e89ee94949',
|
||||
'OpenID.php' => 'cac0c4f546bf7cadd3e0e08045e9496e',
|
||||
'Steam.php' => 'ed4d5df2401d5bda0310902950b5ae63',
|
||||
'Twitter.php' => 'b75922ec5b73dac7048e60628b779723',
|
||||
'Yahoo.php' => '54e31f108103ff5ae541d4b429d4eed2',
|
||||
),
|
||||
'resources' =>
|
||||
array (
|
||||
'config.php.tpl' => 'a98e1313d7f3cb3b09c66be1a173bbe5',
|
||||
'index.html' => '2b328c302ed608451171b3db0f6b92b3',
|
||||
'openid_policy.html' => 'adaae0d22f0b9003a44534a64081d02d',
|
||||
'openid_realm.html' => 'e2930bae092b00340ee16362ec5ac729',
|
||||
'openid_xrds.xml' => 'b46a8e43108e0eca7dca32acca4decac',
|
||||
'windows_live_channel.html' => '479decb220963b4ebb8e0dedd2a399a0',
|
||||
),
|
||||
'thirdparty' =>
|
||||
array (
|
||||
'Facebook' =>
|
||||
array (
|
||||
'base_facebook.php' => '765cff749aa16cc4500f9bd81cbd21ab',
|
||||
'facebook.php' => '6bf73e0998383aaf604c54bc7942b9ab',
|
||||
'fb_ca_chain_bundle.crt' => '98ad487c6bcd023914be60299202eee0',
|
||||
),
|
||||
'LinkedIn' =>
|
||||
array (
|
||||
'LinkedIn.php' => '1cd8fcbb82418c7f81d0de47f02f59c7',
|
||||
),
|
||||
'OAuth' =>
|
||||
array (
|
||||
'OAuth.php' => '50bae8f493620f1fdfb2063b26ebe2a5',
|
||||
'OAuth1Client.php' => 'e6992197dabf5e1bd7f4f4e3c7525ecd',
|
||||
'OAuth2Client.php' => 'f7a5499ef47177ac1ca106e886382872',
|
||||
),
|
||||
'OpenID' =>
|
||||
array (
|
||||
'LightOpenID.php' => '9fa681804a627f14911e458e7a102299',
|
||||
),
|
||||
'WindowsLive' =>
|
||||
array (
|
||||
'OAuthWrapHandler.php' => '7080d96d73a963730a4b3d69c7a7083f',
|
||||
),
|
||||
'index.html' => '2b328c302ed608451171b3db0f6b92b3',
|
||||
),
|
||||
'Auth.php' => '8aaaec7085b894e0554ef19520f59f58',
|
||||
'Endpoint.php' => 'be7e05c19af2a69d4db3e82a2cff5db2',
|
||||
'Error.php' => 'd94721e20cb24b0730acc07fa8a95a14',
|
||||
'Exception.php' => 'd49e817a88114c2dd431335530e9db74',
|
||||
'Logger.php' => 'c5d7d3a272b8c57c83a8d33bbb0e5e7d',
|
||||
'Provider_Adapter.php' => '9ba762f0f1e4ed0e2aa120ca30590ff2',
|
||||
'Provider_Model.php' => '43641d00761ed128767cc4957e2198c4',
|
||||
'Provider_Model_OAuth1.php' => '12aad5fd49338c606c754b398e7323dd',
|
||||
'Provider_Model_OAuth2.php' => '83a61d2bd9a345c0b9bfc8ac411119c3',
|
||||
'Provider_Model_OpenID.php' => '1c5133bc57c3d45aacb522b7b918b8b8',
|
||||
'Storage.php' => '9c58abd4e46c9fecdf248db1022d2289',
|
||||
'StorageInterface.php' => '7a52a9b9bdc3569a98a0e32fc630d424',
|
||||
'User.php' => 'c219b2c31b17127f044e7d425dcd06db',
|
||||
'User_Activity.php' => '4b8c29b5c442915664f864ee4e18ac6b',
|
||||
'User_Contact.php' => 'b7f17423d61d42cb30b36a127f6e0e78',
|
||||
'User_Profile.php' => '4165786a0cc8d26ae683eda0669bf635',
|
||||
'index.html' => '2b328c302ed608451171b3db0f6b92b3',
|
||||
),
|
||||
'index.php' => '9e3830ed561ec508dc00344aebad5152',
|
||||
),
|
||||
'jsshrink' =>
|
||||
'jsshrink' =>
|
||||
array (
|
||||
'Minifier.php' => '10226dbede9950509b846658cac86c28',
|
||||
),
|
||||
|
@ -20,39 +20,21 @@ class core_system_xup_controller extends eController
|
||||
{
|
||||
|
||||
var $backUrl = null;
|
||||
|
||||
|
||||
/**
|
||||
* @var SocialLoginConfigManager
|
||||
*/
|
||||
private $social_login_config_manager;
|
||||
|
||||
public function __construct(eRequest $request, eResponse $response = null)
|
||||
{
|
||||
parent::__construct($request, $response);
|
||||
require_once(e_PLUGIN."social/SocialLoginConfigManager.php");
|
||||
$this->social_login_config_manager = new SocialLoginConfigManager(e107::getConfig());
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
//$back = 'system/xup/test';
|
||||
$this->backUrl = vartrue($_GET['back']) ? base64_decode($_GET['back']) : true;
|
||||
}
|
||||
|
||||
public function actionSignup()
|
||||
{
|
||||
$allow = true;
|
||||
$session = e107::getSession();
|
||||
if($session->get('HAuthError'))
|
||||
{
|
||||
$allow = false;
|
||||
$session->set('HAuthError', null);
|
||||
}
|
||||
|
||||
if($allow && vartrue($_GET['provider']))
|
||||
{
|
||||
require_once(e_HANDLER."user_handler.php");
|
||||
$provider = new e_user_provider($_GET['provider']);
|
||||
try
|
||||
{
|
||||
$provider->signup($this->backUrl, true, false); // redirect to test page is expected, if true - redirect to SITEURL
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
e107::getMessage()->addError('['.$e->getCode().']'.$e->getMessage(), 'default', true);
|
||||
}
|
||||
}
|
||||
|
||||
e107::getRedirect()->redirect(true === $this->backUrl ? SITEURL : $this->backUrl);
|
||||
$this->backUrl = isset($_GET['back']) ? $_GET['back'] : null;
|
||||
}
|
||||
|
||||
public function actionLogin()
|
||||
@ -64,25 +46,34 @@ class core_system_xup_controller extends eController
|
||||
$allow = false;
|
||||
$session->set('HAuthError', null);
|
||||
}
|
||||
|
||||
|
||||
if($allow && vartrue($_GET['provider']))
|
||||
{
|
||||
require_once(e_HANDLER."user_handler.php");
|
||||
$provider = new e_user_provider($_GET['provider']);
|
||||
$provider = e107::getUserProvider($_GET['provider']);
|
||||
try
|
||||
{
|
||||
$provider->login($this->backUrl); // redirect to test page is expected, if true - redirect to SITEURL
|
||||
$provider->login($this->backUrl, true, false); // redirect to test page is expected, if true - redirect to SITEURL
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
e107::getMessage()->addError('['.$e->getCode().']'.$e->getMessage(), 'default', true);
|
||||
}
|
||||
}
|
||||
|
||||
e107::getRedirect()->redirect(true === $this->backUrl ? SITEURL : $this->backUrl);
|
||||
}
|
||||
|
||||
|
||||
public function actionTest()
|
||||
{
|
||||
require_once(e_PLUGIN . "social/SocialLoginConfigManager.php");
|
||||
$manager = new SocialLoginConfigManager(e107::getConfig());
|
||||
|
||||
if (!$manager->isFlagActive($manager::ENABLE_BIT_TEST_PAGE))
|
||||
{
|
||||
e107::getRedirect()->redirect(SITEURL);
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<h3>'.LAN_XUP_ERRM_07.'</h3>';
|
||||
|
||||
if(getperms('0'))
|
||||
@ -91,7 +82,7 @@ class core_system_xup_controller extends eController
|
||||
return;
|
||||
}
|
||||
|
||||
if(isset($_GET['lgt']))
|
||||
if(isset($_GET['logout']))
|
||||
{
|
||||
e107::getUser()->logout();
|
||||
}
|
||||
@ -113,52 +104,23 @@ class core_system_xup_controller extends eController
|
||||
echo ' '.LAN_XUP_ERRM_11.' '.(e107::getUser()->isUser() && !empty($profileData) ? '<span class="label label-success">true</span>' : '<span class="label label-danger">false</span>');
|
||||
|
||||
|
||||
$testUrl = SITEURL."?route=system/xup/test";
|
||||
$providers = e107::getPref('social_login', array());
|
||||
|
||||
$testUrl = SITEURL."?route=system/xup/test";
|
||||
$providers = $manager->getValidConfiguredProviderConfigs();
|
||||
|
||||
foreach($providers as $key=>$var)
|
||||
{
|
||||
if($var['enabled'] == 1)
|
||||
{
|
||||
echo '<h3>'.$key.'</h3><ul>';
|
||||
echo '<li><a class="btn btn-default btn-secondary" href="'.e107::getUrl()->create('system/xup/login?provider='.$key.'&back='.base64_encode($testUrl)).'">'.e107::getParser()->lanVars(LAN_XUP_ERRM_09, array('x'=>$key)).'</a></li>';
|
||||
echo '<li><a class="btn btn-default btn-secondary" href="'.e107::getUrl()->create('system/xup/signup?provider='.$key.'&back='.base64_encode($testUrl)).'">'.e107::getParser()->lanVars(LAN_XUP_ERRM_10, array('x'=>$key)).'</a></li>';
|
||||
|
||||
echo "</ul>";
|
||||
}
|
||||
|
||||
// print_a($var);
|
||||
}
|
||||
|
||||
echo '<br /><br /><a class="btn btn-default btn-secondary" href="'.e107::getUrl()->create('system/xup/test?lgt').'">'.LAN_XUP_ERRM_12.'</a>';
|
||||
|
||||
/*
|
||||
echo '<h3>Facebook</h3>';
|
||||
echo '<br /><a href="'.e107::getUrl()->create('system/xup/login?provider=Facebook').'">Test login with Facebook</a>';
|
||||
echo '<br /><a href="'.e107::getUrl()->create('system/xup/signup?provider=Facebook').'">Test signup with Facebook</a>';
|
||||
|
||||
echo '<h3>Twitter</h3>';
|
||||
echo '<br /><a href="'.e107::getUrl()->create('system/xup/login?provider=Twitter').'">Test login with Twitter</a>';
|
||||
echo '<br /><a href="'.e107::getUrl()->create('system/xup/signup?provider=Twitter').'">Test signup with Twitter</a>';
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
public function actionEndpoint()
|
||||
{
|
||||
require_once( e_HANDLER."hybridauth/Hybrid/Auth.php" );
|
||||
require_once( e_HANDLER."hybridauth/Hybrid/Endpoint.php" );
|
||||
require_once( e_HANDLER."hybridauth/vendor/autoload.php");
|
||||
$testLoginUrl = e107::getUrl()->create('system/xup/login', [
|
||||
'provider' => $key,
|
||||
'back' => $testUrl,
|
||||
]);
|
||||
|
||||
try
|
||||
{
|
||||
Hybrid_Endpoint::process();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
e107::getMessage()->addError('['.$e->getCode().']'.$e->getMessage(), 'default', true);
|
||||
$session = e107::getSession();
|
||||
$session->set('HAuthError', true);
|
||||
echo '<h4>'.$key.'</h4>';
|
||||
echo '<div><a class="btn btn-default btn-secondary" href="'.$testLoginUrl.'">'.e107::getParser()->lanVars(LAN_XUP_ERRM_10, array('x'=>$key)).'</a></div>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '<br /><br /><a class="btn btn-default btn-secondary" href="'.e107::getUrl()->create('system/xup/test?logout=true').'">'.LAN_XUP_ERRM_12.'</a>';
|
||||
}
|
||||
}
|
||||
|
@ -65,95 +65,85 @@ class signup_shortcodes extends e_shortcode
|
||||
// TODO - template
|
||||
function sc_signup_xup_login($parm)
|
||||
{
|
||||
$pref = e107::getPref('social_login_active');
|
||||
$tp = e107::getParser();
|
||||
|
||||
if (!e107::getUserProvider()->isSocialLoginEnabled()) return '';
|
||||
|
||||
$size = empty($parm['size']) ? '3x' : $parm['size'];
|
||||
$class = empty($parm['class']) ? 'btn btn-primary' : $parm['class'] ;
|
||||
|
||||
|
||||
if(!empty($pref))
|
||||
{
|
||||
$text = "";
|
||||
$providers = e107::getPref('social_login');
|
||||
|
||||
foreach($providers as $p=>$v)
|
||||
{
|
||||
$p = strtolower($p);
|
||||
if($v['enabled'] == 1)
|
||||
{
|
||||
|
||||
// $text .= "<a href='".e107::getUrl()->create('system/xup/login?provider='.$p.'&back='.base64_encode(e_REQUEST_URL))."'><img class='e-tip' title='Register using your {$p} account' src='".e_IMAGE_ABS."xup/{$p}.png' alt='' /></a>";
|
||||
|
||||
$ic = strtolower($p);
|
||||
|
||||
if($ic == 'live')
|
||||
{
|
||||
$ic = 'windows';
|
||||
}
|
||||
|
||||
// 'signup' Creates a new XUP user if not found, otherwise it logs the person in.
|
||||
|
||||
$button = (defset('FONTAWESOME')) ? $tp->toGlyph('fa-'.$ic, array('size'=>$size, 'fw'=>true)) : "<img class='e-tip' title='".$tp->lanVars(LAN_PLUGIN_SOCIAL_XUP_SIGNUP, $p)."' src='".e_IMAGE_ABS."xup/{$p}.png' alt='' />";
|
||||
$text .= " <a title='".$tp->lanVars(LAN_PLUGIN_SOCIAL_XUP_SIGNUP, $p)." ' role='button' class='signup-xup ".$class."' href='".e107::getUrl()->create('system/xup/signup?provider='.$p.'&back='.base64_encode(e_REQUEST_URL))."'>".$button."</a> ";
|
||||
}
|
||||
//TODO different icon options. see: http://zocial.smcllns.com/
|
||||
}
|
||||
|
||||
// $text .= "<hr />";
|
||||
return $text;
|
||||
}
|
||||
return $this->generateXupLoginButtons("login", $size, $class);
|
||||
}
|
||||
|
||||
// TODO - template
|
||||
function sc_signup_xup_signup($parm)
|
||||
{
|
||||
$pref = e107::getPref('social_login_active');
|
||||
if (!e107::getUserProvider()->isSocialLoginEnabled()) return '';
|
||||
|
||||
$size = empty($parm['size']) ? '2x' : $parm['size'];
|
||||
$class = empty($parm['class']) ? 'btn btn-primary' : $parm['class'] ;
|
||||
|
||||
if($size == '2x')
|
||||
{
|
||||
$class .= ' btn-lg';
|
||||
}
|
||||
|
||||
return $this->generateXupLoginButtons("signup", $size, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param $size
|
||||
* @param $class
|
||||
* @return string
|
||||
*/
|
||||
private function generateXupLoginButtons($type, $size, $class)
|
||||
{
|
||||
$text = "";
|
||||
$tp = e107::getParser();
|
||||
|
||||
|
||||
|
||||
if(!empty($pref))
|
||||
$lan_plugin_social_xup = '';
|
||||
switch ($type)
|
||||
{
|
||||
$text = "";
|
||||
$providers = e107::pref('core', 'social_login');
|
||||
|
||||
$size = empty($parm['size']) ? '2x' : $parm['size'];
|
||||
$class = empty($parm['class']) ? 'btn btn-primary' : $parm['class'] ;
|
||||
|
||||
if($size == '2x')
|
||||
case "login":
|
||||
$lan_plugin_social_xup = LAN_PLUGIN_SOCIAL_XUP_REG;
|
||||
break;
|
||||
case "signup":
|
||||
$lan_plugin_social_xup = LAN_PLUGIN_SOCIAL_XUP_SIGNUP;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$manager = new SocialLoginConfigManager(e107::getConfig());
|
||||
$providers = $manager->getValidConfiguredProviderConfigs();
|
||||
|
||||
foreach ($providers as $p => $v)
|
||||
{
|
||||
if ($v['enabled'] == 1)
|
||||
{
|
||||
$class .= ' btn-lg';
|
||||
}
|
||||
$ic = strtolower($p);
|
||||
|
||||
|
||||
foreach($providers as $p=>$v)
|
||||
{
|
||||
|
||||
|
||||
$p = strtolower($p);
|
||||
if($v['enabled'] == 1)
|
||||
switch ($ic)
|
||||
{
|
||||
$ic = strtolower($p);
|
||||
|
||||
if($ic == 'live')
|
||||
{
|
||||
case 'windowslive':
|
||||
$ic = 'windows';
|
||||
}
|
||||
|
||||
$button = (defset('FONTAWESOME')) ? "<span title='".$tp->lanVars(LAN_PLUGIN_SOCIAL_XUP_REG, $p)."'>".$tp->toGlyph('fa-'.$ic, array('size'=>$size, 'fw'=>true))."</span>" : "<img class='e-tip' title='".$tp->lanVars(LAN_PLUGIN_SOCIAL_XUP_SIGNUP, $p)."' src='".e_IMAGE_ABS."xup/{$p}.png' alt='' />";
|
||||
|
||||
$text .= " <a class='signup-xup ".$class."' role='button' href='".e107::getUrl()->create('system/xup/signup?provider='.$p.'&back='.base64_encode(e_REQUEST_URL))."'>".$button."</a> ";
|
||||
break;
|
||||
}
|
||||
//TODO different icon options. see: http://zocial.smcllns.com/
|
||||
}
|
||||
|
||||
// $text .= "<hr />";
|
||||
return $text;
|
||||
}
|
||||
|
||||
if (defset('FONTAWESOME') && in_array($ic, e107::getMedia()->getGlyphs()))
|
||||
$button = "<span title='" . $tp->lanVars($lan_plugin_social_xup, $p) . "'>" . $tp->toGlyph('fa-' . $ic, array('size' => $size, 'fw' => true)) . "</span>";
|
||||
elseif (is_file(e107::getFolder('images') . "xup/{$ic}.png"))
|
||||
$button = "<img class='e-tip' title='" . $tp->lanVars($lan_plugin_social_xup, $p) . "' src='" . e_IMAGE_ABS . "xup/{$ic}.png' alt='' />";
|
||||
else
|
||||
$button = "<span title='" . $tp->lanVars($lan_plugin_social_xup, $p) . "'>$p</span>";
|
||||
|
||||
$callback_url = e107::getUserProvider($p)->generateCallbackUrl(e_REQUEST_URL);
|
||||
$text .= " <a title='" . $tp->lanVars($lan_plugin_social_xup, $p) . " ' role='button' class='signup-xup $class' href='$callback_url'>$button</a> ";
|
||||
}
|
||||
//TODO different icon options. see: http://zocial.smcllns.com/
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function sc_signup_form_open()
|
||||
{
|
||||
return "<form action='".e_SELF."' method='post' id='signupform' autocomplete='off'><div>".e107::getForm()->token()."</div>";
|
||||
|
@ -313,7 +313,7 @@ class comment
|
||||
else
|
||||
{ // Comment entry not allowed - point to signup link
|
||||
$userReg = intval(e107::pref('core','user_reg'));
|
||||
$socialLogin = e107::pref('core','social_login_active');
|
||||
$socialLogin = e107::getUserProvider()->isSocialLoginEnabled();
|
||||
|
||||
$text = "<div class='comments-form-login'>";
|
||||
|
||||
|
@ -55,9 +55,11 @@ class _system_cron
|
||||
$mes->addDebug("Removed install.php");
|
||||
}
|
||||
|
||||
if(!deftrue('e_DEVELOPER')) // leave tests folder intact if developer mode is active.
|
||||
if(!deftrue('e_DEVELOPER')) // Leave development files intact if developer mode is active.
|
||||
{
|
||||
$fl->removeDir(e_BASE.'e107_tests');
|
||||
unlink(e_BASE."composer.json");
|
||||
unlink(e_BASE."composer.lock");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -216,6 +216,7 @@ class e107
|
||||
'e_user_model' => '{e_HANDLER}user_model.php',
|
||||
'e_user' => '{e_HANDLER}user_model.php',
|
||||
'e_user_extended_structure_tree' => '{e_HANDLER}user_model.php',
|
||||
'e_user_provider' => '{e_HANDLER}user_handler.php',
|
||||
'e_userperms' => '{e_HANDLER}user_handler.php',
|
||||
'e_validator' => '{e_HANDLER}validator_class.php',
|
||||
'e_vars' => '{e_HANDLER}model_class.php',
|
||||
@ -236,7 +237,6 @@ class e107
|
||||
'eUrl' => '{e_HANDLER}e107Url.php',
|
||||
'eUrlConfig' => '{e_HANDLER}application.php',
|
||||
'eUrlRule' => '{e_HANDLER}application.php',
|
||||
'Hybrid_Auth' => '{e_HANDLER}hybridauth/Hybrid/Auth.php',
|
||||
'language' => '{e_HANDLER}language_class.php',
|
||||
'news' => '{e_HANDLER}news_class.php',
|
||||
'notify' => '{e_HANDLER}notify_class.php',
|
||||
@ -287,6 +287,18 @@ class e107
|
||||
//register_shutdown_function(array($this, 'destruct'));
|
||||
}
|
||||
|
||||
private static function die_http_400()
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
header('Content-Type: text/plain');
|
||||
if (deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ";
|
||||
debug_print_backtrace(0, 1);
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloning is not allowed
|
||||
*
|
||||
@ -1693,22 +1705,33 @@ class e107
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve HybridAuth object
|
||||
* Create a new Hybridauth object based on the provided configuration
|
||||
*
|
||||
* @return object
|
||||
* @return Hybridauth\Hybridauth
|
||||
* @throws \Hybridauth\Exception\InvalidArgumentException if Hybridauth rejects the provided config
|
||||
* @throws ReflectionException if this method is unintentionally broken
|
||||
* @deprecated v2.3.0 Use the e_user_provider interfaces instead (e107::getUserProvider()).
|
||||
* It's the e107 wrapper around Hybridauth.
|
||||
* @see e_user_provider for social login features.
|
||||
* @see e107::getUser() for getting a user object that may or may not have a social login.
|
||||
*/
|
||||
public static function getHybridAuth($config = null)
|
||||
{
|
||||
if(null === $config)
|
||||
{
|
||||
$config = array(
|
||||
'base_url' => self::getUrl()->create('system/xup/endpoint', array(), array('full' => true)),
|
||||
'providers' => self::getPref('social_login', array()),
|
||||
'debug_mode' => false,
|
||||
'debug_file' => ''
|
||||
);
|
||||
}
|
||||
return new Hybrid_Auth($config);
|
||||
$e_user_provider = new e_user_provider(null, $config);
|
||||
$reflection = new ReflectionClass('e_user_provider');
|
||||
$reflection_property = $reflection->getProperty('hybridauth');
|
||||
$reflection_property->setAccessible(true);
|
||||
return $reflection_property->getValue($e_user_provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new social login handler
|
||||
* @param string|null $providerName
|
||||
* @return e_user_provider
|
||||
*/
|
||||
public static function getUserProvider($providerName = null)
|
||||
{
|
||||
return self::getObject('e_user_provider', $providerName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3939,57 +3962,32 @@ class e107
|
||||
$regex = "/(base64_decode|chr|php_uname|fwrite|fopen|fputs|passthru|popen|proc_open|shell_exec|exec|proc_nice|proc_terminate|proc_get_status|proc_close|pfsockopen|apache_child_terminate|posix_kill|posix_mkfifo|posix_setpgid|posix_setsid|posix_setuid|phpinfo) *?\((.*) ?\;?/i";
|
||||
if(preg_match($regex,$input))
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
// Check for XSS JS
|
||||
$regex = "/(document\.location|document\.write|document\.cookie)/i";
|
||||
if(preg_match($regex,$input))
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
|
||||
// Suspicious HTML.
|
||||
if(strpos($input, '<body/onload')!==false)
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
if(preg_match("/system\((.*);.*\)/i",$input))
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
$regex = "/(wget |curl -o |lwp-download|onmouse)/i";
|
||||
if(preg_match($regex,$input))
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
}
|
||||
@ -3998,12 +3996,7 @@ class e107
|
||||
{
|
||||
if(stripos($input, "<script")!==false || stripos($input, "%3Cscript")!==false)
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
}
|
||||
@ -4018,37 +4011,12 @@ class e107
|
||||
|| stripos($input,"%3cscript")!==FALSE
|
||||
))
|
||||
{
|
||||
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
if(($key == "QUERY_STRING") && empty($_GET['hauth_done']) && empty($_GET['hauth.done']) && ( // exception for hybridAuth.
|
||||
strpos(strtolower($input),"=http")!==FALSE
|
||||
|| strpos(strtolower($input),strtolower("http%3A%2F%2F"))!==FALSE
|
||||
))
|
||||
{
|
||||
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
if(($key == "HTTP_USER_AGENT") && strpos($input,"libwww-perl")!==FALSE)
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
|
||||
@ -4056,12 +4024,7 @@ class e107
|
||||
|
||||
if(strpos(str_replace('.', '', $input), '22250738585072011') !== FALSE) // php-bug 53632
|
||||
{
|
||||
header('HTTP/1.0 400 Bad Request', true, 400);
|
||||
if(deftrue('e_DEBUG'))
|
||||
{
|
||||
echo "Bad Request: ".__METHOD__." : ". __LINE__;
|
||||
}
|
||||
exit();
|
||||
self::die_http_400();
|
||||
}
|
||||
|
||||
if($base64 != true)
|
||||
@ -5234,7 +5197,12 @@ class e107
|
||||
|
||||
e107::autoload_register(array(e107::class, 'autoload'));
|
||||
|
||||
|
||||
// Forward compatibility with e107 v3 Composer autoloading
|
||||
$vendor_autoload_file = __DIR__."/vendor/autoload.php";
|
||||
if (file_exists($vendor_autoload_file))
|
||||
{
|
||||
include_once($vendor_autoload_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface e_admin_addon_interface @move to separate addons file?
|
||||
|
@ -1692,6 +1692,8 @@ class e_file
|
||||
'e107-master/CONTRIBUTING.md', # moved to ./.github/CONTRIBUTING.md
|
||||
'e107-master/LICENSE',
|
||||
'e107-master/README.md',
|
||||
'e107-master/composer.json',
|
||||
'e107-master/composer.lock',
|
||||
'e107-master/install.php',
|
||||
'e107-master/favicon.ico',
|
||||
);
|
||||
|
@ -1,414 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Auth class
|
||||
*
|
||||
* Hybrid_Auth class provide a simple way to authenticate users via OpenID and OAuth.
|
||||
*
|
||||
* Generally, Hybrid_Auth is the only class you should instanciate and use throughout your application.
|
||||
*/
|
||||
class Hybrid_Auth {
|
||||
|
||||
public static $version = "2.9.6";
|
||||
|
||||
/**
|
||||
* Configuration array
|
||||
* @var array
|
||||
*/
|
||||
public static $config = array();
|
||||
|
||||
/**
|
||||
* Auth cache
|
||||
* @var Hybrid_Storage
|
||||
*/
|
||||
public static $store = null;
|
||||
|
||||
/**
|
||||
* Error pool
|
||||
* @var Hybrid_Error
|
||||
*/
|
||||
public static $error = null;
|
||||
|
||||
/**
|
||||
* Logger
|
||||
* @var Hybrid_Logger
|
||||
*/
|
||||
public static $logger = null;
|
||||
|
||||
/**
|
||||
* Try to start a new session of none then initialize Hybrid_Auth
|
||||
*
|
||||
* Hybrid_Auth constructor will require either a valid config array or
|
||||
* a path for a configuration file as parameter. To know more please
|
||||
* refer to the Configuration section:
|
||||
* http://hybridauth.sourceforge.net/userguide/Configuration.html
|
||||
*
|
||||
* @param array $config Configuration array or path to a configratuion file
|
||||
*/
|
||||
function __construct($config) {
|
||||
Hybrid_Auth::initialize($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to initialize Hybrid_Auth with given $config hash or file
|
||||
*
|
||||
* @param array $config Configuration array or path to a configratuion file
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function initialize($config) {
|
||||
if (!is_array($config) && !file_exists($config)) {
|
||||
throw new Exception("Hybriauth config does not exist on the given path.", 1);
|
||||
}
|
||||
|
||||
if (!is_array($config)) {
|
||||
$config = include $config;
|
||||
}
|
||||
|
||||
// build some need'd paths
|
||||
$config["path_base"] = realpath(dirname(__FILE__)) . "/";
|
||||
$config["path_libraries"] = $config["path_base"] . "thirdparty/";
|
||||
$config["path_resources"] = $config["path_base"] . "resources/";
|
||||
$config["path_providers"] = $config["path_base"] . "Providers/";
|
||||
|
||||
// reset debug mode
|
||||
if (!isset($config["debug_mode"])) {
|
||||
$config["debug_mode"] = false;
|
||||
$config["debug_file"] = null;
|
||||
}
|
||||
|
||||
# load hybridauth required files, a autoload is on the way...
|
||||
require_once $config["path_base"] . "Error.php";
|
||||
require_once $config["path_base"] . "Exception.php";
|
||||
require_once $config["path_base"] . "Logger.php";
|
||||
|
||||
require_once $config["path_base"] . "Provider_Adapter.php";
|
||||
|
||||
require_once $config["path_base"] . "Provider_Model.php";
|
||||
require_once $config["path_base"] . "Provider_Model_OpenID.php";
|
||||
require_once $config["path_base"] . "Provider_Model_OAuth1.php";
|
||||
require_once $config["path_base"] . "Provider_Model_OAuth2.php";
|
||||
|
||||
require_once $config["path_base"] . "User.php";
|
||||
require_once $config["path_base"] . "User_Profile.php";
|
||||
require_once $config["path_base"] . "User_Contact.php";
|
||||
require_once $config["path_base"] . "User_Activity.php";
|
||||
|
||||
if (!class_exists("Hybrid_Storage", false)) {
|
||||
require_once $config["path_base"] . "Storage.php";
|
||||
}
|
||||
|
||||
// hash given config
|
||||
Hybrid_Auth::$config = $config;
|
||||
|
||||
// instance of log mng
|
||||
Hybrid_Auth::$logger = new Hybrid_Logger();
|
||||
|
||||
// instance of errors mng
|
||||
Hybrid_Auth::$error = new Hybrid_Error();
|
||||
|
||||
// start session storage mng
|
||||
Hybrid_Auth::$store = new Hybrid_Storage();
|
||||
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::initialize()");
|
||||
Hybrid_Logger::info("Hybrid_Auth::initialize(). PHP version: " . PHP_VERSION);
|
||||
Hybrid_Logger::info("Hybrid_Auth::initialize(). Hybrid_Auth version: " . Hybrid_Auth::$version);
|
||||
Hybrid_Logger::info("Hybrid_Auth::initialize(). Hybrid_Auth called from: " . Hybrid_Auth::getCurrentUrl());
|
||||
|
||||
// PHP Curl extension [http://www.php.net/manual/en/intro.curl.php]
|
||||
if (!function_exists('curl_init')) {
|
||||
Hybrid_Logger::error('Hybridauth Library needs the CURL PHP extension.');
|
||||
throw new Exception('Hybridauth Library needs the CURL PHP extension.');
|
||||
}
|
||||
|
||||
// PHP JSON extension [http://php.net/manual/en/book.json.php]
|
||||
if (!function_exists('json_decode')) {
|
||||
Hybrid_Logger::error('Hybridauth Library needs the JSON PHP extension.');
|
||||
throw new Exception('Hybridauth Library needs the JSON PHP extension.');
|
||||
}
|
||||
|
||||
// session.name
|
||||
if (session_name() != "PHPSESSID") {
|
||||
Hybrid_Logger::info('PHP session.name diff from default PHPSESSID. http://php.net/manual/en/session.configuration.php#ini.session.name.');
|
||||
}
|
||||
|
||||
// safe_mode is on
|
||||
if (ini_get('safe_mode')) {
|
||||
Hybrid_Logger::info('PHP safe_mode is on. http://php.net/safe-mode.');
|
||||
}
|
||||
|
||||
// open basedir is on
|
||||
if (ini_get('open_basedir')) {
|
||||
Hybrid_Logger::info('PHP open_basedir is on. http://php.net/open-basedir.');
|
||||
}
|
||||
|
||||
Hybrid_Logger::debug("Hybrid_Auth initialize. dump used config: ", serialize($config));
|
||||
Hybrid_Logger::debug("Hybrid_Auth initialize. dump current session: ", Hybrid_Auth::storage()->getSessionData());
|
||||
Hybrid_Logger::info("Hybrid_Auth initialize: check if any error is stored on the endpoint...");
|
||||
|
||||
if (Hybrid_Error::hasError()) {
|
||||
$m = Hybrid_Error::getErrorMessage();
|
||||
$c = Hybrid_Error::getErrorCode();
|
||||
$p = Hybrid_Error::getErrorPrevious();
|
||||
|
||||
Hybrid_Logger::error("Hybrid_Auth initialize: A stored Error found, Throw an new Exception and delete it from the store: Error#$c, '$m'");
|
||||
|
||||
Hybrid_Error::clearError();
|
||||
|
||||
// try to provide the previous if any
|
||||
// Exception::getPrevious (PHP 5 >= 5.3.0) http://php.net/manual/en/exception.getprevious.php
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=') && ($p instanceof Exception)) {
|
||||
throw new Exception($m, $c, $p);
|
||||
} else {
|
||||
throw new Exception($m, $c);
|
||||
}
|
||||
}
|
||||
|
||||
Hybrid_Logger::info("Hybrid_Auth initialize: no error found. initialization succeed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Hybrid storage system accessor
|
||||
*
|
||||
* Users sessions are stored using HybridAuth storage system ( HybridAuth 2.0 handle PHP Session only) and can be accessed directly by
|
||||
* Hybrid_Auth::storage()->get($key) to retrieves the data for the given key, or calling
|
||||
* Hybrid_Auth::storage()->set($key, $value) to store the key => $value set.
|
||||
*
|
||||
* @return Hybrid_Storage
|
||||
*/
|
||||
public static function storage() {
|
||||
return Hybrid_Auth::$store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hybridauth session data
|
||||
* @return string|null
|
||||
*/
|
||||
function getSessionData() {
|
||||
return Hybrid_Auth::storage()->getSessionData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore hybridauth session data
|
||||
*
|
||||
* @param string $sessiondata Serialized session data
|
||||
* @retun void
|
||||
*/
|
||||
function restoreSessionData($sessiondata = null) {
|
||||
Hybrid_Auth::storage()->restoreSessionData($sessiondata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to authenticate the user with a given provider.
|
||||
*
|
||||
* If the user is already connected we just return and instance of provider adapter,
|
||||
* ELSE, try to authenticate and authorize the user with the provider.
|
||||
*
|
||||
* $params is generally an array with required info in order for this provider and HybridAuth to work,
|
||||
* like :
|
||||
* hauth_return_to: URL to call back after authentication is done
|
||||
* openid_identifier: The OpenID identity provider identifier
|
||||
* google_service: can be "Users" for Google user accounts service or "Apps" for Google hosted Apps
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @param array $params Params
|
||||
* @return
|
||||
*/
|
||||
public static function authenticate($providerId, $params = null) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::authenticate( $providerId )");
|
||||
|
||||
if (!Hybrid_Auth::storage()->get("hauth_session.$providerId.is_logged_in")) {
|
||||
// if user not connected to $providerId then try setup a new adapter and start the login process for this provider
|
||||
Hybrid_Logger::info("Hybrid_Auth::authenticate( $providerId ), User not connected to the provider. Try to authenticate..");
|
||||
$provider_adapter = Hybrid_Auth::setup($providerId, $params);
|
||||
$provider_adapter->login();
|
||||
} else {
|
||||
// else, then return the adapter instance for the given provider
|
||||
Hybrid_Logger::info("Hybrid_Auth::authenticate( $providerId ), User is already connected to this provider. Return the adapter instance.");
|
||||
return Hybrid_Auth::getAdapter($providerId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the adapter instance for an authenticated provider
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @return Hybrid_Provider_Adapter
|
||||
*/
|
||||
public static function getAdapter($providerId = null) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::getAdapter( $providerId )");
|
||||
return Hybrid_Auth::setup($providerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup an adapter for a given provider
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @param array $params Adapter params
|
||||
* @return Hybrid_Provider_Adapter
|
||||
*/
|
||||
public static function setup($providerId, $params = null) {
|
||||
Hybrid_Logger::debug("Enter Hybrid_Auth::setup( $providerId )", $params);
|
||||
|
||||
if (!$params) {
|
||||
$params = Hybrid_Auth::storage()->get("hauth_session.$providerId.id_provider_params");
|
||||
|
||||
Hybrid_Logger::debug("Hybrid_Auth::setup( $providerId ), no params given. Trying to get the stored for this provider.", $params);
|
||||
}
|
||||
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
Hybrid_Logger::info("Hybrid_Auth::setup( $providerId ), no stored params found for this provider. Initialize a new one for new session");
|
||||
}
|
||||
|
||||
if (is_array($params) && !isset($params["hauth_return_to"])) {
|
||||
$params["hauth_return_to"] = Hybrid_Auth::getCurrentUrl();
|
||||
Hybrid_Logger::debug("Hybrid_Auth::setup( $providerId ). HybridAuth Callback URL set to: ", $params["hauth_return_to"]);
|
||||
}
|
||||
|
||||
# instantiate a new IDProvider Adapter
|
||||
$provider = new Hybrid_Provider_Adapter();
|
||||
$provider->factory($providerId, $params);
|
||||
return $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user is connected to a given provider
|
||||
*
|
||||
* @param string $providerId ID of the provider
|
||||
* @return bool
|
||||
*/
|
||||
public static function isConnectedWith($providerId) {
|
||||
return (bool) Hybrid_Auth::storage()->get("hauth_session.{$providerId}.is_logged_in");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array listing all authenticated providers
|
||||
* @return array
|
||||
*/
|
||||
public static function getConnectedProviders() {
|
||||
$idps = array();
|
||||
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
if (Hybrid_Auth::isConnectedWith($idpid)) {
|
||||
$idps[] = $idpid;
|
||||
}
|
||||
}
|
||||
|
||||
return $idps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array listing all enabled providers as well as a flag if you are connected
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'Facebook' => array(
|
||||
* 'connected' => true
|
||||
* )
|
||||
* )
|
||||
* </code>
|
||||
* @return array
|
||||
*/
|
||||
public static function getProviders() {
|
||||
$idps = array();
|
||||
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
if ($params['enabled']) {
|
||||
$idps[$idpid] = array('connected' => false);
|
||||
|
||||
if (Hybrid_Auth::isConnectedWith($idpid)) {
|
||||
$idps[$idpid]['connected'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $idps;
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic function to logout all connected provider at once
|
||||
* @return void
|
||||
*/
|
||||
public static function logoutAllProviders() {
|
||||
$idps = Hybrid_Auth::getConnectedProviders();
|
||||
|
||||
foreach ($idps as $idp) {
|
||||
$adapter = Hybrid_Auth::getAdapter($idp);
|
||||
$adapter->logout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function, redirect to a given URL with php header or using javascript location.href
|
||||
*
|
||||
* @param string $url URL to redirect to
|
||||
* @param string $mode PHP|JS
|
||||
*/
|
||||
public static function redirect($url, $mode = "PHP") {
|
||||
if(!$mode){
|
||||
$mode = 'PHP';
|
||||
}
|
||||
Hybrid_Logger::info("Enter Hybrid_Auth::redirect( $url, $mode )");
|
||||
|
||||
// Ensure session is saved before sending response, see https://github.com/symfony/symfony/pull/12341
|
||||
if ((PHP_VERSION_ID >= 50400 && PHP_SESSION_ACTIVE === session_status()) || (PHP_VERSION_ID < 50400 && isset($_SESSION) && session_id())) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
if ($mode == "PHP") {
|
||||
header("Location: $url");
|
||||
} elseif ($mode == "JS") {
|
||||
echo '<html>';
|
||||
echo '<head>';
|
||||
echo '<script type="text/javascript">';
|
||||
echo 'function redirect(){ window.top.location.href="' . $url . '"; }';
|
||||
echo '</script>';
|
||||
echo '</head>';
|
||||
echo '<body onload="redirect()">';
|
||||
echo 'Redirecting, please wait...';
|
||||
echo '</body>';
|
||||
echo '</html>';
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function, return the current url
|
||||
*
|
||||
* @param bool $request_uri true to get $_SERVER['REQUEST_URI'], false for $_SERVER['PHP_SELF']
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurrentUrl($request_uri = true) {
|
||||
if (php_sapi_name() == 'cli') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$protocol = 'http://';
|
||||
|
||||
if ((isset($_SERVER['HTTPS']) && ( $_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1 ))
|
||||
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
|
||||
{
|
||||
$protocol = 'https://';
|
||||
}
|
||||
|
||||
$url = $protocol . $_SERVER['HTTP_HOST'];
|
||||
|
||||
if ($request_uri) {
|
||||
$url .= $_SERVER['REQUEST_URI'];
|
||||
} else {
|
||||
$url .= $_SERVER['PHP_SELF'];
|
||||
}
|
||||
|
||||
// return current url
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
@ -1,222 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Endpoint class
|
||||
*
|
||||
* Provides a simple way to handle the OpenID and OAuth endpoint
|
||||
*/
|
||||
class Hybrid_Endpoint {
|
||||
|
||||
protected $request = null;
|
||||
protected $initDone = false;
|
||||
|
||||
/**
|
||||
* Process the current request
|
||||
*
|
||||
* @param array $request The current request parameters. Leave as null to default to use $_REQUEST.
|
||||
*/
|
||||
public function __construct($request = null) {
|
||||
if (is_null($request)) {
|
||||
// Fix a strange behavior when some provider call back ha endpoint
|
||||
// with /index.php?hauth.done={provider}?{args}...
|
||||
// >here we need to parse $_SERVER[QUERY_STRING]
|
||||
$request = $_REQUEST;
|
||||
if (isset($_SERVER["QUERY_STRING"]) && strrpos($_SERVER["QUERY_STRING"], '?')) {
|
||||
$_SERVER["QUERY_STRING"] = str_replace("?", "&", $_SERVER["QUERY_STRING"]);
|
||||
parse_str($_SERVER["QUERY_STRING"], $request);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup request variable
|
||||
$this->request = $request;
|
||||
|
||||
// If openid_policy requested, we return our policy document
|
||||
if (isset($this->request["get"]) && $this->request["get"] == "openid_policy") {
|
||||
$this->processOpenidPolicy();
|
||||
}
|
||||
|
||||
// If openid_xrds requested, we return our XRDS document
|
||||
if (isset($this->request["get"]) && $this->request["get"] == "openid_xrds") {
|
||||
$this->processOpenidXRDS();
|
||||
}
|
||||
|
||||
// If we get a hauth.start
|
||||
if (isset($this->request["hauth_start"]) && $this->request["hauth_start"]) {
|
||||
$this->processAuthStart();
|
||||
}
|
||||
// Else if hauth.done
|
||||
elseif (isset($this->request["hauth_done"]) && $this->request["hauth_done"]) {
|
||||
$this->processAuthDone();
|
||||
}
|
||||
// Else we advertise our XRDS document, something supposed to be done from the Realm URL page
|
||||
else {
|
||||
$this->processOpenidRealm();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the current request
|
||||
*
|
||||
* @param array $request The current request parameters. Leave as null to default to use $_REQUEST.
|
||||
* @return Hybrid_Endpoint
|
||||
*/
|
||||
public static function process($request = null) {
|
||||
// Trick for PHP 5.2, because it doesn't support late static binding
|
||||
$class = function_exists('get_called_class') ? get_called_class() : __CLASS__;
|
||||
new $class($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process OpenID policy request
|
||||
* @return void
|
||||
*/
|
||||
protected function processOpenidPolicy() {
|
||||
$output = file_get_contents(dirname(__FILE__) . "/resources/openid_policy.html");
|
||||
print $output;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process OpenID XRDS request
|
||||
* @return void
|
||||
*/
|
||||
protected function processOpenidXRDS() {
|
||||
header("Content-Type: application/xrds+xml");
|
||||
|
||||
$output = str_replace("{RETURN_TO_URL}", str_replace(
|
||||
array("<", ">", "\"", "'", "&"), array("<", ">", """, "'", "&"), Hybrid_Auth::getCurrentUrl(false)
|
||||
), file_get_contents(dirname(__FILE__) . "/resources/openid_xrds.xml"));
|
||||
print $output;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process OpenID realm request
|
||||
* @return void
|
||||
*/
|
||||
protected function processOpenidRealm() {
|
||||
$output = str_replace("{X_XRDS_LOCATION}", htmlentities(Hybrid_Auth::getCurrentUrl(false), ENT_QUOTES, 'UTF-8')
|
||||
. "?get=openid_xrds&v="
|
||||
. Hybrid_Auth::$version, file_get_contents(dirname(__FILE__) . "/resources/openid_realm.html"));
|
||||
print $output;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define: endpoint step 3
|
||||
* @return void
|
||||
* @throws Hybrid_Exception
|
||||
*/
|
||||
protected function processAuthStart() {
|
||||
$this->authInit();
|
||||
|
||||
$provider_id = trim(strip_tags($this->request["hauth_start"]));
|
||||
|
||||
// check if page accessed directly
|
||||
if (!Hybrid_Auth::storage()->get("hauth_session.$provider_id.hauth_endpoint")) {
|
||||
Hybrid_Logger::error("Endpoint: hauth_endpoint parameter is not defined on hauth_start, halt login process!");
|
||||
|
||||
throw new Hybrid_Exception("You cannot access this page directly.");
|
||||
}
|
||||
|
||||
// define:hybrid.endpoint.php step 2.
|
||||
$hauth = Hybrid_Auth::setup($provider_id);
|
||||
|
||||
// if REQUESTed hauth_idprovider is wrong, session not created, etc.
|
||||
if (!$hauth) {
|
||||
Hybrid_Logger::error("Endpoint: Invalid parameter on hauth_start!");
|
||||
throw new Hybrid_Exception("Invalid parameter! Please return to the login page and try again.");
|
||||
}
|
||||
|
||||
try {
|
||||
Hybrid_Logger::info("Endpoint: call adapter [{$provider_id}] loginBegin()");
|
||||
|
||||
$hauth->adapter->loginBegin();
|
||||
} catch (Exception $e) {
|
||||
Hybrid_Logger::error("Exception:" . $e->getMessage(), $e);
|
||||
Hybrid_Error::setError($e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e->getPrevious());
|
||||
|
||||
$hauth->returnToCallbackUrl();
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define: endpoint step 3.1 and 3.2
|
||||
* @return void
|
||||
* @throws Hybrid_Exception
|
||||
*/
|
||||
protected function processAuthDone() {
|
||||
$this->authInit();
|
||||
|
||||
$provider_id = trim(strip_tags($this->request["hauth_done"]));
|
||||
|
||||
$hauth = Hybrid_Auth::setup($provider_id);
|
||||
|
||||
if (!$hauth) {
|
||||
Hybrid_Logger::error("Endpoint: Invalid parameter on hauth_done!");
|
||||
|
||||
$hauth->adapter->setUserUnconnected();
|
||||
|
||||
throw new Hybrid_Exception("Invalid parameter! Please return to the login page and try again.");
|
||||
}
|
||||
|
||||
try {
|
||||
Hybrid_Logger::info("Endpoint: call adapter [{$provider_id}] loginFinish() ");
|
||||
$hauth->adapter->loginFinish();
|
||||
} catch (Exception $e) {
|
||||
Hybrid_Logger::error("Exception:" . $e->getMessage(), $e);
|
||||
Hybrid_Error::setError($e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e->getPrevious());
|
||||
|
||||
$hauth->adapter->setUserUnconnected();
|
||||
}
|
||||
|
||||
Hybrid_Logger::info("Endpoint: job done. return to callback url.");
|
||||
|
||||
$hauth->returnToCallbackUrl();
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes authentication
|
||||
* @throws Hybrid_Exception
|
||||
*/
|
||||
protected function authInit() {
|
||||
if (!$this->initDone) {
|
||||
$this->initDone = true;
|
||||
|
||||
// Init Hybrid_Auth
|
||||
try {
|
||||
if (!class_exists("Hybrid_Storage", false)) {
|
||||
require_once realpath(dirname(__FILE__)) . "/Storage.php";
|
||||
}
|
||||
if (!class_exists("Hybrid_Exception", false)) {
|
||||
require_once realpath(dirname(__FILE__)) . "/Exception.php";
|
||||
}
|
||||
if (!class_exists("Hybrid_Logger", false)) {
|
||||
require_once realpath(dirname(__FILE__)) . "/Logger.php";
|
||||
}
|
||||
|
||||
$storage = new Hybrid_Storage();
|
||||
|
||||
// Check if Hybrid_Auth session already exist
|
||||
if (!$storage->config("CONFIG")) {
|
||||
throw new Hybrid_Exception("You cannot access this page directly.");
|
||||
}
|
||||
|
||||
Hybrid_Auth::initialize($storage->config("CONFIG"));
|
||||
} catch (Exception $e) {
|
||||
Hybrid_Logger::error("Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage());
|
||||
throw new Hybrid_Exception( "Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage(), $e->getCode(), $e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Errors manager
|
||||
*
|
||||
* HybridAuth errors are stored in Hybrid::storage() and not displayed directly to the end user
|
||||
*/
|
||||
class Hybrid_Error {
|
||||
|
||||
/**
|
||||
* Store error in session
|
||||
*
|
||||
* @param string $message Error message
|
||||
* @param int $code Error code
|
||||
* @param string $trace Back trace
|
||||
* @param string $previous Previous exception
|
||||
*/
|
||||
public static function setError($message, $code = null, $trace = null, $previous = null) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Error::setError( $message )");
|
||||
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.status", 1);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.message", $message);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.code", $code);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.trace", $trace);
|
||||
Hybrid_Auth::storage()->set("hauth_session.error.previous", $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the last error
|
||||
* @return void
|
||||
*/
|
||||
public static function clearError() {
|
||||
Hybrid_Logger::info("Enter Hybrid_Error::clearError()");
|
||||
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.status");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.message");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.code");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.trace");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.error.previous");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if there is a an error.
|
||||
* @return boolean true if there is an error.
|
||||
*/
|
||||
public static function hasError() {
|
||||
return (bool) Hybrid_Auth::storage()->get("hauth_session.error.status");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return error message
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorMessage() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.message");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return error code
|
||||
* @return int
|
||||
*/
|
||||
public static function getErrorCode() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.code");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return string detailed error backtrace as string
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorTrace() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.trace");
|
||||
}
|
||||
|
||||
/**
|
||||
* Detailed error backtrace as string
|
||||
* @return string
|
||||
*/
|
||||
public static function getErrorPrevious() {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.error.previous");
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception implementation
|
||||
*
|
||||
* The base Exception is extended to allow applications to handle exceptions from hybrid auth
|
||||
* separately from general exceptions.
|
||||
*/
|
||||
class Hybrid_Exception extends Exception {
|
||||
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Debugging and Logging manager
|
||||
*/
|
||||
class Hybrid_Logger {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct() {
|
||||
// if debug mode is set to true, then check for the writable log file
|
||||
if (Hybrid_Auth::$config["debug_mode"]) {
|
||||
if (!isset(Hybrid_Auth::$config["debug_file"])) {
|
||||
throw new Exception("'debug_mode' is set to 'true' but no log file path 'debug_file' is set.", 1);
|
||||
} elseif (!file_exists(Hybrid_Auth::$config["debug_file"]) && !is_writable(Hybrid_Auth::$config["debug_file"])) {
|
||||
if (!touch(Hybrid_Auth::$config["debug_file"])) {
|
||||
throw new Exception("'debug_mode' is set to 'true', but the file " . Hybrid_Auth::$config['debug_file'] . " in 'debug_file' can not be created.", 1);
|
||||
}
|
||||
} elseif (!is_writable(Hybrid_Auth::$config["debug_file"])) {
|
||||
throw new Exception("'debug_mode' is set to 'true', but the given log file path 'debug_file' is not a writable file.", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a debug message with an object dump
|
||||
*
|
||||
* @param string $message Debug message
|
||||
* @param stdClass $object Object being debugged
|
||||
* @return void
|
||||
*/
|
||||
public static function debug($message, $object = null) {
|
||||
if (Hybrid_Auth::$config["debug_mode"] === true) {
|
||||
$dt = new DateTime('now', new DateTimeZone( 'UTC' ));
|
||||
file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array(
|
||||
"DEBUG",
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
$dt->format(DATE_ATOM),
|
||||
$message,
|
||||
print_r($object, true) . PHP_EOL,
|
||||
)), FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an info message
|
||||
*
|
||||
* @param string $message Info message
|
||||
* @return void
|
||||
*/
|
||||
public static function info($message) {
|
||||
if (in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info'), true)) {
|
||||
$dt = new DateTime('now', new DateTimeZone( 'UTC' ));
|
||||
file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array(
|
||||
"INFO",
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
$dt->format(DATE_ATOM),
|
||||
$message . PHP_EOL,
|
||||
)), FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an error message with an object dump
|
||||
*
|
||||
* @param string $message Error message
|
||||
* @param stdClass $object Object being debugged
|
||||
* @return void
|
||||
*/
|
||||
public static function error($message, $object = null) {
|
||||
if (isset(Hybrid_Auth::$config["debug_mode"]) && in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info', 'error'), true)) {
|
||||
$dt = new DateTime('now', new DateTimeZone( 'UTC' ));
|
||||
file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array(
|
||||
'ERROR',
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
$dt->format(DATE_ATOM),
|
||||
$message,
|
||||
print_r($object, true) . PHP_EOL
|
||||
)), FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the data in the way suitable to be output in log files for debug purposes
|
||||
*
|
||||
* @param mixed $data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function dumpData($data) {
|
||||
return var_export($data, true);
|
||||
}
|
||||
|
||||
}
|
@ -1,340 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Provider_Adapter is the basic class which Hybrid_Auth will use
|
||||
* to connect users to a given provider.
|
||||
*
|
||||
* Basically Hybrid_Provider_Adapter will create a bridge from your php
|
||||
* application to the provider api.
|
||||
*
|
||||
* Hybrid_Auth will automatically load Hybrid_Provider_Adapter and create
|
||||
* an instance of it for each authenticated provider.
|
||||
*/
|
||||
class Hybrid_Provider_Adapter {
|
||||
|
||||
/**
|
||||
* Provider ID (or unique name)
|
||||
* @var mixed
|
||||
*/
|
||||
public $id = null;
|
||||
|
||||
/**
|
||||
* Provider adapter specific config
|
||||
* @var array
|
||||
*/
|
||||
public $config = null;
|
||||
|
||||
/**
|
||||
* Provider adapter extra parameters
|
||||
* @var array
|
||||
*/
|
||||
public $params = array();
|
||||
|
||||
/**
|
||||
* Provider adapter wrapper path
|
||||
* @var string
|
||||
*/
|
||||
public $wrapper = null;
|
||||
|
||||
/**
|
||||
* Provider adapter instance
|
||||
* @var Hybrid_Provider_Model
|
||||
*/
|
||||
public $adapter = null;
|
||||
|
||||
/**
|
||||
* Create a new adapter switch IDp name or ID
|
||||
*
|
||||
* @param string $id The id or name of the IDp
|
||||
* @param array $params (optional) required parameters by the adapter
|
||||
* @return Hybrid_Provider_Adapter
|
||||
* @throws Exception
|
||||
*/
|
||||
function factory($id, $params = array()) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::factory( $id )");
|
||||
|
||||
# init the adapter config and params
|
||||
$this->id = $id;
|
||||
$this->params = $params;
|
||||
$this->id = $this->getProviderCiId($this->id);
|
||||
$this->config = $this->getConfigById($this->id);
|
||||
|
||||
# check the IDp id
|
||||
if (!$this->id) {
|
||||
throw new Exception("No provider ID specified.", 2);
|
||||
}
|
||||
|
||||
# check the IDp config
|
||||
if (!$this->config) {
|
||||
throw new Exception("Unknown Provider ID, check your configuration file.", 3);
|
||||
}
|
||||
|
||||
# check the IDp adapter is enabled
|
||||
if (!$this->config["enabled"]) {
|
||||
throw new Exception("The provider '{$this->id}' is not enabled.", 3);
|
||||
}
|
||||
|
||||
# include the adapter wrapper
|
||||
if (isset($this->config["wrapper"]) && is_array($this->config["wrapper"])) {
|
||||
if (isset($this->config["wrapper"]["path"])) {
|
||||
require_once $this->config["wrapper"]["path"];
|
||||
}
|
||||
|
||||
if (!class_exists($this->config["wrapper"]["class"])) {
|
||||
throw new Exception("Unable to load the adapter class.", 3);
|
||||
}
|
||||
|
||||
$this->wrapper = $this->config["wrapper"]["class"];
|
||||
} else {
|
||||
require_once Hybrid_Auth::$config["path_providers"] . $this->id . ".php";
|
||||
|
||||
$this->wrapper = "Hybrid_Providers_" . $this->id;
|
||||
}
|
||||
|
||||
# create the adapter instance, and pass the current params and config
|
||||
$this->adapter = new $this->wrapper($this->id, $this->config, $this->params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hybrid_Provider_Adapter::login(), prepare the user session and the authentication request
|
||||
* for index.php
|
||||
* @return void
|
||||
* @throw Exception
|
||||
*/
|
||||
function login() {
|
||||
Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::login( {$this->id} ) ");
|
||||
|
||||
if (!$this->adapter) {
|
||||
throw new Exception("Hybrid_Provider_Adapter::login() should not directly used.");
|
||||
}
|
||||
|
||||
// clear all unneeded params
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.hauth_return_to");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.hauth_endpoint");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$idpid}.id_provider_params");
|
||||
}
|
||||
|
||||
// make a fresh start
|
||||
$this->logout();
|
||||
|
||||
# get hybridauth base url
|
||||
if (empty(Hybrid_Auth::$config["base_url"])) {
|
||||
// the base url wasn't provide, so we must use the current
|
||||
// url (which makes sense actually)
|
||||
$url = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off' ? 'http' : 'https';
|
||||
$url .= '://' . $_SERVER['HTTP_HOST'];
|
||||
$url .= $_SERVER['REQUEST_URI'];
|
||||
$HYBRID_AUTH_URL_BASE = $url;
|
||||
} else {
|
||||
$HYBRID_AUTH_URL_BASE = Hybrid_Auth::$config["base_url"];
|
||||
}
|
||||
|
||||
// make sure params is array
|
||||
if (!is_array($this->params)) {
|
||||
$this->params = array();
|
||||
}
|
||||
|
||||
# we make use of session_id() as storage hash to identify the current user
|
||||
# using session_regenerate_id() will be a problem, but ..
|
||||
$this->params["hauth_token"] = session_id();
|
||||
|
||||
# set request timestamp
|
||||
$this->params["hauth_time"] = time();
|
||||
|
||||
# for default HybridAuth endpoint url hauth_login_start_url
|
||||
# auth.start required the IDp ID
|
||||
# auth.time optional login request timestamp
|
||||
if (!isset($this->params["login_start"]) ) {
|
||||
$this->params["login_start"] = $HYBRID_AUTH_URL_BASE . ( strpos($HYBRID_AUTH_URL_BASE, '?') ? '&' : '?' ) . "hauth.start={$this->id}&hauth.time={$this->params["hauth_time"]}";
|
||||
}
|
||||
|
||||
# for default HybridAuth endpoint url hauth_login_done_url
|
||||
# auth.done required the IDp ID
|
||||
if (!isset($this->params["login_done"]) ) {
|
||||
$this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos($HYBRID_AUTH_URL_BASE, '?') ? '&' : '?' ) . "hauth.done={$this->id}";
|
||||
}
|
||||
|
||||
# workaround to solve windows live authentication since microsoft disallowed redirect urls to contain any parameters
|
||||
# http://mywebsite.com/path_to_hybridauth/?hauth.done=Live will not work
|
||||
if ($this->id=="Live") {
|
||||
$this->params["login_done"] = $HYBRID_AUTH_URL_BASE."live.php";
|
||||
}
|
||||
|
||||
# Workaround to fix broken callback urls for the Facebook OAuth client
|
||||
if ($this->adapter->useSafeUrls) {
|
||||
$this->params['login_done'] = str_replace('hauth.done', 'hauth_done', $this->params['login_done']);
|
||||
}
|
||||
|
||||
if (isset($this->params["hauth_return_to"])) {
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->id}.hauth_return_to", $this->params["hauth_return_to"]);
|
||||
}
|
||||
if (isset($this->params["login_done"])) {
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->id}.hauth_endpoint", $this->params["login_done"]);
|
||||
}
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->id}.id_provider_params", $this->params);
|
||||
|
||||
// store config to be used by the end point
|
||||
Hybrid_Auth::storage()->config("CONFIG", Hybrid_Auth::$config);
|
||||
|
||||
// move on
|
||||
Hybrid_Logger::debug("Hybrid_Provider_Adapter::login( {$this->id} ), redirect the user to login_start URL.");
|
||||
|
||||
// redirect
|
||||
if (empty($this->params["redirect_mode"])) {
|
||||
Hybrid_Auth::redirect($this->params["login_start"]);
|
||||
} else {
|
||||
Hybrid_Auth::redirect($this->params["login_start"],$this->params["redirect_mode"]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let hybridauth forget all about the user for the current provider
|
||||
* @return bool
|
||||
*/
|
||||
function logout() {
|
||||
$this->adapter->logout();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return true if the user is connected to the current provider
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserConnected() {
|
||||
return $this->adapter->isUserConnected();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Call adapter methods defined in the adapter model:
|
||||
* getUserProfile()
|
||||
* getUserContacts()
|
||||
* getUserActivity()
|
||||
* setUserStatus()
|
||||
*
|
||||
* @param string $name Method name
|
||||
* @param array $arguments Call arguments
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __call($name, $arguments) {
|
||||
Hybrid_Logger::info("Enter Hybrid_Provider_Adapter::$name(), Provider: {$this->id}");
|
||||
|
||||
if (!$this->isUserConnected()) {
|
||||
throw new Exception("User not connected to the provider {$this->id}.", 7);
|
||||
}
|
||||
|
||||
if (!method_exists($this->adapter, $name)) {
|
||||
throw new Exception("Call to undefined function Hybrid_Providers_{$this->id}::$name().");
|
||||
}
|
||||
|
||||
return call_user_func_array(array($this->adapter, $name), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user is connected, then return the access_token and access_token_secret
|
||||
* if the provider api use oauth
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'access_token' => '',
|
||||
* 'access_token_secret' => '',
|
||||
* 'refresh_token' => '',
|
||||
* 'expires_in' => '',
|
||||
* 'expires_at' => '',
|
||||
* )
|
||||
* </code>
|
||||
* @return array
|
||||
*/
|
||||
public function getAccessToken() {
|
||||
if (!$this->adapter->isUserConnected()) {
|
||||
Hybrid_Logger::error("User not connected to the provider.");
|
||||
throw new Exception("User not connected to the provider.", 7);
|
||||
}
|
||||
|
||||
return array(
|
||||
"access_token" => $this->adapter->token("access_token"), // OAuth access token
|
||||
"access_token_secret" => $this->adapter->token("access_token_secret"), // OAuth access token secret
|
||||
"refresh_token" => $this->adapter->token("refresh_token"), // OAuth refresh token
|
||||
"expires_in" => $this->adapter->token("expires_in"), // OPTIONAL. The duration in seconds of the access token lifetime
|
||||
"expires_at" => $this->adapter->token("expires_at"), // OPTIONAL. Timestamp when the access_token expire. if not provided by the social api, then it should be calculated: expires_at = now + expires_in
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Naive getter of the current connected IDp API client
|
||||
* @return stdClass
|
||||
* @throws Exception
|
||||
*/
|
||||
function api() {
|
||||
if (!$this->adapter->isUserConnected()) {
|
||||
Hybrid_Logger::error("User not connected to the provider.");
|
||||
|
||||
throw new Exception("User not connected to the provider.", 7);
|
||||
}
|
||||
return $this->adapter->api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the user to hauth_return_to (the callback url)
|
||||
* @return void
|
||||
*/
|
||||
function returnToCallbackUrl() {
|
||||
// get the stored callback url
|
||||
$callback_url = Hybrid_Auth::storage()->get("hauth_session.{$this->id}.hauth_return_to");
|
||||
|
||||
// if the user presses the back button in the browser and we already deleted the hauth_return_to from
|
||||
// the session in the previous request, we will redirect to '/' instead of displaying a blank page.
|
||||
if (!$callback_url) {
|
||||
$callback_url = '/';
|
||||
}
|
||||
|
||||
// remove some unneeded stored data
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.hauth_return_to");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.hauth_endpoint");
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->id}.id_provider_params");
|
||||
|
||||
// back to home
|
||||
Hybrid_Auth::redirect($callback_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the provider config by id
|
||||
*
|
||||
* @param string $id Config key
|
||||
* @return mixed
|
||||
*/
|
||||
function getConfigById($id) {
|
||||
if (isset(Hybrid_Auth::$config["providers"][$id])) {
|
||||
return Hybrid_Auth::$config["providers"][$id];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the provider config by id; case insensitive
|
||||
*
|
||||
* @param string $id Provider id
|
||||
* @return mixed
|
||||
*/
|
||||
function getProviderCiId($id) {
|
||||
foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) {
|
||||
if (strtolower($idpid) == strtolower($id)) {
|
||||
return $idpid;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,247 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Provider_Model provide a common interface for supported IDps on HybridAuth.
|
||||
*
|
||||
* Basically, each provider adapter has to define at least 4 methods:
|
||||
* Hybrid_Providers_{provider_name}::initialize()
|
||||
* Hybrid_Providers_{provider_name}::loginBegin()
|
||||
* Hybrid_Providers_{provider_name}::loginFinish()
|
||||
* Hybrid_Providers_{provider_name}::getUserProfile()
|
||||
*
|
||||
* HybridAuth also come with three others models
|
||||
* Class Hybrid_Provider_Model_OpenID for providers that uses the OpenID 1 and 2 protocol.
|
||||
* Class Hybrid_Provider_Model_OAuth1 for providers that uses the OAuth 1 protocol.
|
||||
* Class Hybrid_Provider_Model_OAuth2 for providers that uses the OAuth 2 protocol.
|
||||
*/
|
||||
abstract class Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* IDp ID (or unique name)
|
||||
* @var mixed
|
||||
*/
|
||||
public $providerId = null;
|
||||
|
||||
/**
|
||||
* Specific provider adapter config
|
||||
* @var array
|
||||
*/
|
||||
public $config = null;
|
||||
|
||||
/**
|
||||
* Provider extra parameters
|
||||
* @var array
|
||||
*/
|
||||
public $params = null;
|
||||
|
||||
/**
|
||||
* Endpoint URL for that provider
|
||||
* @var string
|
||||
*/
|
||||
public $endpoint = null;
|
||||
|
||||
/**
|
||||
* Hybrid_User obj, represents the current loggedin user
|
||||
* @var Hybrid_User
|
||||
*/
|
||||
public $user = null;
|
||||
|
||||
/**
|
||||
* The provider api client (optional)
|
||||
* @var stdClass
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Model should use "gzip,deflate" for CURLOPT_ENCODING
|
||||
* @var stdClass
|
||||
*/
|
||||
public $compressed = false;
|
||||
|
||||
/** @var bool $useSafeUrls Enable this to replace '.' with '_' characters in the callback urls */
|
||||
public $useSafeUrls = false;
|
||||
|
||||
/**
|
||||
* Common providers adapter constructor
|
||||
*
|
||||
* @param mixed $providerId Provider ID
|
||||
* @param array $config Provider adapter config
|
||||
* @param array $params Provider extra params
|
||||
*/
|
||||
function __construct($providerId, $config, $params = null) {
|
||||
# init the IDp adapter parameters, get them from the cache if possible
|
||||
if (!$params) {
|
||||
$this->params = Hybrid_Auth::storage()->get("hauth_session.$providerId.id_provider_params");
|
||||
} else {
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
// idp id
|
||||
$this->providerId = $providerId;
|
||||
|
||||
// set HybridAuth endpoint for this provider
|
||||
$this->endpoint = Hybrid_Auth::storage()->get("hauth_session.$providerId.hauth_endpoint");
|
||||
|
||||
// idp config
|
||||
$this->config = $config;
|
||||
|
||||
// new user instance
|
||||
$this->user = new Hybrid_User();
|
||||
$this->user->providerId = $providerId;
|
||||
|
||||
// initialize the current provider adapter
|
||||
$this->initialize();
|
||||
|
||||
Hybrid_Logger::debug("Hybrid_Provider_Model::__construct( $providerId ) initialized. dump current adapter instance: ", serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* IDp wrappers initializer
|
||||
*
|
||||
* The main job of wrappers initializer is to performs (depend on the IDp api client it self):
|
||||
* - include some libs needed by this provider,
|
||||
* - check IDp key and secret,
|
||||
* - set some needed parameters (stored in $this->params) by this IDp api client
|
||||
* - create and setup an instance of the IDp api client on $this->api
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract protected function initialize();
|
||||
|
||||
/**
|
||||
* Begin login
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract public function loginBegin();
|
||||
|
||||
/**
|
||||
* Finish login
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract public function loginFinish();
|
||||
|
||||
/**
|
||||
* Generic logout, just erase current provider adapter stored data to let Hybrid_Auth all forget about it
|
||||
* @return bool
|
||||
*/
|
||||
function logout() {
|
||||
Hybrid_Logger::info("Enter [{$this->providerId}]::logout()");
|
||||
$this->clearTokens();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab the user profile from the IDp api client
|
||||
* @return Hybrid_User_Profile
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserProfile() {
|
||||
Hybrid_Logger::error("HybridAuth do not provide users contacts list for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the current logged in user contacts list from the IDp api client
|
||||
* @return Hybrid_User_Contact[]
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserContacts() {
|
||||
Hybrid_Logger::error("HybridAuth do not provide users contacts list for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user activity stream
|
||||
* @return Hybrid_User_Activity[]
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserActivity($stream) {
|
||||
Hybrid_Logger::error("HybridAuth do not provide user's activity stream for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user status
|
||||
* @return mixed Provider response
|
||||
* @throws Exception
|
||||
*/
|
||||
function setUserStatus($status) {
|
||||
Hybrid_Logger::error("HybridAuth do not provide user's activity stream for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user status
|
||||
* @return mixed Provider response
|
||||
* @throws Exception
|
||||
*/
|
||||
function getUserStatus($statusid) {
|
||||
Hybrid_Logger::error("HybridAuth do not provide user's status for {$this->providerId} yet.");
|
||||
throw new Exception("Provider does not support this feature.", 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the user is connected to the current provider
|
||||
* @return bool
|
||||
*/
|
||||
public function isUserConnected() {
|
||||
return (bool) Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.is_logged_in");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user to connected
|
||||
* @return void
|
||||
*/
|
||||
public function setUserConnected() {
|
||||
Hybrid_Logger::info("Enter [{$this->providerId}]::setUserConnected()");
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.is_logged_in", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user to unconnected
|
||||
* @return void
|
||||
*/
|
||||
public function setUserUnconnected() {
|
||||
Hybrid_Logger::info("Enter [{$this->providerId}]::setUserUnconnected()");
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.is_logged_in", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set a token
|
||||
* @return string
|
||||
*/
|
||||
public function token($token, $value = null) {
|
||||
if ($value === null) {
|
||||
return Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.token.$token");
|
||||
} else {
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.token.$token", $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a stored token
|
||||
* @return void
|
||||
*/
|
||||
public function deleteToken($token) {
|
||||
Hybrid_Auth::storage()->delete("hauth_session.{$this->providerId}.token.$token");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all existent tokens for this provider
|
||||
* @return void
|
||||
*/
|
||||
public function clearTokens() {
|
||||
Hybrid_Auth::storage()->deleteMatch("hauth_session.{$this->providerId}.");
|
||||
}
|
||||
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* To implement an OAuth 1 based service provider, Hybrid_Provider_Model_OAuth1
|
||||
* can be used to save the hassle of the authentication flow.
|
||||
*
|
||||
* Each class that inherit from Hybrid_Provider_Model_OAuth1 have to implement
|
||||
* at least 2 methods:
|
||||
* Hybrid_Providers_{provider_name}::initialize() to setup the provider api end-points urls
|
||||
* Hybrid_Providers_{provider_name}::getUserProfile() to grab the user profile
|
||||
*
|
||||
* Hybrid_Provider_Model_OAuth1 use OAuth1Client v0.1 which can be found on
|
||||
* Hybrid/thirdparty/OAuth/OAuth1Client.php
|
||||
*/
|
||||
class Hybrid_Provider_Model_OAuth1 extends Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* Provider API client
|
||||
* @var OAuth1Client
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Request_tokens as received from provider
|
||||
* @var stdClas
|
||||
*/
|
||||
public $request_tokens_raw = null;
|
||||
|
||||
/**
|
||||
* Access_tokens as received from provider
|
||||
* @var stdClass
|
||||
*/
|
||||
public $access_tokens_raw = null;
|
||||
|
||||
/**
|
||||
* Try to get the error message from provider api
|
||||
*
|
||||
* @param int $code Error code
|
||||
* @return string
|
||||
*/
|
||||
function errorMessageByStatus($code = null) {
|
||||
$http_status_codes = array(
|
||||
200 => "OK: Success!",
|
||||
304 => "Not Modified: There was no new data to return.",
|
||||
400 => "Bad Request: The request was invalid.",
|
||||
401 => "Unauthorized.",
|
||||
403 => "Forbidden: The request is understood, but it has been refused.",
|
||||
404 => "Not Found: The URI requested is invalid or the resource requested does not exists.",
|
||||
406 => "Not Acceptable.",
|
||||
500 => "Internal Server Error: Something is broken.",
|
||||
502 => "Bad Gateway.",
|
||||
503 => "Service Unavailable."
|
||||
);
|
||||
|
||||
if (!$code && $this->api) {
|
||||
$code = $this->api->http_code;
|
||||
}
|
||||
|
||||
if (isset($http_status_codes[$code])) {
|
||||
return $code . " " . $http_status_codes[$code];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
// 1 - check application credentials
|
||||
if (!$this->config["keys"]["key"] || !$this->config["keys"]["secret"]) {
|
||||
throw new Exception("Your application key and secret are required in order to connect to {$this->providerId}.", 4);
|
||||
}
|
||||
|
||||
// 2 - include OAuth lib and client
|
||||
if (! class_exists('OAuthConsumer') ) {
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth.php";
|
||||
}
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth1Client.php";
|
||||
|
||||
// 3.1 - setup access_token if any stored
|
||||
if ($this->token("access_token")) {
|
||||
$this->api = new OAuth1Client(
|
||||
$this->config["keys"]["key"], $this->config["keys"]["secret"], $this->token("access_token"), $this->token("access_token_secret")
|
||||
);
|
||||
}
|
||||
|
||||
// 3.2 - setup request_token if any stored, in order to exchange with an access token
|
||||
elseif ($this->token("request_token")) {
|
||||
$this->api = new OAuth1Client(
|
||||
$this->config["keys"]["key"], $this->config["keys"]["secret"], $this->token("request_token"), $this->token("request_token_secret")
|
||||
);
|
||||
}
|
||||
|
||||
// 3.3 - instanciate OAuth client with client credentials
|
||||
else {
|
||||
$this->api = new OAuth1Client($this->config["keys"]["key"], $this->config["keys"]["secret"]);
|
||||
}
|
||||
|
||||
// Set curl proxy if exist
|
||||
if (isset(Hybrid_Auth::$config["proxy"])) {
|
||||
$this->api->curl_proxy = Hybrid_Auth::$config["proxy"];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
$tokens = $this->api->requestToken($this->endpoint);
|
||||
|
||||
// request tokens as received from provider
|
||||
$this->request_tokens_raw = $tokens;
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth token.", 5);
|
||||
}
|
||||
|
||||
$this->token("request_token", $tokens["oauth_token"]);
|
||||
$this->token("request_token_secret", $tokens["oauth_token_secret"]);
|
||||
|
||||
# redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($tokens));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
$oauth_token = (array_key_exists('oauth_token', $_REQUEST)) ? $_REQUEST['oauth_token'] : "";
|
||||
$oauth_verifier = (array_key_exists('oauth_verifier', $_REQUEST)) ? $_REQUEST['oauth_verifier'] : "";
|
||||
|
||||
if (!$oauth_token || !$oauth_verifier) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth verifier.", 5);
|
||||
}
|
||||
|
||||
// request an access token
|
||||
$tokens = $this->api->accessToken($oauth_verifier);
|
||||
|
||||
// access tokens as received from provider
|
||||
$this->access_tokens_raw = $tokens;
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
|
||||
// we should have an access_token, or else, something has gone wrong
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5);
|
||||
}
|
||||
|
||||
// we no more need to store request tokens
|
||||
$this->deleteToken("request_token");
|
||||
$this->deleteToken("request_token_secret");
|
||||
|
||||
// store access_token for later user
|
||||
$this->token("access_token", $tokens['oauth_token']);
|
||||
$this->token("access_token_secret", $tokens['oauth_token_secret']);
|
||||
|
||||
// set user as logged in to the current provider
|
||||
$this->setUserConnected();
|
||||
}
|
||||
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* To implement an OAuth 2 based service provider, Hybrid_Provider_Model_OAuth2
|
||||
* can be used to save the hassle of the authentication flow.
|
||||
*
|
||||
* Each class that inherit from Hybrid_Provider_Model_OAuth2 have to implement
|
||||
* at least 2 methods:
|
||||
* Hybrid_Providers_{provider_name}::initialize() to setup the provider api end-points urls
|
||||
* Hybrid_Providers_{provider_name}::getUserProfile() to grab the user profile
|
||||
*
|
||||
* Hybrid_Provider_Model_OAuth2 use OAuth2Client v0.1 which can be found on
|
||||
* Hybrid/thirdparty/OAuth/OAuth2Client.php
|
||||
*/
|
||||
class Hybrid_Provider_Model_OAuth2 extends Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* Default permissions
|
||||
* @var string
|
||||
*/
|
||||
public $scope = "";
|
||||
|
||||
/**
|
||||
* Provider API wrapper
|
||||
* @var OAuth2Client
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Try to get the error message from provider api
|
||||
*
|
||||
* @param int $code Error code
|
||||
* @return string
|
||||
*/
|
||||
function errorMessageByStatus($code = null) {
|
||||
$http_status_codes = array(
|
||||
200 => "OK: Success!",
|
||||
304 => "Not Modified: There was no new data to return.",
|
||||
400 => "Bad Request: The request was invalid.",
|
||||
401 => "Unauthorized.",
|
||||
403 => "Forbidden: The request is understood, but it has been refused.",
|
||||
404 => "Not Found: The URI requested is invalid or the resource requested does not exists.",
|
||||
406 => "Not Acceptable.",
|
||||
500 => "Internal Server Error: Something is broken.",
|
||||
502 => "Bad Gateway.",
|
||||
503 => "Service Unavailable."
|
||||
);
|
||||
|
||||
if (!$code && $this->api) {
|
||||
$code = $this->api->http_code;
|
||||
}
|
||||
|
||||
if (isset($http_status_codes[$code])) {
|
||||
return $code . " " . $http_status_codes[$code];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter initializer
|
||||
*/
|
||||
function initialize() {
|
||||
if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) {
|
||||
throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4);
|
||||
}
|
||||
|
||||
// override requested scope
|
||||
if (isset($this->config["scope"]) && !empty($this->config["scope"])) {
|
||||
$this->scope = $this->config["scope"];
|
||||
}
|
||||
|
||||
// include OAuth2 client
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth2Client.php";
|
||||
|
||||
// create a new OAuth2 client instance
|
||||
$this->api = new OAuth2Client($this->config["keys"]["id"], $this->config["keys"]["secret"], $this->endpoint, $this->compressed);
|
||||
|
||||
// If we have an access token, set it
|
||||
if ($this->token("access_token")) {
|
||||
$this->api->access_token = $this->token("access_token");
|
||||
$this->api->refresh_token = $this->token("refresh_token");
|
||||
$this->api->access_token_expires_in = $this->token("expires_in");
|
||||
$this->api->access_token_expires_at = $this->token("expires_at");
|
||||
}
|
||||
|
||||
// Set curl proxy if exist
|
||||
if (isset(Hybrid_Auth::$config["proxy"])) {
|
||||
$this->api->curl_proxy = Hybrid_Auth::$config["proxy"];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
// redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl(array("scope" => $this->scope)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
$error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : "";
|
||||
|
||||
// check for errors
|
||||
if ($error) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error: $error", 5);
|
||||
}
|
||||
|
||||
// try to authenticate user
|
||||
$code = (array_key_exists('code', $_REQUEST)) ? $_REQUEST['code'] : "";
|
||||
|
||||
try {
|
||||
$this->api->authenticate($code);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an error: " . $e->getMessage(), 6);
|
||||
}
|
||||
|
||||
// check if authenticated
|
||||
if (!$this->api->access_token) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5);
|
||||
}
|
||||
|
||||
// store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
|
||||
// set user connected locally
|
||||
$this->setUserConnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function refreshToken() {
|
||||
// have an access token?
|
||||
if ($this->api->access_token) {
|
||||
|
||||
// have to refresh?
|
||||
if ($this->api->refresh_token && $this->api->access_token_expires_at) {
|
||||
|
||||
// expired?
|
||||
if ($this->api->access_token_expires_at <= time()) {
|
||||
$response = $this->api->refreshToken(array("refresh_token" => $this->api->refresh_token));
|
||||
|
||||
if (!isset($response->access_token) || !$response->access_token) {
|
||||
// set the user as disconnected at this point and throw an exception
|
||||
$this->setUserUnconnected();
|
||||
|
||||
throw new Exception("The Authorization Service has return an invalid response while requesting a new access token. " . (string) $response->error);
|
||||
}
|
||||
|
||||
// set new access_token
|
||||
$this->api->access_token = $response->access_token;
|
||||
|
||||
if (isset($response->refresh_token))
|
||||
$this->api->refresh_token = $response->refresh_token;
|
||||
|
||||
if (isset($response->expires_in)) {
|
||||
$this->api->access_token_expires_in = $response->expires_in;
|
||||
|
||||
// even given by some idp, we should calculate this
|
||||
$this->api->access_token_expires_at = time() + $response->expires_in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// re store tokens
|
||||
$this->token("access_token", $this->api->access_token);
|
||||
$this->token("refresh_token", $this->api->refresh_token);
|
||||
$this->token("expires_in", $this->api->access_token_expires_in);
|
||||
$this->token("expires_at", $this->api->access_token_expires_at);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* To implement an OpenID based service provider, Hybrid_Provider_Model_OpenID
|
||||
* can be used to save the hassle of the authentication flow.
|
||||
*
|
||||
* Each class that inherit from Hybrid_Provider_Model_OAuth2 have only to define
|
||||
* the provider identifier : <code>public $openidIdentifier = ""; </code>
|
||||
*
|
||||
* Hybrid_Provider_Model_OpenID use LightOpenID lib which can be found on
|
||||
* Hybrid/thirdparty/OpenID/LightOpenID.php
|
||||
*/
|
||||
class Hybrid_Provider_Model_OpenID extends Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* Provider API client
|
||||
* @var LightOpenID
|
||||
*/
|
||||
public $api = null;
|
||||
|
||||
/**
|
||||
* Openid provider identifier
|
||||
* @var string
|
||||
*/
|
||||
public $openidIdentifier = "";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
if (isset($this->params["openid_identifier"])) {
|
||||
$this->openidIdentifier = $this->params["openid_identifier"];
|
||||
}
|
||||
|
||||
// include LightOpenID lib
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "OpenID/LightOpenID.php";
|
||||
|
||||
// An error was occurring when proxy wasn't set. Not sure where proxy was meant to be set/initialized.
|
||||
Hybrid_Auth::$config['proxy'] = isset(Hybrid_Auth::$config['proxy']) ? Hybrid_Auth::$config['proxy'] : '';
|
||||
|
||||
$hostPort = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_PORT);
|
||||
$hostUrl = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_HOST);
|
||||
|
||||
// Check for port on url
|
||||
if ($hostPort) {
|
||||
$hostUrl .= ':' . $hostPort;
|
||||
}
|
||||
|
||||
$this->api = new LightOpenID($hostUrl, Hybrid_Auth::$config["proxy"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
if (empty($this->openidIdentifier)) {
|
||||
throw new Exception("OpenID adapter require the identity provider identifier 'openid_identifier' as an extra parameter.", 4);
|
||||
}
|
||||
|
||||
$this->api->identity = $this->openidIdentifier;
|
||||
$this->api->returnUrl = $this->endpoint;
|
||||
$this->api->required = array(
|
||||
'namePerson/first',
|
||||
'namePerson/last',
|
||||
'namePerson/friendly',
|
||||
'namePerson',
|
||||
'contact/email',
|
||||
'birthDate',
|
||||
'birthDate/birthDay',
|
||||
'birthDate/birthMonth',
|
||||
'birthDate/birthYear',
|
||||
'person/gender',
|
||||
'pref/language',
|
||||
'contact/postalCode/home',
|
||||
'contact/city/home',
|
||||
'contact/country/home',
|
||||
'media/image/default',
|
||||
);
|
||||
|
||||
# redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
# if user don't grant access of their data to your site, halt with an Exception
|
||||
if ($this->api->mode == 'cancel') {
|
||||
throw new Exception("Authentication failed! User has canceled authentication!", 5);
|
||||
}
|
||||
|
||||
# if something goes wrong
|
||||
if (!$this->api->validate()) {
|
||||
throw new Exception("Authentication failed. Invalid request received!", 5);
|
||||
}
|
||||
|
||||
# fetch received user data
|
||||
$response = $this->api->getAttributes();
|
||||
|
||||
# store the user profile
|
||||
$this->user->profile->identifier = $this->api->identity;
|
||||
|
||||
$this->user->profile->firstName = (array_key_exists("namePerson/first", $response)) ? $response["namePerson/first"] : "";
|
||||
$this->user->profile->lastName = (array_key_exists("namePerson/last", $response)) ? $response["namePerson/last"] : "";
|
||||
$this->user->profile->displayName = (array_key_exists("namePerson", $response)) ? $response["namePerson"] : "";
|
||||
$this->user->profile->email = (array_key_exists("contact/email", $response)) ? $response["contact/email"] : "";
|
||||
$this->user->profile->language = (array_key_exists("pref/language", $response)) ? $response["pref/language"] : "";
|
||||
$this->user->profile->country = (array_key_exists("contact/country/home", $response)) ? $response["contact/country/home"] : "";
|
||||
$this->user->profile->zip = (array_key_exists("contact/postalCode/home", $response)) ? $response["contact/postalCode/home"] : "";
|
||||
$this->user->profile->gender = (array_key_exists("person/gender", $response)) ? $response["person/gender"] : "";
|
||||
$this->user->profile->photoURL = (array_key_exists("media/image/default", $response)) ? $response["media/image/default"] : "";
|
||||
|
||||
$this->user->profile->birthDay = (array_key_exists("birthDate/birthDay", $response)) ? $response["birthDate/birthDay"] : "";
|
||||
$this->user->profile->birthMonth = (array_key_exists("birthDate/birthMonth", $response)) ? $response["birthDate/birthMonth"] : "";
|
||||
$this->user->profile->birthYear = (array_key_exists("birthDate/birthDate", $response)) ? $response["birthDate/birthDate"] : "";
|
||||
|
||||
if (isset($response['namePerson/friendly']) && !empty($response['namePerson/friendly']) && !$this->user->profile->displayName) {
|
||||
$this->user->profile->displayName = $response["namePerson/friendly"];
|
||||
}
|
||||
|
||||
if (isset($response['birthDate']) && !empty($response['birthDate']) && !$this->user->profile->birthDay) {
|
||||
list( $birthday_year, $birthday_month, $birthday_day ) = $response['birthDate'];
|
||||
|
||||
$this->user->profile->birthDay = (int) $birthday_day;
|
||||
$this->user->profile->birthMonth = (int) $birthday_month;
|
||||
$this->user->profile->birthYear = (int) $birthday_year;
|
||||
}
|
||||
|
||||
if (!$this->user->profile->displayName) {
|
||||
$this->user->profile->displayName = trim($this->user->profile->firstName . " " . $this->user->profile->lastName);
|
||||
}
|
||||
|
||||
if ($this->user->profile->gender == "f") {
|
||||
$this->user->profile->gender = "female";
|
||||
}
|
||||
|
||||
if ($this->user->profile->gender == "m") {
|
||||
$this->user->profile->gender = "male";
|
||||
}
|
||||
|
||||
// set user as logged in
|
||||
$this->setUserConnected();
|
||||
|
||||
// with openid providers we get the user profile only once, so store it
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.user", $this->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
// try to get the user profile from stored data
|
||||
$this->user = Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.user");
|
||||
|
||||
// if not found
|
||||
if (!is_object($this->user)) {
|
||||
throw new Exception("User profile request failed! User is not connected to {$this->providerId} or his session has expired.", 6);
|
||||
}
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_AOL provider adapter based on OpenID protocol
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_AOL.html
|
||||
*/
|
||||
class Hybrid_Providers_AOL extends Hybrid_Provider_Model_OpenID {
|
||||
|
||||
var $openidIdentifier = "http://openid.aol.com/";
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/*!
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Amazon provider adapter based on OAuth2 protocol
|
||||
*
|
||||
* added by skyverge | https://github.com/skyverge
|
||||
*
|
||||
* The Provider is very similar to standard Oauth2 providers with a few differences:
|
||||
* - it sets the Content-Type header explicitly to application/x-www-form-urlencoded
|
||||
* as required by Amazon
|
||||
* - it uses a custom OAuth2Client, because the built-in one does not use http_build_query()
|
||||
* to set curl POST params, which causes cURL to set the Content-Type to multipart/form-data
|
||||
*
|
||||
* @property OAuth2Client $api
|
||||
*/
|
||||
class Hybrid_Providers_Amazon extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
// default permissions
|
||||
public $scope = 'profile postal_code';
|
||||
|
||||
/**
|
||||
* IDp wrappers initializer
|
||||
*/
|
||||
function initialize() {
|
||||
|
||||
if ( ! $this->config['keys']['id'] || ! $this->config['keys']['secret'] ) {
|
||||
throw new Exception( "Your application id and secret are required in order to connect to {$this->providerId}.", 4 );
|
||||
}
|
||||
|
||||
// override requested scope
|
||||
if ( isset( $this->config['scope'] ) && ! empty( $this->config['scope'] ) ) {
|
||||
$this->scope = $this->config['scope'];
|
||||
}
|
||||
|
||||
// include OAuth2 client
|
||||
require_once Hybrid_Auth::$config['path_libraries'] . 'OAuth/OAuth2Client.php';
|
||||
require_once Hybrid_Auth::$config['path_libraries'] . 'Amazon/AmazonOAuth2Client.php';
|
||||
|
||||
// create a new OAuth2 client instance
|
||||
$this->api = new AmazonOAuth2Client( $this->config['keys']['id'], $this->config['keys']['secret'], $this->endpoint, $this->compressed );
|
||||
|
||||
$this->api->api_base_url = 'https://api.amazon.com';
|
||||
$this->api->authorize_url = 'https://www.amazon.com/ap/oa';
|
||||
$this->api->token_url = 'https://api.amazon.com/auth/o2/token';
|
||||
|
||||
$this->api->curl_header = array( 'Content-Type: application/x-www-form-urlencoded' );
|
||||
|
||||
// If we have an access token, set it
|
||||
if ( $this->token( 'access_token' ) ) {
|
||||
$this->api->access_token = $this->token('access_token');
|
||||
$this->api->refresh_token = $this->token('refresh_token');
|
||||
$this->api->access_token_expires_in = $this->token('expires_in');
|
||||
$this->api->access_token_expires_at = $this->token('expires_at');
|
||||
}
|
||||
|
||||
// Set curl proxy if exists
|
||||
if ( isset( Hybrid_Auth::$config['proxy'] ) ) {
|
||||
$this->api->curl_proxy = Hybrid_Auth::$config['proxy'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user profile from the IDp api client
|
||||
*/
|
||||
function getUserProfile() {
|
||||
|
||||
$data = $this->api->get( '/user/profile' );
|
||||
|
||||
if ( ! isset( $data->user_id ) ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 );
|
||||
}
|
||||
|
||||
$this->user->profile->identifier = @ $data->user_id;
|
||||
$this->user->profile->email = @ $data->email;
|
||||
$this->user->profile->displayName = @ $data->name;
|
||||
$this->user->profile->zip = @ $data->postal_code;
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
}
|
@ -1,406 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
use Facebook\Facebook as FacebookSDK;
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Facebook provider adapter based on OAuth2 protocol
|
||||
* Hybrid_Providers_Facebook use the Facebook PHP SDK created by Facebook
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_Facebook.html
|
||||
*/
|
||||
class Hybrid_Providers_Facebook extends Hybrid_Provider_Model {
|
||||
|
||||
/**
|
||||
* Default permissions, and a lot of them. You can change them from the configuration by setting the scope to what you want/need.
|
||||
* For a complete list see: https://developers.facebook.com/docs/facebook-login/permissions
|
||||
*
|
||||
* @link https://developers.facebook.com/docs/facebook-login/permissions
|
||||
* @var array $scope
|
||||
*/
|
||||
public $scope = ['email', 'user_about_me', 'user_birthday', 'user_hometown', 'user_location', 'user_website', 'publish_actions', 'read_custom_friendlists'];
|
||||
|
||||
/**
|
||||
* Provider API client
|
||||
*
|
||||
* @var \Facebook\Facebook
|
||||
*/
|
||||
public $api;
|
||||
|
||||
public $useSafeUrls = true;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) {
|
||||
throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4);
|
||||
}
|
||||
|
||||
if (isset($this->config['scope'])) {
|
||||
$scope = $this->config['scope'];
|
||||
if (is_string($scope)) {
|
||||
$scope = explode(",", $scope);
|
||||
}
|
||||
$scope = array_map('trim', $scope);
|
||||
$this->scope = $scope;
|
||||
}
|
||||
|
||||
$trustForwarded = isset($this->config['trustForwarded']) ? (bool)$this->config['trustForwarded'] : false;
|
||||
|
||||
// Check if there is Graph SDK in thirdparty/Facebook.
|
||||
if (file_exists(Hybrid_Auth::$config["path_libraries"] . "Facebook/autoload.php")) {
|
||||
require_once Hybrid_Auth::$config["path_libraries"] . "Facebook/autoload.php";
|
||||
}
|
||||
else {
|
||||
// If Composer install was executed, try to find autoload.php.
|
||||
$vendorDir = dirname(Hybrid_Auth::$config['path_base']);
|
||||
do {
|
||||
if (file_exists($vendorDir . "/vendor/autoload.php")) {
|
||||
require_once $vendorDir . "/vendor/autoload.php";
|
||||
break;
|
||||
}
|
||||
} while (($vendorDir = dirname($vendorDir)) !== '/');
|
||||
}
|
||||
|
||||
$this->api = new FacebookSDK([
|
||||
'app_id' => $this->config["keys"]["id"],
|
||||
'app_secret' => $this->config["keys"]["secret"],
|
||||
'default_graph_version' => 'v2.8',
|
||||
'trustForwarded' => $trustForwarded,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
|
||||
$this->endpoint = $this->params['login_done'];
|
||||
$helper = $this->api->getRedirectLoginHelper();
|
||||
|
||||
// Use re-request, because this will trigger permissions window if not all permissions are granted.
|
||||
$url = $helper->getReRequestUrl($this->endpoint, $this->scope);
|
||||
|
||||
// Redirect to Facebook
|
||||
Hybrid_Auth::redirect($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
|
||||
$helper = $this->api->getRedirectLoginHelper();
|
||||
try {
|
||||
$accessToken = $helper->getAccessToken($this->params['login_done']);
|
||||
} catch (Facebook\Exceptions\FacebookResponseException $e) {
|
||||
throw new Hybrid_Exception('Facebook Graph returned an error: ' . $e->getMessage());
|
||||
} catch (Facebook\Exceptions\FacebookSDKException $e) {
|
||||
throw new Hybrid_Exception('Facebook SDK returned an error: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
if (!isset($accessToken)) {
|
||||
if ($helper->getError()) {
|
||||
throw new Hybrid_Exception(sprintf("Could not authorize user, reason: %s (%d)", $helper->getErrorDescription(), $helper->getErrorCode()));
|
||||
} else {
|
||||
throw new Hybrid_Exception("Could not authorize user. Bad request");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Validate token
|
||||
$oAuth2Client = $this->api->getOAuth2Client();
|
||||
$tokenMetadata = $oAuth2Client->debugToken($accessToken);
|
||||
$tokenMetadata->validateAppId($this->config["keys"]["id"]);
|
||||
$tokenMetadata->validateExpiration();
|
||||
|
||||
// Exchanges a short-lived access token for a long-lived one
|
||||
if (!$accessToken->isLongLived()) {
|
||||
$accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
|
||||
}
|
||||
} catch (FacebookSDKException $e) {
|
||||
throw new Hybrid_Exception($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
$this->setUserConnected();
|
||||
$this->token("access_token", $accessToken->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function logout() {
|
||||
parent::logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user status
|
||||
*
|
||||
* @param mixed $status An array describing the status, or string
|
||||
* @param string $pageid (optional) User page id
|
||||
* @return array
|
||||
* @throw Exception
|
||||
*/
|
||||
function setUserStatus($status, $pageid = null) {
|
||||
|
||||
if (!is_array($status)) {
|
||||
$status = array('message' => $status);
|
||||
}
|
||||
|
||||
$access_token = null;
|
||||
|
||||
if (is_null($pageid)) {
|
||||
$pageid = 'me';
|
||||
$access_token = $this->token('access_token');
|
||||
|
||||
// if post on page, get access_token page
|
||||
} else {
|
||||
|
||||
foreach ($this->getUserPages(true) as $p) {
|
||||
if (isset($p['id']) && intval($p['id']) == intval($pageid)) {
|
||||
$access_token = $p['access_token'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($access_token)) {
|
||||
throw new Exception("Update user page failed, page not found or not writable!");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->api->post('/' . $pageid . '/feed', $status, $access_token);
|
||||
} catch (FacebookSDKException $e) {
|
||||
throw new Exception("Update user status failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheridoc}
|
||||
*/
|
||||
function getUserPages($writableonly = false) {
|
||||
if (( isset($this->config['scope']) && strpos($this->config['scope'], 'manage_pages') === false ) || (!isset($this->config['scope']) && strpos($this->scope, 'manage_pages') === false ))
|
||||
throw new Exception("User status requires manage_page permission!");
|
||||
|
||||
try {
|
||||
$pages = $this->api->get("/me/accounts", $this->token('access_token'));
|
||||
$pages = $pages->getDecodedBody();
|
||||
} catch (FacebookApiException $e) {
|
||||
throw new Exception("Cannot retrieve user pages! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
|
||||
if (!isset($pages['data'])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (!$writableonly) {
|
||||
return $pages['data'];
|
||||
}
|
||||
|
||||
$wrpages = array();
|
||||
foreach ($pages['data'] as $p) {
|
||||
if (isset($p['perms']) && in_array('CREATE_CONTENT', $p['perms'])) {
|
||||
$wrpages[] = $p;
|
||||
}
|
||||
}
|
||||
|
||||
return $wrpages;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
try {
|
||||
$fields = [
|
||||
'id',
|
||||
'name',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'link',
|
||||
'website',
|
||||
'gender',
|
||||
'locale',
|
||||
'about',
|
||||
'email',
|
||||
'hometown',
|
||||
'location',
|
||||
'birthday'
|
||||
];
|
||||
$response = $this->api->get('/me?fields=' . implode(',', $fields), $this->token('access_token'));
|
||||
$data = $response->getDecodedBody();
|
||||
} catch (FacebookSDKException $e) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an error: {$e->getMessage()}", 6, $e);
|
||||
}
|
||||
|
||||
// Store the user profile.
|
||||
$this->user->profile->identifier = (array_key_exists('id', $data)) ? $data['id'] : "";
|
||||
$this->user->profile->displayName = (array_key_exists('name', $data)) ? $data['name'] : "";
|
||||
$this->user->profile->firstName = (array_key_exists('first_name', $data)) ? $data['first_name'] : "";
|
||||
$this->user->profile->lastName = (array_key_exists('last_name', $data)) ? $data['last_name'] : "";
|
||||
$this->user->profile->photoURL = $this->getUserPhoto($this->user->profile->identifier);
|
||||
$this->user->profile->profileURL = (array_key_exists('link', $data)) ? $data['link'] : "";
|
||||
$this->user->profile->webSiteURL = (array_key_exists('website', $data)) ? $data['website'] : "";
|
||||
$this->user->profile->gender = (array_key_exists('gender', $data)) ? $data['gender'] : "";
|
||||
$this->user->profile->language = (array_key_exists('locale', $data)) ? $data['locale'] : "";
|
||||
$this->user->profile->description = (array_key_exists('about', $data)) ? $data['about'] : "";
|
||||
$this->user->profile->email = (array_key_exists('email', $data)) ? $data['email'] : "";
|
||||
$this->user->profile->emailVerified = (array_key_exists('email', $data)) ? $data['email'] : "";
|
||||
$this->user->profile->region = (array_key_exists("location", $data) && array_key_exists("name", $data['location'])) ? $data['location']["name"] : "";
|
||||
|
||||
if (!empty($this->user->profile->region)) {
|
||||
$regionArr = explode(',', $this->user->profile->region);
|
||||
if (count($regionArr) > 1) {
|
||||
$this->user->profile->city = trim($regionArr[0]);
|
||||
$this->user->profile->country = trim(end($regionArr));
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('birthday', $data)) {
|
||||
$birtydayPieces = explode('/', $data['birthday']);
|
||||
|
||||
if (count($birtydayPieces) == 1) {
|
||||
$this->user->profile->birthYear = (int)$birtydayPieces[0];
|
||||
} elseif (count($birtydayPieces) == 2) {
|
||||
$this->user->profile->birthMonth = (int)$birtydayPieces[0];
|
||||
$this->user->profile->birthDay = (int)$birtydayPieces[1];
|
||||
} elseif (count($birtydayPieces) == 3) {
|
||||
$this->user->profile->birthMonth = (int)$birtydayPieces[0];
|
||||
$this->user->profile->birthDay = (int)$birtydayPieces[1];
|
||||
$this->user->profile->birthYear = (int)$birtydayPieces[2];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the Graph API 2.0, the /friends endpoint only returns friend that also use your Facebook app.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
$apiCall = '?fields=link,name';
|
||||
$returnedContacts = [];
|
||||
$pagedList = true;
|
||||
|
||||
while ($pagedList) {
|
||||
try {
|
||||
$response = $this->api->get('/me/friends' . $apiCall, $this->token('access_token'));
|
||||
$response = $response->getDecodedBody();
|
||||
} catch (FacebookSDKException $e) {
|
||||
throw new Hybrid_Exception("User contacts request failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
|
||||
// Prepare the next call if paging links have been returned
|
||||
if (array_key_exists('paging', $response) && array_key_exists('next', $response['paging'])) {
|
||||
$pagedList = true;
|
||||
$next_page = explode('friends', $response['paging']['next']);
|
||||
$apiCall = $next_page[1];
|
||||
} else {
|
||||
$pagedList = false;
|
||||
}
|
||||
|
||||
// Add the new page contacts
|
||||
$returnedContacts = array_merge($returnedContacts, $response['data']);
|
||||
}
|
||||
|
||||
$contacts = [];
|
||||
foreach ($returnedContacts as $item) {
|
||||
|
||||
$uc = new Hybrid_User_Contact();
|
||||
$uc->identifier = (array_key_exists("id", $item)) ? $item["id"] : "";
|
||||
$uc->displayName = (array_key_exists("name", $item)) ? $item["name"] : "";
|
||||
$uc->profileURL = (array_key_exists("link", $item)) ? $item["link"] : "https://www.facebook.com/profile.php?id=" . $uc->identifier;
|
||||
$uc->photoURL = $this->getUserPhoto($uc->identifier);
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the user latest activity, needs 'read_stream' permission
|
||||
*
|
||||
* @param string $stream Which activity to fetch:
|
||||
* - timeline : all the stream
|
||||
* - me : the user activity only
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserActivity($stream = 'timeline') {
|
||||
try {
|
||||
if ($stream == "me") {
|
||||
$response = $this->api->get('/me/feed', $this->token('access_token'));
|
||||
} else {
|
||||
$response = $this->api->get('/me/home', $this->token('access_token'));
|
||||
}
|
||||
$response = $response->getDecodedBody();
|
||||
} catch (FacebookSDKException $e) {
|
||||
throw new Hybrid_Exception("User activity stream request failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
|
||||
if (!$response || !count($response['data'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$activities = [];
|
||||
foreach ($response['data'] as $item) {
|
||||
|
||||
$ua = new Hybrid_User_Activity();
|
||||
|
||||
$ua->id = (array_key_exists("id", $item)) ? $item["id"] : "";
|
||||
$ua->date = (array_key_exists("created_time", $item)) ? strtotime($item["created_time"]) : "";
|
||||
|
||||
if ($item["type"] == "video") {
|
||||
$ua->text = (array_key_exists("link", $item)) ? $item["link"] : "";
|
||||
}
|
||||
|
||||
if ($item["type"] == "link") {
|
||||
$ua->text = (array_key_exists("link", $item)) ? $item["link"] : "";
|
||||
}
|
||||
|
||||
if (empty($ua->text) && isset($item["story"])) {
|
||||
$ua->text = (array_key_exists("link", $item)) ? $item["link"] : "";
|
||||
}
|
||||
|
||||
if (empty($ua->text) && isset($item["message"])) {
|
||||
$ua->text = (array_key_exists("message", $item)) ? $item["message"] : "";
|
||||
}
|
||||
|
||||
if (!empty($ua->text)) {
|
||||
$ua->user->identifier = (array_key_exists("id", $item["from"])) ? $item["from"]["id"] : "";
|
||||
$ua->user->displayName = (array_key_exists("name", $item["from"])) ? $item["from"]["name"] : "";
|
||||
$ua->user->profileURL = "https://www.facebook.com/profile.php?id=" . $ua->user->identifier;
|
||||
$ua->user->photoURL = $this->getUserPhoto($ua->user->identifier);
|
||||
|
||||
$activities[] = $ua;
|
||||
}
|
||||
}
|
||||
|
||||
return $activities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a photo URL for give user.
|
||||
*
|
||||
* @param string $id
|
||||
* The User ID.
|
||||
*
|
||||
* @return string
|
||||
* A photo URL.
|
||||
*/
|
||||
function getUserPhoto($id) {
|
||||
$photo_size = isset($this->config['photo_size']) ? $this->config['photo_size'] : 150;
|
||||
|
||||
return "https://graph.facebook.com/{$id}/picture?width={$photo_size}&height={$photo_size}";
|
||||
}
|
||||
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Foursquare provider adapter based on OAuth2 protocol
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_Foursquare.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Howto define profile photo size:
|
||||
* - add params key into hybridauth config
|
||||
* ...
|
||||
* "Foursquare" => array (
|
||||
* "enabled" => true,
|
||||
* "keys" => ...,
|
||||
* "params" => array( "photo_size" => "16x16" )
|
||||
* ),
|
||||
* ...
|
||||
* - list of valid photo_size values is described here https://developer.foursquare.com/docs/responses/photo.html
|
||||
* - default photo_size is 100x100
|
||||
*/
|
||||
class Hybrid_Providers_Foursquare extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
private static $apiVersion = array("v" => "20120610");
|
||||
private static $defPhotoSize = "100x100";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider apis end-points
|
||||
$this->api->api_base_url = "https://api.foursquare.com/v2/";
|
||||
$this->api->authorize_url = "https://foursquare.com/oauth2/authenticate";
|
||||
$this->api->token_url = "https://foursquare.com/oauth2/access_token";
|
||||
|
||||
$this->api->sign_token_name = "oauth_token";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
$data = $this->api->api("users/self", "GET", Hybrid_Providers_Foursquare::$apiVersion);
|
||||
|
||||
if (!isset($data->response->user->id)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response:" . Hybrid_Logger::dumpData( $data ), 6);
|
||||
}
|
||||
|
||||
$data = $data->response->user;
|
||||
|
||||
$this->user->profile->identifier = $data->id;
|
||||
$this->user->profile->firstName = $data->firstName;
|
||||
$this->user->profile->lastName = $data->lastName;
|
||||
$this->user->profile->displayName = $this->buildDisplayName($this->user->profile->firstName, $this->user->profile->lastName);
|
||||
$this->user->profile->photoURL = $this->buildPhotoURL($data->photo->prefix, $data->photo->suffix);
|
||||
$this->user->profile->profileURL = "https://www.foursquare.com/user/" . $data->id;
|
||||
$this->user->profile->gender = $data->gender;
|
||||
$this->user->profile->city = $data->homeCity;
|
||||
$this->user->profile->email = $data->contact->email;
|
||||
$this->user->profile->emailVerified = $data->contact->email;
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
// refresh tokens if needed
|
||||
$this->refreshToken();
|
||||
|
||||
//
|
||||
$response = array();
|
||||
$contacts = array();
|
||||
try {
|
||||
$response = $this->api->api("users/self/friends", "GET", Hybrid_Providers_Foursquare::$apiVersion);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
|
||||
if (isset($response) && $response->meta->code == 200) {
|
||||
foreach ($response->response->friends->items as $contact) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
//
|
||||
$uc->identifier = $contact->id;
|
||||
//$uc->profileURL = ;
|
||||
//$uc->webSiteURL = ;
|
||||
$uc->photoURL = $this->buildPhotoURL($contact->photo->prefix, $contact->photo->suffix);
|
||||
$uc->displayName = $this->buildDisplayName((isset($contact->firstName) ? ($contact->firstName) : ("")), (isset($contact->lastName) ? ($contact->lastName) : ("")));
|
||||
//$uc->description = ;
|
||||
$uc->email = (isset($contact->contact->email) ? ($contact->contact->email) : (""));
|
||||
//
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
private function buildDisplayName($firstName, $lastName) {
|
||||
return trim($firstName . " " . $lastName);
|
||||
}
|
||||
|
||||
private function buildPhotoURL($prefix, $suffix) {
|
||||
if (isset($prefix) && isset($suffix)) {
|
||||
return $prefix . ((isset($this->config["params"]["photo_size"])) ? ($this->config["params"]["photo_size"]) : (Hybrid_Providers_Foursquare::$defPhotoSize)) . $suffix;
|
||||
}
|
||||
return ("");
|
||||
}
|
||||
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
<?php
|
||||
/*!
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_GitHub
|
||||
*/
|
||||
class Hybrid_Providers_GitHub extends Hybrid_Provider_Model_OAuth2
|
||||
{
|
||||
// default permissions
|
||||
// (no scope) => public read-only access (includes public user profile info, public repo info, and gists).
|
||||
public $scope = "";
|
||||
|
||||
/**
|
||||
* IDp wrappers initializer
|
||||
*/
|
||||
function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points
|
||||
$this->api->api_base_url = "https://api.github.com/";
|
||||
$this->api->authorize_url = "https://github.com/login/oauth/authorize";
|
||||
$this->api->token_url = "https://github.com/login/oauth/access_token";
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user profile from the IDp api client
|
||||
*/
|
||||
function getUserProfile()
|
||||
{
|
||||
$data = $this->api->api( "user" );
|
||||
|
||||
if ( ! isset( $data->id ) ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 );
|
||||
}
|
||||
|
||||
$this->user->profile->identifier = @ $data->id;
|
||||
$this->user->profile->displayName = @ $data->name;
|
||||
$this->user->profile->description = @ $data->bio;
|
||||
$this->user->profile->photoURL = @ $data->avatar_url;
|
||||
$this->user->profile->profileURL = @ $data->html_url;
|
||||
$this->user->profile->email = @ $data->email;
|
||||
$this->user->profile->webSiteURL = @ $data->blog;
|
||||
$this->user->profile->region = @ $data->location;
|
||||
|
||||
if( empty($this->user->profile->displayName) ){
|
||||
$this->user->profile->displayName = @ $data->login;
|
||||
}
|
||||
|
||||
// request user emails from github api
|
||||
if( empty($data->email) ){
|
||||
try{
|
||||
$emails = $this->api->api("user/emails");
|
||||
|
||||
// fail gracefully, and let apps collect the email if not present
|
||||
if (is_array($emails)) {
|
||||
foreach ($emails as $email) {
|
||||
if ($email instanceof stdClass
|
||||
&& property_exists($email, 'primary')
|
||||
&& true === $email->primary
|
||||
&& property_exists($email, 'email')
|
||||
) {
|
||||
$this->user->profile->email = $email->email;
|
||||
|
||||
// record whether the email address is verified
|
||||
if (property_exists($email, 'verified')
|
||||
&& true === $email->verified
|
||||
) {
|
||||
$this->user->profile->emailVerified = $email->email;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( GithubApiException $e ){
|
||||
throw new Exception( "User email request failed! {$this->providerId} returned an error: $e", 6 );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getUserContacts() {
|
||||
// refresh tokens if needed
|
||||
$this->refreshToken();
|
||||
|
||||
//
|
||||
$response = array();
|
||||
$contacts = array();
|
||||
try {
|
||||
$response = $this->api->api( "user/followers" );
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error: $e");
|
||||
}
|
||||
//
|
||||
if ( isset( $response ) ) {
|
||||
foreach ($response as $contact) {
|
||||
try {
|
||||
$contactInfo = $this->api->api( "users/".$contact->login );
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Contact info request failed for user {$contact->login}! {$this->providerId} returned an error: $e");
|
||||
}
|
||||
//
|
||||
$uc = new Hybrid_User_Contact();
|
||||
//
|
||||
$uc->identifier = $contact->id;
|
||||
$uc->profileURL = @$contact->html_url;
|
||||
$uc->webSiteURL = @$contact->blog;
|
||||
$uc->photoURL = @$contact->avatar_url;
|
||||
$uc->displayName = ( isset( $contactInfo->name )?( $contactInfo->name ):( $contact->login ) );
|
||||
//$uc->description = ;
|
||||
$uc->email = @$contactInfo->email;
|
||||
//
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
return $contacts;
|
||||
}
|
||||
}
|
@ -1,306 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Google provider adapter based on OAuth2 protocol
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_Google.html
|
||||
*/
|
||||
class Hybrid_Providers_Google extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
/**
|
||||
* > more infos on google APIs: http://developer.google.com (official site)
|
||||
* or here: http://discovery-check.appspot.com/ (unofficial but up to date)
|
||||
* default permissions
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $scope = "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.profile.emails.read https://www.google.com/m8/feeds/";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points
|
||||
$this->api->authorize_url = "https://accounts.google.com/o/oauth2/auth";
|
||||
$this->api->token_url = "https://accounts.google.com/o/oauth2/token";
|
||||
$this->api->token_info_url = "https://www.googleapis.com/oauth2/v2/tokeninfo";
|
||||
|
||||
// Google POST methods require an access_token in the header
|
||||
$this->api->curl_header = array("Authorization: OAuth " . $this->api->access_token);
|
||||
|
||||
// Override the redirect uri when it's set in the config parameters. This way we prevent
|
||||
// redirect uri mismatches when authenticating with Google.
|
||||
if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) {
|
||||
$this->api->redirect_uri = $this->config['redirect_uri'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
$parameters = array("scope" => $this->scope, "access_type" => "offline");
|
||||
$optionals = array("scope", "access_type", "redirect_uri", "approval_prompt", "hd", "state");
|
||||
|
||||
foreach ($optionals as $parameter) {
|
||||
if (isset($this->config[$parameter]) && !empty($this->config[$parameter])) {
|
||||
$parameters[$parameter] = $this->config[$parameter];
|
||||
}
|
||||
if (isset($this->config["scope"]) && !empty($this->config["scope"])) {
|
||||
$this->scope = $this->config["scope"];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->config['force']) && $this->config['force'] === true) {
|
||||
$parameters['approval_prompt'] = 'force';
|
||||
}
|
||||
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
// refresh tokens if needed
|
||||
$this->refreshToken();
|
||||
|
||||
// ask google api for user infos
|
||||
if (strpos($this->scope, '/auth/plus.profile.emails.read') !== false) {
|
||||
$verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me");
|
||||
|
||||
if (!isset($verified->id) || isset($verified->error))
|
||||
$verified = new stdClass();
|
||||
} else {
|
||||
$verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me/openIdConnect");
|
||||
|
||||
if (!isset($verified->sub) || isset($verified->error))
|
||||
$verified = new stdClass();
|
||||
}
|
||||
|
||||
$response = $this->api->api("https://www.googleapis.com/plus/v1/people/me");
|
||||
if (!isset($response->id) || isset($response->error)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response:" . Hybrid_Logger::dumpData( $response ), 6);
|
||||
}
|
||||
|
||||
$this->user->profile->identifier = (property_exists($verified, 'id')) ? $verified->id : ((property_exists($response, 'id')) ? $response->id : "");
|
||||
$this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name->givenName : "";
|
||||
$this->user->profile->lastName = (property_exists($response, 'name')) ? $response->name->familyName : "";
|
||||
$this->user->profile->displayName = (property_exists($response, 'displayName')) ? $response->displayName : "";
|
||||
$this->user->profile->photoURL = (property_exists($response, 'image')) ? ((property_exists($response->image, 'url')) ? substr($response->image->url, 0, -2) . "200" : '') : '';
|
||||
$this->user->profile->profileURL = (property_exists($response, 'url')) ? $response->url : "";
|
||||
$this->user->profile->description = (property_exists($response, 'aboutMe')) ? $response->aboutMe : "";
|
||||
$this->user->profile->gender = (property_exists($response, 'gender')) ? $response->gender : "";
|
||||
$this->user->profile->language = (property_exists($response, 'locale')) ? $response->locale : ((property_exists($verified, 'locale')) ? $verified->locale : "");
|
||||
$this->user->profile->email = (property_exists($response, 'email')) ? $response->email : ((property_exists($verified, 'email')) ? $verified->email : "");
|
||||
$this->user->profile->emailVerified = (property_exists($verified, 'email')) ? $verified->email : "";
|
||||
if (property_exists($response, 'emails')) {
|
||||
if (count($response->emails) == 1) {
|
||||
$this->user->profile->email = $response->emails[0]->value;
|
||||
} else {
|
||||
foreach ($response->emails as $email) {
|
||||
if ($email->type == 'account') {
|
||||
$this->user->profile->email = $email->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (property_exists($verified, 'emails')) {
|
||||
if (count($verified->emails) == 1) {
|
||||
$this->user->profile->emailVerified = $verified->emails[0]->value;
|
||||
} else {
|
||||
foreach ($verified->emails as $email) {
|
||||
if ($email->type == 'account') {
|
||||
$this->user->profile->emailVerified = $email->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->user->profile->phone = (property_exists($response, 'phone')) ? $response->phone : "";
|
||||
$this->user->profile->country = (property_exists($response, 'country')) ? $response->country : "";
|
||||
$this->user->profile->region = (property_exists($response, 'region')) ? $response->region : "";
|
||||
$this->user->profile->zip = (property_exists($response, 'zip')) ? $response->zip : "";
|
||||
if (property_exists($response, 'placesLived')) {
|
||||
$this->user->profile->city = "";
|
||||
$this->user->profile->address = "";
|
||||
foreach ($response->placesLived as $c) {
|
||||
if (property_exists($c, 'primary')) {
|
||||
if ($c->primary == true) {
|
||||
$this->user->profile->address = $c->value;
|
||||
$this->user->profile->city = $c->value;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (property_exists($c, 'value')) {
|
||||
$this->user->profile->address = $c->value;
|
||||
$this->user->profile->city = $c->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// google API returns multiple urls, but a "website" only if it is verified
|
||||
// see http://support.google.com/plus/answer/1713826?hl=en
|
||||
if (property_exists($response, 'urls')) {
|
||||
foreach ($response->urls as $u) {
|
||||
if (property_exists($u, 'primary') && $u->primary == true)
|
||||
$this->user->profile->webSiteURL = $u->value;
|
||||
}
|
||||
} else {
|
||||
$this->user->profile->webSiteURL = '';
|
||||
}
|
||||
// google API returns age ranges min and/or max as of https://developers.google.com/+/web/api/rest/latest/people#resource
|
||||
if (property_exists($response, 'ageRange')) {
|
||||
if (property_exists($response->ageRange, 'min') && property_exists($response->ageRange, 'max')) {
|
||||
$this->user->profile->age = $response->ageRange->min . ' - ' . $response->ageRange->max;
|
||||
} else {
|
||||
if (property_exists($response->ageRange, 'min')) {
|
||||
$this->user->profile->age = '>= ' . $response->ageRange->min;
|
||||
} else {
|
||||
if (property_exists($response->ageRange, 'max')) {
|
||||
$this->user->profile->age = '<= ' . $response->ageRange->max;
|
||||
} else {
|
||||
$this->user->profile->age = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->user->profile->age = '';
|
||||
}
|
||||
// google API returns birthdays only if a user set 'show in my account'
|
||||
if (property_exists($response, 'birthday')) {
|
||||
list($birthday_year, $birthday_month, $birthday_day) = explode('-', $response->birthday);
|
||||
|
||||
$this->user->profile->birthDay = (int) $birthday_day;
|
||||
$this->user->profile->birthMonth = (int) $birthday_month;
|
||||
$this->user->profile->birthYear = (int) $birthday_year;
|
||||
} else {
|
||||
$this->user->profile->birthDay = 0;
|
||||
$this->user->profile->birthMonth = 0;
|
||||
$this->user->profile->birthYear = 0;
|
||||
}
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
// refresh tokens if needed
|
||||
$this->refreshToken();
|
||||
|
||||
$contacts = array();
|
||||
if (!isset($this->config['contacts_param'])) {
|
||||
$this->config['contacts_param'] = array("max-results" => 500);
|
||||
}
|
||||
|
||||
// Google Gmail and Android contacts
|
||||
if (strpos($this->scope, '/m8/feeds/') !== false) {
|
||||
|
||||
$response = $this->api->api("https://www.google.com/m8/feeds/contacts/default/full?"
|
||||
. http_build_query(array_merge(array('alt' => 'json'), $this->config['contacts_param'])));
|
||||
|
||||
if (!$response) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (isset($response->feed->entry)) {
|
||||
foreach ($response->feed->entry as $idx => $entry) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
$uc->email = isset($entry->{'gd$email'}[0]->address) ? (string) $entry->{'gd$email'}[0]->address : '';
|
||||
$uc->displayName = isset($entry->title->{'$t'}) ? (string) $entry->title->{'$t'} : '';
|
||||
$uc->identifier = ($uc->email != '') ? $uc->email : '';
|
||||
$uc->description = '';
|
||||
if (property_exists($entry, 'link')) {
|
||||
/**
|
||||
* sign links with access_token
|
||||
*/
|
||||
if (is_array($entry->link)) {
|
||||
foreach ($entry->link as $l) {
|
||||
if (property_exists($l, 'gd$etag') && $l->type == "image/*") {
|
||||
$uc->photoURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token));
|
||||
} else if ($l->type == "self") {
|
||||
$uc->profileURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$uc->profileURL = '';
|
||||
}
|
||||
if (property_exists($response, 'website')) {
|
||||
if (is_array($response->website)) {
|
||||
foreach ($response->website as $w) {
|
||||
if ($w->primary == true)
|
||||
$uc->webSiteURL = $w->value;
|
||||
}
|
||||
} else {
|
||||
$uc->webSiteURL = $response->website->value;
|
||||
}
|
||||
} else {
|
||||
$uc->webSiteURL = '';
|
||||
}
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Google social contacts
|
||||
if (strpos($this->scope, '/auth/plus.login') !== false) {
|
||||
|
||||
$response = $this->api->api("https://www.googleapis.com/plus/v1/people/me/people/visible?"
|
||||
. http_build_query($this->config['contacts_param']));
|
||||
|
||||
if (!$response) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($response->items as $idx => $item) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
$uc->email = (property_exists($item, 'email')) ? $item->email : '';
|
||||
$uc->displayName = (property_exists($item, 'displayName')) ? $item->displayName : '';
|
||||
$uc->identifier = (property_exists($item, 'id')) ? $item->id : '';
|
||||
|
||||
$uc->description = (property_exists($item, 'objectType')) ? $item->objectType : '';
|
||||
$uc->photoURL = (property_exists($item, 'image')) ? ((property_exists($item->image, 'url')) ? $item->image->url : '') : '';
|
||||
$uc->profileURL = (property_exists($item, 'url')) ? $item->url : '';
|
||||
$uc->webSiteURL = '';
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add query parameters to the $url
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param array $params Parameters to add
|
||||
* @return string
|
||||
*/
|
||||
function addUrlParam($url, array $params){
|
||||
$query = parse_url($url, PHP_URL_QUERY);
|
||||
|
||||
// Returns the URL string with new parameters
|
||||
if ($query) {
|
||||
$url .= '&' . http_build_query($params);
|
||||
} else {
|
||||
$url .= '?' . http_build_query($params);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/*!
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Google OpenID based
|
||||
*
|
||||
* Provided as a way to keep backward compatibility for Google OpenID based on HybridAuth <= 2.0.8
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_Google.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* To replace the default google adapter, we should use this config instead:
|
||||
*
|
||||
* "Google" => array (
|
||||
* "enabled" => true,
|
||||
* "wrapper" => array( "path" => "Providers/GoogleOpenID.php", "class" => "Hybrid_Providers_Google" )
|
||||
* )
|
||||
*/
|
||||
class Hybrid_Providers_Google extends Hybrid_Provider_Model_OpenID
|
||||
{
|
||||
var $openidIdentifier = "https://www.google.com/accounts/o8/id";
|
||||
|
||||
/**
|
||||
* finish login step
|
||||
*/
|
||||
function loginFinish()
|
||||
{
|
||||
parent::loginFinish();
|
||||
|
||||
$this->user->profile->emailVerified = $this->user->profile->email;
|
||||
|
||||
// restore the user profile
|
||||
Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.user", $this->user );
|
||||
}
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* Hybridauth
|
||||
* https://hybridauth.github.io/hybridauth | https://github.com/hybridauth/hybridauth
|
||||
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_LinkedIn OAuth2 provider adapter.
|
||||
*/
|
||||
class Hybrid_Providers_LinkedIn extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $scope = "r_basicprofile r_emailaddress";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points.
|
||||
$this->api->api_base_url = "https://api.linkedin.com/v1/";
|
||||
$this->api->authorize_url = "https://www.linkedin.com/oauth/v2/authorization";
|
||||
$this->api->token_url = "https://www.linkedin.com/oauth/v2/accessToken";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
if (is_array($this->scope)) {
|
||||
$this->scope = implode(" ", $this->scope);
|
||||
}
|
||||
parent::loginBegin();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see https://developer.linkedin.com/docs/rest-api
|
||||
*/
|
||||
function getUserProfile() {
|
||||
// Refresh tokens if needed.
|
||||
$this->setHeaders("token");
|
||||
$this->refreshToken();
|
||||
|
||||
// https://developer.linkedin.com/docs/fields.
|
||||
$fields = isset($this->config["fields"]) ? $this->config["fields"] : [
|
||||
"id",
|
||||
"email-address",
|
||||
"first-name",
|
||||
"last-name",
|
||||
"headline",
|
||||
"location",
|
||||
"industry",
|
||||
"picture-url",
|
||||
"public-profile-url",
|
||||
];
|
||||
|
||||
$this->setHeaders();
|
||||
$response = $this->api->get(
|
||||
"people/~:(" . implode(",", $fields) . ")",
|
||||
array(
|
||||
"format" => "json",
|
||||
)
|
||||
);
|
||||
|
||||
if (!isset($response->id)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData($response), 6);
|
||||
}
|
||||
|
||||
$this->user->profile->identifier = isset($response->id) ? $response->id : "";
|
||||
$this->user->profile->firstName = isset($response->firstName) ? $response->firstName : "";
|
||||
$this->user->profile->lastName = isset($response->lastName) ? $response->lastName : "";
|
||||
$this->user->profile->photoURL = isset($response->pictureUrl) ? $response->pictureUrl : "";
|
||||
$this->user->profile->profileURL = isset($response->publicProfileUrl) ? $response->publicProfileUrl : "";
|
||||
$this->user->profile->email = isset($response->emailAddress) ? $response->emailAddress : "";
|
||||
$this->user->profile->description = isset($response->headline) ? $response->headline : "";
|
||||
$this->user->profile->country = isset($response->location) ? $response->location->name : "";
|
||||
$this->user->profile->emailVerified = $this->user->profile->email;
|
||||
$this->user->profile->displayName = trim($this->user->profile->firstName . " " . $this->user->profile->lastName);
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $status
|
||||
* An associative array containing:
|
||||
* - content: A collection of fields describing the shared content.
|
||||
* - comment: A comment by the member to associated with the share.
|
||||
* - visibility: A collection of visibility information about the share.
|
||||
*
|
||||
* @return object
|
||||
* An object containing:
|
||||
* - updateKey - A unique ID for the shared content posting that was just created.
|
||||
* - updateUrl - A direct link to the newly shared content on LinkedIn.com that you can direct the user's web browser to.
|
||||
* @throws Exception
|
||||
* @see https://developer.linkedin.com/docs/share-on-linkedin
|
||||
*/
|
||||
function setUserStatus($status) {
|
||||
// Refresh tokens if needed.
|
||||
$this->setHeaders("token");
|
||||
$this->refreshToken();
|
||||
|
||||
try {
|
||||
// Define default visibility.
|
||||
if (!isset($status["visibility"])) {
|
||||
$status["visibility"]["code"] = "anyone";
|
||||
}
|
||||
|
||||
$this->setHeaders("share");
|
||||
$response = $this->api->post(
|
||||
"people/~/shares?format=json",
|
||||
array(
|
||||
"body" => $status,
|
||||
)
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Update user status failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e);
|
||||
}
|
||||
|
||||
if (!isset($response->updateKey)) {
|
||||
throw new Exception("Update user status failed! {$this->providerId} returned an error: {$response->message}", $response->errorCode);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set correct request headers.
|
||||
*
|
||||
* @param string $api_type
|
||||
* (optional) Specify api type.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setHeaders($api_type = null) {
|
||||
$this->api->curl_header = array(
|
||||
"Authorization: Bearer {$this->api->access_token}",
|
||||
);
|
||||
|
||||
switch ($api_type) {
|
||||
case "share":
|
||||
$this->api->curl_header = array_merge(
|
||||
$this->api->curl_header,
|
||||
array(
|
||||
"Content-Type: application/json",
|
||||
"x-li-format: json",
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case "token":
|
||||
$this->api->curl_header = array_merge(
|
||||
$this->api->curl_header,
|
||||
array(
|
||||
"Content-Type: application/x-www-form-urlencoded",
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Windows Live OAuth2 Class
|
||||
*
|
||||
* @package HybridAuth providers package
|
||||
* @author Lukasz Koprowski <azram19@gmail.com>
|
||||
* @version 0.2
|
||||
* @license BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Live - Windows Live provider adapter based on OAuth2 protocol
|
||||
*/
|
||||
class Hybrid_Providers_Live extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $scope = 'wl.basic wl.contacts_emails wl.emails wl.signin wl.share wl.birthday';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points
|
||||
$this->api->api_base_url = 'https://apis.live.net/v5.0/';
|
||||
$this->api->authorize_url = 'https://login.live.com/oauth20_authorize.srf';
|
||||
$this->api->token_url = 'https://login.live.com/oauth20_token.srf';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
$data = $this->api->get("me");
|
||||
|
||||
if (!isset($data->id)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData( $data ), 6);
|
||||
}
|
||||
|
||||
$this->user->profile->identifier = (property_exists($data, 'id')) ? $data->id : "";
|
||||
$this->user->profile->firstName = (property_exists($data, 'first_name')) ? $data->first_name : "";
|
||||
$this->user->profile->lastName = (property_exists($data, 'last_name')) ? $data->last_name : "";
|
||||
$this->user->profile->displayName = (property_exists($data, 'name')) ? trim($data->name) : "";
|
||||
$this->user->profile->gender = (property_exists($data, 'gender')) ? $data->gender : "";
|
||||
|
||||
//wl.basic
|
||||
$this->user->profile->profileURL = (property_exists($data, 'link')) ? $data->link : "";
|
||||
|
||||
//wl.emails
|
||||
$this->user->profile->email = (property_exists($data, 'emails')) ? $data->emails->preferred : "";
|
||||
$this->user->profile->emailVerified = (property_exists($data, 'emails')) ? $data->emails->account : "";
|
||||
|
||||
//wl.birthday
|
||||
$this->user->profile->birthDay = (property_exists($data, 'birth_day')) ? $data->birth_day : "";
|
||||
$this->user->profile->birthMonth = (property_exists($data, 'birth_month')) ? $data->birth_month : "";
|
||||
$this->user->profile->birthYear = (property_exists($data, 'birth_year')) ? $data->birth_year : "";
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows Live api does not support retrieval of email addresses (only hashes :/)
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
$response = $this->api->get('me/contacts');
|
||||
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception('User contacts request failed! ' . $this->providerId . ' returned an error: ' . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
if (!isset($response->data) || ( isset($response->errcode) && $response->errcode != 0 )) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$contacts = array();
|
||||
|
||||
foreach ($response->data as $item) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
|
||||
$uc->identifier = (property_exists($item, 'id')) ? $item->id : "";
|
||||
$uc->displayName = (property_exists($item, 'name')) ? $item->name : "";
|
||||
$uc->email = (property_exists($item, 'emails')) ? $item->emails->preferred : "";
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
<?php
|
||||
/*!
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_MySpace provider adapter based on OAuth1 protocol
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_MySpace.html
|
||||
*/
|
||||
class Hybrid_Providers_MySpace extends Hybrid_Provider_Model_OAuth1
|
||||
{
|
||||
/**
|
||||
* IDp wrappers initializer
|
||||
*/
|
||||
function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points
|
||||
$this->api->api_endpoint_url = "http://api.myspace.com/v1/";
|
||||
$this->api->authorize_url = "http://api.myspace.com/authorize";
|
||||
$this->api->request_token_url = "http://api.myspace.com/request_token";
|
||||
$this->api->access_token_url = "http://api.myspace.com/access_token";
|
||||
}
|
||||
|
||||
/**
|
||||
* get the connected uid from myspace api
|
||||
*/
|
||||
public function getCurrentUserId()
|
||||
{
|
||||
$response = $this->api->get( 'http://api.myspace.com/v1/user.json' );
|
||||
|
||||
if ( ! isset( $response->userId ) ){
|
||||
throw new Exception( "User id request failed! {$this->providerId} returned an invalid response." );
|
||||
}
|
||||
|
||||
return $response->userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user profile from the IDp api client
|
||||
*/
|
||||
function getUserProfile()
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
$data = $this->api->get( 'http://api.myspace.com/v1/users/' . $userId . '/profile.json' );
|
||||
|
||||
if ( ! is_object( $data ) ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 );
|
||||
}
|
||||
|
||||
$this->user->profile->identifier = $userId;
|
||||
$this->user->profile->displayName = $data->basicprofile->name;
|
||||
$this->user->profile->description = $data->aboutme;
|
||||
$this->user->profile->gender = $data->basicprofile->gender;
|
||||
$this->user->profile->photoURL = $data->basicprofile->image;
|
||||
$this->user->profile->profileURL = $data->basicprofile->webUri;
|
||||
$this->user->profile->age = $data->age;
|
||||
$this->user->profile->country = $data->country;
|
||||
$this->user->profile->region = $data->region;
|
||||
$this->user->profile->city = $data->city;
|
||||
$this->user->profile->zip = $data->postalcode;
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user contacts
|
||||
*/
|
||||
function getUserContacts()
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
$response = $this->api->get( "http://api.myspace.com/v1/users/" . $userId . "/friends.json" );
|
||||
|
||||
if ( ! is_object( $response ) ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 );
|
||||
}
|
||||
|
||||
$contacts = ARRAY();
|
||||
|
||||
foreach( $response->Friends as $item ){
|
||||
$uc = new Hybrid_User_Contact();
|
||||
|
||||
$uc->identifier = $item->userId;
|
||||
$uc->displayName = $item->name;
|
||||
$uc->profileURL = $item->webUri;
|
||||
$uc->photoURL = $item->image;
|
||||
$uc->description = $item->status;
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* update user status
|
||||
*/
|
||||
function setUserStatus( $status )
|
||||
{
|
||||
// crappy myspace... gonna see this asaic
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
$parameters = array( 'status' => $status );
|
||||
|
||||
$response = $this->api->api( "http://api.myspace.com/v1/users/" . $userId . "/status", 'PUT', $parameters );
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ( $this->api->http_code != 200 )
|
||||
{
|
||||
throw new Exception( "Update user status failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus( $this->api->http_code ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user latest activity
|
||||
* - timeline : all the stream
|
||||
* - me : the user activity only
|
||||
*/
|
||||
function getUserActivity( $stream )
|
||||
{
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
if( $stream == "me" ){
|
||||
$response = $this->api->get( "http://api.myspace.com/v1/users/" . $userId . "/status.json" );
|
||||
}
|
||||
else{
|
||||
$response = $this->api->get( "http://api.myspace.com/v1/users/" . $userId . "/friends/status.json" );
|
||||
}
|
||||
|
||||
if ( ! is_object( $response ) ){
|
||||
throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 );
|
||||
}
|
||||
|
||||
$activities = ARRAY();
|
||||
|
||||
if( $stream == "me" ){
|
||||
// todo
|
||||
}
|
||||
else{
|
||||
foreach( $response->FriendsStatus as $item ){
|
||||
$ua = new Hybrid_User_Activity();
|
||||
|
||||
$ua->id = $item->statusId;
|
||||
$ua->date = NULL; // to find out!!
|
||||
$ua->text = $item->status;
|
||||
|
||||
$ua->user->identifier = $item->user->userId;
|
||||
$ua->user->displayName = $item->user->name;
|
||||
$ua->user->profileURL = $item->user->uri;
|
||||
$ua->user->photoURL = $item->user->image;
|
||||
|
||||
$activities[] = $ua;
|
||||
}
|
||||
}
|
||||
|
||||
return $activities;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_OpenID provider adapter for any idp openid based
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_OpenID.html
|
||||
*/
|
||||
class Hybrid_Providers_OpenID extends Hybrid_Provider_Model_OpenID {
|
||||
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
<?php
|
||||
/*!
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Steam provider adapter based on OpenID protocol
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/IDProvider_info_Steam.html
|
||||
*
|
||||
* This class has been entirely reworked for the new Steam API (http://steamcommunity.com/dev)
|
||||
*/
|
||||
class Hybrid_Providers_Steam extends Hybrid_Provider_Model_OpenID
|
||||
{
|
||||
var $openidIdentifier = "http://steamcommunity.com/openid";
|
||||
|
||||
function loginFinish()
|
||||
{
|
||||
parent::loginFinish();
|
||||
|
||||
$this->user->profile->identifier = str_ireplace("http://steamcommunity.com/openid/id/",
|
||||
"", $this->user->profile->identifier);
|
||||
|
||||
if (!$this->user->profile->identifier) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid user ID.", 5);
|
||||
}
|
||||
|
||||
// If API key is not provided, use legacy API methods
|
||||
if (!empty($this->config['keys']['key'])) {
|
||||
$this->getUserProfileWebAPI($this->config['keys']['key']);
|
||||
} else {
|
||||
$this->getUserProfileLegacyAPI();
|
||||
}
|
||||
|
||||
Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.user", $this->user);
|
||||
}
|
||||
|
||||
function getUserProfileWebAPI($apiKey)
|
||||
{
|
||||
$apiUrl = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key='
|
||||
. $apiKey . '&steamids=' . $this->user->profile->identifier;
|
||||
|
||||
$data = @file_get_contents($apiUrl);
|
||||
$data = json_decode($data);
|
||||
|
||||
if (!is_object($data) || !isset($data->response->players[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the first index in 'players' array
|
||||
$data = $data->response->players[0];
|
||||
|
||||
$this->user->profile->displayName = property_exists($data, 'personaname') ? $data->personaname : '';
|
||||
$this->user->profile->firstName = property_exists($data, 'realname') ? $data->realname : '';
|
||||
$this->user->profile->photoURL = property_exists($data, 'avatarfull') ? $data->avatarfull : '';
|
||||
$this->user->profile->profileURL = property_exists($data, 'profileurl') ? $data->profileurl : '';
|
||||
$this->user->profile->country = property_exists($data, 'loccountrycode') ? $data->loccountrycode : '';
|
||||
}
|
||||
|
||||
function getUserProfileLegacyAPI()
|
||||
{
|
||||
$apiUrl = 'http://steamcommunity.com/profiles/' . $this->user->profile->identifier . '/?xml=1';
|
||||
|
||||
try {
|
||||
$data = @file_get_contents($apiUrl);
|
||||
$data = @ new SimpleXMLElement($data);
|
||||
} catch(Exception $e) {
|
||||
Hybrid_Logger::error( "Steam::getUserProfileLegacyAPI() error: ", $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_object($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
# store the user profile.
|
||||
//$this->user->profile->identifier = "";
|
||||
if (property_exists($data, 'customURL') && (string) $data->customURL != '') {
|
||||
$this->user->profile->profileURL = 'http://steamcommunity.com/id/' . (string) $data->customURL . '/';
|
||||
}
|
||||
else {
|
||||
$this->user->profile->profileURL = "http://steamcommunity.com/profiles/{$this->user->profile->identifier}/";
|
||||
}
|
||||
|
||||
$this->user->profile->webSiteURL = "";
|
||||
$this->user->profile->photoURL = property_exists($data, 'avatarFull') ? (string)$data->avatarFull : '';
|
||||
$this->user->profile->displayName = property_exists($data, 'steamID') ? (string)$data->steamID : '';
|
||||
$this->user->profile->description = property_exists($data, 'summary') ? (string)$data->summary : '';
|
||||
$this->user->profile->firstName = property_exists($data, 'realname') ? (string)$data->realname : '';
|
||||
$this->user->profile->lastName = "";
|
||||
$this->user->profile->gender = "";
|
||||
$this->user->profile->language = "";
|
||||
$this->user->profile->age = "";
|
||||
$this->user->profile->birthDay = "";
|
||||
$this->user->profile->birthMonth = "";
|
||||
$this->user->profile->birthYear = "";
|
||||
$this->user->profile->email = "";
|
||||
$this->user->profile->emailVerified = "";
|
||||
$this->user->profile->phone = "";
|
||||
$this->user->profile->address = "";
|
||||
$this->user->profile->country = "";
|
||||
$this->user->profile->region = property_exists($data, 'location') ? (string)$data->location : '';
|
||||
$this->user->profile->city = "";
|
||||
$this->user->profile->zip = "";
|
||||
}
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Twitter provider adapter based on OAuth1 protocol
|
||||
*/
|
||||
class Hybrid_Providers_Twitter extends Hybrid_Provider_Model_OAuth1 {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points
|
||||
$this->api->api_base_url = "https://api.twitter.com/1.1/";
|
||||
$this->api->authorize_url = "https://api.twitter.com/oauth/authenticate";
|
||||
$this->api->request_token_url = "https://api.twitter.com/oauth/request_token";
|
||||
$this->api->access_token_url = "https://api.twitter.com/oauth/access_token";
|
||||
|
||||
if (isset($this->config['api_version']) && $this->config['api_version']) {
|
||||
$this->api->api_base_url = "https://api.twitter.com/{$this->config['api_version']}/";
|
||||
}
|
||||
|
||||
if (isset($this->config['authorize']) && $this->config['authorize']) {
|
||||
$this->api->authorize_url = "https://api.twitter.com/oauth/authorize";
|
||||
}
|
||||
|
||||
$this->api->curl_auth_header = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
// Initiate the Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth
|
||||
if (isset($_REQUEST['reverse_auth']) && ($_REQUEST['reverse_auth'] == 'yes')) {
|
||||
$stage1 = $this->api->signedRequest($this->api->request_token_url, 'POST', array('x_auth_mode' => 'reverse_auth'));
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
$responseObj = array('x_reverse_auth_parameters' => $stage1, 'x_reverse_auth_target' => $this->config["keys"]["key"]);
|
||||
$response = json_encode($responseObj);
|
||||
header("Content-Type: application/json", true, 200);
|
||||
echo $response;
|
||||
die();
|
||||
}
|
||||
$tokens = $this->api->requestToken($this->endpoint);
|
||||
|
||||
// request tokens as received from provider
|
||||
$this->request_tokens_raw = $tokens;
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5);
|
||||
}
|
||||
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid oauth token.", 5);
|
||||
}
|
||||
|
||||
$this->token("request_token", $tokens["oauth_token"]);
|
||||
$this->token("request_token_secret", $tokens["oauth_token_secret"]);
|
||||
|
||||
// redirect the user to the provider authentication url with force_login
|
||||
if (( isset($this->config['force_login']) && $this->config['force_login'] ) || ( isset($this->config['force']) && $this->config['force'] === true )) {
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($tokens, array('force_login' => true)));
|
||||
}
|
||||
|
||||
// else, redirect the user to the provider authentication url
|
||||
Hybrid_Auth::redirect($this->api->authorizeUrl($tokens));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginFinish() {
|
||||
// in case we are completing a Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth
|
||||
if (isset($_REQUEST['oauth_token_secret'])) {
|
||||
$tokens = $_REQUEST;
|
||||
$this->access_tokens_raw = $tokens;
|
||||
|
||||
// we should have an access_token unless something has gone wrong
|
||||
if (!isset($tokens["oauth_token"])) {
|
||||
throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5);
|
||||
}
|
||||
|
||||
// Get rid of tokens we don't need
|
||||
$this->deleteToken("request_token");
|
||||
$this->deleteToken("request_token_secret");
|
||||
|
||||
// Store access_token and secret for later use
|
||||
$this->token("access_token", $tokens['oauth_token']);
|
||||
$this->token("access_token_secret", $tokens['oauth_token_secret']);
|
||||
|
||||
// set user as logged in to the current provider
|
||||
$this->setUserConnected();
|
||||
return;
|
||||
}
|
||||
parent::loginFinish();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
$includeEmail = isset($this->config['includeEmail']) ? (bool) $this->config['includeEmail'] : false;
|
||||
$response = $this->api->get('account/verify_credentials.json'. ($includeEmail ? '?include_email=true' : ''));
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 6);
|
||||
}
|
||||
|
||||
if (!is_object($response) || !isset($response->id)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $response ), 6);
|
||||
}
|
||||
|
||||
# store the user profile.
|
||||
$this->user->profile->identifier = (property_exists($response, 'id')) ? $response->id : "";
|
||||
$this->user->profile->displayName = (property_exists($response, 'screen_name')) ? $response->screen_name : "";
|
||||
$this->user->profile->description = (property_exists($response, 'description')) ? $response->description : "";
|
||||
$this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name : "";
|
||||
$this->user->profile->photoURL = (property_exists($response, 'profile_image_url')) ? (str_replace('_normal', '', $response->profile_image_url)) : "";
|
||||
$this->user->profile->profileURL = (property_exists($response, 'screen_name')) ? ("http://twitter.com/" . $response->screen_name) : "";
|
||||
$this->user->profile->webSiteURL = (property_exists($response, 'url')) ? $response->url : "";
|
||||
$this->user->profile->region = (property_exists($response, 'location')) ? $response->location : "";
|
||||
if($includeEmail) $this->user->profile->email = (property_exists($response, 'email')) ? $response->email : "";
|
||||
if($includeEmail) $this->user->profile->emailVerified = (property_exists($response, 'email')) ? $response->email : "";
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
$parameters = array('cursor' => '-1');
|
||||
$response = $this->api->get('friends/ids.json', $parameters);
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
if (!$response || !count($response->ids)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// 75 id per time should be okey
|
||||
$contactsids = array_chunk($response->ids, 75);
|
||||
|
||||
$contacts = array();
|
||||
|
||||
foreach ($contactsids as $chunk) {
|
||||
$parameters = array('user_id' => implode(",", $chunk));
|
||||
$response = $this->api->get('users/lookup.json', $parameters);
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
if ($response && count($response)) {
|
||||
foreach ($response as $item) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
|
||||
$uc->identifier = (property_exists($item, 'id')) ? $item->id : "";
|
||||
$uc->displayName = (property_exists($item, 'name')) ? $item->name : "";
|
||||
$uc->profileURL = (property_exists($item, 'screen_name')) ? ("http://twitter.com/" . $item->screen_name) : "";
|
||||
$uc->photoURL = (property_exists($item, 'profile_image_url')) ? $item->profile_image_url : "";
|
||||
$uc->description = (property_exists($item, 'description')) ? $item->description : "";
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function setUserStatus($status) {
|
||||
|
||||
if (is_array($status) && isset($status['message']) && isset($status['picture'])) {
|
||||
$response = $this->api->post('statuses/update_with_media.json', array('status' => $status['message'], 'media[]' => file_get_contents($status['picture'])), null, null, true);
|
||||
} else {
|
||||
$response = $this->api->post('statuses/update.json', array('status' => $status));
|
||||
}
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("Update user status failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserStatus($tweetid) {
|
||||
$info = $this->api->get('statuses/show.json?id=' . $tweetid . '&include_entities=true');
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200 || !isset($info->id)) {
|
||||
throw new Exception("Cannot retrieve user status! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* load the user latest activity
|
||||
* - timeline : all the stream
|
||||
* - me : the user activity only
|
||||
*
|
||||
* by default return the timeline
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserActivity($stream) {
|
||||
if ($stream == "me") {
|
||||
$response = $this->api->get('statuses/user_timeline.json');
|
||||
} else {
|
||||
$response = $this->api->get('statuses/home_timeline.json');
|
||||
}
|
||||
|
||||
// check the last HTTP status code returned
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User activity stream request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code));
|
||||
}
|
||||
|
||||
if (!$response) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$activities = array();
|
||||
|
||||
foreach ($response as $item) {
|
||||
$ua = new Hybrid_User_Activity();
|
||||
|
||||
$ua->id = (property_exists($item, 'id')) ? $item->id : "";
|
||||
$ua->date = (property_exists($item, 'created_at')) ? strtotime($item->created_at) : "";
|
||||
$ua->text = (property_exists($item, 'text')) ? $item->text : "";
|
||||
|
||||
$ua->user->identifier = (property_exists($item->user, 'id')) ? $item->user->id : "";
|
||||
$ua->user->displayName = (property_exists($item->user, 'name')) ? $item->user->name : "";
|
||||
$ua->user->profileURL = (property_exists($item->user, 'screen_name')) ? ("http://twitter.com/" . $item->user->screen_name) : "";
|
||||
$ua->user->photoURL = (property_exists($item->user, 'profile_image_url')) ? $item->user->profile_image_url : "";
|
||||
|
||||
$activities[] = $ua;
|
||||
}
|
||||
|
||||
return $activities;
|
||||
}
|
||||
|
||||
}
|
@ -1,269 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* !
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Yahoo OAuth Class.
|
||||
*
|
||||
* @package HybridAuth providers package
|
||||
* @author Lukasz Koprowski <azram19@gmail.com>
|
||||
* @author Oleg Kuzava <olegkuzava@gmail.com>
|
||||
* @version 1.0
|
||||
* @license BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_Providers_Yahoo - Yahoo provider adapter based on OAuth2 protocol.
|
||||
*/
|
||||
class Hybrid_Providers_Yahoo extends Hybrid_Provider_Model_OAuth2 {
|
||||
|
||||
/**
|
||||
* Define Yahoo scopes.
|
||||
*
|
||||
* @var array $scope
|
||||
* If empty will be used YDN App scopes.
|
||||
* @see https://developer.yahoo.com/oauth2/guide/yahoo_scopes.
|
||||
*/
|
||||
public $scope = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// Provider api end-points.
|
||||
$this->api->api_base_url = "https://social.yahooapis.com/v1/";
|
||||
$this->api->authorize_url = "https://api.login.yahoo.com/oauth2/request_auth";
|
||||
$this->api->token_url = "https://api.login.yahoo.com/oauth2/get_token";
|
||||
|
||||
// Set token headers.
|
||||
$this->setAuthorizationHeaders("basic");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function loginBegin() {
|
||||
if (is_array($this->scope)) {
|
||||
$this->scope = implode(",", $this->scope);
|
||||
}
|
||||
parent::loginBegin();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserProfile() {
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
$response = $this->api->get("user/{$userId}/profile", array(
|
||||
"format" => "json",
|
||||
));
|
||||
|
||||
if (!isset($response->profile)) {
|
||||
throw new Exception("User profile request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData($response), 6);
|
||||
}
|
||||
|
||||
$data = $response->profile;
|
||||
|
||||
$this->user->profile->identifier = isset($data->guid) ? $data->guid : "";
|
||||
$this->user->profile->firstName = isset($data->givenName) ? $data->givenName : "";
|
||||
$this->user->profile->lastName = isset($data->familyName) ? $data->familyName : "";
|
||||
$this->user->profile->displayName = isset($data->nickname) ? trim($data->nickname) : "";
|
||||
$this->user->profile->profileURL = isset($data->profileUrl) ? $data->profileUrl : "";
|
||||
$this->user->profile->gender = isset($data->gender) ? $data->gender : "";
|
||||
|
||||
if ($this->user->profile->gender === "F") {
|
||||
$this->user->profile->gender = "female";
|
||||
}
|
||||
elseif ($this->user->profile->gender === "M") {
|
||||
$this->user->profile->gender = "male";
|
||||
}
|
||||
|
||||
if (isset($data->emails)) {
|
||||
$email = "";
|
||||
foreach ($data->emails as $v) {
|
||||
if (isset($v->primary) && $v->primary) {
|
||||
$email = isset($v->handle) ? $v->handle : "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->user->profile->email = $email;
|
||||
$this->user->profile->emailVerified = $email;
|
||||
}
|
||||
|
||||
$this->user->profile->age = isset($data->displayAge) ? $data->displayAge : "";
|
||||
$this->user->profile->photoURL = isset($data->image) ? $data->image->imageUrl : "";
|
||||
|
||||
$this->user->profile->address = isset($data->location) ? $data->location : "";
|
||||
$this->user->profile->language = isset($data->lang) ? $data->lang : "";
|
||||
|
||||
return $this->user->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getUserContacts() {
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
$response = $this->api->get("user/{$userId}/contacts", array(
|
||||
"format" => "json",
|
||||
"count" => "max",
|
||||
));
|
||||
|
||||
if ($this->api->http_code != 200) {
|
||||
throw new Exception("User contacts request failed! {$this->providerId} returned an error: " . $this->errorMessageByStatus());
|
||||
}
|
||||
|
||||
if (!isset($response->contacts) || !isset($response->contacts->contact) || (isset($response->errcode) && $response->errcode != 0)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$contacts = array();
|
||||
foreach ($response->contacts->contact as $item) {
|
||||
$uc = new Hybrid_User_Contact();
|
||||
|
||||
$uc->identifier = isset($item->id) ? $item->id : "";
|
||||
$uc->email = $this->selectEmail($item->fields);
|
||||
$uc->displayName = $this->selectName($item->fields);
|
||||
$uc->photoURL = $this->selectPhoto($item->fields);
|
||||
|
||||
$contacts[] = $uc;
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current user id.
|
||||
*
|
||||
* @return string
|
||||
* Current user ID.
|
||||
* @throws Exception
|
||||
*/
|
||||
function getCurrentUserId() {
|
||||
// Set headers to get refresh token.
|
||||
$this->setAuthorizationHeaders("basic");
|
||||
|
||||
// Refresh tokens if needed.
|
||||
$this->refreshToken();
|
||||
|
||||
// Set headers to make api call.
|
||||
$this->setAuthorizationHeaders("bearer");
|
||||
|
||||
$response = $this->api->get("me/guid", array(
|
||||
"format" => "json",
|
||||
));
|
||||
|
||||
if (!isset($response->guid->value)) {
|
||||
throw new Exception("User id request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData($response));
|
||||
}
|
||||
|
||||
return $response->guid->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function for returning values from XML-like objects.
|
||||
*
|
||||
* @param stdClass $vs
|
||||
* Object.
|
||||
* @param string $t
|
||||
* Property name.
|
||||
* @return mixed
|
||||
*/
|
||||
private function select($vs, $t) {
|
||||
foreach ($vs as $v) {
|
||||
if ($v->type == $t) {
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses user name.
|
||||
*
|
||||
* @param stdClass $v
|
||||
* Object.
|
||||
* @return string
|
||||
* User name.
|
||||
*/
|
||||
private function selectName($v) {
|
||||
$s = $this->select($v, "name");
|
||||
if (!$s) {
|
||||
$s = $this->select($v, "nickname");
|
||||
return isset($s->value) ? $s->value : "";
|
||||
}
|
||||
return isset($s->value) ? "{$s->value->givenName} {$s->value->familyName}" : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses photo URL.
|
||||
*
|
||||
* @param stdClass $v
|
||||
* Object.
|
||||
* @return string
|
||||
* Photo URL.
|
||||
*/
|
||||
private function selectPhoto($v) {
|
||||
$s = $this->select($v, "image");
|
||||
|
||||
return isset($s->value) ? $s->value->imageUrl : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses email.
|
||||
*
|
||||
* @param stdClass $v
|
||||
* Object
|
||||
* @return string
|
||||
* An email address.
|
||||
*/
|
||||
private function selectEmail($v) {
|
||||
$s = $this->select($v, "email");
|
||||
if (empty($s)) {
|
||||
$s = $this->select($v, "yahooid");
|
||||
if (isset($s->value) && strpos($s->value, "@") === FALSE) {
|
||||
$s->value .= "@yahoo.com";
|
||||
}
|
||||
}
|
||||
|
||||
return isset($s->value) ? $s->value : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set correct Authorization headers.
|
||||
*
|
||||
* @param string $token_type
|
||||
* Specify token type.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setAuthorizationHeaders($token_type) {
|
||||
switch ($token_type) {
|
||||
case "basic":
|
||||
// The /get_token requires authorization header.
|
||||
$token = base64_encode("{$this->config["keys"]["id"]}:{$this->config["keys"]["secret"]}");
|
||||
$this->api->curl_header = array(
|
||||
"Authorization: Basic {$token}",
|
||||
"Content-Type: application/x-www-form-urlencoded",
|
||||
);
|
||||
break;
|
||||
|
||||
case "bearer":
|
||||
// Yahoo API requires the token to be passed as a Bearer within the authorization header.
|
||||
$this->api->curl_header = array(
|
||||
"Authorization: Bearer {$this->api->access_token}",
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
require_once realpath(dirname(__FILE__)) . "/StorageInterface.php";
|
||||
|
||||
/**
|
||||
* HybridAuth storage manager
|
||||
*/
|
||||
class Hybrid_Storage implements Hybrid_Storage_Interface {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function __construct() {
|
||||
if (!session_id()) {
|
||||
if (!session_start()) {
|
||||
throw new Exception("Hybridauth requires the use of 'session_start()' at the start of your script, which appears to be disabled.", 1);
|
||||
}
|
||||
}
|
||||
|
||||
$this->config("php_session_id", session_id());
|
||||
$this->config("version", Hybrid_Auth::$version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a value in the config storage, or returns config if value is null
|
||||
*
|
||||
* @param string $key Config name
|
||||
* @param string $value Config value
|
||||
* @return array|null
|
||||
*/
|
||||
public function config($key, $value = null) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if ($value) {
|
||||
$_SESSION["HA::CONFIG"][$key] = serialize($value);
|
||||
} elseif (isset($_SESSION["HA::CONFIG"][$key])) {
|
||||
return unserialize($_SESSION["HA::CONFIG"][$key]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value from session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @return string|null
|
||||
*/
|
||||
public function get($key) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) {
|
||||
return unserialize($_SESSION["HA::STORE"][$key]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a key value pair to the session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @param string $value Value
|
||||
* @return void
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
$key = strtolower($key);
|
||||
$_SESSION["HA::STORE"][$key] = serialize($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear session storage
|
||||
* @return void
|
||||
*/
|
||||
function clear() {
|
||||
$_SESSION["HA::STORE"] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a specific key from session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @return void
|
||||
*/
|
||||
function delete($key) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) {
|
||||
$f = $_SESSION['HA::STORE'];
|
||||
unset($f[$key]);
|
||||
$_SESSION["HA::STORE"] = $f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all keys recursively from session storage
|
||||
*
|
||||
* @param string $key Key
|
||||
* @retun void
|
||||
*/
|
||||
function deleteMatch($key) {
|
||||
$key = strtolower($key);
|
||||
|
||||
if (isset($_SESSION["HA::STORE"]) && count($_SESSION["HA::STORE"])) {
|
||||
$f = $_SESSION['HA::STORE'];
|
||||
foreach ($f as $k => $v) {
|
||||
if (strstr($k, $key)) {
|
||||
unset($f[$k]);
|
||||
}
|
||||
}
|
||||
$_SESSION["HA::STORE"] = $f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns session storage as a serialized string
|
||||
* @return string|null
|
||||
*/
|
||||
function getSessionData() {
|
||||
if (isset($_SESSION["HA::STORE"])) {
|
||||
return serialize($_SESSION["HA::STORE"]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the session from serialized session data
|
||||
*
|
||||
* @param string $sessiondata Serialized session data
|
||||
* @return void
|
||||
*/
|
||||
function restoreSessionData($sessiondata = null) {
|
||||
$_SESSION["HA::STORE"] = unserialize($sessiondata);
|
||||
}
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* HybridAuth storage manager interface
|
||||
*/
|
||||
interface Hybrid_Storage_Interface {
|
||||
|
||||
public function config($key, $value = null);
|
||||
|
||||
public function get($key);
|
||||
|
||||
public function set($key, $value);
|
||||
|
||||
function clear();
|
||||
|
||||
function delete($key);
|
||||
|
||||
function deleteMatch($key);
|
||||
|
||||
function getSessionData();
|
||||
|
||||
function restoreSessionData($sessiondata = null);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Hybrid_User class represents the current logged in user
|
||||
*/
|
||||
class Hybrid_User {
|
||||
|
||||
/**
|
||||
* The ID (name) of the connected provider
|
||||
* @var mixed
|
||||
*/
|
||||
public $providerId = null;
|
||||
|
||||
/**
|
||||
* Timestamp connection to the provider
|
||||
* @var int
|
||||
*/
|
||||
public $timestamp = null;
|
||||
|
||||
/**
|
||||
* User profile, contains the list of fields available in the normalized user profile structure used by HybridAuth
|
||||
* @var Hybrid_User_Profile
|
||||
*/
|
||||
public $profile = null;
|
||||
|
||||
/**
|
||||
* Initialize the user object
|
||||
*/
|
||||
function __construct() {
|
||||
$this->timestamp = time();
|
||||
$this->profile = new Hybrid_User_Profile();
|
||||
}
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_User_Activity
|
||||
*
|
||||
* used to provider the connected user activity stream on a standardized structure across supported social apis.
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/Profile_Data_User_Activity.html
|
||||
*/
|
||||
class Hybrid_User_Activity {
|
||||
|
||||
/**
|
||||
* Activity id on the provider side, usually given as integer
|
||||
* @var mixed
|
||||
*/
|
||||
public $id = null;
|
||||
|
||||
/**
|
||||
* Activity date of creation
|
||||
* @var int
|
||||
*/
|
||||
public $date = null;
|
||||
|
||||
/**
|
||||
* Activity content as a string
|
||||
* @var string
|
||||
*/
|
||||
public $text = null;
|
||||
|
||||
/**
|
||||
* User who created the activity
|
||||
* @var stdClass
|
||||
*/
|
||||
public $user = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->user = new stdClass();
|
||||
|
||||
// typically, we should have a few information about the user who created the event from social apis
|
||||
$this->user->identifier = null;
|
||||
$this->user->displayName = null;
|
||||
$this->user->profileURL = null;
|
||||
$this->user->photoURL = null;
|
||||
}
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_User_Contact
|
||||
*
|
||||
* used to provider the connected user contacts list on a standardized structure across supported social apis.
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/Profile_Data_User_Contacts.html
|
||||
*/
|
||||
class Hybrid_User_Contact {
|
||||
|
||||
/**
|
||||
* The Unique contact user ID
|
||||
* @var mixed
|
||||
*/
|
||||
public $identifier = null;
|
||||
|
||||
/**
|
||||
* User website, blog, web page
|
||||
* @var string
|
||||
*/
|
||||
public $webSiteURL = null;
|
||||
|
||||
/**
|
||||
* URL link to profile page on the IDp web site
|
||||
* @var string
|
||||
*/
|
||||
public $profileURL = null;
|
||||
|
||||
/**
|
||||
* URL link to user photo or avatar
|
||||
* @var string
|
||||
*/
|
||||
public $photoURL = null;
|
||||
|
||||
/**
|
||||
* User displayName provided by the IDp or a concatenation of first and last name
|
||||
* @var string
|
||||
*/
|
||||
public $displayName = null;
|
||||
|
||||
/**
|
||||
* A short about_me
|
||||
* @var string
|
||||
*/
|
||||
public $description = null;
|
||||
|
||||
/**
|
||||
* User email. Not all of IDp grant access to the user email
|
||||
* @var string
|
||||
*/
|
||||
public $email = null;
|
||||
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Hybrid_User_Profile object represents the current logged in user profile.
|
||||
* The list of fields available in the normalized user profile structure used by HybridAuth.
|
||||
*
|
||||
* The Hybrid_User_Profile object is populated with as much information about the user as
|
||||
* HybridAuth was able to pull from the given API or authentication provider.
|
||||
*
|
||||
* http://hybridauth.sourceforge.net/userguide/Profile_Data_User_Profile.html
|
||||
*/
|
||||
class Hybrid_User_Profile {
|
||||
|
||||
/**
|
||||
* The Unique user's ID on the connected provider
|
||||
* @var mixed
|
||||
*/
|
||||
public $identifier = null;
|
||||
|
||||
/**
|
||||
* User website, blog, web page
|
||||
* @var string
|
||||
*/
|
||||
public $webSiteURL = null;
|
||||
|
||||
/**
|
||||
* URL link to profile page on the IDp web site
|
||||
* @var string
|
||||
*/
|
||||
public $profileURL = null;
|
||||
|
||||
/**
|
||||
* URL link to user photo or avatar
|
||||
* @var string
|
||||
*/
|
||||
public $photoURL = null;
|
||||
|
||||
/**
|
||||
* User displayName provided by the IDp or a concatenation of first and last name.
|
||||
* @var string
|
||||
*/
|
||||
public $displayName = null;
|
||||
|
||||
/**
|
||||
* A short about_me
|
||||
* @var string
|
||||
*/
|
||||
public $description = null;
|
||||
|
||||
/**
|
||||
* User's first name
|
||||
* @var string
|
||||
*/
|
||||
public $firstName = null;
|
||||
|
||||
/**
|
||||
* User's last name
|
||||
* @var string
|
||||
*/
|
||||
public $lastName = null;
|
||||
|
||||
/**
|
||||
* Male or female
|
||||
* @var string
|
||||
*/
|
||||
public $gender = null;
|
||||
|
||||
/**
|
||||
* Language
|
||||
* @var string
|
||||
*/
|
||||
public $language = null;
|
||||
|
||||
/**
|
||||
* User age, we don't calculate it. we return it as is if the IDp provide it.
|
||||
* @var int
|
||||
*/
|
||||
public $age = null;
|
||||
|
||||
/**
|
||||
* User birth Day
|
||||
* @var int
|
||||
*/
|
||||
public $birthDay = null;
|
||||
|
||||
/**
|
||||
* User birth Month
|
||||
* @var int
|
||||
*/
|
||||
public $birthMonth = null;
|
||||
|
||||
/**
|
||||
* User birth Year
|
||||
* @var int
|
||||
*/
|
||||
public $birthYear = null;
|
||||
|
||||
/**
|
||||
* User email. Note: not all of IDp grant access to the user email
|
||||
* @var string
|
||||
*/
|
||||
public $email = null;
|
||||
|
||||
/**
|
||||
* Verified user email. Note: not all of IDp grant access to verified user email
|
||||
* @var string
|
||||
*/
|
||||
public $emailVerified = null;
|
||||
|
||||
/**
|
||||
* Phone number
|
||||
* @var string
|
||||
*/
|
||||
public $phone = null;
|
||||
|
||||
/**
|
||||
* Complete user address
|
||||
* @var string
|
||||
*/
|
||||
public $address = null;
|
||||
|
||||
/**
|
||||
* User country
|
||||
* @var string
|
||||
*/
|
||||
public $country = null;
|
||||
|
||||
/**
|
||||
* Region
|
||||
* @var string
|
||||
*/
|
||||
public $region = null;
|
||||
|
||||
/**
|
||||
* City
|
||||
* @var string
|
||||
*/
|
||||
public $city = null;
|
||||
|
||||
/**
|
||||
* Postal code
|
||||
* @var string
|
||||
*/
|
||||
public $zip = null;
|
||||
|
||||
/**
|
||||
* Job title
|
||||
* @var string
|
||||
*/
|
||||
public $job_title = null;
|
||||
|
||||
/**
|
||||
* Organization name
|
||||
* @var string
|
||||
*/
|
||||
public $organization_name = null;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/*!
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// HybridAuth Config file: http://hybridauth.sourceforge.net/userguide/Configuration.html
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
return
|
||||
array(
|
||||
"base_url" => "#GLOBAL_HYBRID_AUTH_URL_BASE#",
|
||||
|
||||
"providers" => array (
|
||||
// openid providers
|
||||
"OpenID" => array (
|
||||
"enabled" => #OPENID_ADAPTER_STATUS#
|
||||
),
|
||||
|
||||
"AOL" => array (
|
||||
"enabled" => #AOL_ADAPTER_STATUS#
|
||||
),
|
||||
|
||||
"Yahoo" => array (
|
||||
"enabled" => #YAHOO_ADAPTER_STATUS#,
|
||||
"keys" => array ( "id" => "#YAHOO_APPLICATION_APP_ID#", "secret" => "#YAHOO_APPLICATION_SECRET#" )
|
||||
),
|
||||
|
||||
"Google" => array (
|
||||
"enabled" => #GOOGLE_ADAPTER_STATUS#,
|
||||
"keys" => array ( "id" => "#GOOGLE_APPLICATION_APP_ID#", "secret" => "#GOOGLE_APPLICATION_SECRET#" )
|
||||
),
|
||||
|
||||
"Facebook" => array (
|
||||
"enabled" => #FACEBOOK_ADAPTER_STATUS#,
|
||||
"keys" => array ( "id" => "#FACEBOOK_APPLICATION_APP_ID#", "secret" => "#FACEBOOK_APPLICATION_SECRET#" )
|
||||
),
|
||||
|
||||
"Twitter" => array (
|
||||
"enabled" => #TWITTER_ADAPTER_STATUS#,
|
||||
"keys" => array ( "key" => "#TWITTER_APPLICATION_KEY#", "secret" => "#TWITTER_APPLICATION_SECRET#" )
|
||||
),
|
||||
|
||||
// windows live
|
||||
"Live" => array (
|
||||
"enabled" => #LIVE_ADAPTER_STATUS#,
|
||||
"keys" => array ( "id" => "#LIVE_APPLICATION_APP_ID#", "secret" => "#LIVE_APPLICATION_SECRET#" )
|
||||
),
|
||||
|
||||
"MySpace" => array (
|
||||
"enabled" => #MYSPACE_ADAPTER_STATUS#,
|
||||
"keys" => array ( "key" => "#MYSPACE_APPLICATION_KEY#", "secret" => "#MYSPACE_APPLICATION_SECRET#" )
|
||||
),
|
||||
|
||||
"LinkedIn" => array (
|
||||
"enabled" => #LINKEDIN_ADAPTER_STATUS#,
|
||||
"keys" => array ( "key" => "#LINKEDIN_APPLICATION_KEY#", "secret" => "#LINKEDIN_APPLICATION_SECRET#" )
|
||||
),
|
||||
|
||||
"Foursquare" => array (
|
||||
"enabled" => #FOURSQUARE_ADAPTER_STATUS#,
|
||||
"keys" => array ( "id" => "#FOURSQUARE_APPLICATION_APP_ID#", "secret" => "#FOURSQUARE_APPLICATION_SECRET#" )
|
||||
),
|
||||
),
|
||||
|
||||
// if you want to enable logging, set 'debug_mode' to true then provide a writable file by the web server on "debug_file"
|
||||
"debug_mode" => false,
|
||||
|
||||
"debug_file" => ""
|
||||
);
|
@ -1,10 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenID Policy</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
Set here your OpenID Policy,
|
||||
-->
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HybridAuth Endpoint</title>
|
||||
<meta name="robots" content="NOINDEX, NOFOLLOW">
|
||||
<meta http-equiv="X-XRDS-Location" content="{X_XRDS_LOCATION}" />
|
||||
</head>
|
||||
<body>
|
||||
<h3 style="margin-bottom: 2px;">HybridAuth</h3>
|
||||
Open Source Social Sign On PHP Library.
|
||||
<br />
|
||||
<a href="http://hybridauth.sourceforge.net/" style="color:green;text-decoration:none;">hybridauth.sourceforge.net/</a>
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xrds:XRDS
|
||||
xmlns:xrds="xri://$xrds"
|
||||
xmlns:openid="http://openid.net/xmlns/1.0"
|
||||
xmlns="xri://$xrd*($v*2.0)">
|
||||
<XRD>
|
||||
<Service priority="1">
|
||||
<Type>http://specs.openid.net/auth/2.0/return_to</Type>
|
||||
<URI>{RETURN_TO_URL}</URI>
|
||||
</Service>
|
||||
</XRD>
|
||||
</xrds:XRDS>
|
@ -1,37 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="ROBOTS" content="NONE" />
|
||||
<script type="text/javascript">
|
||||
function parseIsLiveUserResponse(e) {
|
||||
var b = "isLiveUser";
|
||||
if (!e) return false;
|
||||
for (var d = e.substring(1).split("&"), a = [], c = 0; c < d.length; c++) {
|
||||
parm = d[c].split("=");
|
||||
a[unescape(parm[0])] = unescape(parm[1])
|
||||
}
|
||||
if (a[b] !== undefined && a[b].length != 0 && window.parent && window.parent.parent && window.parent.parent.Microsoft !== undefined) {
|
||||
var f = a[b] == "true";
|
||||
window.parent.parent.Microsoft.Live.App.get_auth().set_isLiveUser(f);
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
function onLoad() {
|
||||
try {
|
||||
var c = window.location.hash.substr(1),
|
||||
d = window.location.search;
|
||||
if (window.location.replace == null) window.location.replace = window.location.assign;
|
||||
window.location.replace("about:blank");
|
||||
if (parseIsLiveUserResponse(d)) return;
|
||||
var b = c.split("/")[0],
|
||||
a = null;
|
||||
if (b && b != ".parent") a = window.parent.frames[b];
|
||||
else a = window.parent.parent;
|
||||
a.Microsoft && a.Microsoft.Live.Channels.Mux._recv_chunk(c)
|
||||
} catch (e) {}
|
||||
}
|
||||
< /script>
|
||||
</head>
|
||||
<body onload="onLoad();">
|
||||
</body>
|
||||
</html>
|
@ -1,125 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* A service client for the Amazon ID OAuth 2 flow.
|
||||
*
|
||||
* The sole purpose of this subclass is to make sure the POST params
|
||||
* for cURL are provided as an urlencoded string rather than an array.
|
||||
* This is because Amazon requires COntent-Type header to be application/x-www-form-urlencoded,
|
||||
* which cURL overrides to multipart/form-data when POST fields are provided as an array
|
||||
*
|
||||
* The only difference from Oauth2CLient in authenticate() method is http_build_query()
|
||||
* wrapped around $params. request() and parseRequestResult() methods are exact copies
|
||||
* from Oauth2Client. They are copied here because private scope does not allow calling them
|
||||
* from subclass.
|
||||
*
|
||||
* @link http://stackoverflow.com/questions/5224790/curl-post-format-for-curlopt-postfields
|
||||
*
|
||||
*/
|
||||
class AmazonOAuth2Client extends OAuth2Client {
|
||||
|
||||
public function authenticate( $code ) {
|
||||
|
||||
$params = array(
|
||||
"client_id" => $this->client_id,
|
||||
"client_secret" => $this->client_secret,
|
||||
"grant_type" => 'authorization_code',
|
||||
"redirect_uri" => $this->redirect_uri,
|
||||
"code" => $code,
|
||||
);
|
||||
|
||||
$response = $this->request( $this->token_url, http_build_query($params), $this->curl_authenticate_method );
|
||||
|
||||
$response = $this->parseRequestResult( $response );
|
||||
|
||||
if ( ! $response || ! isset( $response->access_token ) ){
|
||||
throw new Exception( "The Authorization Service has return: " . $response->error );
|
||||
}
|
||||
|
||||
if( isset( $response->access_token ) ) $this->access_token = $response->access_token;
|
||||
if( isset( $response->refresh_token ) ) $this->refresh_token = $response->refresh_token;
|
||||
if( isset( $response->expires_in ) ) $this->access_token_expires_in = $response->expires_in;
|
||||
|
||||
// calculate when the access token expire
|
||||
if( isset($response->expires_in)) {
|
||||
$this->access_token_expires_at = time() + $response->expires_in;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function request( $url, $params=false, $type="GET" )
|
||||
{
|
||||
Hybrid_Logger::info( "Enter OAuth2Client::request( $url )" );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request params: ", serialize( $params ) );
|
||||
|
||||
if( $type == "GET" ){
|
||||
$url = $url . ( strpos( $url, '?' ) ? '&' : '?' ) . http_build_query($params, '', '&');
|
||||
}
|
||||
|
||||
$this->http_info = array();
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL , $url );
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 );
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT , $this->curl_time_out );
|
||||
curl_setopt($ch, CURLOPT_USERAGENT , $this->curl_useragent );
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , $this->curl_connect_time_out );
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , $this->curl_ssl_verifypeer );
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , $this->curl_ssl_verifyhost );
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER , $this->curl_header );
|
||||
|
||||
if ($this->curl_compressed){
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
|
||||
}
|
||||
|
||||
if($this->curl_proxy){
|
||||
curl_setopt( $ch, CURLOPT_PROXY , $this->curl_proxy);
|
||||
}
|
||||
|
||||
if( $type == "POST" ){
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
if($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, $params );
|
||||
}
|
||||
if( $type == "DELETE" ){
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
}
|
||||
if( $type == "PATCH" ){
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
if($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, $params );
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
if( $response === false ) {
|
||||
Hybrid_Logger::error( "OAuth2Client::request(). curl_exec error: ", curl_error($ch) );
|
||||
}
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize( curl_getinfo($ch) ) );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize( $response ) );
|
||||
|
||||
$this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$this->http_info = array_merge($this->http_info, curl_getinfo($ch));
|
||||
|
||||
curl_close ($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function parseRequestResult( $result )
|
||||
{
|
||||
if( json_decode( $result ) ) return json_decode( $result );
|
||||
|
||||
parse_str( $result, $output );
|
||||
|
||||
$result = new StdClass();
|
||||
|
||||
foreach( $output as $k => $v )
|
||||
$result->$k = $v;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,228 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
require_once "base_facebook.php";
|
||||
|
||||
/**
|
||||
* Extends the BaseFacebook class with the intent of using
|
||||
* PHP sessions to store user ids and access tokens.
|
||||
*/
|
||||
class Facebook extends BaseFacebook
|
||||
{
|
||||
/**
|
||||
* Cookie prefix
|
||||
*/
|
||||
const FBSS_COOKIE_NAME = 'fbss';
|
||||
|
||||
/**
|
||||
* We can set this to a high number because the main session
|
||||
* expiration will trump this.
|
||||
*/
|
||||
const FBSS_COOKIE_EXPIRE = 31556926; // 1 year
|
||||
|
||||
/**
|
||||
* Stores the shared session ID if one is set.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sharedSessionID;
|
||||
|
||||
/**
|
||||
* Identical to the parent constructor, except that
|
||||
* we start a PHP session to store the user ID and
|
||||
* access token if during the course of execution
|
||||
* we discover them.
|
||||
*
|
||||
* @param array $config the application configuration. Additionally
|
||||
* accepts "sharedSession" as a boolean to turn on a secondary
|
||||
* cookie for environments with a shared session (that is, your app
|
||||
* shares the domain with other apps).
|
||||
*
|
||||
* @see BaseFacebook::__construct
|
||||
*/
|
||||
public function __construct($config) {
|
||||
if ((function_exists('session_status')
|
||||
&& session_status() !== PHP_SESSION_ACTIVE) || !session_id()) {
|
||||
session_start();
|
||||
}
|
||||
parent::__construct($config);
|
||||
if (!empty($config['sharedSession'])) {
|
||||
$this->initSharedSession();
|
||||
|
||||
// re-load the persisted state, since parent
|
||||
// attempted to read out of non-shared cookie
|
||||
$state = $this->getPersistentData('state');
|
||||
if (!empty($state)) {
|
||||
$this->state = $state;
|
||||
} else {
|
||||
$this->state = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported keys for persistent data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $kSupportedKeys =
|
||||
array('state', 'code', 'access_token', 'user_id');
|
||||
|
||||
/**
|
||||
* Initiates Shared Session
|
||||
*/
|
||||
protected function initSharedSession() {
|
||||
$cookie_name = $this->getSharedSessionCookieName();
|
||||
if (isset($_COOKIE[$cookie_name])) {
|
||||
$data = $this->parseSignedRequest($_COOKIE[$cookie_name]);
|
||||
if ($data && !empty($data['domain']) &&
|
||||
self::isAllowedDomain($this->getHttpHost(), $data['domain'])) {
|
||||
// good case
|
||||
$this->sharedSessionID = $data['id'];
|
||||
return;
|
||||
}
|
||||
// ignoring potentially unreachable data
|
||||
}
|
||||
// evil/corrupt/missing case
|
||||
$base_domain = $this->getBaseDomain();
|
||||
$this->sharedSessionID = md5(uniqid(mt_rand(), true));
|
||||
$cookie_value = $this->makeSignedRequest(
|
||||
array(
|
||||
'domain' => $base_domain,
|
||||
'id' => $this->sharedSessionID,
|
||||
)
|
||||
);
|
||||
$_COOKIE[$cookie_name] = $cookie_value;
|
||||
if (!headers_sent()) {
|
||||
$expire = time() + self::FBSS_COOKIE_EXPIRE;
|
||||
setcookie($cookie_name, $cookie_value, $expire, '/', '.'.$base_domain);
|
||||
} else {
|
||||
// @codeCoverageIgnoreStart
|
||||
self::errorLog(
|
||||
'Shared session ID cookie could not be set! You must ensure you '.
|
||||
'create the Facebook instance before headers have been sent. This '.
|
||||
'will cause authentication issues after the first request.'
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the implementations of the inherited abstract
|
||||
* methods. The implementation uses PHP sessions to maintain
|
||||
* a store for authorization codes, user ids, CSRF states, and
|
||||
* access tokens.
|
||||
*/
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see BaseFacebook::setPersistentData()
|
||||
*/
|
||||
protected function setPersistentData($key, $value) {
|
||||
if (!in_array($key, self::$kSupportedKeys)) {
|
||||
self::errorLog('Unsupported key passed to setPersistentData.');
|
||||
return;
|
||||
}
|
||||
|
||||
$session_var_name = $this->constructSessionVariableName($key);
|
||||
$_SESSION[$session_var_name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see BaseFacebook::getPersistentData()
|
||||
*/
|
||||
protected function getPersistentData($key, $default = false) {
|
||||
if (!in_array($key, self::$kSupportedKeys)) {
|
||||
self::errorLog('Unsupported key passed to getPersistentData.');
|
||||
return $default;
|
||||
}
|
||||
|
||||
$session_var_name = $this->constructSessionVariableName($key);
|
||||
return isset($_SESSION[$session_var_name]) ?
|
||||
$_SESSION[$session_var_name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see BaseFacebook::clearPersistentData()
|
||||
*/
|
||||
protected function clearPersistentData($key) {
|
||||
if (!in_array($key, self::$kSupportedKeys)) {
|
||||
self::errorLog('Unsupported key passed to clearPersistentData.');
|
||||
return;
|
||||
}
|
||||
|
||||
$session_var_name = $this->constructSessionVariableName($key);
|
||||
if (isset($_SESSION[$session_var_name])) {
|
||||
unset($_SESSION[$session_var_name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see BaseFacebook::clearAllPersistentData()
|
||||
*/
|
||||
protected function clearAllPersistentData() {
|
||||
foreach (self::$kSupportedKeys as $key) {
|
||||
$this->clearPersistentData($key);
|
||||
}
|
||||
if ($this->sharedSessionID) {
|
||||
$this->deleteSharedSessionCookie();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes Shared session cookie
|
||||
*/
|
||||
protected function deleteSharedSessionCookie() {
|
||||
$cookie_name = $this->getSharedSessionCookieName();
|
||||
unset($_COOKIE[$cookie_name]);
|
||||
$base_domain = $this->getBaseDomain();
|
||||
setcookie($cookie_name, '', 1, '/', '.'.$base_domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Shared session cookie name
|
||||
*
|
||||
* @return string The Shared session cookie name
|
||||
*/
|
||||
protected function getSharedSessionCookieName() {
|
||||
return self::FBSS_COOKIE_NAME . '_' . $this->getAppId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns the name of the session key.
|
||||
*
|
||||
* @see setPersistentData()
|
||||
* @param string $key The key for which the session variable name to construct.
|
||||
*
|
||||
* @return string The name of the session key.
|
||||
*/
|
||||
protected function constructSessionVariableName($key) {
|
||||
$parts = array('fb', $this->getAppId(), $key);
|
||||
if ($this->sharedSessionID) {
|
||||
array_unshift($parts, $this->sharedSessionID);
|
||||
}
|
||||
return implode('_', $parts);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,901 +0,0 @@
|
||||
<?php
|
||||
// http://oauth.googlecode.com/svn/code/php/OAuth.php
|
||||
// rev 1276, July 4, 2014
|
||||
|
||||
// vim: foldmethod=marker
|
||||
|
||||
/* Generic exception class
|
||||
*/
|
||||
if (!class_exists('OAuthException', false)) {
|
||||
class OAuthException extends Exception {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthConsumer {
|
||||
public $key;
|
||||
public $secret;
|
||||
|
||||
function __construct($key, $secret, $callback_url=null) {
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$this->callback_url = $callback_url;
|
||||
}
|
||||
|
||||
function __toString() {
|
||||
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthToken {
|
||||
// access tokens and request tokens
|
||||
public $key;
|
||||
public $secret;
|
||||
|
||||
/**
|
||||
* key = the token
|
||||
* secret = the token secret
|
||||
*/
|
||||
function __construct($key, $secret) {
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates the basic string serialization of a token that a server
|
||||
* would respond to request_token and access_token calls with
|
||||
*/
|
||||
function to_string() {
|
||||
return "oauth_token=" .
|
||||
OAuthUtil::urlencode_rfc3986($this->key) .
|
||||
"&oauth_token_secret=" .
|
||||
OAuthUtil::urlencode_rfc3986($this->secret);
|
||||
}
|
||||
|
||||
function __toString() {
|
||||
return $this->to_string();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class for implementing a Signature Method
|
||||
* See section 9 ("Signing Requests") in the spec
|
||||
*/
|
||||
abstract class OAuthSignatureMethod {
|
||||
/**
|
||||
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_name();
|
||||
|
||||
/**
|
||||
* Build up the signature
|
||||
* NOTE: The output of this function MUST NOT be urlencoded.
|
||||
* the encoding is handled in OAuthRequest when the final
|
||||
* request is serialized
|
||||
* @param OAuthRequest $request
|
||||
* @param OAuthConsumer $consumer
|
||||
* @param OAuthToken $token
|
||||
* @return string
|
||||
*/
|
||||
abstract public function build_signature($request, $consumer, $token);
|
||||
|
||||
/**
|
||||
* Verifies that a given signature is correct
|
||||
* @param OAuthRequest $request
|
||||
* @param OAuthConsumer $consumer
|
||||
* @param OAuthToken $token
|
||||
* @param string $signature
|
||||
* @return bool
|
||||
*/
|
||||
public function check_signature($request, $consumer, $token, $signature) {
|
||||
$built = $this->build_signature($request, $consumer, $token);
|
||||
|
||||
// Check for zero length, although unlikely here
|
||||
if (strlen($built) == 0 || strlen($signature) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strlen($built) != strlen($signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid a timing leak with a (hopefully) time insensitive compare
|
||||
$result = 0;
|
||||
for ($i = 0; $i < strlen($signature); $i++) {
|
||||
$result |= ord($built[$i]) ^ ord($signature[$i]);
|
||||
}
|
||||
|
||||
return $result == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
|
||||
* where the Signature Base String is the text and the key is the concatenated values (each first
|
||||
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
||||
* character (ASCII code 38) even if empty.
|
||||
* - Chapter 9.2 ("HMAC-SHA1")
|
||||
*/
|
||||
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
||||
function get_name() {
|
||||
return "HMAC-SHA1";
|
||||
}
|
||||
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
||||
$key_parts = array(
|
||||
$consumer->secret,
|
||||
($token) ? $token->secret : ""
|
||||
);
|
||||
|
||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
||||
$key = implode('&', $key_parts);
|
||||
|
||||
return base64_encode(hash_hmac('sha1', $base_string, $key, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The PLAINTEXT method does not provide any security protection and SHOULD only be used
|
||||
* over a secure channel such as HTTPS. It does not use the Signature Base String.
|
||||
* - Chapter 9.4 ("PLAINTEXT")
|
||||
*/
|
||||
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
||||
public function get_name() {
|
||||
return "PLAINTEXT";
|
||||
}
|
||||
|
||||
/**
|
||||
* oauth_signature is set to the concatenated encoded values of the Consumer Secret and
|
||||
* Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
|
||||
* empty. The result MUST be encoded again.
|
||||
* - Chapter 9.4.1 ("Generating Signatures")
|
||||
*
|
||||
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
||||
* OAuthRequest handles this!
|
||||
*/
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
$key_parts = array(
|
||||
$consumer->secret,
|
||||
($token) ? $token->secret : ""
|
||||
);
|
||||
|
||||
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
||||
$key = implode('&', $key_parts);
|
||||
$request->base_string = $key;
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
|
||||
* [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
|
||||
* EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
|
||||
* verified way to the Service Provider, in a manner which is beyond the scope of this
|
||||
* specification.
|
||||
* - Chapter 9.3 ("RSA-SHA1")
|
||||
*/
|
||||
abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
||||
public function get_name() {
|
||||
return "RSA-SHA1";
|
||||
}
|
||||
|
||||
// Up to the SP to implement this lookup of keys. Possible ideas are:
|
||||
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
||||
// (2) fetch via http using a url provided by the requester
|
||||
// (3) some sort of specific discovery code based on request
|
||||
//
|
||||
// Either way should return a string representation of the certificate
|
||||
protected abstract function fetch_public_cert(&$request);
|
||||
|
||||
// Up to the SP to implement this lookup of keys. Possible ideas are:
|
||||
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
||||
//
|
||||
// Either way should return a string representation of the certificate
|
||||
protected abstract function fetch_private_cert(&$request);
|
||||
|
||||
public function build_signature($request, $consumer, $token) {
|
||||
$base_string = $request->get_signature_base_string();
|
||||
$request->base_string = $base_string;
|
||||
|
||||
// Fetch the private key cert based on the request
|
||||
$cert = $this->fetch_private_cert($request);
|
||||
|
||||
// Pull the private key ID from the certificate
|
||||
$privatekeyid = openssl_get_privatekey($cert);
|
||||
|
||||
// Sign using the key
|
||||
$ok = openssl_sign($base_string, $signature, $privatekeyid);
|
||||
|
||||
// Release the key resource
|
||||
openssl_free_key($privatekeyid);
|
||||
|
||||
return base64_encode($signature);
|
||||
}
|
||||
|
||||
public function check_signature($request, $consumer, $token, $signature) {
|
||||
$decoded_sig = base64_decode($signature);
|
||||
|
||||
$base_string = $request->get_signature_base_string();
|
||||
|
||||
// Fetch the public key cert based on the request
|
||||
$cert = $this->fetch_public_cert($request);
|
||||
|
||||
// Pull the public key ID from the certificate
|
||||
$publickeyid = openssl_get_publickey($cert);
|
||||
|
||||
// Check the computed signature against the one passed in the query
|
||||
$ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
|
||||
|
||||
// Release the key resource
|
||||
openssl_free_key($publickeyid);
|
||||
|
||||
return $ok == 1;
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthRequest {
|
||||
protected $parameters;
|
||||
protected $http_method;
|
||||
protected $http_url;
|
||||
// for debug purposes
|
||||
public $base_string;
|
||||
public static $version = '1.0';
|
||||
public static $POST_INPUT = 'php://input';
|
||||
|
||||
function __construct($http_method, $http_url, $parameters=null) {
|
||||
$parameters = ($parameters) ? $parameters : array();
|
||||
$parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
|
||||
$this->parameters = $parameters;
|
||||
$this->http_method = $http_method;
|
||||
$this->http_url = $http_url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* attempt to build up a request from what was passed to the server
|
||||
*/
|
||||
public static function from_request($http_method=null, $http_url=null, $parameters=null) {
|
||||
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
|
||||
? 'http'
|
||||
: 'https';
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
|
||||
$scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'];
|
||||
}
|
||||
$http_url = ($http_url) ? $http_url : $scheme .
|
||||
'://' . $_SERVER['SERVER_NAME'] .
|
||||
':' .
|
||||
$_SERVER['SERVER_PORT'] .
|
||||
$_SERVER['REQUEST_URI'];
|
||||
$http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
// We weren't handed any parameters, so let's find the ones relevant to
|
||||
// this request.
|
||||
// If you run XML-RPC or similar you should use this to provide your own
|
||||
// parsed parameter-list
|
||||
if (!$parameters) {
|
||||
// Find request headers
|
||||
$request_headers = OAuthUtil::get_headers();
|
||||
|
||||
// Parse the query-string to find GET parameters
|
||||
$parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
|
||||
|
||||
// It's a POST request of the proper content-type, so parse POST
|
||||
// parameters and add those overriding any duplicates from GET
|
||||
if ($http_method == "POST"
|
||||
&& isset($request_headers['Content-Type'])
|
||||
&& strstr($request_headers['Content-Type'],
|
||||
'application/x-www-form-urlencoded')
|
||||
) {
|
||||
$post_data = OAuthUtil::parse_parameters(
|
||||
file_get_contents(self::$POST_INPUT)
|
||||
);
|
||||
$parameters = array_merge($parameters, $post_data);
|
||||
}
|
||||
|
||||
// We have a Authorization-header with OAuth data. Parse the header
|
||||
// and add those overriding any duplicates from GET or POST
|
||||
if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') {
|
||||
$header_parameters = OAuthUtil::split_header(
|
||||
$request_headers['Authorization']
|
||||
);
|
||||
$parameters = array_merge($parameters, $header_parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* pretty much a helper function to set up the request
|
||||
*/
|
||||
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=null) {
|
||||
$parameters = ($parameters) ? $parameters : array();
|
||||
$defaults = array("oauth_version" => OAuthRequest::$version,
|
||||
"oauth_nonce" => OAuthRequest::generate_nonce(),
|
||||
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
|
||||
"oauth_consumer_key" => $consumer->key);
|
||||
if ($token)
|
||||
$defaults['oauth_token'] = $token->key;
|
||||
|
||||
$parameters = array_merge($defaults, $parameters);
|
||||
|
||||
return new OAuthRequest($http_method, $http_url, $parameters);
|
||||
}
|
||||
|
||||
public function set_parameter($name, $value, $allow_duplicates = true) {
|
||||
if ($allow_duplicates && isset($this->parameters[$name])) {
|
||||
// We have already added parameter(s) with this name, so add to the list
|
||||
if (is_scalar($this->parameters[$name])) {
|
||||
// This is the first duplicate, so transform scalar (string)
|
||||
// into an array so we can add the duplicates
|
||||
$this->parameters[$name] = array($this->parameters[$name]);
|
||||
}
|
||||
|
||||
$this->parameters[$name][] = $value;
|
||||
} else {
|
||||
$this->parameters[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_parameter($name) {
|
||||
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
|
||||
}
|
||||
|
||||
public function get_parameters() {
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
public function unset_parameter($name) {
|
||||
unset($this->parameters[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The request parameters, sorted and concatenated into a normalized string.
|
||||
* @return string
|
||||
*/
|
||||
public function get_signable_parameters() {
|
||||
// Grab all parameters
|
||||
$params = $this->parameters;
|
||||
|
||||
// Remove oauth_signature if present
|
||||
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
|
||||
if (isset($params['oauth_signature'])) {
|
||||
unset($params['oauth_signature']);
|
||||
}
|
||||
|
||||
return OAuthUtil::build_http_query($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base string of this request
|
||||
*
|
||||
* The base string defined as the method, the url
|
||||
* and the parameters (normalized), each urlencoded
|
||||
* and the concated with &.
|
||||
*/
|
||||
public function get_signature_base_string() {
|
||||
$parts = array(
|
||||
$this->get_normalized_http_method(),
|
||||
$this->get_normalized_http_url(),
|
||||
$this->get_signable_parameters()
|
||||
);
|
||||
|
||||
$parts = OAuthUtil::urlencode_rfc3986($parts);
|
||||
|
||||
return implode('&', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* just uppercases the http method
|
||||
*/
|
||||
public function get_normalized_http_method() {
|
||||
return strtoupper($this->http_method);
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the url and rebuilds it to be
|
||||
* scheme://host/path
|
||||
*/
|
||||
public function get_normalized_http_url() {
|
||||
$parts = parse_url($this->http_url);
|
||||
|
||||
$scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
|
||||
$port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
|
||||
$host = (isset($parts['host'])) ? strtolower($parts['host']) : '';
|
||||
$path = (isset($parts['path'])) ? $parts['path'] : '';
|
||||
|
||||
if (($scheme == 'https' && $port != '443')
|
||||
|| ($scheme == 'http' && $port != '80')) {
|
||||
$host = "$host:$port";
|
||||
}
|
||||
return "$scheme://$host$path";
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a url usable for a GET request
|
||||
*/
|
||||
public function to_url() {
|
||||
$post_data = $this->to_postdata();
|
||||
$out = $this->get_normalized_http_url();
|
||||
if ($post_data) {
|
||||
$out .= '?'.$post_data;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* builds the data one would send in a POST request
|
||||
*/
|
||||
public function to_postdata() {
|
||||
return OAuthUtil::build_http_query($this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* builds the Authorization: header
|
||||
*/
|
||||
public function to_header($realm=null) {
|
||||
$first = true;
|
||||
if($realm) {
|
||||
$out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
|
||||
$first = false;
|
||||
} else
|
||||
$out = 'Authorization: OAuth';
|
||||
|
||||
$total = array();
|
||||
foreach ($this->parameters as $k => $v) {
|
||||
if (substr($k, 0, 5) != "oauth") continue;
|
||||
if (is_array($v)) {
|
||||
throw new OAuthException('arrays not supported in headers');
|
||||
}
|
||||
$out .= ($first) ? ' ' : ',';
|
||||
$out .= OAuthUtil::urlencode_rfc3986($k) .
|
||||
'="' .
|
||||
OAuthUtil::urlencode_rfc3986($v) .
|
||||
'"';
|
||||
$first = false;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->to_url();
|
||||
}
|
||||
|
||||
|
||||
public function sign_request($signature_method, $consumer, $token) {
|
||||
$this->set_parameter(
|
||||
"oauth_signature_method",
|
||||
$signature_method->get_name(),
|
||||
false
|
||||
);
|
||||
$signature = $this->build_signature($signature_method, $consumer, $token);
|
||||
$this->set_parameter("oauth_signature", $signature, false);
|
||||
}
|
||||
|
||||
public function build_signature($signature_method, $consumer, $token) {
|
||||
$signature = $signature_method->build_signature($this, $consumer, $token);
|
||||
return $signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* util function: current timestamp
|
||||
*/
|
||||
private static function generate_timestamp() {
|
||||
return time();
|
||||
}
|
||||
|
||||
/**
|
||||
* util function: current nonce
|
||||
*/
|
||||
private static function generate_nonce() {
|
||||
$mt = microtime();
|
||||
$rand = mt_rand();
|
||||
|
||||
return md5($mt . $rand); // md5s look nicer than numbers
|
||||
}
|
||||
}
|
||||
|
||||
class OAuthServer {
|
||||
protected $timestamp_threshold = 300; // in seconds, five minutes
|
||||
protected $version = '1.0'; // hi blaine
|
||||
protected $signature_methods = array();
|
||||
|
||||
protected $data_store;
|
||||
|
||||
function __construct($data_store) {
|
||||
$this->data_store = $data_store;
|
||||
}
|
||||
|
||||
public function add_signature_method($signature_method) {
|
||||
$this->signature_methods[$signature_method->get_name()] =
|
||||
$signature_method;
|
||||
}
|
||||
|
||||
// high level functions
|
||||
|
||||
/**
|
||||
* process a request_token request
|
||||
* returns the request token on success
|
||||
*/
|
||||
public function fetch_request_token(&$request) {
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
||||
// no token required for the initial token request
|
||||
$token = null;
|
||||
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
|
||||
// Rev A change
|
||||
$callback = $request->get_parameter('oauth_callback');
|
||||
$new_token = $this->data_store->new_request_token($consumer, $callback);
|
||||
|
||||
return $new_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* process an access_token request
|
||||
* returns the access token on success
|
||||
*/
|
||||
public function fetch_access_token(&$request) {
|
||||
$this->get_version($request);
|
||||
|
||||
$consumer = $this->get_consumer($request);
|
||||
|
||||
// requires authorized request token
|
||||
$token = $this->get_token($request, $consumer, "request");
|
||||
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
|
||||
// Rev A change
|
||||
$verifier = $request->get_parameter('oauth_verifier');
|
||||
$new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
|
||||
|
||||
return $new_token;
|
||||
}
|
||||
|
||||
/**
|
||||
* verify an api call, checks all the parameters
|
||||
*/
|
||||
public function verify_request(&$request) {
|
||||
$this->get_version($request);
|
||||
$consumer = $this->get_consumer($request);
|
||||
$token = $this->get_token($request, $consumer, "access");
|
||||
$this->check_signature($request, $consumer, $token);
|
||||
return array($consumer, $token);
|
||||
}
|
||||
|
||||
// Internals from here
|
||||
/**
|
||||
* version 1
|
||||
*/
|
||||
private function get_version(&$request) {
|
||||
$version = $request->get_parameter("oauth_version");
|
||||
if (!$version) {
|
||||
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
|
||||
// Chapter 7.0 ("Accessing Protected Ressources")
|
||||
$version = '1.0';
|
||||
}
|
||||
if ($version !== $this->version) {
|
||||
throw new OAuthException("OAuth version '$version' not supported");
|
||||
}
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* figure out the signature with some defaults
|
||||
*/
|
||||
private function get_signature_method($request) {
|
||||
$signature_method = $request instanceof OAuthRequest
|
||||
? $request->get_parameter("oauth_signature_method")
|
||||
: null;
|
||||
|
||||
if (!$signature_method) {
|
||||
// According to chapter 7 ("Accessing Protected Ressources") the signature-method
|
||||
// parameter is required, and we can't just fallback to PLAINTEXT
|
||||
throw new OAuthException('No signature method parameter. This parameter is required');
|
||||
}
|
||||
|
||||
if (!in_array($signature_method,
|
||||
array_keys($this->signature_methods))) {
|
||||
throw new OAuthException(
|
||||
"Signature method '$signature_method' not supported " .
|
||||
"try one of the following: " .
|
||||
implode(", ", array_keys($this->signature_methods))
|
||||
);
|
||||
}
|
||||
return $this->signature_methods[$signature_method];
|
||||
}
|
||||
|
||||
/**
|
||||
* try to find the consumer for the provided request's consumer key
|
||||
*/
|
||||
private function get_consumer($request) {
|
||||
$consumer_key = $request instanceof OAuthRequest
|
||||
? $request->get_parameter("oauth_consumer_key")
|
||||
: null;
|
||||
|
||||
if (!$consumer_key) {
|
||||
throw new OAuthException("Invalid consumer key");
|
||||
}
|
||||
|
||||
$consumer = $this->data_store->lookup_consumer($consumer_key);
|
||||
if (!$consumer) {
|
||||
throw new OAuthException("Invalid consumer");
|
||||
}
|
||||
|
||||
return $consumer;
|
||||
}
|
||||
|
||||
/**
|
||||
* try to find the token for the provided request's token key
|
||||
*/
|
||||
private function get_token($request, $consumer, $token_type="access") {
|
||||
$token_field = $request instanceof OAuthRequest
|
||||
? $request->get_parameter('oauth_token')
|
||||
: null;
|
||||
|
||||
$token = $this->data_store->lookup_token(
|
||||
$consumer, $token_type, $token_field
|
||||
);
|
||||
if (!$token) {
|
||||
throw new OAuthException("Invalid $token_type token: $token_field");
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* all-in-one function to check the signature on a request
|
||||
* should guess the signature method appropriately
|
||||
*/
|
||||
private function check_signature($request, $consumer, $token) {
|
||||
// this should probably be in a different method
|
||||
$timestamp = $request instanceof OAuthRequest
|
||||
? $request->get_parameter('oauth_timestamp')
|
||||
: null;
|
||||
$nonce = $request instanceof OAuthRequest
|
||||
? $request->get_parameter('oauth_nonce')
|
||||
: null;
|
||||
|
||||
$this->check_timestamp($timestamp);
|
||||
$this->check_nonce($consumer, $token, $nonce, $timestamp);
|
||||
|
||||
$signature_method = $this->get_signature_method($request);
|
||||
|
||||
$signature = $request->get_parameter('oauth_signature');
|
||||
$valid_sig = $signature_method->check_signature(
|
||||
$request,
|
||||
$consumer,
|
||||
$token,
|
||||
$signature
|
||||
);
|
||||
|
||||
if (!$valid_sig) {
|
||||
throw new OAuthException("Invalid signature");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check that the timestamp is new enough
|
||||
*/
|
||||
private function check_timestamp($timestamp) {
|
||||
if( ! $timestamp )
|
||||
throw new OAuthException(
|
||||
'Missing timestamp parameter. The parameter is required'
|
||||
);
|
||||
|
||||
// verify that timestamp is recentish
|
||||
$now = time();
|
||||
if (abs($now - $timestamp) > $this->timestamp_threshold) {
|
||||
throw new OAuthException(
|
||||
"Expired timestamp, yours $timestamp, ours $now"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check that the nonce is not repeated
|
||||
*/
|
||||
private function check_nonce($consumer, $token, $nonce, $timestamp) {
|
||||
if( ! $nonce )
|
||||
throw new OAuthException(
|
||||
'Missing nonce parameter. The parameter is required'
|
||||
);
|
||||
|
||||
// verify that the nonce is uniqueish
|
||||
$found = $this->data_store->lookup_nonce(
|
||||
$consumer,
|
||||
$token,
|
||||
$nonce,
|
||||
$timestamp
|
||||
);
|
||||
if ($found) {
|
||||
throw new OAuthException("Nonce already used: $nonce");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OAuthDataStore {
|
||||
function lookup_consumer($consumer_key) {
|
||||
// implement me
|
||||
}
|
||||
|
||||
function lookup_token($consumer, $token_type, $token) {
|
||||
// implement me
|
||||
}
|
||||
|
||||
function lookup_nonce($consumer, $token, $nonce, $timestamp) {
|
||||
// implement me
|
||||
}
|
||||
|
||||
function new_request_token($consumer, $callback = null) {
|
||||
// return a new token attached to this consumer
|
||||
}
|
||||
|
||||
function new_access_token($token, $consumer, $verifier = null) {
|
||||
// return a new access token attached to this consumer
|
||||
// for the user associated with this token if the request token
|
||||
// is authorized
|
||||
// should also invalidate the request token
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OAuthUtil {
|
||||
public static function urlencode_rfc3986($input) {
|
||||
if (is_array($input)) {
|
||||
return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
|
||||
} else if (is_scalar($input)) {
|
||||
return str_replace(
|
||||
'+',
|
||||
' ',
|
||||
str_replace('%7E', '~', rawurlencode($input))
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This decode function isn't taking into consideration the above
|
||||
// modifications to the encoding process. However, this method doesn't
|
||||
// seem to be used anywhere so leaving it as is.
|
||||
public static function urldecode_rfc3986($string) {
|
||||
return urldecode($string);
|
||||
}
|
||||
|
||||
// Utility function for turning the Authorization: header into
|
||||
// parameters, has to do some unescaping
|
||||
// Can filter out any non-oauth parameters if needed (default behaviour)
|
||||
// May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
|
||||
// see http://code.google.com/p/oauth/issues/detail?id=163
|
||||
public static function split_header($header, $only_allow_oauth_parameters = true) {
|
||||
$params = array();
|
||||
if (preg_match_all('/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) {
|
||||
foreach ($matches[1] as $i => $h) {
|
||||
$params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]);
|
||||
}
|
||||
if (isset($params['realm'])) {
|
||||
unset($params['realm']);
|
||||
}
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
|
||||
// helper to try to sort out headers for people who aren't running apache
|
||||
public static function get_headers() {
|
||||
if (function_exists('apache_request_headers')) {
|
||||
// we need this to get the actual Authorization: header
|
||||
// because apache tends to tell us it doesn't exist
|
||||
$headers = apache_request_headers();
|
||||
|
||||
// sanitize the output of apache_request_headers because
|
||||
// we always want the keys to be Cased-Like-This and arh()
|
||||
// returns the headers in the same case as they are in the
|
||||
// request
|
||||
$out = array();
|
||||
foreach ($headers AS $key => $value) {
|
||||
$key = str_replace(
|
||||
" ",
|
||||
"-",
|
||||
ucwords(strtolower(str_replace("-", " ", $key)))
|
||||
);
|
||||
$out[$key] = $value;
|
||||
}
|
||||
} else {
|
||||
// otherwise we don't have apache and are just going to have to hope
|
||||
// that $_SERVER actually contains what we need
|
||||
$out = array();
|
||||
if( isset($_SERVER['CONTENT_TYPE']) )
|
||||
$out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
|
||||
if( isset($_ENV['CONTENT_TYPE']) )
|
||||
$out['Content-Type'] = $_ENV['CONTENT_TYPE'];
|
||||
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
if (substr($key, 0, 5) == "HTTP_") {
|
||||
// this is chaos, basically it is just there to capitalize the first
|
||||
// letter of every word that is not an initial HTTP and strip HTTP
|
||||
// code from przemek
|
||||
$key = str_replace(
|
||||
" ",
|
||||
"-",
|
||||
ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
|
||||
);
|
||||
$out[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
// This function takes a input like a=b&a=c&d=e and returns the parsed
|
||||
// parameters like this
|
||||
// array('a' => array('b','c'), 'd' => 'e')
|
||||
public static function parse_parameters( $input ) {
|
||||
if (!isset($input) || !$input) return array();
|
||||
|
||||
$pairs = explode('&', $input);
|
||||
|
||||
$parsed_parameters = array();
|
||||
foreach ($pairs as $pair) {
|
||||
$split = explode('=', $pair, 2);
|
||||
$parameter = OAuthUtil::urldecode_rfc3986($split[0]);
|
||||
$value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
|
||||
|
||||
if (isset($parsed_parameters[$parameter])) {
|
||||
// We have already recieved parameter(s) with this name, so add to the list
|
||||
// of parameters with this name
|
||||
|
||||
if (is_scalar($parsed_parameters[$parameter])) {
|
||||
// This is the first duplicate, so transform scalar (string) into an array
|
||||
// so we can add the duplicates
|
||||
$parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
|
||||
}
|
||||
|
||||
$parsed_parameters[$parameter][] = $value;
|
||||
} else {
|
||||
$parsed_parameters[$parameter] = $value;
|
||||
}
|
||||
}
|
||||
return $parsed_parameters;
|
||||
}
|
||||
|
||||
public static function build_http_query($params) {
|
||||
if (!$params) return '';
|
||||
|
||||
// Urlencode both keys and values
|
||||
$keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
|
||||
$values = OAuthUtil::urlencode_rfc3986(array_values($params));
|
||||
$params = array_combine($keys, $values);
|
||||
|
||||
// Parameters are sorted by name, using lexicographical byte value ordering.
|
||||
// Ref: Spec: 9.1.1 (1)
|
||||
uksort($params, 'strcmp');
|
||||
|
||||
$pairs = array();
|
||||
foreach ($params as $parameter => $value) {
|
||||
if (is_array($value)) {
|
||||
// If two or more parameters share the same name, they are sorted by their value
|
||||
// Ref: Spec: 9.1.1 (1)
|
||||
// June 12th, 2010 - changed to sort because of issue 164 by hidetaka
|
||||
sort($value, SORT_STRING);
|
||||
foreach ($value as $duplicate_value) {
|
||||
$pairs[] = $parameter . '=' . $duplicate_value;
|
||||
}
|
||||
} else {
|
||||
$pairs[] = $parameter . '=' . $value;
|
||||
}
|
||||
}
|
||||
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
|
||||
// Each name-value pair is separated by an '&' character (ASCII code 38)
|
||||
return implode('&', $pairs);
|
||||
}
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2014, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
// A service client for the OAuth 1/1.0a flow.
|
||||
// v0.1
|
||||
class OAuth1Client{
|
||||
public $api_base_url = "";
|
||||
public $authorize_url = "";
|
||||
public $authenticate_url = "";
|
||||
public $request_token_url = "";
|
||||
public $access_token_url = "";
|
||||
|
||||
public $request_token_method = "GET";
|
||||
public $access_token_method = "GET";
|
||||
|
||||
public $redirect_uri = "";
|
||||
|
||||
public $decode_json = true;
|
||||
public $curl_time_out = 30;
|
||||
public $curl_connect_time_out = 30;
|
||||
public $curl_ssl_verifypeer = false;
|
||||
public $curl_auth_header = true;
|
||||
public $curl_useragent = "OAuth/1 Simple PHP Client v0.1; HybridAuth http://hybridauth.sourceforge.net/";
|
||||
public $curl_proxy = null;
|
||||
|
||||
//--
|
||||
|
||||
public $http_code = "";
|
||||
public $http_info = "";
|
||||
protected $response = null;
|
||||
|
||||
/**
|
||||
* OAuth client constructor
|
||||
*/
|
||||
function __construct( $consumer_key, $consumer_secret, $oauth_token = null, $oauth_token_secret = null )
|
||||
{
|
||||
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
$this->consumer = new OAuthConsumer( $consumer_key, $consumer_secret );
|
||||
$this->token = null;
|
||||
|
||||
if ( $oauth_token && $oauth_token_secret ){
|
||||
$this->token = new OAuthConsumer( $oauth_token, $oauth_token_secret );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build authorize url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function authorizeUrl( $token, $extras =array() )
|
||||
{
|
||||
if ( is_array( $token ) ){
|
||||
$token = $token['oauth_token'];
|
||||
}
|
||||
|
||||
$parameters = array( "oauth_token" => $token );
|
||||
|
||||
if( count($extras) )
|
||||
foreach( $extras as $k=>$v )
|
||||
$parameters[$k] = $v;
|
||||
|
||||
return $this->authorize_url . "?" . http_build_query( $parameters );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a request_token from provider
|
||||
*
|
||||
* @return array a key/value array containing oauth_token and oauth_token_secret
|
||||
*/
|
||||
function requestToken( $callback = null )
|
||||
{
|
||||
$parameters = array();
|
||||
|
||||
if ( $callback ) {
|
||||
$this->redirect_uri = $parameters['oauth_callback'] = $callback;
|
||||
}
|
||||
|
||||
$request = $this->signedRequest( $this->request_token_url, $this->request_token_method, $parameters );
|
||||
$token = OAuthUtil::parse_parameters( $request );
|
||||
$this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange the request token and secret for an access token and secret, to sign API calls.
|
||||
*
|
||||
* @return array array('oauth_token' => the access token, 'oauth_token_secret' => the access secret)
|
||||
*/
|
||||
function accessToken( $oauth_verifier = false, $oauth_token = false )
|
||||
{
|
||||
$parameters = array();
|
||||
|
||||
// 1.0a
|
||||
if ( $oauth_verifier ) {
|
||||
$parameters['oauth_verifier'] = $oauth_verifier;
|
||||
}
|
||||
|
||||
$request = $this->signedRequest( $this->access_token_url, $this->access_token_method, $parameters );
|
||||
$token = OAuthUtil::parse_parameters( $request );
|
||||
$this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET wrapper for provider apis request
|
||||
*/
|
||||
function get($url, $parameters = array(), $content_type = null)
|
||||
{
|
||||
return $this->api($url, 'GET', $parameters, null, $content_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST wrapper for provider apis request
|
||||
*/
|
||||
function post($url, $parameters = array(), $body = null, $content_type = null, $multipart = false)
|
||||
{
|
||||
return $this->api($url, 'POST', $parameters, $body, $content_type, $multipart );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and sign an oauth for provider api
|
||||
*/
|
||||
function api( $url, $method = 'GET', $parameters = array(), $body = null, $content_type = null, $multipart = false )
|
||||
{
|
||||
if ( strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0 ) {
|
||||
$url = $this->api_base_url . $url;
|
||||
}
|
||||
|
||||
$response = $this->signedRequest( $url, $method, $parameters, $body, $content_type, $multipart );
|
||||
|
||||
if( $this->decode_json ){
|
||||
$response = json_decode( $response );
|
||||
}
|
||||
|
||||
return $this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the response object afer the fact
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make signed request
|
||||
*/
|
||||
function signedRequest( $url, $method, $parameters, $body = null, $content_type = null, $multipart = false )
|
||||
{
|
||||
|
||||
$signature_parameters = array();
|
||||
|
||||
// when making a multipart request, use only oauth_* keys for signature
|
||||
foreach( $parameters AS $key => $value ){
|
||||
if( !$multipart || strpos( $key, 'oauth_' ) === 0 ){
|
||||
$signature_parameters[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $signature_parameters);
|
||||
$request->sign_request($this->sha1_method, $this->consumer, $this->token);
|
||||
switch ($method) {
|
||||
case 'GET': return $this->request( $request->to_url(), 'GET', null, null, $content_type );
|
||||
default :
|
||||
if ($body)
|
||||
return $this->request( $request->to_url(), $method, $body, $request->to_header(), $content_type );
|
||||
else
|
||||
return $this->request( $request->get_normalized_http_url(), $method, ($multipart ? $parameters : $request->to_postdata()), $request->to_header(), $content_type, $multipart ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make http request
|
||||
*/
|
||||
function request( $url, $method, $postfields = null, $auth_header = null, $content_type = null, $multipart = false )
|
||||
{
|
||||
Hybrid_Logger::info( "Enter OAuth1Client::request( $method, $url )" );
|
||||
Hybrid_Logger::debug( "OAuth1Client::request(). dump post fields: ", serialize( $postfields ) );
|
||||
|
||||
$this->http_info = array();
|
||||
$ci = curl_init();
|
||||
|
||||
/* Curl settings */
|
||||
curl_setopt( $ci, CURLOPT_USERAGENT , $this->curl_useragent );
|
||||
curl_setopt( $ci, CURLOPT_CONNECTTIMEOUT, $this->curl_connect_time_out );
|
||||
curl_setopt( $ci, CURLOPT_TIMEOUT , $this->curl_time_out );
|
||||
curl_setopt( $ci, CURLOPT_RETURNTRANSFER, true );
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER , array('Expect:') );
|
||||
curl_setopt( $ci, CURLOPT_SSL_VERIFYPEER, $this->curl_ssl_verifypeer );
|
||||
curl_setopt( $ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader') );
|
||||
curl_setopt( $ci, CURLOPT_HEADER , false );
|
||||
|
||||
if( $multipart ){
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER, array( 'Expect:', $auth_header ) );
|
||||
|
||||
}elseif ($content_type)
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER, array('Expect:', "Content-Type: $content_type") );
|
||||
|
||||
if($this->curl_proxy){
|
||||
curl_setopt( $ci, CURLOPT_PROXY , $this->curl_proxy);
|
||||
}
|
||||
|
||||
switch ($method){
|
||||
case 'POST':
|
||||
curl_setopt( $ci, CURLOPT_POST, true );
|
||||
|
||||
if ( !empty($postfields) ){
|
||||
curl_setopt( $ci, CURLOPT_POSTFIELDS, $postfields );
|
||||
}
|
||||
|
||||
if ( !empty($auth_header) && $this->curl_auth_header && !$multipart ){
|
||||
curl_setopt( $ci, CURLOPT_HTTPHEADER, array( 'Content-Type: application/atom+xml', $auth_header ) );
|
||||
}
|
||||
break;
|
||||
case 'DELETE':
|
||||
curl_setopt( $ci, CURLOPT_CUSTOMREQUEST, 'DELETE' );
|
||||
if ( !empty($postfields) ){
|
||||
$url = "{$url}?{$postfields}";
|
||||
}
|
||||
}
|
||||
|
||||
curl_setopt($ci, CURLOPT_URL, $url);
|
||||
$response = curl_exec($ci);
|
||||
if( $response === false ) {
|
||||
Hybrid_Logger::error( "OAuth1Client::request(). curl_exec error: ", curl_error($ci) );
|
||||
}
|
||||
|
||||
|
||||
Hybrid_Logger::debug( "OAuth1Client::request(). dump request info: ", serialize( curl_getinfo($ci) ) );
|
||||
Hybrid_Logger::debug( "OAuth1Client::request(). dump request result: ", serialize( $response ) );
|
||||
|
||||
$this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
|
||||
$this->http_info = array_merge($this->http_info, curl_getinfo($ci));
|
||||
|
||||
curl_close ($ci);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the header info to store.
|
||||
*/
|
||||
function getHeader($ch, $header) {
|
||||
$i = strpos($header, ':');
|
||||
|
||||
if ( !empty($i) ){
|
||||
$key = str_replace('-', '_', strtolower(substr($header, 0, $i)));
|
||||
$value = trim(substr($header, $i + 2));
|
||||
$this->http_header[$key] = $value;
|
||||
}
|
||||
|
||||
return strlen($header);
|
||||
}
|
||||
}
|
@ -1,302 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
// A service client for the OAuth 2 flow.
|
||||
// v0.1.1
|
||||
class OAuth2Client
|
||||
{
|
||||
public $api_base_url = "";
|
||||
public $authorize_url = "";
|
||||
public $token_url = "";
|
||||
public $token_info_url = "";
|
||||
|
||||
public $client_id = "" ;
|
||||
public $client_secret = "" ;
|
||||
public $redirect_uri = "" ;
|
||||
public $access_token = "" ;
|
||||
public $refresh_token = "" ;
|
||||
|
||||
public $access_token_expires_in = "" ;
|
||||
public $access_token_expires_at = "" ;
|
||||
|
||||
//--
|
||||
|
||||
public $sign_token_name = "access_token";
|
||||
public $curl_time_out = 30;
|
||||
public $curl_connect_time_out = 30;
|
||||
public $curl_ssl_verifypeer = false;
|
||||
public $curl_ssl_verifyhost = false;
|
||||
public $curl_header = array();
|
||||
public $curl_useragent = "OAuth/2 Simple PHP Client v0.1.1; HybridAuth http://hybridauth.sourceforge.net/";
|
||||
public $curl_authenticate_method = "POST";
|
||||
public $curl_proxy = null;
|
||||
public $curl_compressed = false;
|
||||
//--
|
||||
|
||||
public $http_code = "";
|
||||
public $http_info = "";
|
||||
protected $response = null;
|
||||
|
||||
//--
|
||||
|
||||
public function __construct( $client_id = false, $client_secret = false, $redirect_uri='', $compressed = false )
|
||||
{
|
||||
$this->client_id = $client_id;
|
||||
$this->client_secret = $client_secret;
|
||||
$this->redirect_uri = $redirect_uri;
|
||||
$this->curl_compressed = $compressed;
|
||||
}
|
||||
|
||||
public function authorizeUrl( $extras = array() )
|
||||
{
|
||||
$params = array(
|
||||
"client_id" => $this->client_id,
|
||||
"redirect_uri" => $this->redirect_uri,
|
||||
"response_type" => "code"
|
||||
);
|
||||
|
||||
if( count($extras) )
|
||||
foreach( $extras as $k=>$v )
|
||||
$params[$k] = $v;
|
||||
|
||||
return $this->authorize_url . "?" . http_build_query($params, '', '&');
|
||||
}
|
||||
|
||||
public function authenticate( $code )
|
||||
{
|
||||
$params = array(
|
||||
"client_id" => $this->client_id,
|
||||
"client_secret" => $this->client_secret,
|
||||
"grant_type" => "authorization_code",
|
||||
"redirect_uri" => $this->redirect_uri,
|
||||
"code" => $code
|
||||
);
|
||||
|
||||
$response = $this->request( $this->token_url, $params, $this->curl_authenticate_method );
|
||||
|
||||
$response = $this->parseRequestResult( $response );
|
||||
|
||||
if( ! $response || ! isset( $response->access_token ) ){
|
||||
throw new Exception( "The Authorization Service has return: " . $response->error );
|
||||
}
|
||||
|
||||
if( isset( $response->access_token ) ) $this->access_token = $response->access_token;
|
||||
if( isset( $response->refresh_token ) ) $this->refresh_token = $response->refresh_token;
|
||||
if( isset( $response->expires_in ) ) $this->access_token_expires_in = $response->expires_in;
|
||||
|
||||
// calculate when the access token expire
|
||||
if( isset($response->expires_in)) {
|
||||
$this->access_token_expires_at = time() + $response->expires_in;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function authenticated()
|
||||
{
|
||||
if ( $this->access_token ){
|
||||
if ( $this->token_info_url && $this->refresh_token ){
|
||||
// check if this access token has expired,
|
||||
$tokeninfo = $this->tokenInfo( $this->access_token );
|
||||
|
||||
// if yes, access_token has expired, then ask for a new one
|
||||
if( $tokeninfo && isset( $tokeninfo->error ) ){
|
||||
$response = $this->refreshToken( $this->refresh_token );
|
||||
|
||||
// if wrong response
|
||||
if( ! isset( $response->access_token ) || ! $response->access_token ){
|
||||
throw new Exception( "The Authorization Service has return an invalid response while requesting a new access token. given up!" );
|
||||
}
|
||||
|
||||
// set new access_token
|
||||
$this->access_token = $response->access_token;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format and sign an oauth for provider api
|
||||
*/
|
||||
public function api( $url, $method = "GET", $parameters = array(), $decode_json = true )
|
||||
{
|
||||
if ( strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0 ) {
|
||||
$url = $this->api_base_url . $url;
|
||||
}
|
||||
|
||||
$parameters[$this->sign_token_name] = $this->access_token;
|
||||
$response = null;
|
||||
|
||||
switch( $method ){
|
||||
case 'GET' : $response = $this->request( $url, $parameters, "GET" ); break;
|
||||
case 'POST' : $response = $this->request( $url, $parameters, "POST" ); break;
|
||||
case 'DELETE' : $response = $this->request( $url, $parameters, "DELETE" ); break;
|
||||
case 'PATCH' : $response = $this->request( $url, $parameters, "PATCH" ); break;
|
||||
}
|
||||
|
||||
if( $response && $decode_json ){
|
||||
return $this->response = json_decode( $response );
|
||||
}
|
||||
|
||||
return $this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the response object afer the fact
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET wrapper for provider apis request
|
||||
*/
|
||||
function get( $url, $parameters = array(), $decode_json = true )
|
||||
{
|
||||
return $this->api( $url, 'GET', $parameters, $decode_json );
|
||||
}
|
||||
|
||||
/**
|
||||
* POST wrapper for provider apis request
|
||||
*/
|
||||
function post( $url, $parameters = array(), $decode_json = true )
|
||||
{
|
||||
return $this->api( $url, 'POST', $parameters, $decode_json );
|
||||
}
|
||||
|
||||
// -- tokens
|
||||
|
||||
public function tokenInfo($accesstoken)
|
||||
{
|
||||
$params['access_token'] = $this->access_token;
|
||||
$response = $this->request( $this->token_info_url, $params );
|
||||
return $this->parseRequestResult( $response );
|
||||
}
|
||||
|
||||
public function refreshToken( $parameters = array() )
|
||||
{
|
||||
$params = array(
|
||||
"client_id" => $this->client_id,
|
||||
"client_secret" => $this->client_secret,
|
||||
"grant_type" => "refresh_token"
|
||||
);
|
||||
|
||||
foreach($parameters as $k=>$v ){
|
||||
$params[$k] = $v;
|
||||
}
|
||||
|
||||
$response = $this->request( $this->token_url, $params, "POST" );
|
||||
return $this->parseRequestResult( $response );
|
||||
}
|
||||
|
||||
// -- utilities
|
||||
|
||||
private function request( $url, $params=false, $type="GET" )
|
||||
{
|
||||
Hybrid_Logger::info( "Enter OAuth2Client::request( $url )" );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request params: ", serialize( $params ) );
|
||||
|
||||
$urlEncodedParams = http_build_query($params, '', '&');
|
||||
|
||||
if( $type == "GET" ){
|
||||
$url = $url . ( strpos( $url, '?' ) ? '&' : '?' ) . $urlEncodedParams;
|
||||
}
|
||||
|
||||
$this->http_info = array();
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL , $url );
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 );
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT , $this->curl_time_out );
|
||||
curl_setopt($ch, CURLOPT_USERAGENT , $this->curl_useragent );
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT , $this->curl_connect_time_out );
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER , $this->curl_ssl_verifypeer );
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST , $this->curl_ssl_verifyhost );
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER , $this->curl_header );
|
||||
|
||||
if ($this->curl_compressed){
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
|
||||
}
|
||||
|
||||
if($this->curl_proxy){
|
||||
curl_setopt( $ch, CURLOPT_PROXY , $this->curl_proxy);
|
||||
}
|
||||
|
||||
if ($type == "POST") {
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
|
||||
// If request body exists then encode it for "application/json".
|
||||
if (isset($params['body'])) {
|
||||
$urlEncodedParams = json_encode($params['body']);
|
||||
}
|
||||
|
||||
// Using URL encoded params here instead of a more convenient array
|
||||
// cURL will set a wrong HTTP Content-Type header if using an array (cf. http://www.php.net/manual/en/function.curl-setopt.php, Notes section for "CURLOPT_POSTFIELDS")
|
||||
// OAuth requires application/x-www-form-urlencoded Content-Type (cf. https://tools.ietf.org/html/rfc6749#section-2.3.1)
|
||||
if ($params) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $urlEncodedParams);
|
||||
}
|
||||
}
|
||||
|
||||
if( $type == "DELETE" ){
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
}
|
||||
if( $type == "PATCH" ){
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
if($params) curl_setopt( $ch, CURLOPT_POSTFIELDS, $params );
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
}
|
||||
$response = curl_exec($ch);
|
||||
if( $response === false ) {
|
||||
Hybrid_Logger::error( "OAuth2Client::request(). curl_exec error: ", curl_error($ch) );
|
||||
}
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request info: ", serialize( curl_getinfo($ch) ) );
|
||||
Hybrid_Logger::debug( "OAuth2Client::request(). dump request result: ", serialize( $response ) );
|
||||
|
||||
$this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$this->http_info = array_merge($this->http_info, curl_getinfo($ch));
|
||||
|
||||
curl_close ($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function parseRequestResult( $result )
|
||||
{
|
||||
if( json_decode( $result ) ) return json_decode( $result );
|
||||
|
||||
parse_str( $result, $output );
|
||||
|
||||
$result = new StdClass();
|
||||
|
||||
foreach( $output as $k => $v )
|
||||
$result->$k = $v;
|
||||
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* DELETE wrapper for provider apis request
|
||||
*/
|
||||
function delete( $url, $parameters = array() )
|
||||
{
|
||||
return $this->api( $url, 'DELETE', $parameters );
|
||||
}
|
||||
/**
|
||||
* PATCH wrapper for provider apis request
|
||||
*/
|
||||
function patch( $url, $parameters = array() )
|
||||
{
|
||||
return $this->api( $url, 'PATCH', $parameters );
|
||||
}
|
||||
}
|
@ -1,194 +0,0 @@
|
||||
<?php
|
||||
// OAuthWrapHandler.php 1.1
|
||||
|
||||
/**
|
||||
* FILE: OAuthWrapHandler.php
|
||||
*
|
||||
* DESCRIPTION: Sample implementation of OAuth WRAP Authentication protocol.
|
||||
*
|
||||
* VERSION: 1.1
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* OAuthWrapHandler
|
||||
* This handler is used to both process the raw HTTP requests that generate the
|
||||
* required cookies for the Windows Live javascript control to work within a
|
||||
* php applicaiton.
|
||||
*/
|
||||
class OAuthWrapHandler
|
||||
{
|
||||
public function ProcessRequest()
|
||||
{
|
||||
$this->ExpireCookies();
|
||||
$cookies_setup = $this->convertParamsToCookies($_REQUEST);
|
||||
if(isset($cookies_setup['verification_code']))
|
||||
{
|
||||
$auth_params = $this->getAuthorizationToken(
|
||||
WRAP_ACCESS_URL
|
||||
, WRAP_CLIENT_ID
|
||||
, WRAP_CLIENT_SECRET
|
||||
, WRAP_CALLBACK
|
||||
, $cookies_setup['verification_code']
|
||||
);
|
||||
|
||||
unset($cookies_setup['verification_code']);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("No verification Code returned from Windows Live Services.");
|
||||
}
|
||||
|
||||
$cookies_auth = $this->convertParamsToCookies($auth_params);
|
||||
$cookies = array_merge($cookies_setup, $cookies_auth);
|
||||
$this->setAuthCookies($cookies);
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
public function ExpireCookies()
|
||||
{
|
||||
setcookie ("c_accessToken", "", time() - 3600);
|
||||
setcookie ("c_clientId", "", time() - 3600);
|
||||
setcookie ("c_clientState", "", time() - 3600);
|
||||
setcookie ("c_scope", "", time() - 3600);
|
||||
setcookie ("c_error", "", time() - 3600);
|
||||
setcookie ("c_uid", "", time() - 3600);
|
||||
setcookie ("c_expiry", "", time() - 3600);
|
||||
setcookie ("lca", "", time() - 3600);
|
||||
}
|
||||
|
||||
private function setAuthCookies($cookies)
|
||||
{
|
||||
foreach($cookies as $key => $value)
|
||||
{
|
||||
setcookie ($key, $value, time() + 36000);
|
||||
}
|
||||
setcookie ('c_clientId', WRAP_CLIENT_ID, time() + 36000); //clientID == appId
|
||||
setcookie ('lca', 'done', time() + 36000); //lca //done
|
||||
}
|
||||
|
||||
private function convertParamsToCookies($array)
|
||||
{
|
||||
$cookies = array();
|
||||
|
||||
foreach(array_keys($array) as $getParam)
|
||||
{
|
||||
$getParam = urldecode($getParam);
|
||||
switch($getParam)
|
||||
{
|
||||
case 'wrap_client_state':
|
||||
$cookies['c_clientState'] = $array['wrap_client_state'];
|
||||
break;
|
||||
case 'wrap_verification_code':
|
||||
$cookies['verification_code'] = $array['wrap_verification_code'];
|
||||
break;
|
||||
case 'exp': //scope
|
||||
$cookies['c_scope'] = str_replace(';', ',',$array['exp']);
|
||||
break;
|
||||
case 'error_code':
|
||||
$cookies['c_error'] = ' ' . $array['error_code'];
|
||||
break;
|
||||
case 'wrap_error_reason':
|
||||
$cookies['c_error'] = ' ' . $array['wrap_error_reason'];
|
||||
break;
|
||||
case 'wrap_access_token':
|
||||
$cookies['c_accessToken']= $array['wrap_access_token'];
|
||||
break;
|
||||
case 'wrap_access_token_expires_in':
|
||||
$cookies['c_expiry']= date('j/m/Y g:i:s A', $array['wrap_access_token_expires_in']);
|
||||
break;
|
||||
case 'uid':
|
||||
$cookies['c_uid']= $array['uid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
private function getAuthorizationToken($authUrl, $appId, $appSecret, $callbackUrl, $verificationCode)
|
||||
{
|
||||
$tokenRequest = 'wrap_client_id=' . urlencode($appId)
|
||||
. '&wrap_client_secret=' . urlencode($appSecret)
|
||||
. '&wrap_callback=' . urlencode($callbackUrl)
|
||||
. '&wrap_verification_code=' . urlencode($verificationCode);
|
||||
$response = $this->postWRAPRequest($authUrl, $tokenRequest);
|
||||
return $this->parseWRAPResponse($response);
|
||||
}
|
||||
|
||||
private function postWRAPRequest($posturl, $postvars)
|
||||
{
|
||||
$ch = curl_init($posturl);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
|
||||
@ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$Rec_Data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return urldecode($Rec_Data);
|
||||
}
|
||||
|
||||
private function parseWRAPResponse($response)
|
||||
{
|
||||
$pos = strpos($response, 'wrap_access_token=');
|
||||
if ($pos === false)
|
||||
{
|
||||
$pos = strpos($response, 'wrap_error_reason=');
|
||||
}
|
||||
$codes = '?' . substr($response, $pos, strlen($response));
|
||||
|
||||
if (preg_match_all('/[?&]([^&=]+)=([^&=]+)/', $codes, $matches))
|
||||
{
|
||||
for($i =0; $i < count($matches[1]); $i++)
|
||||
{
|
||||
$contents[$matches[1][$i]] = $matches[2][$i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception('No matches for regular expression.');
|
||||
}
|
||||
return $contents;
|
||||
}
|
||||
|
||||
public function GET($url,$params=false,$auth=false){
|
||||
|
||||
$url = $this->MakeUrl($url,$params);
|
||||
// borrowed from Andy Langton: http://andylangton.co.uk/
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL,$url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
|
||||
|
||||
curl_setopt($ch,CURLOPT_HTTPHEADER,array (
|
||||
"Authorization: WRAP access_token=$auth",
|
||||
"Content-Type: application/json",
|
||||
"Accept: application/json"
|
||||
));
|
||||
|
||||
if ( isset($_SERVER['HTTP_USER_AGENT']) ) {
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] );
|
||||
}else {
|
||||
// Handle the useragent like we are Google Chrome
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.X.Y.Z Safari/525.13.');
|
||||
}
|
||||
curl_setopt($ch , CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$result=curl_exec($ch);
|
||||
$info=curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function MakeUrl($url,$params){
|
||||
if(!empty($params) && $params){
|
||||
foreach($params as $k=>$v) $kv[] = "$k=$v";
|
||||
$url_params = str_replace(" ","+",implode('&',$kv));
|
||||
$url = trim($url) . '?' . $url_params;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// HybridAuth End Point
|
||||
// ------------------------------------------------------------------------
|
||||
require_once("../../class2.php");
|
||||
require_once( "Hybrid/Auth.php" );
|
||||
require_once( "Hybrid/Endpoint.php" );
|
||||
require_once("vendor/autoload.php");
|
||||
|
||||
Hybrid_Endpoint::process();
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* HybridAuth
|
||||
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||||
* (c) 2009-2015, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
|
||||
*/
|
||||
// ------------------------------------------------------------------------
|
||||
// HybridAuth End Point
|
||||
// ------------------------------------------------------------------------
|
||||
$_REQUEST['hauth_done'] = 'Live';
|
||||
require_once( "Hybrid/Auth.php" );
|
||||
require_once( "Hybrid/Endpoint.php" );
|
||||
Hybrid_Endpoint::process();
|
7
e107_handlers/hybridauth/vendor/autoload.php
vendored
7
e107_handlers/hybridauth/vendor/autoload.php
vendored
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit511ca3f38d99caa04d5c2a22fdfca775::getLoader();
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Hybrid_Auth' => $baseDir . '/hybridauth/Hybrid/Auth.php',
|
||||
'Hybrid_Endpoint' => $baseDir . '/hybridauth/Hybrid/Endpoint.php',
|
||||
'Hybrid_Error' => $baseDir . '/hybridauth/Hybrid/Error.php',
|
||||
'Hybrid_Exception' => $baseDir . '/hybridauth/Hybrid/Exception.php',
|
||||
'Hybrid_Logger' => $baseDir . '/hybridauth/Hybrid/Logger.php',
|
||||
'Hybrid_Provider_Adapter' => $baseDir . '/hybridauth/Hybrid/Provider_Adapter.php',
|
||||
'Hybrid_Provider_Model' => $baseDir . '/hybridauth/Hybrid/Provider_Model.php',
|
||||
'Hybrid_Provider_Model_OAuth1' => $baseDir . '/hybridauth/Hybrid/Provider_Model_OAuth1.php',
|
||||
'Hybrid_Provider_Model_OAuth2' => $baseDir . '/hybridauth/Hybrid/Provider_Model_OAuth2.php',
|
||||
'Hybrid_Provider_Model_OpenID' => $baseDir . '/hybridauth/Hybrid/Provider_Model_OpenID.php',
|
||||
'Hybrid_Providers_AOL' => $baseDir . '/hybridauth/Hybrid/Providers/AOL.php',
|
||||
'Hybrid_Providers_Facebook' => $baseDir . '/hybridauth/Hybrid/Providers/Facebook.php',
|
||||
'Hybrid_Providers_Foursquare' => $baseDir . '/hybridauth/Hybrid/Providers/Foursquare.php',
|
||||
'Hybrid_Providers_Google' => $baseDir . '/hybridauth/Hybrid/Providers/Google.php',
|
||||
'Hybrid_Providers_LinkedIn' => $baseDir . '/hybridauth/Hybrid/Providers/LinkedIn.php',
|
||||
'Hybrid_Providers_Live' => $baseDir . '/hybridauth/Hybrid/Providers/Live.php',
|
||||
'Hybrid_Providers_OpenID' => $baseDir . '/hybridauth/Hybrid/Providers/OpenID.php',
|
||||
'Hybrid_Providers_Twitter' => $baseDir . '/hybridauth/Hybrid/Providers/Twitter.php',
|
||||
'Hybrid_Providers_Yahoo' => $baseDir . '/hybridauth/Hybrid/Providers/Yahoo.php',
|
||||
'Hybrid_Storage' => $baseDir . '/hybridauth/Hybrid/Storage.php',
|
||||
'Hybrid_Storage_Interface' => $baseDir . '/hybridauth/Hybrid/StorageInterface.php',
|
||||
'Hybrid_User' => $baseDir . '/hybridauth/Hybrid/User.php',
|
||||
'Hybrid_User_Activity' => $baseDir . '/hybridauth/Hybrid/User_Activity.php',
|
||||
'Hybrid_User_Contact' => $baseDir . '/hybridauth/Hybrid/User_Contact.php',
|
||||
'Hybrid_User_Profile' => $baseDir . '/hybridauth/Hybrid/User_Profile.php',
|
||||
'LightOpenID' => $baseDir . '/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php',
|
||||
'OAuth1Client' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth1Client.php',
|
||||
'OAuth2Client' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth2Client.php',
|
||||
'OAuthConsumer' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthDataStore' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthException' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthRequest' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthServer' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthSignatureMethod' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthSignatureMethod_HMAC_SHA1' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthSignatureMethod_PLAINTEXT' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthSignatureMethod_RSA_SHA1' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthToken' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
'OAuthUtil' => $baseDir . '/hybridauth/Hybrid/thirdparty/OAuth/OAuth.php',
|
||||
);
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'c65d09b6820da036953a371c8c73a9b1' => $vendorDir . '/facebook/graph-sdk/src/Facebook/polyfills.php',
|
||||
);
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Facebook\\' => array($vendorDir . '/facebook/graph-sdk/src/Facebook'),
|
||||
);
|
@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit511ca3f38d99caa04d5c2a22fdfca775
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit511ca3f38d99caa04d5c2a22fdfca775', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit511ca3f38d99caa04d5c2a22fdfca775', 'loadClassLoader'));
|
||||
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire511ca3f38d99caa04d5c2a22fdfca775($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequire511ca3f38d99caa04d5c2a22fdfca775($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "facebook/graph-sdk",
|
||||
"version": "5.6.1",
|
||||
"version_normalized": "5.6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/php-graph-sdk.git",
|
||||
"reference": "2f9639c15ae043911f40ffe44080b32bac2c5280"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facebook/php-graph-sdk/zipball/2f9639c15ae043911f40ffe44080b32bac2c5280",
|
||||
"reference": "2f9639c15ae043911f40ffe44080b32bac2c5280",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.4|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "~5.0",
|
||||
"mockery/mockery": "~0.8",
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"guzzlehttp/guzzle": "Allows for implementation of the Guzzle HTTP client",
|
||||
"paragonie/random_compat": "Provides a better CSPRNG option in PHP 5"
|
||||
},
|
||||
"time": "2017-08-16 17:28:07",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facebook\\": "src/Facebook/"
|
||||
},
|
||||
"files": [
|
||||
"src/Facebook/polyfills.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Facebook Platform"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Facebook",
|
||||
"homepage": "https://github.com/facebook/php-graph-sdk/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Facebook SDK for PHP",
|
||||
"homepage": "https://github.com/facebook/php-graph-sdk",
|
||||
"keywords": [
|
||||
"facebook",
|
||||
"sdk"
|
||||
]
|
||||
}
|
||||
]
|
@ -1,19 +0,0 @@
|
||||
Copyright 2017 Facebook, Inc.
|
||||
|
||||
You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
use, copy, modify, and distribute this software in source code or binary
|
||||
form for use in connection with the web services and APIs provided by
|
||||
Facebook.
|
||||
|
||||
As with any software that integrates with the Facebook platform, your use
|
||||
of this software is subject to the Facebook Developer Principles and
|
||||
Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
shall be included in all copies or substantial portions of the software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
@ -1,42 +0,0 @@
|
||||
{
|
||||
"name": "facebook/graph-sdk",
|
||||
"description": "Facebook SDK for PHP",
|
||||
"keywords": ["facebook", "sdk"],
|
||||
"type": "library",
|
||||
"homepage": "https://github.com/facebook/php-graph-sdk",
|
||||
"license": "Facebook Platform",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Facebook",
|
||||
"homepage": "https://github.com/facebook/php-graph-sdk/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.4|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"mockery/mockery": "~0.8",
|
||||
"guzzlehttp/guzzle": "~5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"paragonie/random_compat": "Provides a better CSPRNG option in PHP 5",
|
||||
"guzzlehttp/guzzle": "Allows for implementation of the Guzzle HTTP client"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facebook\\": "src/Facebook/"
|
||||
},
|
||||
"files": ["src/Facebook/polyfills.php"]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Facebook\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset>
|
||||
<file>src/</file>
|
||||
<file>tests/</file>
|
||||
<arg value="spn" />
|
||||
<rule ref="PSR2" />
|
||||
</ruleset>
|
@ -1,160 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Authentication;
|
||||
|
||||
/**
|
||||
* Class AccessToken
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class AccessToken
|
||||
{
|
||||
/**
|
||||
* The access token value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $value = '';
|
||||
|
||||
/**
|
||||
* Date when token expires.
|
||||
*
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
protected $expiresAt;
|
||||
|
||||
/**
|
||||
* Create a new access token entity.
|
||||
*
|
||||
* @param string $accessToken
|
||||
* @param int $expiresAt
|
||||
*/
|
||||
public function __construct($accessToken, $expiresAt = 0)
|
||||
{
|
||||
$this->value = $accessToken;
|
||||
if ($expiresAt) {
|
||||
$this->setExpiresAtFromTimeStamp($expiresAt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an app secret proof to sign a request to Graph.
|
||||
*
|
||||
* @param string $appSecret The app secret.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAppSecretProof($appSecret)
|
||||
{
|
||||
return hash_hmac('sha256', $this->value, $appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for expiresAt.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getExpiresAt()
|
||||
{
|
||||
return $this->expiresAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not this is an app access token.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAppAccessToken()
|
||||
{
|
||||
return strpos($this->value, '|') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not this is a long-lived token.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLongLived()
|
||||
{
|
||||
if ($this->expiresAt) {
|
||||
return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2);
|
||||
}
|
||||
|
||||
if ($this->isAppAccessToken()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the expiration of the access token.
|
||||
*
|
||||
* @return boolean|null
|
||||
*/
|
||||
public function isExpired()
|
||||
{
|
||||
if ($this->getExpiresAt() instanceof \DateTime) {
|
||||
return $this->getExpiresAt()->getTimestamp() < time();
|
||||
}
|
||||
|
||||
if ($this->isAppAccessToken()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the access token as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the access token as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for expires_at.
|
||||
*
|
||||
* @param int $timeStamp
|
||||
*/
|
||||
protected function setExpiresAtFromTimeStamp($timeStamp)
|
||||
{
|
||||
$dt = new \DateTime();
|
||||
$dt->setTimestamp($timeStamp);
|
||||
$this->expiresAt = $dt;
|
||||
}
|
||||
}
|
@ -1,390 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Authentication;
|
||||
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class AccessTokenMetadata
|
||||
*
|
||||
* Represents metadata from an access token.
|
||||
*
|
||||
* @package Facebook
|
||||
* @see https://developers.facebook.com/docs/graph-api/reference/debug_token
|
||||
*/
|
||||
class AccessTokenMetadata
|
||||
{
|
||||
/**
|
||||
* The access token metadata.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $metadata = [];
|
||||
|
||||
/**
|
||||
* Properties that should be cast as DateTime objects.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $dateProperties = ['expires_at', 'issued_at'];
|
||||
|
||||
/**
|
||||
* @param array $metadata
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function __construct(array $metadata)
|
||||
{
|
||||
if (!isset($metadata['data'])) {
|
||||
throw new FacebookSDKException('Unexpected debug token response data.', 401);
|
||||
}
|
||||
|
||||
$this->metadata = $metadata['data'];
|
||||
|
||||
$this->castTimestampsToDateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value from the metadata.
|
||||
*
|
||||
* @param string $field The property to retrieve.
|
||||
* @param mixed $default The default to return if the property doesn't exist.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getField($field, $default = null)
|
||||
{
|
||||
if (isset($this->metadata[$field])) {
|
||||
return $this->metadata[$field];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value from the metadata.
|
||||
*
|
||||
* @param string $field The property to retrieve.
|
||||
* @param mixed $default The default to return if the property doesn't exist.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @deprecated 5.0.0 getProperty() has been renamed to getField()
|
||||
* @todo v6: Remove this method
|
||||
*/
|
||||
public function getProperty($field, $default = null)
|
||||
{
|
||||
return $this->getField($field, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value from a child property in the metadata.
|
||||
*
|
||||
* @param string $parentField The parent property.
|
||||
* @param string $field The property to retrieve.
|
||||
* @param mixed $default The default to return if the property doesn't exist.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getChildProperty($parentField, $field, $default = null)
|
||||
{
|
||||
if (!isset($this->metadata[$parentField])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (!isset($this->metadata[$parentField][$field])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->metadata[$parentField][$field];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value from the error metadata.
|
||||
*
|
||||
* @param string $field The property to retrieve.
|
||||
* @param mixed $default The default to return if the property doesn't exist.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getErrorProperty($field, $default = null)
|
||||
{
|
||||
return $this->getChildProperty('error', $field, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value from the "metadata" metadata. *Brain explodes*
|
||||
*
|
||||
* @param string $field The property to retrieve.
|
||||
* @param mixed $default The default to return if the property doesn't exist.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMetadataProperty($field, $default = null)
|
||||
{
|
||||
return $this->getChildProperty('metadata', $field, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the application this access token is for.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAppId()
|
||||
{
|
||||
return $this->getField('app_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the application this access token is for.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApplication()
|
||||
{
|
||||
return $this->getField('application');
|
||||
}
|
||||
|
||||
/**
|
||||
* Any error that a request to the graph api
|
||||
* would return due to the access token.
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isError()
|
||||
{
|
||||
return $this->getField('error') !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The error code for the error.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getErrorCode()
|
||||
{
|
||||
return $this->getErrorProperty('code');
|
||||
}
|
||||
|
||||
/**
|
||||
* The error message for the error.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getErrorMessage()
|
||||
{
|
||||
return $this->getErrorProperty('message');
|
||||
}
|
||||
|
||||
/**
|
||||
* The error subcode for the error.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getErrorSubcode()
|
||||
{
|
||||
return $this->getErrorProperty('subcode');
|
||||
}
|
||||
|
||||
/**
|
||||
* DateTime when this access token expires.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getExpiresAt()
|
||||
{
|
||||
return $this->getField('expires_at');
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the access token is still valid or not.
|
||||
*
|
||||
* @return boolean|null
|
||||
*/
|
||||
public function getIsValid()
|
||||
{
|
||||
return $this->getField('is_valid');
|
||||
}
|
||||
|
||||
/**
|
||||
* DateTime when this access token was issued.
|
||||
*
|
||||
* Note that the issued_at field is not returned
|
||||
* for short-lived access tokens.
|
||||
*
|
||||
* @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getIssuedAt()
|
||||
{
|
||||
return $this->getField('issued_at');
|
||||
}
|
||||
|
||||
/**
|
||||
* General metadata associated with the access token.
|
||||
* Can contain data like 'sso', 'auth_type', 'auth_nonce'.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getMetadata()
|
||||
{
|
||||
return $this->getField('metadata');
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'sso' child property from the 'metadata' parent property.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSso()
|
||||
{
|
||||
return $this->getMetadataProperty('sso');
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'auth_type' child property from the 'metadata' parent property.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAuthType()
|
||||
{
|
||||
return $this->getMetadataProperty('auth_type');
|
||||
}
|
||||
|
||||
/**
|
||||
* The 'auth_nonce' child property from the 'metadata' parent property.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAuthNonce()
|
||||
{
|
||||
return $this->getMetadataProperty('auth_nonce');
|
||||
}
|
||||
|
||||
/**
|
||||
* For impersonated access tokens, the ID of
|
||||
* the page this token contains.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getProfileId()
|
||||
{
|
||||
return $this->getField('profile_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* List of permissions that the user has granted for
|
||||
* the app in this access token.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getScopes()
|
||||
{
|
||||
return $this->getField('scopes');
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the user this access token is for.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->getField('user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the app ID from the access token
|
||||
* metadata is what we expect.
|
||||
*
|
||||
* @param string $appId
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function validateAppId($appId)
|
||||
{
|
||||
if ($this->getAppId() !== $appId) {
|
||||
throw new FacebookSDKException('Access token metadata contains unexpected app ID.', 401);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the user ID from the access token
|
||||
* metadata is what we expect.
|
||||
*
|
||||
* @param string $userId
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function validateUserId($userId)
|
||||
{
|
||||
if ($this->getUserId() !== $userId) {
|
||||
throw new FacebookSDKException('Access token metadata contains unexpected user ID.', 401);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the access token has not expired yet.
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function validateExpiration()
|
||||
{
|
||||
if (!$this->getExpiresAt() instanceof \DateTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->getExpiresAt()->getTimestamp() < time()) {
|
||||
throw new FacebookSDKException('Inspection of access token metadata shows that the access token has expired.', 401);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a unix timestamp into a DateTime entity.
|
||||
*
|
||||
* @param int $timestamp
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
private function convertTimestampToDateTime($timestamp)
|
||||
{
|
||||
$dt = new \DateTime();
|
||||
$dt->setTimestamp($timestamp);
|
||||
|
||||
return $dt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts the unix timestamps as DateTime entities.
|
||||
*/
|
||||
private function castTimestampsToDateTime()
|
||||
{
|
||||
foreach (static::$dateProperties as $key) {
|
||||
if (isset($this->metadata[$key]) && $this->metadata[$key] !== 0) {
|
||||
$this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,292 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Authentication;
|
||||
|
||||
use Facebook\Facebook;
|
||||
use Facebook\FacebookApp;
|
||||
use Facebook\FacebookRequest;
|
||||
use Facebook\FacebookResponse;
|
||||
use Facebook\FacebookClient;
|
||||
use Facebook\Exceptions\FacebookResponseException;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class OAuth2Client
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class OAuth2Client
|
||||
{
|
||||
/**
|
||||
* @const string The base authorization URL.
|
||||
*/
|
||||
const BASE_AUTHORIZATION_URL = 'https://www.facebook.com';
|
||||
|
||||
/**
|
||||
* The FacebookApp entity.
|
||||
*
|
||||
* @var FacebookApp
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* The Facebook client.
|
||||
*
|
||||
* @var FacebookClient
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* The version of the Graph API to use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $graphVersion;
|
||||
|
||||
/**
|
||||
* The last request sent to Graph.
|
||||
*
|
||||
* @var FacebookRequest|null
|
||||
*/
|
||||
protected $lastRequest;
|
||||
|
||||
/**
|
||||
* @param FacebookApp $app
|
||||
* @param FacebookClient $client
|
||||
* @param string|null $graphVersion The version of the Graph API to use.
|
||||
*/
|
||||
public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->client = $client;
|
||||
$this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last FacebookRequest that was sent.
|
||||
* Useful for debugging and testing.
|
||||
*
|
||||
* @return FacebookRequest|null
|
||||
*/
|
||||
public function getLastRequest()
|
||||
{
|
||||
return $this->lastRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the metadata associated with the access token.
|
||||
*
|
||||
* @param AccessToken|string $accessToken The access token to debug.
|
||||
*
|
||||
* @return AccessTokenMetadata
|
||||
*/
|
||||
public function debugToken($accessToken)
|
||||
{
|
||||
$accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken;
|
||||
$params = ['input_token' => $accessToken];
|
||||
|
||||
$this->lastRequest = new FacebookRequest(
|
||||
$this->app,
|
||||
$this->app->getAccessToken(),
|
||||
'GET',
|
||||
'/debug_token',
|
||||
$params,
|
||||
null,
|
||||
$this->graphVersion
|
||||
);
|
||||
$response = $this->client->sendRequest($this->lastRequest);
|
||||
$metadata = $response->getDecodedBody();
|
||||
|
||||
return new AccessTokenMetadata($metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an authorization URL to begin the process of authenticating a user.
|
||||
*
|
||||
* @param string $redirectUrl The callback URL to redirect to.
|
||||
* @param string $state The CSPRNG-generated CSRF value.
|
||||
* @param array $scope An array of permissions to request.
|
||||
* @param array $params An array of parameters to generate URL.
|
||||
* @param string $separator The separator to use in http_build_query().
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], array $params = [], $separator = '&')
|
||||
{
|
||||
$params += [
|
||||
'client_id' => $this->app->getId(),
|
||||
'state' => $state,
|
||||
'response_type' => 'code',
|
||||
'sdk' => 'php-sdk-' . Facebook::VERSION,
|
||||
'redirect_uri' => $redirectUrl,
|
||||
'scope' => implode(',', $scope)
|
||||
];
|
||||
|
||||
return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . http_build_query($params, null, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a valid access token from a code.
|
||||
*
|
||||
* @param string $code
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @return AccessToken
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getAccessTokenFromCode($code, $redirectUri = '')
|
||||
{
|
||||
$params = [
|
||||
'code' => $code,
|
||||
'redirect_uri' => $redirectUri,
|
||||
];
|
||||
|
||||
return $this->requestAnAccessToken($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchanges a short-lived access token with a long-lived access token.
|
||||
*
|
||||
* @param AccessToken|string $accessToken
|
||||
*
|
||||
* @return AccessToken
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getLongLivedAccessToken($accessToken)
|
||||
{
|
||||
$accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken;
|
||||
$params = [
|
||||
'grant_type' => 'fb_exchange_token',
|
||||
'fb_exchange_token' => $accessToken,
|
||||
];
|
||||
|
||||
return $this->requestAnAccessToken($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a valid code from an access token.
|
||||
*
|
||||
* @param AccessToken|string $accessToken
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @return AccessToken
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '')
|
||||
{
|
||||
$params = [
|
||||
'redirect_uri' => $redirectUri,
|
||||
];
|
||||
|
||||
$response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken);
|
||||
$data = $response->getDecodedBody();
|
||||
|
||||
if (!isset($data['code'])) {
|
||||
throw new FacebookSDKException('Code was not returned from Graph.', 401);
|
||||
}
|
||||
|
||||
return $data['code'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to the OAuth endpoint.
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return AccessToken
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
protected function requestAnAccessToken(array $params)
|
||||
{
|
||||
$response = $this->sendRequestWithClientParams('/oauth/access_token', $params);
|
||||
$data = $response->getDecodedBody();
|
||||
|
||||
if (!isset($data['access_token'])) {
|
||||
throw new FacebookSDKException('Access token was not returned from Graph.', 401);
|
||||
}
|
||||
|
||||
// Graph returns two different key names for expiration time
|
||||
// on the same endpoint. Doh! :/
|
||||
$expiresAt = 0;
|
||||
if (isset($data['expires'])) {
|
||||
// For exchanging a short lived token with a long lived token.
|
||||
// The expiration time in seconds will be returned as "expires".
|
||||
$expiresAt = time() + $data['expires'];
|
||||
} elseif (isset($data['expires_in'])) {
|
||||
// For exchanging a code for a short lived access token.
|
||||
// The expiration time in seconds will be returned as "expires_in".
|
||||
// See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code
|
||||
$expiresAt = time() + $data['expires_in'];
|
||||
}
|
||||
|
||||
return new AccessToken($data['access_token'], $expiresAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to Graph with an app access token.
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param array $params
|
||||
* @param AccessToken|string|null $accessToken
|
||||
*
|
||||
* @return FacebookResponse
|
||||
*
|
||||
* @throws FacebookResponseException
|
||||
*/
|
||||
protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null)
|
||||
{
|
||||
$params += $this->getClientParams();
|
||||
|
||||
$accessToken = $accessToken ?: $this->app->getAccessToken();
|
||||
|
||||
$this->lastRequest = new FacebookRequest(
|
||||
$this->app,
|
||||
$accessToken,
|
||||
'GET',
|
||||
$endpoint,
|
||||
$params,
|
||||
null,
|
||||
$this->graphVersion
|
||||
);
|
||||
|
||||
return $this->client->sendRequest($this->lastRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the client_* params for OAuth requests.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getClientParams()
|
||||
{
|
||||
return [
|
||||
'client_id' => $this->app->getId(),
|
||||
'client_secret' => $this->app->getSecret(),
|
||||
];
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookAuthenticationException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookAuthenticationException extends FacebookSDKException
|
||||
{
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookAuthorizationException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookAuthorizationException extends FacebookSDKException
|
||||
{
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookClientException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookClientException extends FacebookSDKException
|
||||
{
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookOtherException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookOtherException extends FacebookSDKException
|
||||
{
|
||||
}
|
@ -1,214 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
use Facebook\FacebookResponse;
|
||||
|
||||
/**
|
||||
* Class FacebookResponseException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookResponseException extends FacebookSDKException
|
||||
{
|
||||
/**
|
||||
* @var FacebookResponse The response that threw the exception.
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var array Decoded response.
|
||||
*/
|
||||
protected $responseData;
|
||||
|
||||
/**
|
||||
* Creates a FacebookResponseException.
|
||||
*
|
||||
* @param FacebookResponse $response The response that threw the exception.
|
||||
* @param FacebookSDKException $previousException The more detailed exception.
|
||||
*/
|
||||
public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null)
|
||||
{
|
||||
$this->response = $response;
|
||||
$this->responseData = $response->getDecodedBody();
|
||||
|
||||
$errorMessage = $this->get('message', 'Unknown error from Graph.');
|
||||
$errorCode = $this->get('code', -1);
|
||||
|
||||
parent::__construct($errorMessage, $errorCode, $previousException);
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory for creating the appropriate exception based on the response from Graph.
|
||||
*
|
||||
* @param FacebookResponse $response The response that threw the exception.
|
||||
*
|
||||
* @return FacebookResponseException
|
||||
*/
|
||||
public static function create(FacebookResponse $response)
|
||||
{
|
||||
$data = $response->getDecodedBody();
|
||||
|
||||
if (!isset($data['error']['code']) && isset($data['code'])) {
|
||||
$data = ['error' => $data];
|
||||
}
|
||||
|
||||
$code = isset($data['error']['code']) ? $data['error']['code'] : null;
|
||||
$message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.';
|
||||
|
||||
if (isset($data['error']['error_subcode'])) {
|
||||
switch ($data['error']['error_subcode']) {
|
||||
// Other authentication issues
|
||||
case 458:
|
||||
case 459:
|
||||
case 460:
|
||||
case 463:
|
||||
case 464:
|
||||
case 467:
|
||||
return new static($response, new FacebookAuthenticationException($message, $code));
|
||||
// Video upload resumable error
|
||||
case 1363030:
|
||||
case 1363019:
|
||||
case 1363037:
|
||||
case 1363033:
|
||||
case 1363021:
|
||||
case 1363041:
|
||||
return new static($response, new FacebookResumableUploadException($message, $code));
|
||||
}
|
||||
}
|
||||
|
||||
switch ($code) {
|
||||
// Login status or token expired, revoked, or invalid
|
||||
case 100:
|
||||
case 102:
|
||||
case 190:
|
||||
return new static($response, new FacebookAuthenticationException($message, $code));
|
||||
|
||||
// Server issue, possible downtime
|
||||
case 1:
|
||||
case 2:
|
||||
return new static($response, new FacebookServerException($message, $code));
|
||||
|
||||
// API Throttling
|
||||
case 4:
|
||||
case 17:
|
||||
case 341:
|
||||
return new static($response, new FacebookThrottleException($message, $code));
|
||||
|
||||
// Duplicate Post
|
||||
case 506:
|
||||
return new static($response, new FacebookClientException($message, $code));
|
||||
}
|
||||
|
||||
// Missing Permissions
|
||||
if ($code == 10 || ($code >= 200 && $code <= 299)) {
|
||||
return new static($response, new FacebookAuthorizationException($message, $code));
|
||||
}
|
||||
|
||||
// OAuth authentication error
|
||||
if (isset($data['error']['type']) && $data['error']['type'] === 'OAuthException') {
|
||||
return new static($response, new FacebookAuthenticationException($message, $code));
|
||||
}
|
||||
|
||||
// All others
|
||||
return new static($response, new FacebookOtherException($message, $code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks isset and returns that or a default value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function get($key, $default = null)
|
||||
{
|
||||
if (isset($this->responseData['error'][$key])) {
|
||||
return $this->responseData['error'][$key];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP status code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHttpStatusCode()
|
||||
{
|
||||
return $this->response->getHttpStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sub-error code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSubErrorCode()
|
||||
{
|
||||
return $this->get('error_subcode', -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getErrorType()
|
||||
{
|
||||
return $this->get('type', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw response used to create the exception.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRawResponse()
|
||||
{
|
||||
return $this->response->getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the decoded response used to create the exception.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResponseData()
|
||||
{
|
||||
return $this->responseData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response entity used to create the exception.
|
||||
*
|
||||
* @return FacebookResponse
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookResumableUploadException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookResumableUploadException extends FacebookSDKException
|
||||
{
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookSDKException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookSDKException extends \Exception
|
||||
{
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookServerException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookServerException extends FacebookSDKException
|
||||
{
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FacebookThrottleException
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookThrottleException extends FacebookSDKException
|
||||
{
|
||||
}
|
@ -1,635 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook;
|
||||
|
||||
use Facebook\Authentication\AccessToken;
|
||||
use Facebook\Authentication\OAuth2Client;
|
||||
use Facebook\FileUpload\FacebookFile;
|
||||
use Facebook\FileUpload\FacebookResumableUploader;
|
||||
use Facebook\FileUpload\FacebookTransferChunk;
|
||||
use Facebook\FileUpload\FacebookVideo;
|
||||
use Facebook\GraphNodes\GraphEdge;
|
||||
use Facebook\Url\UrlDetectionInterface;
|
||||
use Facebook\Url\FacebookUrlDetectionHandler;
|
||||
use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory;
|
||||
use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface;
|
||||
use Facebook\HttpClients\HttpClientsFactory;
|
||||
use Facebook\PersistentData\PersistentDataFactory;
|
||||
use Facebook\PersistentData\PersistentDataInterface;
|
||||
use Facebook\Helpers\FacebookCanvasHelper;
|
||||
use Facebook\Helpers\FacebookJavaScriptHelper;
|
||||
use Facebook\Helpers\FacebookPageTabHelper;
|
||||
use Facebook\Helpers\FacebookRedirectLoginHelper;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class Facebook
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class Facebook
|
||||
{
|
||||
/**
|
||||
* @const string Version number of the Facebook PHP SDK.
|
||||
*/
|
||||
const VERSION = '5.6.1';
|
||||
|
||||
/**
|
||||
* @const string Default Graph API version for requests.
|
||||
*/
|
||||
const DEFAULT_GRAPH_VERSION = 'v2.10';
|
||||
|
||||
/**
|
||||
* @const string The name of the environment variable that contains the app ID.
|
||||
*/
|
||||
const APP_ID_ENV_NAME = 'FACEBOOK_APP_ID';
|
||||
|
||||
/**
|
||||
* @const string The name of the environment variable that contains the app secret.
|
||||
*/
|
||||
const APP_SECRET_ENV_NAME = 'FACEBOOK_APP_SECRET';
|
||||
|
||||
/**
|
||||
* @var FacebookApp The FacebookApp entity.
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var FacebookClient The Facebook client service.
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @var OAuth2Client The OAuth 2.0 client service.
|
||||
*/
|
||||
protected $oAuth2Client;
|
||||
|
||||
/**
|
||||
* @var UrlDetectionInterface|null The URL detection handler.
|
||||
*/
|
||||
protected $urlDetectionHandler;
|
||||
|
||||
/**
|
||||
* @var PseudoRandomStringGeneratorInterface|null The cryptographically secure pseudo-random string generator.
|
||||
*/
|
||||
protected $pseudoRandomStringGenerator;
|
||||
|
||||
/**
|
||||
* @var AccessToken|null The default access token to use with requests.
|
||||
*/
|
||||
protected $defaultAccessToken;
|
||||
|
||||
/**
|
||||
* @var string|null The default Graph version we want to use.
|
||||
*/
|
||||
protected $defaultGraphVersion;
|
||||
|
||||
/**
|
||||
* @var PersistentDataInterface|null The persistent data handler.
|
||||
*/
|
||||
protected $persistentDataHandler;
|
||||
|
||||
/**
|
||||
* @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph.
|
||||
*/
|
||||
protected $lastResponse;
|
||||
|
||||
/**
|
||||
* Instantiates a new Facebook super-class object.
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$config = array_merge([
|
||||
'app_id' => getenv(static::APP_ID_ENV_NAME),
|
||||
'app_secret' => getenv(static::APP_SECRET_ENV_NAME),
|
||||
'default_graph_version' => static::DEFAULT_GRAPH_VERSION,
|
||||
'enable_beta_mode' => false,
|
||||
'http_client_handler' => null,
|
||||
'persistent_data_handler' => null,
|
||||
'pseudo_random_string_generator' => null,
|
||||
'url_detection_handler' => null,
|
||||
], $config);
|
||||
|
||||
if (!$config['app_id']) {
|
||||
throw new FacebookSDKException('Required "app_id" key not supplied in config and could not find fallback environment variable "' . static::APP_ID_ENV_NAME . '"');
|
||||
}
|
||||
if (!$config['app_secret']) {
|
||||
throw new FacebookSDKException('Required "app_secret" key not supplied in config and could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME . '"');
|
||||
}
|
||||
|
||||
$this->app = new FacebookApp($config['app_id'], $config['app_secret']);
|
||||
$this->client = new FacebookClient(
|
||||
HttpClientsFactory::createHttpClient($config['http_client_handler']),
|
||||
$config['enable_beta_mode']
|
||||
);
|
||||
$this->pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator(
|
||||
$config['pseudo_random_string_generator']
|
||||
);
|
||||
$this->setUrlDetectionHandler($config['url_detection_handler'] ?: new FacebookUrlDetectionHandler());
|
||||
$this->persistentDataHandler = PersistentDataFactory::createPersistentDataHandler(
|
||||
$config['persistent_data_handler']
|
||||
);
|
||||
|
||||
if (isset($config['default_access_token'])) {
|
||||
$this->setDefaultAccessToken($config['default_access_token']);
|
||||
}
|
||||
|
||||
// @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set
|
||||
$this->defaultGraphVersion = $config['default_graph_version'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the FacebookApp entity.
|
||||
*
|
||||
* @return FacebookApp
|
||||
*/
|
||||
public function getApp()
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the FacebookClient service.
|
||||
*
|
||||
* @return FacebookClient
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OAuth 2.0 client service.
|
||||
*
|
||||
* @return OAuth2Client
|
||||
*/
|
||||
public function getOAuth2Client()
|
||||
{
|
||||
if (!$this->oAuth2Client instanceof OAuth2Client) {
|
||||
$app = $this->getApp();
|
||||
$client = $this->getClient();
|
||||
$this->oAuth2Client = new OAuth2Client($app, $client, $this->defaultGraphVersion);
|
||||
}
|
||||
|
||||
return $this->oAuth2Client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last response returned from Graph.
|
||||
*
|
||||
* @return FacebookResponse|FacebookBatchResponse|null
|
||||
*/
|
||||
public function getLastResponse()
|
||||
{
|
||||
return $this->lastResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL detection handler.
|
||||
*
|
||||
* @return UrlDetectionInterface
|
||||
*/
|
||||
public function getUrlDetectionHandler()
|
||||
{
|
||||
return $this->urlDetectionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the URL detection handler.
|
||||
*
|
||||
* @param UrlDetectionInterface $urlDetectionHandler
|
||||
*/
|
||||
private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler)
|
||||
{
|
||||
$this->urlDetectionHandler = $urlDetectionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default AccessToken entity.
|
||||
*
|
||||
* @return AccessToken|null
|
||||
*/
|
||||
public function getDefaultAccessToken()
|
||||
{
|
||||
return $this->defaultAccessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default access token to use with requests.
|
||||
*
|
||||
* @param AccessToken|string $accessToken The access token to save.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setDefaultAccessToken($accessToken)
|
||||
{
|
||||
if (is_string($accessToken)) {
|
||||
$this->defaultAccessToken = new AccessToken($accessToken);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($accessToken instanceof AccessToken) {
|
||||
$this->defaultAccessToken = $accessToken;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException('The default access token must be of type "string" or Facebook\AccessToken');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default Graph version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultGraphVersion()
|
||||
{
|
||||
return $this->defaultGraphVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the redirect login helper.
|
||||
*
|
||||
* @return FacebookRedirectLoginHelper
|
||||
*/
|
||||
public function getRedirectLoginHelper()
|
||||
{
|
||||
return new FacebookRedirectLoginHelper(
|
||||
$this->getOAuth2Client(),
|
||||
$this->persistentDataHandler,
|
||||
$this->urlDetectionHandler,
|
||||
$this->pseudoRandomStringGenerator
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JavaScript helper.
|
||||
*
|
||||
* @return FacebookJavaScriptHelper
|
||||
*/
|
||||
public function getJavaScriptHelper()
|
||||
{
|
||||
return new FacebookJavaScriptHelper($this->app, $this->client, $this->defaultGraphVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the canvas helper.
|
||||
*
|
||||
* @return FacebookCanvasHelper
|
||||
*/
|
||||
public function getCanvasHelper()
|
||||
{
|
||||
return new FacebookCanvasHelper($this->app, $this->client, $this->defaultGraphVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page tab helper.
|
||||
*
|
||||
* @return FacebookPageTabHelper
|
||||
*/
|
||||
public function getPageTabHelper()
|
||||
{
|
||||
return new FacebookPageTabHelper($this->app, $this->client, $this->defaultGraphVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a GET request to Graph and returns the result.
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $eTag
|
||||
* @param string|null $graphVersion
|
||||
*
|
||||
* @return FacebookResponse
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function get($endpoint, $accessToken = null, $eTag = null, $graphVersion = null)
|
||||
{
|
||||
return $this->sendRequest(
|
||||
'GET',
|
||||
$endpoint,
|
||||
$params = [],
|
||||
$accessToken,
|
||||
$eTag,
|
||||
$graphVersion
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a POST request to Graph and returns the result.
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param array $params
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $eTag
|
||||
* @param string|null $graphVersion
|
||||
*
|
||||
* @return FacebookResponse
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function post($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null)
|
||||
{
|
||||
return $this->sendRequest(
|
||||
'POST',
|
||||
$endpoint,
|
||||
$params,
|
||||
$accessToken,
|
||||
$eTag,
|
||||
$graphVersion
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a DELETE request to Graph and returns the result.
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param array $params
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $eTag
|
||||
* @param string|null $graphVersion
|
||||
*
|
||||
* @return FacebookResponse
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function delete($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null)
|
||||
{
|
||||
return $this->sendRequest(
|
||||
'DELETE',
|
||||
$endpoint,
|
||||
$params,
|
||||
$accessToken,
|
||||
$eTag,
|
||||
$graphVersion
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to Graph for the next page of results.
|
||||
*
|
||||
* @param GraphEdge $graphEdge The GraphEdge to paginate over.
|
||||
*
|
||||
* @return GraphEdge|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function next(GraphEdge $graphEdge)
|
||||
{
|
||||
return $this->getPaginationResults($graphEdge, 'next');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to Graph for the previous page of results.
|
||||
*
|
||||
* @param GraphEdge $graphEdge The GraphEdge to paginate over.
|
||||
*
|
||||
* @return GraphEdge|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function previous(GraphEdge $graphEdge)
|
||||
{
|
||||
return $this->getPaginationResults($graphEdge, 'previous');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to Graph for the next page of results.
|
||||
*
|
||||
* @param GraphEdge $graphEdge The GraphEdge to paginate over.
|
||||
* @param string $direction The direction of the pagination: next|previous.
|
||||
*
|
||||
* @return GraphEdge|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getPaginationResults(GraphEdge $graphEdge, $direction)
|
||||
{
|
||||
$paginationRequest = $graphEdge->getPaginationRequest($direction);
|
||||
if (!$paginationRequest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->lastResponse = $this->client->sendRequest($paginationRequest);
|
||||
|
||||
// Keep the same GraphNode subclass
|
||||
$subClassName = $graphEdge->getSubClassName();
|
||||
$graphEdge = $this->lastResponse->getGraphEdge($subClassName, false);
|
||||
|
||||
return count($graphEdge) > 0 ? $graphEdge : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to Graph and returns the result.
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $endpoint
|
||||
* @param array $params
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $eTag
|
||||
* @param string|null $graphVersion
|
||||
*
|
||||
* @return FacebookResponse
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function sendRequest($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null)
|
||||
{
|
||||
$accessToken = $accessToken ?: $this->defaultAccessToken;
|
||||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
|
||||
$request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion);
|
||||
|
||||
return $this->lastResponse = $this->client->sendRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a batched request to Graph and returns the result.
|
||||
*
|
||||
* @param array $requests
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $graphVersion
|
||||
*
|
||||
* @return FacebookBatchResponse
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function sendBatchRequest(array $requests, $accessToken = null, $graphVersion = null)
|
||||
{
|
||||
$accessToken = $accessToken ?: $this->defaultAccessToken;
|
||||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
|
||||
$batchRequest = new FacebookBatchRequest(
|
||||
$this->app,
|
||||
$requests,
|
||||
$accessToken,
|
||||
$graphVersion
|
||||
);
|
||||
|
||||
return $this->lastResponse = $this->client->sendBatchRequest($batchRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates an empty FacebookBatchRequest entity.
|
||||
*
|
||||
* @param AccessToken|string|null $accessToken The top-level access token. Requests with no access token
|
||||
* will fallback to this.
|
||||
* @param string|null $graphVersion The Graph API version to use.
|
||||
* @return FacebookBatchRequest
|
||||
*/
|
||||
public function newBatchRequest($accessToken = null, $graphVersion = null)
|
||||
{
|
||||
$accessToken = $accessToken ?: $this->defaultAccessToken;
|
||||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
|
||||
|
||||
return new FacebookBatchRequest(
|
||||
$this->app,
|
||||
[],
|
||||
$accessToken,
|
||||
$graphVersion
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new FacebookRequest entity.
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $endpoint
|
||||
* @param array $params
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $eTag
|
||||
* @param string|null $graphVersion
|
||||
*
|
||||
* @return FacebookRequest
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function request($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null)
|
||||
{
|
||||
$accessToken = $accessToken ?: $this->defaultAccessToken;
|
||||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
|
||||
|
||||
return new FacebookRequest(
|
||||
$this->app,
|
||||
$accessToken,
|
||||
$method,
|
||||
$endpoint,
|
||||
$params,
|
||||
$eTag,
|
||||
$graphVersion
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to create FacebookFile's.
|
||||
*
|
||||
* @param string $pathToFile
|
||||
*
|
||||
* @return FacebookFile
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function fileToUpload($pathToFile)
|
||||
{
|
||||
return new FacebookFile($pathToFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to create FacebookVideo's.
|
||||
*
|
||||
* @param string $pathToFile
|
||||
*
|
||||
* @return FacebookVideo
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function videoToUpload($pathToFile)
|
||||
{
|
||||
return new FacebookVideo($pathToFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a video in chunks.
|
||||
*
|
||||
* @param int $target The id of the target node before the /videos edge.
|
||||
* @param string $pathToFile The full path to the file.
|
||||
* @param array $metadata The metadata associated with the video file.
|
||||
* @param string|null $accessToken The access token.
|
||||
* @param int $maxTransferTries The max times to retry a failed upload chunk.
|
||||
* @param string|null $graphVersion The Graph API version to use.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = null, $maxTransferTries = 5, $graphVersion = null)
|
||||
{
|
||||
$accessToken = $accessToken ?: $this->defaultAccessToken;
|
||||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
|
||||
|
||||
$uploader = new FacebookResumableUploader($this->app, $this->client, $accessToken, $graphVersion);
|
||||
$endpoint = '/'.$target.'/videos';
|
||||
$file = $this->videoToUpload($pathToFile);
|
||||
$chunk = $uploader->start($endpoint, $file);
|
||||
|
||||
do {
|
||||
$chunk = $this->maxTriesTransfer($uploader, $endpoint, $chunk, $maxTransferTries);
|
||||
} while (!$chunk->isLastChunk());
|
||||
|
||||
return [
|
||||
'video_id' => $chunk->getVideoId(),
|
||||
'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId(), $metadata),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to upload a chunk of a file in $retryCountdown tries.
|
||||
*
|
||||
* @param FacebookResumableUploader $uploader
|
||||
* @param string $endpoint
|
||||
* @param FacebookTransferChunk $chunk
|
||||
* @param int $retryCountdown
|
||||
*
|
||||
* @return FacebookTransferChunk
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
private function maxTriesTransfer(FacebookResumableUploader $uploader, $endpoint, FacebookTransferChunk $chunk, $retryCountdown)
|
||||
{
|
||||
$newChunk = $uploader->transfer($endpoint, $chunk, $retryCountdown < 1);
|
||||
|
||||
if ($newChunk !== $chunk) {
|
||||
return $newChunk;
|
||||
}
|
||||
|
||||
$retryCountdown--;
|
||||
|
||||
// If transfer() returned the same chunk entity, the transfer failed but is resumable.
|
||||
return $this->maxTriesTransfer($uploader, $endpoint, $chunk, $retryCountdown);
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook;
|
||||
|
||||
use Facebook\Authentication\AccessToken;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
class FacebookApp implements \Serializable
|
||||
{
|
||||
/**
|
||||
* @var string The app ID.
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var string The app secret.
|
||||
*/
|
||||
protected $secret;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $secret
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function __construct($id, $secret)
|
||||
{
|
||||
if (!is_string($id)
|
||||
// Keeping this for BC. Integers greater than PHP_INT_MAX will make is_int() return false
|
||||
&& !is_int($id)) {
|
||||
throw new FacebookSDKException('The "app_id" must be formatted as a string since many app ID\'s are greater than PHP_INT_MAX on some systems.');
|
||||
}
|
||||
// We cast as a string in case a valid int was set on a 64-bit system and this is unserialised on a 32-bit system
|
||||
$this->id = (string) $id;
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the app ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the app secret.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSecret()
|
||||
{
|
||||
return $this->secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an app access token.
|
||||
*
|
||||
* @return AccessToken
|
||||
*/
|
||||
public function getAccessToken()
|
||||
{
|
||||
return new AccessToken($this->id . '|' . $this->secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the FacebookApp entity as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return implode('|', [$this->id, $this->secret]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes a string as a FacebookApp entity.
|
||||
*
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
list($id, $secret) = explode('|', $serialized);
|
||||
|
||||
$this->__construct($id, $secret);
|
||||
}
|
||||
}
|
@ -1,322 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook;
|
||||
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use ArrayAccess;
|
||||
use Facebook\Authentication\AccessToken;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class BatchRequest
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookBatchRequest extends FacebookRequest implements IteratorAggregate, ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var array An array of FacebookRequest entities to send.
|
||||
*/
|
||||
protected $requests;
|
||||
|
||||
/**
|
||||
* @var array An array of files to upload.
|
||||
*/
|
||||
protected $attachedFiles;
|
||||
|
||||
/**
|
||||
* Creates a new Request entity.
|
||||
*
|
||||
* @param FacebookApp|null $app
|
||||
* @param array $requests
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $graphVersion
|
||||
*/
|
||||
public function __construct(FacebookApp $app = null, array $requests = [], $accessToken = null, $graphVersion = null)
|
||||
{
|
||||
parent::__construct($app, $accessToken, 'POST', '', [], null, $graphVersion);
|
||||
|
||||
$this->add($requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new request to the array.
|
||||
*
|
||||
* @param FacebookRequest|array $request
|
||||
* @param string|null|array $options Array of batch request options e.g. 'name', 'omit_response_on_success'.
|
||||
* If a string is given, it is the value of the 'name' option.
|
||||
*
|
||||
* @return FacebookBatchRequest
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function add($request, $options = null)
|
||||
{
|
||||
if (is_array($request)) {
|
||||
foreach ($request as $key => $req) {
|
||||
$this->add($req, $key);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!$request instanceof FacebookRequest) {
|
||||
throw new \InvalidArgumentException('Argument for add() must be of type array or FacebookRequest.');
|
||||
}
|
||||
|
||||
if (null === $options) {
|
||||
$options = [];
|
||||
} elseif (!is_array($options)) {
|
||||
$options = ['name' => $options];
|
||||
}
|
||||
|
||||
$this->addFallbackDefaults($request);
|
||||
|
||||
// File uploads
|
||||
$attachedFiles = $this->extractFileAttachments($request);
|
||||
|
||||
$name = isset($options['name']) ? $options['name'] : null;
|
||||
|
||||
unset($options['name']);
|
||||
|
||||
$requestToAdd = [
|
||||
'name' => $name,
|
||||
'request' => $request,
|
||||
'options' => $options,
|
||||
'attached_files' => $attachedFiles,
|
||||
];
|
||||
|
||||
$this->requests[] = $requestToAdd;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the FacebookApp and access token fall back when missing.
|
||||
*
|
||||
* @param FacebookRequest $request
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function addFallbackDefaults(FacebookRequest $request)
|
||||
{
|
||||
if (!$request->getApp()) {
|
||||
$app = $this->getApp();
|
||||
if (!$app) {
|
||||
throw new FacebookSDKException('Missing FacebookApp on FacebookRequest and no fallback detected on FacebookBatchRequest.');
|
||||
}
|
||||
$request->setApp($app);
|
||||
}
|
||||
|
||||
if (!$request->getAccessToken()) {
|
||||
$accessToken = $this->getAccessToken();
|
||||
if (!$accessToken) {
|
||||
throw new FacebookSDKException('Missing access token on FacebookRequest and no fallback detected on FacebookBatchRequest.');
|
||||
}
|
||||
$request->setAccessToken($accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the files from a request.
|
||||
*
|
||||
* @param FacebookRequest $request
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function extractFileAttachments(FacebookRequest $request)
|
||||
{
|
||||
if (!$request->containsFileUploads()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$files = $request->getFiles();
|
||||
$fileNames = [];
|
||||
foreach ($files as $file) {
|
||||
$fileName = uniqid();
|
||||
$this->addFile($fileName, $file);
|
||||
$fileNames[] = $fileName;
|
||||
}
|
||||
|
||||
$request->resetFiles();
|
||||
|
||||
// @TODO Does Graph support multiple uploads on one endpoint?
|
||||
return implode(',', $fileNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FacebookRequest entities.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRequests()
|
||||
{
|
||||
return $this->requests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the requests to be sent as a batch request.
|
||||
*/
|
||||
public function prepareRequestsForBatch()
|
||||
{
|
||||
$this->validateBatchRequestCount();
|
||||
|
||||
$params = [
|
||||
'batch' => $this->convertRequestsToJson(),
|
||||
'include_headers' => true,
|
||||
];
|
||||
$this->setParams($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the requests into a JSON(P) string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function convertRequestsToJson()
|
||||
{
|
||||
$requests = [];
|
||||
foreach ($this->requests as $request) {
|
||||
$options = [];
|
||||
|
||||
if (null !== $request['name']) {
|
||||
$options['name'] = $request['name'];
|
||||
}
|
||||
|
||||
$options += $request['options'];
|
||||
|
||||
$requests[] = $this->requestEntityToBatchArray($request['request'], $options, $request['attached_files']);
|
||||
}
|
||||
|
||||
return json_encode($requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the request count before sending them as a batch.
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function validateBatchRequestCount()
|
||||
{
|
||||
$batchCount = count($this->requests);
|
||||
if ($batchCount === 0) {
|
||||
throw new FacebookSDKException('There are no batch requests to send.');
|
||||
} elseif ($batchCount > 50) {
|
||||
// Per: https://developers.facebook.com/docs/graph-api/making-multiple-requests#limits
|
||||
throw new FacebookSDKException('You cannot send more than 50 batch requests at a time.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Request entity into an array that is batch-friendly.
|
||||
*
|
||||
* @param FacebookRequest $request The request entity to convert.
|
||||
* @param string|null|array $options Array of batch request options e.g. 'name', 'omit_response_on_success'.
|
||||
* If a string is given, it is the value of the 'name' option.
|
||||
* @param string|null $attachedFiles Names of files associated with the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function requestEntityToBatchArray(FacebookRequest $request, $options = null, $attachedFiles = null)
|
||||
{
|
||||
|
||||
if (null === $options) {
|
||||
$options = [];
|
||||
} elseif (!is_array($options)) {
|
||||
$options = ['name' => $options];
|
||||
}
|
||||
|
||||
$compiledHeaders = [];
|
||||
$headers = $request->getHeaders();
|
||||
foreach ($headers as $name => $value) {
|
||||
$compiledHeaders[] = $name . ': ' . $value;
|
||||
}
|
||||
|
||||
$batch = [
|
||||
'headers' => $compiledHeaders,
|
||||
'method' => $request->getMethod(),
|
||||
'relative_url' => $request->getUrl(),
|
||||
];
|
||||
|
||||
// Since file uploads are moved to the root request of a batch request,
|
||||
// the child requests will always be URL-encoded.
|
||||
$body = $request->getUrlEncodedBody()->getBody();
|
||||
if ($body) {
|
||||
$batch['body'] = $body;
|
||||
}
|
||||
|
||||
$batch += $options;
|
||||
|
||||
if (null !== $attachedFiles) {
|
||||
$batch['attached_files'] = $attachedFiles;
|
||||
}
|
||||
|
||||
return $batch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the items.
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->add($value, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->requests[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->requests[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->requests[$offset]) ? $this->requests[$offset] : null;
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook;
|
||||
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use ArrayAccess;
|
||||
|
||||
/**
|
||||
* Class FacebookBatchResponse
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate, ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var FacebookBatchRequest The original entity that made the batch request.
|
||||
*/
|
||||
protected $batchRequest;
|
||||
|
||||
/**
|
||||
* @var array An array of FacebookResponse entities.
|
||||
*/
|
||||
protected $responses = [];
|
||||
|
||||
/**
|
||||
* Creates a new Response entity.
|
||||
*
|
||||
* @param FacebookBatchRequest $batchRequest
|
||||
* @param FacebookResponse $response
|
||||
*/
|
||||
public function __construct(FacebookBatchRequest $batchRequest, FacebookResponse $response)
|
||||
{
|
||||
$this->batchRequest = $batchRequest;
|
||||
|
||||
$request = $response->getRequest();
|
||||
$body = $response->getBody();
|
||||
$httpStatusCode = $response->getHttpStatusCode();
|
||||
$headers = $response->getHeaders();
|
||||
parent::__construct($request, $body, $httpStatusCode, $headers);
|
||||
|
||||
$responses = $response->getDecodedBody();
|
||||
$this->setResponses($responses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of FacebookResponse entities.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResponses()
|
||||
{
|
||||
return $this->responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main batch response will be an array of requests so
|
||||
* we need to iterate over all the responses.
|
||||
*
|
||||
* @param array $responses
|
||||
*/
|
||||
public function setResponses(array $responses)
|
||||
{
|
||||
$this->responses = [];
|
||||
|
||||
foreach ($responses as $key => $graphResponse) {
|
||||
$this->addResponse($key, $graphResponse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a response to the list.
|
||||
*
|
||||
* @param int $key
|
||||
* @param array|null $response
|
||||
*/
|
||||
public function addResponse($key, $response)
|
||||
{
|
||||
$originalRequestName = isset($this->batchRequest[$key]['name']) ? $this->batchRequest[$key]['name'] : $key;
|
||||
$originalRequest = isset($this->batchRequest[$key]['request']) ? $this->batchRequest[$key]['request'] : null;
|
||||
|
||||
$httpResponseBody = isset($response['body']) ? $response['body'] : null;
|
||||
$httpResponseCode = isset($response['code']) ? $response['code'] : null;
|
||||
// @TODO With PHP 5.5 support, this becomes array_column($response['headers'], 'value', 'name')
|
||||
$httpResponseHeaders = isset($response['headers']) ? $this->normalizeBatchHeaders($response['headers']) : [];
|
||||
|
||||
$this->responses[$originalRequestName] = new FacebookResponse(
|
||||
$originalRequest,
|
||||
$httpResponseBody,
|
||||
$httpResponseCode,
|
||||
$httpResponseHeaders
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->responses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->addResponse($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->responses[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->responses[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->responses[$offset]) ? $this->responses[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the batch header array into a standard format.
|
||||
* @TODO replace with array_column() when PHP 5.5 is supported.
|
||||
*
|
||||
* @param array $batchHeaders
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function normalizeBatchHeaders(array $batchHeaders)
|
||||
{
|
||||
$headers = [];
|
||||
|
||||
foreach ($batchHeaders as $header) {
|
||||
$headers[$header['name']] = $header['value'];
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
@ -1,250 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook;
|
||||
|
||||
use Facebook\HttpClients\FacebookHttpClientInterface;
|
||||
use Facebook\HttpClients\FacebookCurlHttpClient;
|
||||
use Facebook\HttpClients\FacebookStreamHttpClient;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class FacebookClient
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookClient
|
||||
{
|
||||
/**
|
||||
* @const string Production Graph API URL.
|
||||
*/
|
||||
const BASE_GRAPH_URL = 'https://graph.facebook.com';
|
||||
|
||||
/**
|
||||
* @const string Graph API URL for video uploads.
|
||||
*/
|
||||
const BASE_GRAPH_VIDEO_URL = 'https://graph-video.facebook.com';
|
||||
|
||||
/**
|
||||
* @const string Beta Graph API URL.
|
||||
*/
|
||||
const BASE_GRAPH_URL_BETA = 'https://graph.beta.facebook.com';
|
||||
|
||||
/**
|
||||
* @const string Beta Graph API URL for video uploads.
|
||||
*/
|
||||
const BASE_GRAPH_VIDEO_URL_BETA = 'https://graph-video.beta.facebook.com';
|
||||
|
||||
/**
|
||||
* @const int The timeout in seconds for a normal request.
|
||||
*/
|
||||
const DEFAULT_REQUEST_TIMEOUT = 60;
|
||||
|
||||
/**
|
||||
* @const int The timeout in seconds for a request that contains file uploads.
|
||||
*/
|
||||
const DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT = 3600;
|
||||
|
||||
/**
|
||||
* @const int The timeout in seconds for a request that contains video uploads.
|
||||
*/
|
||||
const DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT = 7200;
|
||||
|
||||
/**
|
||||
* @var bool Toggle to use Graph beta url.
|
||||
*/
|
||||
protected $enableBetaMode = false;
|
||||
|
||||
/**
|
||||
* @var FacebookHttpClientInterface HTTP client handler.
|
||||
*/
|
||||
protected $httpClientHandler;
|
||||
|
||||
/**
|
||||
* @var int The number of calls that have been made to Graph.
|
||||
*/
|
||||
public static $requestCount = 0;
|
||||
|
||||
/**
|
||||
* Instantiates a new FacebookClient object.
|
||||
*
|
||||
* @param FacebookHttpClientInterface|null $httpClientHandler
|
||||
* @param boolean $enableBeta
|
||||
*/
|
||||
public function __construct(FacebookHttpClientInterface $httpClientHandler = null, $enableBeta = false)
|
||||
{
|
||||
$this->httpClientHandler = $httpClientHandler ?: $this->detectHttpClientHandler();
|
||||
$this->enableBetaMode = $enableBeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP client handler.
|
||||
*
|
||||
* @param FacebookHttpClientInterface $httpClientHandler
|
||||
*/
|
||||
public function setHttpClientHandler(FacebookHttpClientInterface $httpClientHandler)
|
||||
{
|
||||
$this->httpClientHandler = $httpClientHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP client handler.
|
||||
*
|
||||
* @return FacebookHttpClientInterface
|
||||
*/
|
||||
public function getHttpClientHandler()
|
||||
{
|
||||
return $this->httpClientHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects which HTTP client handler to use.
|
||||
*
|
||||
* @return FacebookHttpClientInterface
|
||||
*/
|
||||
public function detectHttpClientHandler()
|
||||
{
|
||||
return extension_loaded('curl') ? new FacebookCurlHttpClient() : new FacebookStreamHttpClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle beta mode.
|
||||
*
|
||||
* @param boolean $betaMode
|
||||
*/
|
||||
public function enableBetaMode($betaMode = true)
|
||||
{
|
||||
$this->enableBetaMode = $betaMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base Graph URL.
|
||||
*
|
||||
* @param boolean $postToVideoUrl Post to the video API if videos are being uploaded.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBaseGraphUrl($postToVideoUrl = false)
|
||||
{
|
||||
if ($postToVideoUrl) {
|
||||
return $this->enableBetaMode ? static::BASE_GRAPH_VIDEO_URL_BETA : static::BASE_GRAPH_VIDEO_URL;
|
||||
}
|
||||
|
||||
return $this->enableBetaMode ? static::BASE_GRAPH_URL_BETA : static::BASE_GRAPH_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the request for sending to the client handler.
|
||||
*
|
||||
* @param FacebookRequest $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function prepareRequestMessage(FacebookRequest $request)
|
||||
{
|
||||
$postToVideoUrl = $request->containsVideoUploads();
|
||||
$url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl();
|
||||
|
||||
// If we're sending files they should be sent as multipart/form-data
|
||||
if ($request->containsFileUploads()) {
|
||||
$requestBody = $request->getMultipartBody();
|
||||
$request->setHeaders([
|
||||
'Content-Type' => 'multipart/form-data; boundary=' . $requestBody->getBoundary(),
|
||||
]);
|
||||
} else {
|
||||
$requestBody = $request->getUrlEncodedBody();
|
||||
$request->setHeaders([
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
$url,
|
||||
$request->getMethod(),
|
||||
$request->getHeaders(),
|
||||
$requestBody->getBody(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the request to Graph and returns the result.
|
||||
*
|
||||
* @param FacebookRequest $request
|
||||
*
|
||||
* @return FacebookResponse
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function sendRequest(FacebookRequest $request)
|
||||
{
|
||||
if (get_class($request) === 'Facebook\FacebookRequest') {
|
||||
$request->validateAccessToken();
|
||||
}
|
||||
|
||||
list($url, $method, $headers, $body) = $this->prepareRequestMessage($request);
|
||||
|
||||
// Since file uploads can take a while, we need to give more time for uploads
|
||||
$timeOut = static::DEFAULT_REQUEST_TIMEOUT;
|
||||
if ($request->containsFileUploads()) {
|
||||
$timeOut = static::DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT;
|
||||
} elseif ($request->containsVideoUploads()) {
|
||||
$timeOut = static::DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT;
|
||||
}
|
||||
|
||||
// Should throw `FacebookSDKException` exception on HTTP client error.
|
||||
// Don't catch to allow it to bubble up.
|
||||
$rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers, $timeOut);
|
||||
|
||||
static::$requestCount++;
|
||||
|
||||
$returnResponse = new FacebookResponse(
|
||||
$request,
|
||||
$rawResponse->getBody(),
|
||||
$rawResponse->getHttpResponseCode(),
|
||||
$rawResponse->getHeaders()
|
||||
);
|
||||
|
||||
if ($returnResponse->isError()) {
|
||||
throw $returnResponse->getThrownException();
|
||||
}
|
||||
|
||||
return $returnResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a batched request to Graph and returns the result.
|
||||
*
|
||||
* @param FacebookBatchRequest $request
|
||||
*
|
||||
* @return FacebookBatchResponse
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function sendBatchRequest(FacebookBatchRequest $request)
|
||||
{
|
||||
$request->prepareRequestsForBatch();
|
||||
$facebookResponse = $this->sendRequest($request);
|
||||
|
||||
return new FacebookBatchResponse($request, $facebookResponse);
|
||||
}
|
||||
}
|
@ -1,534 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook;
|
||||
|
||||
use Facebook\Authentication\AccessToken;
|
||||
use Facebook\Url\FacebookUrlManipulator;
|
||||
use Facebook\FileUpload\FacebookFile;
|
||||
use Facebook\FileUpload\FacebookVideo;
|
||||
use Facebook\Http\RequestBodyMultipart;
|
||||
use Facebook\Http\RequestBodyUrlEncoded;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class Request
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookRequest
|
||||
{
|
||||
/**
|
||||
* @var FacebookApp The Facebook app entity.
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var string|null The access token to use for this request.
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* @var string The HTTP method for this request.
|
||||
*/
|
||||
protected $method;
|
||||
|
||||
/**
|
||||
* @var string The Graph endpoint for this request.
|
||||
*/
|
||||
protected $endpoint;
|
||||
|
||||
/**
|
||||
* @var array The headers to send with this request.
|
||||
*/
|
||||
protected $headers = [];
|
||||
|
||||
/**
|
||||
* @var array The parameters to send with this request.
|
||||
*/
|
||||
protected $params = [];
|
||||
|
||||
/**
|
||||
* @var array The files to send with this request.
|
||||
*/
|
||||
protected $files = [];
|
||||
|
||||
/**
|
||||
* @var string ETag to send with this request.
|
||||
*/
|
||||
protected $eTag;
|
||||
|
||||
/**
|
||||
* @var string Graph version to use for this request.
|
||||
*/
|
||||
protected $graphVersion;
|
||||
|
||||
/**
|
||||
* Creates a new Request entity.
|
||||
*
|
||||
* @param FacebookApp|null $app
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string|null $method
|
||||
* @param string|null $endpoint
|
||||
* @param array|null $params
|
||||
* @param string|null $eTag
|
||||
* @param string|null $graphVersion
|
||||
*/
|
||||
public function __construct(FacebookApp $app = null, $accessToken = null, $method = null, $endpoint = null, array $params = [], $eTag = null, $graphVersion = null)
|
||||
{
|
||||
$this->setApp($app);
|
||||
$this->setAccessToken($accessToken);
|
||||
$this->setMethod($method);
|
||||
$this->setEndpoint($endpoint);
|
||||
$this->setParams($params);
|
||||
$this->setETag($eTag);
|
||||
$this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the access token for this request.
|
||||
*
|
||||
* @param AccessToken|string|null
|
||||
*
|
||||
* @return FacebookRequest
|
||||
*/
|
||||
public function setAccessToken($accessToken)
|
||||
{
|
||||
$this->accessToken = $accessToken;
|
||||
if ($accessToken instanceof AccessToken) {
|
||||
$this->accessToken = $accessToken->getValue();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the access token with one harvested from a URL or POST params.
|
||||
*
|
||||
* @param string $accessToken The access token.
|
||||
*
|
||||
* @return FacebookRequest
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function setAccessTokenFromParams($accessToken)
|
||||
{
|
||||
$existingAccessToken = $this->getAccessToken();
|
||||
if (!$existingAccessToken) {
|
||||
$this->setAccessToken($accessToken);
|
||||
} elseif ($accessToken !== $existingAccessToken) {
|
||||
throw new FacebookSDKException('Access token mismatch. The access token provided in the FacebookRequest and the one provided in the URL or POST params do not match.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access token for this request.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAccessToken()
|
||||
{
|
||||
return $this->accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access token for this request as an AccessToken entity.
|
||||
*
|
||||
* @return AccessToken|null
|
||||
*/
|
||||
public function getAccessTokenEntity()
|
||||
{
|
||||
return $this->accessToken ? new AccessToken($this->accessToken) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the FacebookApp entity used for this request.
|
||||
*
|
||||
* @param FacebookApp|null $app
|
||||
*/
|
||||
public function setApp(FacebookApp $app = null)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FacebookApp entity used for this request.
|
||||
*
|
||||
* @return FacebookApp
|
||||
*/
|
||||
public function getApp()
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an app secret proof to sign this request.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAppSecretProof()
|
||||
{
|
||||
if (!$accessTokenEntity = $this->getAccessTokenEntity()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $accessTokenEntity->getAppSecretProof($this->app->getSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an access token exists for this request.
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function validateAccessToken()
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
if (!$accessToken) {
|
||||
throw new FacebookSDKException('You must provide an access token.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTTP method for this request.
|
||||
*
|
||||
* @param string
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = strtoupper($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTTP method for this request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the HTTP method is set.
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function validateMethod()
|
||||
{
|
||||
if (!$this->method) {
|
||||
throw new FacebookSDKException('HTTP method not specified.');
|
||||
}
|
||||
|
||||
if (!in_array($this->method, ['GET', 'POST', 'DELETE'])) {
|
||||
throw new FacebookSDKException('Invalid HTTP method specified.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the endpoint for this request.
|
||||
*
|
||||
* @param string
|
||||
*
|
||||
* @return FacebookRequest
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function setEndpoint($endpoint)
|
||||
{
|
||||
// Harvest the access token from the endpoint to keep things in sync
|
||||
$params = FacebookUrlManipulator::getParamsAsArray($endpoint);
|
||||
if (isset($params['access_token'])) {
|
||||
$this->setAccessTokenFromParams($params['access_token']);
|
||||
}
|
||||
|
||||
// Clean the token & app secret proof from the endpoint.
|
||||
$filterParams = ['access_token', 'appsecret_proof'];
|
||||
$this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint, $filterParams);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the endpoint for this request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEndpoint()
|
||||
{
|
||||
// For batch requests, this will be empty
|
||||
return $this->endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return the headers for this request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
$headers = static::getDefaultHeaders();
|
||||
|
||||
if ($this->eTag) {
|
||||
$headers['If-None-Match'] = $this->eTag;
|
||||
}
|
||||
|
||||
return array_merge($this->headers, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the headers for this request.
|
||||
*
|
||||
* @param array $headers
|
||||
*/
|
||||
public function setHeaders(array $headers)
|
||||
{
|
||||
$this->headers = array_merge($this->headers, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the eTag value.
|
||||
*
|
||||
* @param string $eTag
|
||||
*/
|
||||
public function setETag($eTag)
|
||||
{
|
||||
$this->eTag = $eTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the params for this request.
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return FacebookRequest
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function setParams(array $params = [])
|
||||
{
|
||||
if (isset($params['access_token'])) {
|
||||
$this->setAccessTokenFromParams($params['access_token']);
|
||||
}
|
||||
|
||||
// Don't let these buggers slip in.
|
||||
unset($params['access_token'], $params['appsecret_proof']);
|
||||
|
||||
// @TODO Refactor code above with this
|
||||
//$params = $this->sanitizeAuthenticationParams($params);
|
||||
$params = $this->sanitizeFileParams($params);
|
||||
$this->dangerouslySetParams($params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the params for this request without filtering them first.
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return FacebookRequest
|
||||
*/
|
||||
public function dangerouslySetParams(array $params = [])
|
||||
{
|
||||
$this->params = array_merge($this->params, $params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over the params and pull out the file uploads.
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sanitizeFileParams(array $params)
|
||||
{
|
||||
foreach ($params as $key => $value) {
|
||||
if ($value instanceof FacebookFile) {
|
||||
$this->addFile($key, $value);
|
||||
unset($params[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file to be uploaded.
|
||||
*
|
||||
* @param string $key
|
||||
* @param FacebookFile $file
|
||||
*/
|
||||
public function addFile($key, FacebookFile $file)
|
||||
{
|
||||
$this->files[$key] = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the files from the upload queue.
|
||||
*/
|
||||
public function resetFiles()
|
||||
{
|
||||
$this->files = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of files to be uploaded.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFiles()
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's us know if there is a file upload with this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function containsFileUploads()
|
||||
{
|
||||
return !empty($this->files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's us know if there is a video upload with this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function containsVideoUploads()
|
||||
{
|
||||
foreach ($this->files as $file) {
|
||||
if ($file instanceof FacebookVideo) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body of the request as multipart/form-data.
|
||||
*
|
||||
* @return RequestBodyMultipart
|
||||
*/
|
||||
public function getMultipartBody()
|
||||
{
|
||||
$params = $this->getPostParams();
|
||||
|
||||
return new RequestBodyMultipart($params, $this->files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the body of the request as URL-encoded.
|
||||
*
|
||||
* @return RequestBodyUrlEncoded
|
||||
*/
|
||||
public function getUrlEncodedBody()
|
||||
{
|
||||
$params = $this->getPostParams();
|
||||
|
||||
return new RequestBodyUrlEncoded($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return the params for this request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
$params = $this->params;
|
||||
|
||||
$accessToken = $this->getAccessToken();
|
||||
if ($accessToken) {
|
||||
$params['access_token'] = $accessToken;
|
||||
$params['appsecret_proof'] = $this->getAppSecretProof();
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only return params on POST requests.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPostParams()
|
||||
{
|
||||
if ($this->getMethod() === 'POST') {
|
||||
return $this->getParams();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* The graph version used for this request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGraphVersion()
|
||||
{
|
||||
return $this->graphVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return the URL for this request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
$this->validateMethod();
|
||||
|
||||
$graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion);
|
||||
$endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint());
|
||||
|
||||
$url = $graphVersion . $endpoint;
|
||||
|
||||
if ($this->getMethod() !== 'POST') {
|
||||
$params = $this->getParams();
|
||||
$url = FacebookUrlManipulator::appendParamsToUrl($url, $params);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default headers that every request should use.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getDefaultHeaders()
|
||||
{
|
||||
return [
|
||||
'User-Agent' => 'fb-php-' . Facebook::VERSION,
|
||||
'Accept-Encoding' => '*',
|
||||
];
|
||||
}
|
||||
}
|
@ -1,410 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook;
|
||||
|
||||
use Facebook\GraphNodes\GraphNodeFactory;
|
||||
use Facebook\Exceptions\FacebookResponseException;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class FacebookResponse
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookResponse
|
||||
{
|
||||
/**
|
||||
* @var int The HTTP status code response from Graph.
|
||||
*/
|
||||
protected $httpStatusCode;
|
||||
|
||||
/**
|
||||
* @var array The headers returned from Graph.
|
||||
*/
|
||||
protected $headers;
|
||||
|
||||
/**
|
||||
* @var string The raw body of the response from Graph.
|
||||
*/
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
* @var array The decoded body of the Graph response.
|
||||
*/
|
||||
protected $decodedBody = [];
|
||||
|
||||
/**
|
||||
* @var FacebookRequest The original request that returned this response.
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var FacebookSDKException The exception thrown by this request.
|
||||
*/
|
||||
protected $thrownException;
|
||||
|
||||
/**
|
||||
* Creates a new Response entity.
|
||||
*
|
||||
* @param FacebookRequest $request
|
||||
* @param string|null $body
|
||||
* @param int|null $httpStatusCode
|
||||
* @param array|null $headers
|
||||
*/
|
||||
public function __construct(FacebookRequest $request, $body = null, $httpStatusCode = null, array $headers = [])
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->body = $body;
|
||||
$this->httpStatusCode = $httpStatusCode;
|
||||
$this->headers = $headers;
|
||||
|
||||
$this->decodeBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the original request that returned this response.
|
||||
*
|
||||
* @return FacebookRequest
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the FacebookApp entity used for this response.
|
||||
*
|
||||
* @return FacebookApp
|
||||
*/
|
||||
public function getApp()
|
||||
{
|
||||
return $this->request->getApp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access token that was used for this response.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAccessToken()
|
||||
{
|
||||
return $this->request->getAccessToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTTP status code for this response.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHttpStatusCode()
|
||||
{
|
||||
return $this->httpStatusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTTP headers for this response.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw body response.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the decoded body response.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDecodedBody()
|
||||
{
|
||||
return $this->decodedBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the app secret proof that was used for this response.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAppSecretProof()
|
||||
{
|
||||
return $this->request->getAppSecretProof();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ETag associated with the response.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getETag()
|
||||
{
|
||||
return isset($this->headers['ETag']) ? $this->headers['ETag'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of Graph that returned this response.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getGraphVersion()
|
||||
{
|
||||
return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-Version'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Graph returned an error message.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isError()
|
||||
{
|
||||
return isset($this->decodedBody['error']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws the exception.
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function throwException()
|
||||
{
|
||||
throw $this->thrownException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates an exception to be thrown later.
|
||||
*/
|
||||
public function makeException()
|
||||
{
|
||||
$this->thrownException = FacebookResponseException::create($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exception that was thrown for this request.
|
||||
*
|
||||
* @return FacebookResponseException|null
|
||||
*/
|
||||
public function getThrownException()
|
||||
{
|
||||
return $this->thrownException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the raw response into an array if possible.
|
||||
*
|
||||
* Graph will return 2 types of responses:
|
||||
* - JSON(P)
|
||||
* Most responses from Graph are JSON(P)
|
||||
* - application/x-www-form-urlencoded key/value pairs
|
||||
* Happens on the `/oauth/access_token` endpoint when exchanging
|
||||
* a short-lived access token for a long-lived access token
|
||||
* - And sometimes nothing :/ but that'd be a bug.
|
||||
*/
|
||||
public function decodeBody()
|
||||
{
|
||||
$this->decodedBody = json_decode($this->body, true);
|
||||
|
||||
if ($this->decodedBody === null) {
|
||||
$this->decodedBody = [];
|
||||
parse_str($this->body, $this->decodedBody);
|
||||
} elseif (is_bool($this->decodedBody)) {
|
||||
// Backwards compatibility for Graph < 2.1.
|
||||
// Mimics 2.1 responses.
|
||||
// @TODO Remove this after Graph 2.0 is no longer supported
|
||||
$this->decodedBody = ['success' => $this->decodedBody];
|
||||
} elseif (is_numeric($this->decodedBody)) {
|
||||
$this->decodedBody = ['id' => $this->decodedBody];
|
||||
}
|
||||
|
||||
if (!is_array($this->decodedBody)) {
|
||||
$this->decodedBody = [];
|
||||
}
|
||||
|
||||
if ($this->isError()) {
|
||||
$this->makeException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new GraphObject from response.
|
||||
*
|
||||
* @param string|null $subclassName The GraphNode subclass to cast to.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphObject
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*
|
||||
* @deprecated 5.0.0 getGraphObject() has been renamed to getGraphNode()
|
||||
* @todo v6: Remove this method
|
||||
*/
|
||||
public function getGraphObject($subclassName = null)
|
||||
{
|
||||
return $this->getGraphNode($subclassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new GraphNode from response.
|
||||
*
|
||||
* @param string|null $subclassName The GraphNode subclass to cast to.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphNode
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphNode($subclassName = null)
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphNode($subclassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for creating a GraphAlbum collection.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphAlbum
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphAlbum()
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphAlbum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for creating a GraphPage collection.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphPage
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphPage()
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for creating a GraphSessionInfo collection.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphSessionInfo
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphSessionInfo()
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphSessionInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for creating a GraphUser collection.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphUser
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphUser()
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for creating a GraphEvent collection.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphEvent
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphEvent()
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for creating a GraphGroup collection.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphGroup
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphGroup()
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphGroup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new GraphList from response.
|
||||
*
|
||||
* @param string|null $subclassName The GraphNode subclass to cast list items to.
|
||||
* @param boolean $auto_prefix Toggle to auto-prefix the subclass name.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphList
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*
|
||||
* @deprecated 5.0.0 getGraphList() has been renamed to getGraphEdge()
|
||||
* @todo v6: Remove this method
|
||||
*/
|
||||
public function getGraphList($subclassName = null, $auto_prefix = true)
|
||||
{
|
||||
return $this->getGraphEdge($subclassName, $auto_prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new GraphEdge from response.
|
||||
*
|
||||
* @param string|null $subclassName The GraphNode subclass to cast list items to.
|
||||
* @param boolean $auto_prefix Toggle to auto-prefix the subclass name.
|
||||
*
|
||||
* @return \Facebook\GraphNodes\GraphEdge
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getGraphEdge($subclassName = null, $auto_prefix = true)
|
||||
{
|
||||
$factory = new GraphNodeFactory($this);
|
||||
|
||||
return $factory->makeGraphEdge($subclassName, $auto_prefix);
|
||||
}
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\FileUpload;
|
||||
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class FacebookFile
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookFile
|
||||
{
|
||||
/**
|
||||
* @var string The path to the file on the system.
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var int The maximum bytes to read. Defaults to -1 (read all the remaining buffer).
|
||||
*/
|
||||
private $maxLength;
|
||||
|
||||
/**
|
||||
* @var int Seek to the specified offset before reading. If this number is negative, no seeking will occur and reading will start from the current position.
|
||||
*/
|
||||
private $offset;
|
||||
|
||||
/**
|
||||
* @var resource The stream pointing to the file.
|
||||
*/
|
||||
protected $stream;
|
||||
|
||||
/**
|
||||
* Creates a new FacebookFile entity.
|
||||
*
|
||||
* @param string $filePath
|
||||
* @param int $maxLength
|
||||
* @param int $offset
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function __construct($filePath, $maxLength = -1, $offset = -1)
|
||||
{
|
||||
$this->path = $filePath;
|
||||
$this->maxLength = $maxLength;
|
||||
$this->offset = $offset;
|
||||
$this->open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream when destructed.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a stream for the file.
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function open()
|
||||
{
|
||||
if (!$this->isRemoteFile($this->path) && !is_readable($this->path)) {
|
||||
throw new FacebookSDKException('Failed to create FacebookFile entity. Unable to read resource: ' . $this->path . '.');
|
||||
}
|
||||
|
||||
$this->stream = fopen($this->path, 'r');
|
||||
|
||||
if (!$this->stream) {
|
||||
throw new FacebookSDKException('Failed to create FacebookFile entity. Unable to open resource: ' . $this->path . '.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the file stream.
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if (is_resource($this->stream)) {
|
||||
fclose($this->stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contents of the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
return stream_get_contents($this->stream, $this->maxLength, $this->offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName()
|
||||
{
|
||||
return basename($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path of the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilePath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the file.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return filesize($this->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mimetype of the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMimetype()
|
||||
{
|
||||
return Mimetypes::getInstance()->fromFilename($this->path) ?: 'text/plain';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the path to the file is remote.
|
||||
*
|
||||
* @param string $pathToFile
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isRemoteFile($pathToFile)
|
||||
{
|
||||
return preg_match('/^(https?|ftp):\/\/.*/', $pathToFile) === 1;
|
||||
}
|
||||
}
|
@ -1,167 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\FileUpload;
|
||||
|
||||
use Facebook\Authentication\AccessToken;
|
||||
use Facebook\Exceptions\FacebookResponseException;
|
||||
use Facebook\Exceptions\FacebookResumableUploadException;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
use Facebook\FacebookApp;
|
||||
use Facebook\FacebookClient;
|
||||
use Facebook\FacebookRequest;
|
||||
|
||||
/**
|
||||
* Class FacebookResumableUploader
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookResumableUploader
|
||||
{
|
||||
/**
|
||||
* @var FacebookApp
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* @var FacebookClient The Facebook client service.
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* @var string Graph version to use for this request.
|
||||
*/
|
||||
protected $graphVersion;
|
||||
|
||||
/**
|
||||
* @param FacebookApp $app
|
||||
* @param FacebookClient $client
|
||||
* @param AccessToken|string|null $accessToken
|
||||
* @param string $graphVersion
|
||||
*/
|
||||
public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $graphVersion)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->client = $client;
|
||||
$this->accessToken = $accessToken;
|
||||
$this->graphVersion = $graphVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload by chunks - start phase
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param FacebookFile $file
|
||||
*
|
||||
* @return FacebookTransferChunk
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function start($endpoint, FacebookFile $file)
|
||||
{
|
||||
$params = [
|
||||
'upload_phase' => 'start',
|
||||
'file_size' => $file->getSize(),
|
||||
];
|
||||
$response = $this->sendUploadRequest($endpoint, $params);
|
||||
|
||||
return new FacebookTransferChunk($file, $response['upload_session_id'], $response['video_id'], $response['start_offset'], $response['end_offset']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload by chunks - transfer phase
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param FacebookTransferChunk $chunk
|
||||
* @param boolean $allowToThrow
|
||||
*
|
||||
* @return FacebookTransferChunk
|
||||
*
|
||||
* @throws FacebookResponseException
|
||||
*/
|
||||
public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow = false)
|
||||
{
|
||||
$params = [
|
||||
'upload_phase' => 'transfer',
|
||||
'upload_session_id' => $chunk->getUploadSessionId(),
|
||||
'start_offset' => $chunk->getStartOffset(),
|
||||
'video_file_chunk' => $chunk->getPartialFile(),
|
||||
];
|
||||
|
||||
try {
|
||||
$response = $this->sendUploadRequest($endpoint, $params);
|
||||
} catch (FacebookResponseException $e) {
|
||||
$preException = $e->getPrevious();
|
||||
if ($allowToThrow || !$preException instanceof FacebookResumableUploadException) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Return the same chunk entity so it can be retried.
|
||||
return $chunk;
|
||||
}
|
||||
|
||||
return new FacebookTransferChunk($chunk->getFile(), $chunk->getUploadSessionId(), $chunk->getVideoId(), $response['start_offset'], $response['end_offset']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload by chunks - finish phase
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param string $uploadSessionId
|
||||
* @param array $metadata The metadata associated with the file.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function finish($endpoint, $uploadSessionId, $metadata = [])
|
||||
{
|
||||
$params = array_merge($metadata, [
|
||||
'upload_phase' => 'finish',
|
||||
'upload_session_id' => $uploadSessionId,
|
||||
]);
|
||||
$response = $this->sendUploadRequest($endpoint, $params);
|
||||
|
||||
return $response['success'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to make a FacebookRequest and send it.
|
||||
*
|
||||
* @param string $endpoint The endpoint to POST to.
|
||||
* @param array $params The params to send with the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function sendUploadRequest($endpoint, $params = [])
|
||||
{
|
||||
$request = new FacebookRequest($this->app, $this->accessToken, 'POST', $endpoint, $params, null, $this->graphVersion);
|
||||
|
||||
return $this->client->sendRequest($request)->getDecodedBody();
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\FileUpload;
|
||||
|
||||
/**
|
||||
* Class FacebookTransferChunk
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookTransferChunk
|
||||
{
|
||||
/**
|
||||
* @var FacebookFile The file to chunk during upload.
|
||||
*/
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* @var int The ID of the upload session.
|
||||
*/
|
||||
private $uploadSessionId;
|
||||
|
||||
/**
|
||||
* @var int Start byte position of the next file chunk.
|
||||
*/
|
||||
private $startOffset;
|
||||
|
||||
/**
|
||||
* @var int End byte position of the next file chunk.
|
||||
*/
|
||||
private $endOffset;
|
||||
|
||||
/**
|
||||
* @var int The ID of the video.
|
||||
*/
|
||||
private $videoId;
|
||||
|
||||
/**
|
||||
* @param FacebookFile $file
|
||||
* @param int $uploadSessionId
|
||||
* @param int $videoId
|
||||
* @param int $startOffset
|
||||
* @param int $endOffset
|
||||
*/
|
||||
public function __construct(FacebookFile $file, $uploadSessionId, $videoId, $startOffset, $endOffset)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->uploadSessionId = $uploadSessionId;
|
||||
$this->videoId = $videoId;
|
||||
$this->startOffset = $startOffset;
|
||||
$this->endOffset = $endOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the file entity.
|
||||
*
|
||||
* @return FacebookFile
|
||||
*/
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a FacebookFile entity with partial content.
|
||||
*
|
||||
* @return FacebookFile
|
||||
*/
|
||||
public function getPartialFile()
|
||||
{
|
||||
$maxLength = $this->endOffset - $this->startOffset;
|
||||
|
||||
return new FacebookFile($this->file->getFilePath(), $maxLength, $this->startOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return upload session Id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getUploadSessionId()
|
||||
{
|
||||
return $this->uploadSessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether is the last chunk
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLastChunk()
|
||||
{
|
||||
return $this->startOffset === $this->endOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStartOffset()
|
||||
{
|
||||
return $this->startOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uploaded video Id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getVideoId()
|
||||
{
|
||||
return $this->videoId;
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\FileUpload;
|
||||
|
||||
/**
|
||||
* Class FacebookVideo
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class FacebookVideo extends FacebookFile
|
||||
{
|
||||
}
|
@ -1,988 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\FileUpload;
|
||||
|
||||
/**
|
||||
* Provides mappings of file extensions to mimetypes
|
||||
*
|
||||
* Taken from Guzzle
|
||||
*
|
||||
* @see https://github.com/guzzle/guzzle/blob/master/src/Mimetypes.php
|
||||
*
|
||||
* @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
|
||||
*/
|
||||
class Mimetypes
|
||||
{
|
||||
/** @var self */
|
||||
protected static $instance;
|
||||
|
||||
/** @var array Mapping of extension to mimetype */
|
||||
protected $mimetypes = [
|
||||
'3dml' => 'text/vnd.in3d.3dml',
|
||||
'3g2' => 'video/3gpp2',
|
||||
'3gp' => 'video/3gpp',
|
||||
'7z' => 'application/x-7z-compressed',
|
||||
'aab' => 'application/x-authorware-bin',
|
||||
'aac' => 'audio/x-aac',
|
||||
'aam' => 'application/x-authorware-map',
|
||||
'aas' => 'application/x-authorware-seg',
|
||||
'abw' => 'application/x-abiword',
|
||||
'ac' => 'application/pkix-attr-cert',
|
||||
'acc' => 'application/vnd.americandynamics.acc',
|
||||
'ace' => 'application/x-ace-compressed',
|
||||
'acu' => 'application/vnd.acucobol',
|
||||
'acutc' => 'application/vnd.acucorp',
|
||||
'adp' => 'audio/adpcm',
|
||||
'aep' => 'application/vnd.audiograph',
|
||||
'afm' => 'application/x-font-type1',
|
||||
'afp' => 'application/vnd.ibm.modcap',
|
||||
'ahead' => 'application/vnd.ahead.space',
|
||||
'ai' => 'application/postscript',
|
||||
'aif' => 'audio/x-aiff',
|
||||
'aifc' => 'audio/x-aiff',
|
||||
'aiff' => 'audio/x-aiff',
|
||||
'air' => 'application/vnd.adobe.air-application-installer-package+zip',
|
||||
'ait' => 'application/vnd.dvb.ait',
|
||||
'ami' => 'application/vnd.amiga.ami',
|
||||
'apk' => 'application/vnd.android.package-archive',
|
||||
'application' => 'application/x-ms-application',
|
||||
'apr' => 'application/vnd.lotus-approach',
|
||||
'asa' => 'text/plain',
|
||||
'asax' => 'application/octet-stream',
|
||||
'asc' => 'application/pgp-signature',
|
||||
'ascx' => 'text/plain',
|
||||
'asf' => 'video/x-ms-asf',
|
||||
'ashx' => 'text/plain',
|
||||
'asm' => 'text/x-asm',
|
||||
'asmx' => 'text/plain',
|
||||
'aso' => 'application/vnd.accpac.simply.aso',
|
||||
'asp' => 'text/plain',
|
||||
'aspx' => 'text/plain',
|
||||
'asx' => 'video/x-ms-asf',
|
||||
'atc' => 'application/vnd.acucorp',
|
||||
'atom' => 'application/atom+xml',
|
||||
'atomcat' => 'application/atomcat+xml',
|
||||
'atomsvc' => 'application/atomsvc+xml',
|
||||
'atx' => 'application/vnd.antix.game-component',
|
||||
'au' => 'audio/basic',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'aw' => 'application/applixware',
|
||||
'axd' => 'text/plain',
|
||||
'azf' => 'application/vnd.airzip.filesecure.azf',
|
||||
'azs' => 'application/vnd.airzip.filesecure.azs',
|
||||
'azw' => 'application/vnd.amazon.ebook',
|
||||
'bat' => 'application/x-msdownload',
|
||||
'bcpio' => 'application/x-bcpio',
|
||||
'bdf' => 'application/x-font-bdf',
|
||||
'bdm' => 'application/vnd.syncml.dm+wbxml',
|
||||
'bed' => 'application/vnd.realvnc.bed',
|
||||
'bh2' => 'application/vnd.fujitsu.oasysprs',
|
||||
'bin' => 'application/octet-stream',
|
||||
'bmi' => 'application/vnd.bmi',
|
||||
'bmp' => 'image/bmp',
|
||||
'book' => 'application/vnd.framemaker',
|
||||
'box' => 'application/vnd.previewsystems.box',
|
||||
'boz' => 'application/x-bzip2',
|
||||
'bpk' => 'application/octet-stream',
|
||||
'btif' => 'image/prs.btif',
|
||||
'bz' => 'application/x-bzip',
|
||||
'bz2' => 'application/x-bzip2',
|
||||
'c' => 'text/x-c',
|
||||
'c11amc' => 'application/vnd.cluetrust.cartomobile-config',
|
||||
'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg',
|
||||
'c4d' => 'application/vnd.clonk.c4group',
|
||||
'c4f' => 'application/vnd.clonk.c4group',
|
||||
'c4g' => 'application/vnd.clonk.c4group',
|
||||
'c4p' => 'application/vnd.clonk.c4group',
|
||||
'c4u' => 'application/vnd.clonk.c4group',
|
||||
'cab' => 'application/vnd.ms-cab-compressed',
|
||||
'car' => 'application/vnd.curl.car',
|
||||
'cat' => 'application/vnd.ms-pki.seccat',
|
||||
'cc' => 'text/x-c',
|
||||
'cct' => 'application/x-director',
|
||||
'ccxml' => 'application/ccxml+xml',
|
||||
'cdbcmsg' => 'application/vnd.contact.cmsg',
|
||||
'cdf' => 'application/x-netcdf',
|
||||
'cdkey' => 'application/vnd.mediastation.cdkey',
|
||||
'cdmia' => 'application/cdmi-capability',
|
||||
'cdmic' => 'application/cdmi-container',
|
||||
'cdmid' => 'application/cdmi-domain',
|
||||
'cdmio' => 'application/cdmi-object',
|
||||
'cdmiq' => 'application/cdmi-queue',
|
||||
'cdx' => 'chemical/x-cdx',
|
||||
'cdxml' => 'application/vnd.chemdraw+xml',
|
||||
'cdy' => 'application/vnd.cinderella',
|
||||
'cer' => 'application/pkix-cert',
|
||||
'cfc' => 'application/x-coldfusion',
|
||||
'cfm' => 'application/x-coldfusion',
|
||||
'cgm' => 'image/cgm',
|
||||
'chat' => 'application/x-chat',
|
||||
'chm' => 'application/vnd.ms-htmlhelp',
|
||||
'chrt' => 'application/vnd.kde.kchart',
|
||||
'cif' => 'chemical/x-cif',
|
||||
'cii' => 'application/vnd.anser-web-certificate-issue-initiation',
|
||||
'cil' => 'application/vnd.ms-artgalry',
|
||||
'cla' => 'application/vnd.claymore',
|
||||
'class' => 'application/java-vm',
|
||||
'clkk' => 'application/vnd.crick.clicker.keyboard',
|
||||
'clkp' => 'application/vnd.crick.clicker.palette',
|
||||
'clkt' => 'application/vnd.crick.clicker.template',
|
||||
'clkw' => 'application/vnd.crick.clicker.wordbank',
|
||||
'clkx' => 'application/vnd.crick.clicker',
|
||||
'clp' => 'application/x-msclip',
|
||||
'cmc' => 'application/vnd.cosmocaller',
|
||||
'cmdf' => 'chemical/x-cmdf',
|
||||
'cml' => 'chemical/x-cml',
|
||||
'cmp' => 'application/vnd.yellowriver-custom-menu',
|
||||
'cmx' => 'image/x-cmx',
|
||||
'cod' => 'application/vnd.rim.cod',
|
||||
'com' => 'application/x-msdownload',
|
||||
'conf' => 'text/plain',
|
||||
'cpio' => 'application/x-cpio',
|
||||
'cpp' => 'text/x-c',
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'crd' => 'application/x-mscardfile',
|
||||
'crl' => 'application/pkix-crl',
|
||||
'crt' => 'application/x-x509-ca-cert',
|
||||
'cryptonote' => 'application/vnd.rig.cryptonote',
|
||||
'cs' => 'text/plain',
|
||||
'csh' => 'application/x-csh',
|
||||
'csml' => 'chemical/x-csml',
|
||||
'csp' => 'application/vnd.commonspace',
|
||||
'css' => 'text/css',
|
||||
'cst' => 'application/x-director',
|
||||
'csv' => 'text/csv',
|
||||
'cu' => 'application/cu-seeme',
|
||||
'curl' => 'text/vnd.curl',
|
||||
'cww' => 'application/prs.cww',
|
||||
'cxt' => 'application/x-director',
|
||||
'cxx' => 'text/x-c',
|
||||
'dae' => 'model/vnd.collada+xml',
|
||||
'daf' => 'application/vnd.mobius.daf',
|
||||
'dataless' => 'application/vnd.fdsn.seed',
|
||||
'davmount' => 'application/davmount+xml',
|
||||
'dcr' => 'application/x-director',
|
||||
'dcurl' => 'text/vnd.curl.dcurl',
|
||||
'dd2' => 'application/vnd.oma.dd2+xml',
|
||||
'ddd' => 'application/vnd.fujixerox.ddd',
|
||||
'deb' => 'application/x-debian-package',
|
||||
'def' => 'text/plain',
|
||||
'deploy' => 'application/octet-stream',
|
||||
'der' => 'application/x-x509-ca-cert',
|
||||
'dfac' => 'application/vnd.dreamfactory',
|
||||
'dic' => 'text/x-c',
|
||||
'dir' => 'application/x-director',
|
||||
'dis' => 'application/vnd.mobius.dis',
|
||||
'dist' => 'application/octet-stream',
|
||||
'distz' => 'application/octet-stream',
|
||||
'djv' => 'image/vnd.djvu',
|
||||
'djvu' => 'image/vnd.djvu',
|
||||
'dll' => 'application/x-msdownload',
|
||||
'dmg' => 'application/octet-stream',
|
||||
'dms' => 'application/octet-stream',
|
||||
'dna' => 'application/vnd.dna',
|
||||
'doc' => 'application/msword',
|
||||
'docm' => 'application/vnd.ms-word.document.macroenabled.12',
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'dot' => 'application/msword',
|
||||
'dotm' => 'application/vnd.ms-word.template.macroenabled.12',
|
||||
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
||||
'dp' => 'application/vnd.osgi.dp',
|
||||
'dpg' => 'application/vnd.dpgraph',
|
||||
'dra' => 'audio/vnd.dra',
|
||||
'dsc' => 'text/prs.lines.tag',
|
||||
'dssc' => 'application/dssc+der',
|
||||
'dtb' => 'application/x-dtbook+xml',
|
||||
'dtd' => 'application/xml-dtd',
|
||||
'dts' => 'audio/vnd.dts',
|
||||
'dtshd' => 'audio/vnd.dts.hd',
|
||||
'dump' => 'application/octet-stream',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'dwf' => 'model/vnd.dwf',
|
||||
'dwg' => 'image/vnd.dwg',
|
||||
'dxf' => 'image/vnd.dxf',
|
||||
'dxp' => 'application/vnd.spotfire.dxp',
|
||||
'dxr' => 'application/x-director',
|
||||
'ecelp4800' => 'audio/vnd.nuera.ecelp4800',
|
||||
'ecelp7470' => 'audio/vnd.nuera.ecelp7470',
|
||||
'ecelp9600' => 'audio/vnd.nuera.ecelp9600',
|
||||
'ecma' => 'application/ecmascript',
|
||||
'edm' => 'application/vnd.novadigm.edm',
|
||||
'edx' => 'application/vnd.novadigm.edx',
|
||||
'efif' => 'application/vnd.picsel',
|
||||
'ei6' => 'application/vnd.pg.osasli',
|
||||
'elc' => 'application/octet-stream',
|
||||
'eml' => 'message/rfc822',
|
||||
'emma' => 'application/emma+xml',
|
||||
'eol' => 'audio/vnd.digital-winds',
|
||||
'eot' => 'application/vnd.ms-fontobject',
|
||||
'eps' => 'application/postscript',
|
||||
'epub' => 'application/epub+zip',
|
||||
'es3' => 'application/vnd.eszigno3+xml',
|
||||
'esf' => 'application/vnd.epson.esf',
|
||||
'et3' => 'application/vnd.eszigno3+xml',
|
||||
'etx' => 'text/x-setext',
|
||||
'exe' => 'application/x-msdownload',
|
||||
'exi' => 'application/exi',
|
||||
'ext' => 'application/vnd.novadigm.ext',
|
||||
'ez' => 'application/andrew-inset',
|
||||
'ez2' => 'application/vnd.ezpix-album',
|
||||
'ez3' => 'application/vnd.ezpix-package',
|
||||
'f' => 'text/x-fortran',
|
||||
'f4v' => 'video/x-f4v',
|
||||
'f77' => 'text/x-fortran',
|
||||
'f90' => 'text/x-fortran',
|
||||
'fbs' => 'image/vnd.fastbidsheet',
|
||||
'fcs' => 'application/vnd.isac.fcs',
|
||||
'fdf' => 'application/vnd.fdf',
|
||||
'fe_launch' => 'application/vnd.denovo.fcselayout-link',
|
||||
'fg5' => 'application/vnd.fujitsu.oasysgp',
|
||||
'fgd' => 'application/x-director',
|
||||
'fh' => 'image/x-freehand',
|
||||
'fh4' => 'image/x-freehand',
|
||||
'fh5' => 'image/x-freehand',
|
||||
'fh7' => 'image/x-freehand',
|
||||
'fhc' => 'image/x-freehand',
|
||||
'fig' => 'application/x-xfig',
|
||||
'fli' => 'video/x-fli',
|
||||
'flo' => 'application/vnd.micrografx.flo',
|
||||
'flv' => 'video/x-flv',
|
||||
'flw' => 'application/vnd.kde.kivio',
|
||||
'flx' => 'text/vnd.fmi.flexstor',
|
||||
'fly' => 'text/vnd.fly',
|
||||
'fm' => 'application/vnd.framemaker',
|
||||
'fnc' => 'application/vnd.frogans.fnc',
|
||||
'for' => 'text/x-fortran',
|
||||
'fpx' => 'image/vnd.fpx',
|
||||
'frame' => 'application/vnd.framemaker',
|
||||
'fsc' => 'application/vnd.fsc.weblaunch',
|
||||
'fst' => 'image/vnd.fst',
|
||||
'ftc' => 'application/vnd.fluxtime.clip',
|
||||
'fti' => 'application/vnd.anser-web-funds-transfer-initiation',
|
||||
'fvt' => 'video/vnd.fvt',
|
||||
'fxp' => 'application/vnd.adobe.fxp',
|
||||
'fxpl' => 'application/vnd.adobe.fxp',
|
||||
'fzs' => 'application/vnd.fuzzysheet',
|
||||
'g2w' => 'application/vnd.geoplan',
|
||||
'g3' => 'image/g3fax',
|
||||
'g3w' => 'application/vnd.geospace',
|
||||
'gac' => 'application/vnd.groove-account',
|
||||
'gdl' => 'model/vnd.gdl',
|
||||
'geo' => 'application/vnd.dynageo',
|
||||
'gex' => 'application/vnd.geometry-explorer',
|
||||
'ggb' => 'application/vnd.geogebra.file',
|
||||
'ggt' => 'application/vnd.geogebra.tool',
|
||||
'ghf' => 'application/vnd.groove-help',
|
||||
'gif' => 'image/gif',
|
||||
'gim' => 'application/vnd.groove-identity-message',
|
||||
'gmx' => 'application/vnd.gmx',
|
||||
'gnumeric' => 'application/x-gnumeric',
|
||||
'gph' => 'application/vnd.flographit',
|
||||
'gqf' => 'application/vnd.grafeq',
|
||||
'gqs' => 'application/vnd.grafeq',
|
||||
'gram' => 'application/srgs',
|
||||
'gre' => 'application/vnd.geometry-explorer',
|
||||
'grv' => 'application/vnd.groove-injector',
|
||||
'grxml' => 'application/srgs+xml',
|
||||
'gsf' => 'application/x-font-ghostscript',
|
||||
'gtar' => 'application/x-gtar',
|
||||
'gtm' => 'application/vnd.groove-tool-message',
|
||||
'gtw' => 'model/vnd.gtw',
|
||||
'gv' => 'text/vnd.graphviz',
|
||||
'gxt' => 'application/vnd.geonext',
|
||||
'h' => 'text/x-c',
|
||||
'h261' => 'video/h261',
|
||||
'h263' => 'video/h263',
|
||||
'h264' => 'video/h264',
|
||||
'hal' => 'application/vnd.hal+xml',
|
||||
'hbci' => 'application/vnd.hbci',
|
||||
'hdf' => 'application/x-hdf',
|
||||
'hh' => 'text/x-c',
|
||||
'hlp' => 'application/winhlp',
|
||||
'hpgl' => 'application/vnd.hp-hpgl',
|
||||
'hpid' => 'application/vnd.hp-hpid',
|
||||
'hps' => 'application/vnd.hp-hps',
|
||||
'hqx' => 'application/mac-binhex40',
|
||||
'hta' => 'application/octet-stream',
|
||||
'htc' => 'text/html',
|
||||
'htke' => 'application/vnd.kenameaapp',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'hvd' => 'application/vnd.yamaha.hv-dic',
|
||||
'hvp' => 'application/vnd.yamaha.hv-voice',
|
||||
'hvs' => 'application/vnd.yamaha.hv-script',
|
||||
'i2g' => 'application/vnd.intergeo',
|
||||
'icc' => 'application/vnd.iccprofile',
|
||||
'ice' => 'x-conference/x-cooltalk',
|
||||
'icm' => 'application/vnd.iccprofile',
|
||||
'ico' => 'image/x-icon',
|
||||
'ics' => 'text/calendar',
|
||||
'ief' => 'image/ief',
|
||||
'ifb' => 'text/calendar',
|
||||
'ifm' => 'application/vnd.shana.informed.formdata',
|
||||
'iges' => 'model/iges',
|
||||
'igl' => 'application/vnd.igloader',
|
||||
'igm' => 'application/vnd.insors.igm',
|
||||
'igs' => 'model/iges',
|
||||
'igx' => 'application/vnd.micrografx.igx',
|
||||
'iif' => 'application/vnd.shana.informed.interchange',
|
||||
'imp' => 'application/vnd.accpac.simply.imp',
|
||||
'ims' => 'application/vnd.ms-ims',
|
||||
'in' => 'text/plain',
|
||||
'ini' => 'text/plain',
|
||||
'ipfix' => 'application/ipfix',
|
||||
'ipk' => 'application/vnd.shana.informed.package',
|
||||
'irm' => 'application/vnd.ibm.rights-management',
|
||||
'irp' => 'application/vnd.irepository.package+xml',
|
||||
'iso' => 'application/octet-stream',
|
||||
'itp' => 'application/vnd.shana.informed.formtemplate',
|
||||
'ivp' => 'application/vnd.immervision-ivp',
|
||||
'ivu' => 'application/vnd.immervision-ivu',
|
||||
'jad' => 'text/vnd.sun.j2me.app-descriptor',
|
||||
'jam' => 'application/vnd.jam',
|
||||
'jar' => 'application/java-archive',
|
||||
'java' => 'text/x-java-source',
|
||||
'jisp' => 'application/vnd.jisp',
|
||||
'jlt' => 'application/vnd.hp-jlyt',
|
||||
'jnlp' => 'application/x-java-jnlp-file',
|
||||
'joda' => 'application/vnd.joost.joda-archive',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpgm' => 'video/jpm',
|
||||
'jpgv' => 'video/jpeg',
|
||||
'jpm' => 'video/jpm',
|
||||
'js' => 'text/javascript',
|
||||
'json' => 'application/json',
|
||||
'kar' => 'audio/midi',
|
||||
'karbon' => 'application/vnd.kde.karbon',
|
||||
'kfo' => 'application/vnd.kde.kformula',
|
||||
'kia' => 'application/vnd.kidspiration',
|
||||
'kml' => 'application/vnd.google-earth.kml+xml',
|
||||
'kmz' => 'application/vnd.google-earth.kmz',
|
||||
'kne' => 'application/vnd.kinar',
|
||||
'knp' => 'application/vnd.kinar',
|
||||
'kon' => 'application/vnd.kde.kontour',
|
||||
'kpr' => 'application/vnd.kde.kpresenter',
|
||||
'kpt' => 'application/vnd.kde.kpresenter',
|
||||
'ksp' => 'application/vnd.kde.kspread',
|
||||
'ktr' => 'application/vnd.kahootz',
|
||||
'ktx' => 'image/ktx',
|
||||
'ktz' => 'application/vnd.kahootz',
|
||||
'kwd' => 'application/vnd.kde.kword',
|
||||
'kwt' => 'application/vnd.kde.kword',
|
||||
'lasxml' => 'application/vnd.las.las+xml',
|
||||
'latex' => 'application/x-latex',
|
||||
'lbd' => 'application/vnd.llamagraphics.life-balance.desktop',
|
||||
'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
|
||||
'les' => 'application/vnd.hhe.lesson-player',
|
||||
'lha' => 'application/octet-stream',
|
||||
'link66' => 'application/vnd.route66.link66+xml',
|
||||
'list' => 'text/plain',
|
||||
'list3820' => 'application/vnd.ibm.modcap',
|
||||
'listafp' => 'application/vnd.ibm.modcap',
|
||||
'log' => 'text/plain',
|
||||
'lostxml' => 'application/lost+xml',
|
||||
'lrf' => 'application/octet-stream',
|
||||
'lrm' => 'application/vnd.ms-lrm',
|
||||
'ltf' => 'application/vnd.frogans.ltf',
|
||||
'lvp' => 'audio/vnd.lucent.voice',
|
||||
'lwp' => 'application/vnd.lotus-wordpro',
|
||||
'lzh' => 'application/octet-stream',
|
||||
'm13' => 'application/x-msmediaview',
|
||||
'm14' => 'application/x-msmediaview',
|
||||
'm1v' => 'video/mpeg',
|
||||
'm21' => 'application/mp21',
|
||||
'm2a' => 'audio/mpeg',
|
||||
'm2v' => 'video/mpeg',
|
||||
'm3a' => 'audio/mpeg',
|
||||
'm3u' => 'audio/x-mpegurl',
|
||||
'm3u8' => 'application/vnd.apple.mpegurl',
|
||||
'm4a' => 'audio/mp4',
|
||||
'm4u' => 'video/vnd.mpegurl',
|
||||
'm4v' => 'video/mp4',
|
||||
'ma' => 'application/mathematica',
|
||||
'mads' => 'application/mads+xml',
|
||||
'mag' => 'application/vnd.ecowin.chart',
|
||||
'maker' => 'application/vnd.framemaker',
|
||||
'man' => 'text/troff',
|
||||
'mathml' => 'application/mathml+xml',
|
||||
'mb' => 'application/mathematica',
|
||||
'mbk' => 'application/vnd.mobius.mbk',
|
||||
'mbox' => 'application/mbox',
|
||||
'mc1' => 'application/vnd.medcalcdata',
|
||||
'mcd' => 'application/vnd.mcd',
|
||||
'mcurl' => 'text/vnd.curl.mcurl',
|
||||
'mdb' => 'application/x-msaccess',
|
||||
'mdi' => 'image/vnd.ms-modi',
|
||||
'me' => 'text/troff',
|
||||
'mesh' => 'model/mesh',
|
||||
'meta4' => 'application/metalink4+xml',
|
||||
'mets' => 'application/mets+xml',
|
||||
'mfm' => 'application/vnd.mfmp',
|
||||
'mgp' => 'application/vnd.osgeo.mapguide.package',
|
||||
'mgz' => 'application/vnd.proteus.magazine',
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'mime' => 'message/rfc822',
|
||||
'mj2' => 'video/mj2',
|
||||
'mjp2' => 'video/mj2',
|
||||
'mlp' => 'application/vnd.dolby.mlp',
|
||||
'mmd' => 'application/vnd.chipnuts.karaoke-mmd',
|
||||
'mmf' => 'application/vnd.smaf',
|
||||
'mmr' => 'image/vnd.fujixerox.edmics-mmr',
|
||||
'mny' => 'application/x-msmoney',
|
||||
'mobi' => 'application/x-mobipocket-ebook',
|
||||
'mods' => 'application/mods+xml',
|
||||
'mov' => 'video/quicktime',
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp21' => 'application/mp21',
|
||||
'mp2a' => 'audio/mpeg',
|
||||
'mp3' => 'audio/mpeg',
|
||||
'mp4' => 'video/mp4',
|
||||
'mp4a' => 'audio/mp4',
|
||||
'mp4s' => 'application/mp4',
|
||||
'mp4v' => 'video/mp4',
|
||||
'mpc' => 'application/vnd.mophun.certificate',
|
||||
'mpe' => 'video/mpeg',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpg4' => 'video/mp4',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'mpkg' => 'application/vnd.apple.installer+xml',
|
||||
'mpm' => 'application/vnd.blueice.multipass',
|
||||
'mpn' => 'application/vnd.mophun.application',
|
||||
'mpp' => 'application/vnd.ms-project',
|
||||
'mpt' => 'application/vnd.ms-project',
|
||||
'mpy' => 'application/vnd.ibm.minipay',
|
||||
'mqy' => 'application/vnd.mobius.mqy',
|
||||
'mrc' => 'application/marc',
|
||||
'mrcx' => 'application/marcxml+xml',
|
||||
'ms' => 'text/troff',
|
||||
'mscml' => 'application/mediaservercontrol+xml',
|
||||
'mseed' => 'application/vnd.fdsn.mseed',
|
||||
'mseq' => 'application/vnd.mseq',
|
||||
'msf' => 'application/vnd.epson.msf',
|
||||
'msh' => 'model/mesh',
|
||||
'msi' => 'application/x-msdownload',
|
||||
'msl' => 'application/vnd.mobius.msl',
|
||||
'msty' => 'application/vnd.muvee.style',
|
||||
'mts' => 'model/vnd.mts',
|
||||
'mus' => 'application/vnd.musician',
|
||||
'musicxml' => 'application/vnd.recordare.musicxml+xml',
|
||||
'mvb' => 'application/x-msmediaview',
|
||||
'mwf' => 'application/vnd.mfer',
|
||||
'mxf' => 'application/mxf',
|
||||
'mxl' => 'application/vnd.recordare.musicxml',
|
||||
'mxml' => 'application/xv+xml',
|
||||
'mxs' => 'application/vnd.triscape.mxs',
|
||||
'mxu' => 'video/vnd.mpegurl',
|
||||
'n-gage' => 'application/vnd.nokia.n-gage.symbian.install',
|
||||
'n3' => 'text/n3',
|
||||
'nb' => 'application/mathematica',
|
||||
'nbp' => 'application/vnd.wolfram.player',
|
||||
'nc' => 'application/x-netcdf',
|
||||
'ncx' => 'application/x-dtbncx+xml',
|
||||
'ngdat' => 'application/vnd.nokia.n-gage.data',
|
||||
'nlu' => 'application/vnd.neurolanguage.nlu',
|
||||
'nml' => 'application/vnd.enliven',
|
||||
'nnd' => 'application/vnd.noblenet-directory',
|
||||
'nns' => 'application/vnd.noblenet-sealer',
|
||||
'nnw' => 'application/vnd.noblenet-web',
|
||||
'npx' => 'image/vnd.net-fpx',
|
||||
'nsf' => 'application/vnd.lotus-notes',
|
||||
'oa2' => 'application/vnd.fujitsu.oasys2',
|
||||
'oa3' => 'application/vnd.fujitsu.oasys3',
|
||||
'oas' => 'application/vnd.fujitsu.oasys',
|
||||
'obd' => 'application/x-msbinder',
|
||||
'oda' => 'application/oda',
|
||||
'odb' => 'application/vnd.oasis.opendocument.database',
|
||||
'odc' => 'application/vnd.oasis.opendocument.chart',
|
||||
'odf' => 'application/vnd.oasis.opendocument.formula',
|
||||
'odft' => 'application/vnd.oasis.opendocument.formula-template',
|
||||
'odg' => 'application/vnd.oasis.opendocument.graphics',
|
||||
'odi' => 'application/vnd.oasis.opendocument.image',
|
||||
'odm' => 'application/vnd.oasis.opendocument.text-master',
|
||||
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'oga' => 'audio/ogg',
|
||||
'ogg' => 'audio/ogg',
|
||||
'ogv' => 'video/ogg',
|
||||
'ogx' => 'application/ogg',
|
||||
'onepkg' => 'application/onenote',
|
||||
'onetmp' => 'application/onenote',
|
||||
'onetoc' => 'application/onenote',
|
||||
'onetoc2' => 'application/onenote',
|
||||
'opf' => 'application/oebps-package+xml',
|
||||
'oprc' => 'application/vnd.palm',
|
||||
'org' => 'application/vnd.lotus-organizer',
|
||||
'osf' => 'application/vnd.yamaha.openscoreformat',
|
||||
'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml',
|
||||
'otc' => 'application/vnd.oasis.opendocument.chart-template',
|
||||
'otf' => 'application/x-font-otf',
|
||||
'otg' => 'application/vnd.oasis.opendocument.graphics-template',
|
||||
'oth' => 'application/vnd.oasis.opendocument.text-web',
|
||||
'oti' => 'application/vnd.oasis.opendocument.image-template',
|
||||
'otp' => 'application/vnd.oasis.opendocument.presentation-template',
|
||||
'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
|
||||
'ott' => 'application/vnd.oasis.opendocument.text-template',
|
||||
'oxt' => 'application/vnd.openofficeorg.extension',
|
||||
'p' => 'text/x-pascal',
|
||||
'p10' => 'application/pkcs10',
|
||||
'p12' => 'application/x-pkcs12',
|
||||
'p7b' => 'application/x-pkcs7-certificates',
|
||||
'p7c' => 'application/pkcs7-mime',
|
||||
'p7m' => 'application/pkcs7-mime',
|
||||
'p7r' => 'application/x-pkcs7-certreqresp',
|
||||
'p7s' => 'application/pkcs7-signature',
|
||||
'p8' => 'application/pkcs8',
|
||||
'pas' => 'text/x-pascal',
|
||||
'paw' => 'application/vnd.pawaafile',
|
||||
'pbd' => 'application/vnd.powerbuilder6',
|
||||
'pbm' => 'image/x-portable-bitmap',
|
||||
'pcf' => 'application/x-font-pcf',
|
||||
'pcl' => 'application/vnd.hp-pcl',
|
||||
'pclxl' => 'application/vnd.hp-pclxl',
|
||||
'pct' => 'image/x-pict',
|
||||
'pcurl' => 'application/vnd.curl.pcurl',
|
||||
'pcx' => 'image/x-pcx',
|
||||
'pdb' => 'application/vnd.palm',
|
||||
'pdf' => 'application/pdf',
|
||||
'pfa' => 'application/x-font-type1',
|
||||
'pfb' => 'application/x-font-type1',
|
||||
'pfm' => 'application/x-font-type1',
|
||||
'pfr' => 'application/font-tdpfr',
|
||||
'pfx' => 'application/x-pkcs12',
|
||||
'pgm' => 'image/x-portable-graymap',
|
||||
'pgn' => 'application/x-chess-pgn',
|
||||
'pgp' => 'application/pgp-encrypted',
|
||||
'php' => 'text/x-php',
|
||||
'phps' => 'application/x-httpd-phps',
|
||||
'pic' => 'image/x-pict',
|
||||
'pkg' => 'application/octet-stream',
|
||||
'pki' => 'application/pkixcmp',
|
||||
'pkipath' => 'application/pkix-pkipath',
|
||||
'plb' => 'application/vnd.3gpp.pic-bw-large',
|
||||
'plc' => 'application/vnd.mobius.plc',
|
||||
'plf' => 'application/vnd.pocketlearn',
|
||||
'pls' => 'application/pls+xml',
|
||||
'pml' => 'application/vnd.ctc-posml',
|
||||
'png' => 'image/png',
|
||||
'pnm' => 'image/x-portable-anymap',
|
||||
'portpkg' => 'application/vnd.macports.portpkg',
|
||||
'pot' => 'application/vnd.ms-powerpoint',
|
||||
'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12',
|
||||
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
||||
'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12',
|
||||
'ppd' => 'application/vnd.cups-ppd',
|
||||
'ppm' => 'image/x-portable-pixmap',
|
||||
'pps' => 'application/vnd.ms-powerpoint',
|
||||
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12',
|
||||
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'pqa' => 'application/vnd.palm',
|
||||
'prc' => 'application/x-mobipocket-ebook',
|
||||
'pre' => 'application/vnd.lotus-freelance',
|
||||
'prf' => 'application/pics-rules',
|
||||
'ps' => 'application/postscript',
|
||||
'psb' => 'application/vnd.3gpp.pic-bw-small',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'psf' => 'application/x-font-linux-psf',
|
||||
'pskcxml' => 'application/pskc+xml',
|
||||
'ptid' => 'application/vnd.pvi.ptid1',
|
||||
'pub' => 'application/x-mspublisher',
|
||||
'pvb' => 'application/vnd.3gpp.pic-bw-var',
|
||||
'pwn' => 'application/vnd.3m.post-it-notes',
|
||||
'pya' => 'audio/vnd.ms-playready.media.pya',
|
||||
'pyv' => 'video/vnd.ms-playready.media.pyv',
|
||||
'qam' => 'application/vnd.epson.quickanime',
|
||||
'qbo' => 'application/vnd.intu.qbo',
|
||||
'qfx' => 'application/vnd.intu.qfx',
|
||||
'qps' => 'application/vnd.publishare-delta-tree',
|
||||
'qt' => 'video/quicktime',
|
||||
'qwd' => 'application/vnd.quark.quarkxpress',
|
||||
'qwt' => 'application/vnd.quark.quarkxpress',
|
||||
'qxb' => 'application/vnd.quark.quarkxpress',
|
||||
'qxd' => 'application/vnd.quark.quarkxpress',
|
||||
'qxl' => 'application/vnd.quark.quarkxpress',
|
||||
'qxt' => 'application/vnd.quark.quarkxpress',
|
||||
'ra' => 'audio/x-pn-realaudio',
|
||||
'ram' => 'audio/x-pn-realaudio',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'ras' => 'image/x-cmu-raster',
|
||||
'rb' => 'text/plain',
|
||||
'rcprofile' => 'application/vnd.ipunplugged.rcprofile',
|
||||
'rdf' => 'application/rdf+xml',
|
||||
'rdz' => 'application/vnd.data-vision.rdz',
|
||||
'rep' => 'application/vnd.businessobjects',
|
||||
'res' => 'application/x-dtbresource+xml',
|
||||
'resx' => 'text/xml',
|
||||
'rgb' => 'image/x-rgb',
|
||||
'rif' => 'application/reginfo+xml',
|
||||
'rip' => 'audio/vnd.rip',
|
||||
'rl' => 'application/resource-lists+xml',
|
||||
'rlc' => 'image/vnd.fujixerox.edmics-rlc',
|
||||
'rld' => 'application/resource-lists-diff+xml',
|
||||
'rm' => 'application/vnd.rn-realmedia',
|
||||
'rmi' => 'audio/midi',
|
||||
'rmp' => 'audio/x-pn-realaudio-plugin',
|
||||
'rms' => 'application/vnd.jcp.javame.midlet-rms',
|
||||
'rnc' => 'application/relax-ng-compact-syntax',
|
||||
'roff' => 'text/troff',
|
||||
'rp9' => 'application/vnd.cloanto.rp9',
|
||||
'rpss' => 'application/vnd.nokia.radio-presets',
|
||||
'rpst' => 'application/vnd.nokia.radio-preset',
|
||||
'rq' => 'application/sparql-query',
|
||||
'rs' => 'application/rls-services+xml',
|
||||
'rsd' => 'application/rsd+xml',
|
||||
'rss' => 'application/rss+xml',
|
||||
'rtf' => 'application/rtf',
|
||||
'rtx' => 'text/richtext',
|
||||
's' => 'text/x-asm',
|
||||
'saf' => 'application/vnd.yamaha.smaf-audio',
|
||||
'sbml' => 'application/sbml+xml',
|
||||
'sc' => 'application/vnd.ibm.secure-container',
|
||||
'scd' => 'application/x-msschedule',
|
||||
'scm' => 'application/vnd.lotus-screencam',
|
||||
'scq' => 'application/scvp-cv-request',
|
||||
'scs' => 'application/scvp-cv-response',
|
||||
'scurl' => 'text/vnd.curl.scurl',
|
||||
'sda' => 'application/vnd.stardivision.draw',
|
||||
'sdc' => 'application/vnd.stardivision.calc',
|
||||
'sdd' => 'application/vnd.stardivision.impress',
|
||||
'sdkd' => 'application/vnd.solent.sdkm+xml',
|
||||
'sdkm' => 'application/vnd.solent.sdkm+xml',
|
||||
'sdp' => 'application/sdp',
|
||||
'sdw' => 'application/vnd.stardivision.writer',
|
||||
'see' => 'application/vnd.seemail',
|
||||
'seed' => 'application/vnd.fdsn.seed',
|
||||
'sema' => 'application/vnd.sema',
|
||||
'semd' => 'application/vnd.semd',
|
||||
'semf' => 'application/vnd.semf',
|
||||
'ser' => 'application/java-serialized-object',
|
||||
'setpay' => 'application/set-payment-initiation',
|
||||
'setreg' => 'application/set-registration-initiation',
|
||||
'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data',
|
||||
'sfs' => 'application/vnd.spotfire.sfs',
|
||||
'sgl' => 'application/vnd.stardivision.writer-global',
|
||||
'sgm' => 'text/sgml',
|
||||
'sgml' => 'text/sgml',
|
||||
'sh' => 'application/x-sh',
|
||||
'shar' => 'application/x-shar',
|
||||
'shf' => 'application/shf+xml',
|
||||
'sig' => 'application/pgp-signature',
|
||||
'silo' => 'model/mesh',
|
||||
'sis' => 'application/vnd.symbian.install',
|
||||
'sisx' => 'application/vnd.symbian.install',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'sitx' => 'application/x-stuffitx',
|
||||
'skd' => 'application/vnd.koan',
|
||||
'skm' => 'application/vnd.koan',
|
||||
'skp' => 'application/vnd.koan',
|
||||
'skt' => 'application/vnd.koan',
|
||||
'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12',
|
||||
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
|
||||
'slt' => 'application/vnd.epson.salt',
|
||||
'sm' => 'application/vnd.stepmania.stepchart',
|
||||
'smf' => 'application/vnd.stardivision.math',
|
||||
'smi' => 'application/smil+xml',
|
||||
'smil' => 'application/smil+xml',
|
||||
'snd' => 'audio/basic',
|
||||
'snf' => 'application/x-font-snf',
|
||||
'so' => 'application/octet-stream',
|
||||
'spc' => 'application/x-pkcs7-certificates',
|
||||
'spf' => 'application/vnd.yamaha.smaf-phrase',
|
||||
'spl' => 'application/x-futuresplash',
|
||||
'spot' => 'text/vnd.in3d.spot',
|
||||
'spp' => 'application/scvp-vp-response',
|
||||
'spq' => 'application/scvp-vp-request',
|
||||
'spx' => 'audio/ogg',
|
||||
'src' => 'application/x-wais-source',
|
||||
'srt' => 'application/octet-stream',
|
||||
'sru' => 'application/sru+xml',
|
||||
'srx' => 'application/sparql-results+xml',
|
||||
'sse' => 'application/vnd.kodak-descriptor',
|
||||
'ssf' => 'application/vnd.epson.ssf',
|
||||
'ssml' => 'application/ssml+xml',
|
||||
'st' => 'application/vnd.sailingtracker.track',
|
||||
'stc' => 'application/vnd.sun.xml.calc.template',
|
||||
'std' => 'application/vnd.sun.xml.draw.template',
|
||||
'stf' => 'application/vnd.wt.stf',
|
||||
'sti' => 'application/vnd.sun.xml.impress.template',
|
||||
'stk' => 'application/hyperstudio',
|
||||
'stl' => 'application/vnd.ms-pki.stl',
|
||||
'str' => 'application/vnd.pg.format',
|
||||
'stw' => 'application/vnd.sun.xml.writer.template',
|
||||
'sub' => 'image/vnd.dvb.subtitle',
|
||||
'sus' => 'application/vnd.sus-calendar',
|
||||
'susp' => 'application/vnd.sus-calendar',
|
||||
'sv4cpio' => 'application/x-sv4cpio',
|
||||
'sv4crc' => 'application/x-sv4crc',
|
||||
'svc' => 'application/vnd.dvb.service',
|
||||
'svd' => 'application/vnd.svd',
|
||||
'svg' => 'image/svg+xml',
|
||||
'svgz' => 'image/svg+xml',
|
||||
'swa' => 'application/x-director',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'swi' => 'application/vnd.aristanetworks.swi',
|
||||
'sxc' => 'application/vnd.sun.xml.calc',
|
||||
'sxd' => 'application/vnd.sun.xml.draw',
|
||||
'sxg' => 'application/vnd.sun.xml.writer.global',
|
||||
'sxi' => 'application/vnd.sun.xml.impress',
|
||||
'sxm' => 'application/vnd.sun.xml.math',
|
||||
'sxw' => 'application/vnd.sun.xml.writer',
|
||||
't' => 'text/troff',
|
||||
'tao' => 'application/vnd.tao.intent-module-archive',
|
||||
'tar' => 'application/x-tar',
|
||||
'tcap' => 'application/vnd.3gpp2.tcap',
|
||||
'tcl' => 'application/x-tcl',
|
||||
'teacher' => 'application/vnd.smart.teacher',
|
||||
'tei' => 'application/tei+xml',
|
||||
'teicorpus' => 'application/tei+xml',
|
||||
'tex' => 'application/x-tex',
|
||||
'texi' => 'application/x-texinfo',
|
||||
'texinfo' => 'application/x-texinfo',
|
||||
'text' => 'text/plain',
|
||||
'tfi' => 'application/thraud+xml',
|
||||
'tfm' => 'application/x-tex-tfm',
|
||||
'thmx' => 'application/vnd.ms-officetheme',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'tmo' => 'application/vnd.tmobile-livetv',
|
||||
'torrent' => 'application/x-bittorrent',
|
||||
'tpl' => 'application/vnd.groove-tool-template',
|
||||
'tpt' => 'application/vnd.trid.tpt',
|
||||
'tr' => 'text/troff',
|
||||
'tra' => 'application/vnd.trueapp',
|
||||
'trm' => 'application/x-msterminal',
|
||||
'tsd' => 'application/timestamped-data',
|
||||
'tsv' => 'text/tab-separated-values',
|
||||
'ttc' => 'application/x-font-ttf',
|
||||
'ttf' => 'application/x-font-ttf',
|
||||
'ttl' => 'text/turtle',
|
||||
'twd' => 'application/vnd.simtech-mindmapper',
|
||||
'twds' => 'application/vnd.simtech-mindmapper',
|
||||
'txd' => 'application/vnd.genomatix.tuxedo',
|
||||
'txf' => 'application/vnd.mobius.txf',
|
||||
'txt' => 'text/plain',
|
||||
'u32' => 'application/x-authorware-bin',
|
||||
'udeb' => 'application/x-debian-package',
|
||||
'ufd' => 'application/vnd.ufdl',
|
||||
'ufdl' => 'application/vnd.ufdl',
|
||||
'umj' => 'application/vnd.umajin',
|
||||
'unityweb' => 'application/vnd.unity',
|
||||
'uoml' => 'application/vnd.uoml+xml',
|
||||
'uri' => 'text/uri-list',
|
||||
'uris' => 'text/uri-list',
|
||||
'urls' => 'text/uri-list',
|
||||
'ustar' => 'application/x-ustar',
|
||||
'utz' => 'application/vnd.uiq.theme',
|
||||
'uu' => 'text/x-uuencode',
|
||||
'uva' => 'audio/vnd.dece.audio',
|
||||
'uvd' => 'application/vnd.dece.data',
|
||||
'uvf' => 'application/vnd.dece.data',
|
||||
'uvg' => 'image/vnd.dece.graphic',
|
||||
'uvh' => 'video/vnd.dece.hd',
|
||||
'uvi' => 'image/vnd.dece.graphic',
|
||||
'uvm' => 'video/vnd.dece.mobile',
|
||||
'uvp' => 'video/vnd.dece.pd',
|
||||
'uvs' => 'video/vnd.dece.sd',
|
||||
'uvt' => 'application/vnd.dece.ttml+xml',
|
||||
'uvu' => 'video/vnd.uvvu.mp4',
|
||||
'uvv' => 'video/vnd.dece.video',
|
||||
'uvva' => 'audio/vnd.dece.audio',
|
||||
'uvvd' => 'application/vnd.dece.data',
|
||||
'uvvf' => 'application/vnd.dece.data',
|
||||
'uvvg' => 'image/vnd.dece.graphic',
|
||||
'uvvh' => 'video/vnd.dece.hd',
|
||||
'uvvi' => 'image/vnd.dece.graphic',
|
||||
'uvvm' => 'video/vnd.dece.mobile',
|
||||
'uvvp' => 'video/vnd.dece.pd',
|
||||
'uvvs' => 'video/vnd.dece.sd',
|
||||
'uvvt' => 'application/vnd.dece.ttml+xml',
|
||||
'uvvu' => 'video/vnd.uvvu.mp4',
|
||||
'uvvv' => 'video/vnd.dece.video',
|
||||
'uvvx' => 'application/vnd.dece.unspecified',
|
||||
'uvx' => 'application/vnd.dece.unspecified',
|
||||
'vcd' => 'application/x-cdlink',
|
||||
'vcf' => 'text/x-vcard',
|
||||
'vcg' => 'application/vnd.groove-vcard',
|
||||
'vcs' => 'text/x-vcalendar',
|
||||
'vcx' => 'application/vnd.vcx',
|
||||
'vis' => 'application/vnd.visionary',
|
||||
'viv' => 'video/vnd.vivo',
|
||||
'vor' => 'application/vnd.stardivision.writer',
|
||||
'vox' => 'application/x-authorware-bin',
|
||||
'vrml' => 'model/vrml',
|
||||
'vsd' => 'application/vnd.visio',
|
||||
'vsf' => 'application/vnd.vsf',
|
||||
'vss' => 'application/vnd.visio',
|
||||
'vst' => 'application/vnd.visio',
|
||||
'vsw' => 'application/vnd.visio',
|
||||
'vtu' => 'model/vnd.vtu',
|
||||
'vxml' => 'application/voicexml+xml',
|
||||
'w3d' => 'application/x-director',
|
||||
'wad' => 'application/x-doom',
|
||||
'wav' => 'audio/x-wav',
|
||||
'wax' => 'audio/x-ms-wax',
|
||||
'wbmp' => 'image/vnd.wap.wbmp',
|
||||
'wbs' => 'application/vnd.criticaltools.wbs+xml',
|
||||
'wbxml' => 'application/vnd.wap.wbxml',
|
||||
'wcm' => 'application/vnd.ms-works',
|
||||
'wdb' => 'application/vnd.ms-works',
|
||||
'weba' => 'audio/webm',
|
||||
'webm' => 'video/webm',
|
||||
'webp' => 'image/webp',
|
||||
'wg' => 'application/vnd.pmi.widget',
|
||||
'wgt' => 'application/widget',
|
||||
'wks' => 'application/vnd.ms-works',
|
||||
'wm' => 'video/x-ms-wm',
|
||||
'wma' => 'audio/x-ms-wma',
|
||||
'wmd' => 'application/x-ms-wmd',
|
||||
'wmf' => 'application/x-msmetafile',
|
||||
'wml' => 'text/vnd.wap.wml',
|
||||
'wmlc' => 'application/vnd.wap.wmlc',
|
||||
'wmls' => 'text/vnd.wap.wmlscript',
|
||||
'wmlsc' => 'application/vnd.wap.wmlscriptc',
|
||||
'wmv' => 'video/x-ms-wmv',
|
||||
'wmx' => 'video/x-ms-wmx',
|
||||
'wmz' => 'application/x-ms-wmz',
|
||||
'woff' => 'application/x-font-woff',
|
||||
'wpd' => 'application/vnd.wordperfect',
|
||||
'wpl' => 'application/vnd.ms-wpl',
|
||||
'wps' => 'application/vnd.ms-works',
|
||||
'wqd' => 'application/vnd.wqd',
|
||||
'wri' => 'application/x-mswrite',
|
||||
'wrl' => 'model/vrml',
|
||||
'wsdl' => 'application/wsdl+xml',
|
||||
'wspolicy' => 'application/wspolicy+xml',
|
||||
'wtb' => 'application/vnd.webturbo',
|
||||
'wvx' => 'video/x-ms-wvx',
|
||||
'x32' => 'application/x-authorware-bin',
|
||||
'x3d' => 'application/vnd.hzn-3d-crossword',
|
||||
'xap' => 'application/x-silverlight-app',
|
||||
'xar' => 'application/vnd.xara',
|
||||
'xbap' => 'application/x-ms-xbap',
|
||||
'xbd' => 'application/vnd.fujixerox.docuworks.binder',
|
||||
'xbm' => 'image/x-xbitmap',
|
||||
'xdf' => 'application/xcap-diff+xml',
|
||||
'xdm' => 'application/vnd.syncml.dm+xml',
|
||||
'xdp' => 'application/vnd.adobe.xdp+xml',
|
||||
'xdssc' => 'application/dssc+xml',
|
||||
'xdw' => 'application/vnd.fujixerox.docuworks',
|
||||
'xenc' => 'application/xenc+xml',
|
||||
'xer' => 'application/patch-ops-error+xml',
|
||||
'xfdf' => 'application/vnd.adobe.xfdf',
|
||||
'xfdl' => 'application/vnd.xfdl',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xhvml' => 'application/xv+xml',
|
||||
'xif' => 'image/vnd.xiff',
|
||||
'xla' => 'application/vnd.ms-excel',
|
||||
'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12',
|
||||
'xlc' => 'application/vnd.ms-excel',
|
||||
'xlm' => 'application/vnd.ms-excel',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12',
|
||||
'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xlt' => 'application/vnd.ms-excel',
|
||||
'xltm' => 'application/vnd.ms-excel.template.macroenabled.12',
|
||||
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
||||
'xlw' => 'application/vnd.ms-excel',
|
||||
'xml' => 'application/xml',
|
||||
'xo' => 'application/vnd.olpc-sugar',
|
||||
'xop' => 'application/xop+xml',
|
||||
'xpi' => 'application/x-xpinstall',
|
||||
'xpm' => 'image/x-xpixmap',
|
||||
'xpr' => 'application/vnd.is-xpr',
|
||||
'xps' => 'application/vnd.ms-xpsdocument',
|
||||
'xpw' => 'application/vnd.intercon.formnet',
|
||||
'xpx' => 'application/vnd.intercon.formnet',
|
||||
'xsl' => 'application/xml',
|
||||
'xslt' => 'application/xslt+xml',
|
||||
'xsm' => 'application/vnd.syncml+xml',
|
||||
'xspf' => 'application/xspf+xml',
|
||||
'xul' => 'application/vnd.mozilla.xul+xml',
|
||||
'xvm' => 'application/xv+xml',
|
||||
'xvml' => 'application/xv+xml',
|
||||
'xwd' => 'image/x-xwindowdump',
|
||||
'xyz' => 'chemical/x-xyz',
|
||||
'yaml' => 'text/yaml',
|
||||
'yang' => 'application/yang',
|
||||
'yin' => 'application/yin+xml',
|
||||
'yml' => 'text/yaml',
|
||||
'zaz' => 'application/vnd.zzazz.deck+xml',
|
||||
'zip' => 'application/zip',
|
||||
'zir' => 'application/vnd.zul',
|
||||
'zirz' => 'application/vnd.zul',
|
||||
'zmm' => 'application/vnd.handheld-entertainment+xml'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get a singleton instance of the class
|
||||
*
|
||||
* @return self
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mimetype value from a file extension
|
||||
*
|
||||
* @param string $extension File extension
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function fromExtension($extension)
|
||||
{
|
||||
$extension = strtolower($extension);
|
||||
|
||||
return isset($this->mimetypes[$extension]) ? $this->mimetypes[$extension] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mimetype from a filename
|
||||
*
|
||||
* @param string $filename Filename to generate a mimetype from
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function fromFilename($filename)
|
||||
{
|
||||
return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Birthday object to handle various Graph return formats
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class Birthday extends DateTime
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasDate = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasYear = false;
|
||||
|
||||
/**
|
||||
* Parses Graph birthday format to set indication flags, possible values:
|
||||
*
|
||||
* MM/DD/YYYY
|
||||
* MM/DD
|
||||
* YYYY
|
||||
*
|
||||
* @link https://developers.facebook.com/docs/graph-api/reference/user
|
||||
*
|
||||
* @param string $date
|
||||
*/
|
||||
public function __construct($date)
|
||||
{
|
||||
$parts = explode('/', $date);
|
||||
|
||||
$this->hasYear = count($parts) === 3 || count($parts) === 1;
|
||||
$this->hasDate = count($parts) === 3 || count($parts) === 2;
|
||||
|
||||
parent::__construct($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether date object contains birth day and month
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasDate()
|
||||
{
|
||||
return $this->hasDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether date object contains birth year
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasYear()
|
||||
{
|
||||
return $this->hasYear;
|
||||
}
|
||||
}
|
@ -1,242 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
/**
|
||||
* Class Collection
|
||||
*
|
||||
* Modified version of Collection in "illuminate/support" by Taylor Otwell
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
|
||||
class Collection implements ArrayAccess, Countable, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* The items contained in the collection.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $items = [];
|
||||
|
||||
/**
|
||||
* Create a new collection.
|
||||
*
|
||||
* @param array $items
|
||||
*/
|
||||
public function __construct(array $items = [])
|
||||
{
|
||||
$this->items = $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a field from the Graph node.
|
||||
*
|
||||
* @param string $name The field to retrieve.
|
||||
* @param mixed $default The default to return if the field doesn't exist.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getField($name, $default = null)
|
||||
{
|
||||
if (isset($this->items[$name])) {
|
||||
return $this->items[$name];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the named property for this graph object.
|
||||
*
|
||||
* @param string $name The property to retrieve.
|
||||
* @param mixed $default The default to return if the property doesn't exist.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @deprecated 5.0.0 getProperty() has been renamed to getField()
|
||||
* @todo v6: Remove this method
|
||||
*/
|
||||
public function getProperty($name, $default = null)
|
||||
{
|
||||
return $this->getField($name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all fields set on the object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFieldNames()
|
||||
{
|
||||
return array_keys($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all properties set on the object.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated 5.0.0 getPropertyNames() has been renamed to getFieldNames()
|
||||
* @todo v6: Remove this method
|
||||
*/
|
||||
public function getPropertyNames()
|
||||
{
|
||||
return $this->getFieldNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the items in the collection.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection of items as a plain array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function asArray()
|
||||
{
|
||||
return array_map(function ($value) {
|
||||
return $value instanceof Collection ? $value->asArray() : $value;
|
||||
}, $this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a map over each of the items.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function map(\Closure $callback)
|
||||
{
|
||||
return new static(array_map($callback, $this->items, array_keys($this->items)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection of items as JSON.
|
||||
*
|
||||
* @param int $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function asJson($options = 0)
|
||||
{
|
||||
return json_encode($this->asArray(), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of items in the collection.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the items.
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an item exists at an offset.
|
||||
*
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return array_key_exists($key, $this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item at a given offset.
|
||||
*
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return $this->items[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item at a given offset.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
$this->items[] = $value;
|
||||
} else {
|
||||
$this->items[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the item at a given offset.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
unset($this->items[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the collection to its string representation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->asJson();
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
/**
|
||||
* Class GraphAchievement
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class GraphAchievement extends GraphNode
|
||||
{
|
||||
/**
|
||||
* @var array Maps object key names to Graph object types.
|
||||
*/
|
||||
protected static $graphObjectMap = [
|
||||
'from' => '\Facebook\GraphNodes\GraphUser',
|
||||
'application' => '\Facebook\GraphNodes\GraphApplication',
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the ID for the achievement.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->getField('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user who achieved this.
|
||||
*
|
||||
* @return GraphUser|null
|
||||
*/
|
||||
public function getFrom()
|
||||
{
|
||||
return $this->getField('from');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time at which this was achieved.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getPublishTime()
|
||||
{
|
||||
return $this->getField('publish_time');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the app in which the user achieved this.
|
||||
*
|
||||
* @return GraphApplication|null
|
||||
*/
|
||||
public function getApplication()
|
||||
{
|
||||
return $this->getField('application');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the achievement type this instance is connected with.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->getField('data');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of achievement.
|
||||
*
|
||||
* @see https://developers.facebook.com/docs/graph-api/reference/achievement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'game.achievement';
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether gaining the achievement published a feed story for the user.
|
||||
*
|
||||
* @return boolean|null
|
||||
*/
|
||||
public function isNoFeedStory()
|
||||
{
|
||||
return $this->getField('no_feed_story');
|
||||
}
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
/**
|
||||
* Class GraphAlbum
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
|
||||
class GraphAlbum extends GraphNode
|
||||
{
|
||||
/**
|
||||
* @var array Maps object key names to Graph object types.
|
||||
*/
|
||||
protected static $graphObjectMap = [
|
||||
'from' => '\Facebook\GraphNodes\GraphUser',
|
||||
'place' => '\Facebook\GraphNodes\GraphPage',
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the ID for the album.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->getField('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the viewer can upload photos to this album.
|
||||
*
|
||||
* @return boolean|null
|
||||
*/
|
||||
public function getCanUpload()
|
||||
{
|
||||
return $this->getField('can_upload');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of photos in this album.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getCount()
|
||||
{
|
||||
return $this->getField('count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the album's cover photo.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCoverPhoto()
|
||||
{
|
||||
return $this->getField('cover_photo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time the album was initially created.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getCreatedTime()
|
||||
{
|
||||
return $this->getField('created_time');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time the album was updated.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getUpdatedTime()
|
||||
{
|
||||
return $this->getField('updated_time');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the album.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->getField('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns profile that created the album.
|
||||
*
|
||||
* @return GraphUser|null
|
||||
*/
|
||||
public function getFrom()
|
||||
{
|
||||
return $this->getField('from');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns profile that created the album.
|
||||
*
|
||||
* @return GraphPage|null
|
||||
*/
|
||||
public function getPlace()
|
||||
{
|
||||
return $this->getField('place');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a link to this album on Facebook.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
return $this->getField('link');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the textual location of the album.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLocation()
|
||||
{
|
||||
return $this->getField('location');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title of the album.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->getField('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the privacy settings for the album.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPrivacy()
|
||||
{
|
||||
return $this->getField('privacy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the album.
|
||||
*
|
||||
* enum{ profile, mobile, wall, normal, album }
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->getField('type');
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
/**
|
||||
* Class GraphApplication
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
|
||||
class GraphApplication extends GraphNode
|
||||
{
|
||||
/**
|
||||
* Returns the ID for the application.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->getField('id');
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
/**
|
||||
* Class GraphCoverPhoto
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class GraphCoverPhoto extends GraphNode
|
||||
{
|
||||
/**
|
||||
* Returns the id of cover if it exists
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->getField('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source of cover if it exists
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSource()
|
||||
{
|
||||
return $this->getField('source');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset_x of cover if it exists
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getOffsetX()
|
||||
{
|
||||
return $this->getField('offset_x');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset_y of cover if it exists
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getOffsetY()
|
||||
{
|
||||
return $this->getField('offset_y');
|
||||
}
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
use Facebook\FacebookRequest;
|
||||
use Facebook\Url\FacebookUrlManipulator;
|
||||
use Facebook\Exceptions\FacebookSDKException;
|
||||
|
||||
/**
|
||||
* Class GraphEdge
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class GraphEdge extends Collection
|
||||
{
|
||||
/**
|
||||
* @var FacebookRequest The original request that generated this data.
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var array An array of Graph meta data like pagination, etc.
|
||||
*/
|
||||
protected $metaData = [];
|
||||
|
||||
/**
|
||||
* @var string|null The parent Graph edge endpoint that generated the list.
|
||||
*/
|
||||
protected $parentEdgeEndpoint;
|
||||
|
||||
/**
|
||||
* @var string|null The subclass of the child GraphNode's.
|
||||
*/
|
||||
protected $subclassName;
|
||||
|
||||
/**
|
||||
* Init this collection of GraphNode's.
|
||||
*
|
||||
* @param FacebookRequest $request The original request that generated this data.
|
||||
* @param array $data An array of GraphNode's.
|
||||
* @param array $metaData An array of Graph meta data like pagination, etc.
|
||||
* @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list.
|
||||
* @param string|null $subclassName The subclass of the child GraphNode's.
|
||||
*/
|
||||
public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->metaData = $metaData;
|
||||
$this->parentEdgeEndpoint = $parentEdgeEndpoint;
|
||||
$this->subclassName = $subclassName;
|
||||
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent Graph edge endpoint that generated the list.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getParentGraphEdge()
|
||||
{
|
||||
return $this->parentEdgeEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subclass name that the child GraphNode's are cast as.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSubClassName()
|
||||
{
|
||||
return $this->subclassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw meta data associated with this GraphEdge.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaData()
|
||||
{
|
||||
return $this->metaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next cursor if it exists.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getNextCursor()
|
||||
{
|
||||
return $this->getCursor('after');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the previous cursor if it exists.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPreviousCursor()
|
||||
{
|
||||
return $this->getCursor('before');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cursor for a specific direction if it exists.
|
||||
*
|
||||
* @param string $direction The direction of the page: after|before
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCursor($direction)
|
||||
{
|
||||
if (isset($this->metaData['paging']['cursors'][$direction])) {
|
||||
return $this->metaData['paging']['cursors'][$direction];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a pagination URL based on a cursor.
|
||||
*
|
||||
* @param string $direction The direction of the page: next|previous
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getPaginationUrl($direction)
|
||||
{
|
||||
$this->validateForPagination();
|
||||
|
||||
// Do we have a paging URL?
|
||||
if (!isset($this->metaData['paging'][$direction])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$pageUrl = $this->metaData['paging'][$direction];
|
||||
|
||||
return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates whether or not we can paginate on this request.
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function validateForPagination()
|
||||
{
|
||||
if ($this->request->getMethod() !== 'GET') {
|
||||
throw new FacebookSDKException('You can only paginate on a GET request.', 720);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request object needed to make a next|previous page request.
|
||||
*
|
||||
* @param string $direction The direction of the page: next|previous
|
||||
*
|
||||
* @return FacebookRequest|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getPaginationRequest($direction)
|
||||
{
|
||||
$pageUrl = $this->getPaginationUrl($direction);
|
||||
if (!$pageUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$newRequest = clone $this->request;
|
||||
$newRequest->setEndpoint($pageUrl);
|
||||
|
||||
return $newRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request object needed to make a "next" page request.
|
||||
*
|
||||
* @return FacebookRequest|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getNextPageRequest()
|
||||
{
|
||||
return $this->getPaginationRequest('next');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request object needed to make a "previous" page request.
|
||||
*
|
||||
* @return FacebookRequest|null
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public function getPreviousPageRequest()
|
||||
{
|
||||
return $this->getPaginationRequest('previous');
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of results according to Graph if it exists.
|
||||
*
|
||||
* This will be returned if the summary=true modifier is present in the request.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getTotalCount()
|
||||
{
|
||||
if (isset($this->metaData['summary']['total_count'])) {
|
||||
return $this->metaData['summary']['total_count'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function map(\Closure $callback)
|
||||
{
|
||||
return new static(
|
||||
$this->request,
|
||||
array_map($callback, $this->items, array_keys($this->items)),
|
||||
$this->metaData,
|
||||
$this->parentEdgeEndpoint,
|
||||
$this->subclassName
|
||||
);
|
||||
}
|
||||
}
|
@ -1,242 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\GraphNodes;
|
||||
|
||||
/**
|
||||
* Class GraphEvent
|
||||
*
|
||||
* @package Facebook
|
||||
*/
|
||||
class GraphEvent extends GraphNode
|
||||
{
|
||||
/**
|
||||
* @var array Maps object key names to GraphNode types.
|
||||
*/
|
||||
protected static $graphObjectMap = [
|
||||
'cover' => '\Facebook\GraphNodes\GraphCoverPhoto',
|
||||
'place' => '\Facebook\GraphNodes\GraphPage',
|
||||
'picture' => '\Facebook\GraphNodes\GraphPicture',
|
||||
'parent_group' => '\Facebook\GraphNodes\GraphGroup',
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the `id` (The event ID) as string if present.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->getField('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `cover` (Cover picture) as GraphCoverPhoto if present.
|
||||
*
|
||||
* @return GraphCoverPhoto|null
|
||||
*/
|
||||
public function getCover()
|
||||
{
|
||||
return $this->getField('cover');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `description` (Long-form description) as string if present.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->getField('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `end_time` (End time, if one has been set) as DateTime if present.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getEndTime()
|
||||
{
|
||||
return $this->getField('end_time');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `is_date_only` (Whether the event only has a date specified, but no time) as bool if present.
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getIsDateOnly()
|
||||
{
|
||||
return $this->getField('is_date_only');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `name` (Event name) as string if present.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->getField('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `owner` (The profile that created the event) as GraphNode if present.
|
||||
*
|
||||
* @return GraphNode|null
|
||||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->getField('owner');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `parent_group` (The group the event belongs to) as GraphGroup if present.
|
||||
*
|
||||
* @return GraphGroup|null
|
||||
*/
|
||||
public function getParentGroup()
|
||||
{
|
||||
return $this->getField('parent_group');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `place` (Event Place information) as GraphPage if present.
|
||||
*
|
||||
* @return GraphPage|null
|
||||
*/
|
||||
public function getPlace()
|
||||
{
|
||||
return $this->getField('place');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `privacy` (Who can see the event) as string if present.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPrivacy()
|
||||
{
|
||||
return $this->getField('privacy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `start_time` (Start time) as DateTime if present.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getStartTime()
|
||||
{
|
||||
return $this->getField('start_time');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `ticket_uri` (The link users can visit to buy a ticket to this event) as string if present.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTicketUri()
|
||||
{
|
||||
return $this->getField('ticket_uri');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `timezone` (Timezone) as string if present.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTimezone()
|
||||
{
|
||||
return $this->getField('timezone');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `updated_time` (Last update time) as DateTime if present.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getUpdatedTime()
|
||||
{
|
||||
return $this->getField('updated_time');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `picture` (Event picture) as GraphPicture if present.
|
||||
*
|
||||
* @return GraphPicture|null
|
||||
*/
|
||||
public function getPicture()
|
||||
{
|
||||
return $this->getField('picture');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `attending_count` (Number of people attending the event) as int if present.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getAttendingCount()
|
||||
{
|
||||
return $this->getField('attending_count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `declined_count` (Number of people who declined the event) as int if present.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getDeclinedCount()
|
||||
{
|
||||
return $this->getField('declined_count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `maybe_count` (Number of people who maybe going to the event) as int if present.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getMaybeCount()
|
||||
{
|
||||
return $this->getField('maybe_count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `noreply_count` (Number of people who did not reply to the event) as int if present.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getNoreplyCount()
|
||||
{
|
||||
return $this->getField('noreply_count');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `invited_count` (Number of people invited to the event) as int if present.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getInvitedCount()
|
||||
{
|
||||
return $this->getField('invited_count');
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user