diff --git a/.gitignore b/.gitignore index 40eaa50..01d0421 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ atlassian-ide-plugin.xml # Composer vendor composer.lock + +# Project +var diff --git a/README.md b/README.md index c9aa18b..3a5c489 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,28 @@ There are two kinds of tests that we include in our sdk package. Unit tests, and ## Developer Notes +### Caching - Performance Improvement + +PayPal API SDK now has the ability to cache Access Tokens for multiple request uses. Generally, an access token is valid for approximately 15 min to 8 hours based on security settings by PayPal. However, by default PHP requests a new access token each time a new process/request is made in your website. To re-use the access token, we enabled cache storage via file under /var/auth.cache. + +To enable this, you need to configure by updating the configuration settings in your sdk_config.ini file or dynamic values as shown below: + +Please visit our [sample sdk_config.ini](https://github.com/paypal/PayPal-PHP-SDK/blob/master/sample/sdk_config.ini) +``` +;Caching Configuration +[cache] +; If Cache is enabled, it stores the access token retrieved from ClientId and Secret from the +; server into a file provided in constant $CACHE_PATH in PayPal/Cache/AuthorizationCache. +; If the value is set to 'true', it would try to create a file and store the information. +; For any other value, it would disable it +; Please note, this is a very good performance improvement, and we would encourage you to +; set this up properly to reduce the number of calls, to almost 50% on normal use cases +; PLEASE NOTE: You may need to provide proper write permissions to /var directory under PayPal-PHP-SDK on +; your hosting server +cache.enabled=true +``` +##### PLEASE NOTE: You may need to provide proper write permissions to /var directory under PayPal-PHP-SDK on your hosting server + ### API Model Constructor You can intialize the API objects by passing JSON string or Array representation of object to the constructor. E.g.: diff --git a/lib/PayPal/Auth/OAuthTokenCredential.php b/lib/PayPal/Auth/OAuthTokenCredential.php index 44fc55a..2e43df9 100644 --- a/lib/PayPal/Auth/OAuthTokenCredential.php +++ b/lib/PayPal/Auth/OAuthTokenCredential.php @@ -2,6 +2,8 @@ namespace PayPal\Auth; +use PayPal\Cache\AuthorizationCache; +use PayPal\Common\PPModel; use PayPal\Common\PPUserAgent; use PayPal\Common\ResourceModel; use PayPal\Core\PPConstants; @@ -10,12 +12,15 @@ use PayPal\Core\PPHttpConnection; use PayPal\Core\PPLoggingManager; use PayPal\Exception\PPConfigurationException; use PayPal\Rest\RestHandler; +use PayPal\Validation\JsonValidator; /** * Class OAuthTokenCredential */ class OAuthTokenCredential extends ResourceModel { + + public static $CACHE_PATH = '/../../../var/auth.cache'; /** * Private Variable * @@ -107,6 +112,15 @@ class OAuthTokenCredential extends ResourceModel */ public function getAccessToken($config) { + // Check for persisted data first + $token = AuthorizationCache::pull($config, $this->clientId); + if ($token) { + // We found it + $this->accessToken = $token['accessToken']; + $this->tokenCreateTime = $token['tokenCreateTime']; + $this->tokenExpiresIn = $token['tokenExpiresIn']; + } + // Check if Access Token is not null and has not expired. // The API returns expiry time as a relative time unit // We use a buffer time when checking for token expiry to account @@ -121,12 +135,15 @@ class OAuthTokenCredential extends ResourceModel // If accessToken is Null, obtain a new token if ($this->accessToken == null) { + // Get a new one by making calls to API $this->updateAccessToken($config); + AuthorizationCache::push($config, $this->clientId, $this->accessToken, $this->tokenCreateTime, $this->tokenExpiresIn); } return $this->accessToken; } + /** * Get a Refresh Token from Authorization Code * diff --git a/lib/PayPal/Cache/AuthorizationCache.php b/lib/PayPal/Cache/AuthorizationCache.php index e69de29..c1f7cfd 100644 --- a/lib/PayPal/Cache/AuthorizationCache.php +++ b/lib/PayPal/Cache/AuthorizationCache.php @@ -0,0 +1,94 @@ + $clientId, + 'accessToken' => $accessToken, + 'tokenCreateTime' => $tokenCreateTime, + 'tokenExpiresIn' => $tokenExpiresIn + ); + } + file_put_contents(__DIR__ . self::$CACHE_PATH, json_encode($tokens)); + } + + /** + * Determines from the Configuration if caching is currently enabled/disabled + * + * @param $config + * @return bool + */ + public static function isEnabled($config) + { + $config = ($config && is_array($config)) ? $config : PPConfigManager::getInstance()->getConfigHashmap(); + if (array_key_exists("cache.enabled", $config)) { + $value = $config['cache.enabled']; + return (trim($value) == 'true') ? true : false; + } + return false; + } + + +} diff --git a/lib/PayPal/Core/PPConstants.php b/lib/PayPal/Core/PPConstants.php index 19ca9f5..8f6ebf1 100644 --- a/lib/PayPal/Core/PPConstants.php +++ b/lib/PayPal/Core/PPConstants.php @@ -12,7 +12,7 @@ class PPConstants { const SDK_NAME = 'PayPal-PHP-SDK'; - const SDK_VERSION = '0.15.1'; + const SDK_VERSION = '0.16.0'; const REST_SANDBOX_ENDPOINT = "https://api.sandbox.paypal.com/"; const OPENID_REDIRECT_SANDBOX_URL = "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect"; diff --git a/release_notes.md b/release_notes.md index d1dcde3..8e0c99f 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,5 +1,9 @@ PayPal PHP SDK release notes ============================ +v0.16.0 +---- +* Enabled Caching Abilities for Access Tokens + v0.15.1 ---- * Enabled Deleting Billing Plans diff --git a/sample/bootstrap.php b/sample/bootstrap.php index abed4b9..eedbfe0 100644 --- a/sample/bootstrap.php +++ b/sample/bootstrap.php @@ -40,6 +40,14 @@ return $apiContext; */ function getApiContext($clientId, $clientSecret) { + // Register the sdk_config.ini file in current directory + // as the configuration source. + /* + if(!defined("PP_CONFIG_PATH")) { + define("PP_CONFIG_PATH", __DIR__); + } + */ + // ### Api context // Use an ApiContext object to authenticate @@ -60,7 +68,6 @@ function getApiContext($clientId, $clientSecret) // Comment this line out and uncomment the PP_CONFIG_PATH // 'define' block if you want to use static file // based configuration - $apiContext->setConfig( array( 'mode' => 'sandbox', @@ -68,17 +75,10 @@ function getApiContext($clientId, $clientSecret) 'log.LogEnabled' => true, 'log.FileName' => '../PayPal.log', 'log.LogLevel' => 'FINE', - 'validation.level' => 'log' + 'validation.level' => 'log', + 'cache.enabled' => 'true' ) ); - /* - // Register the sdk_config.ini file in current directory - // as the configuration source. - if(!defined("PP_CONFIG_PATH")) { - define("PP_CONFIG_PATH", __DIR__); - } - */ - return $apiContext; } diff --git a/sample/sdk_config.ini b/sample/sdk_config.ini index e3bd63e..530e76e 100644 --- a/sample/sdk_config.ini +++ b/sample/sdk_config.ini @@ -1,13 +1,11 @@ +;## This is an example configuration file for the SDK. +;## The sample scripts configure the SDK dynamically +;## but you can choose to go for file based configuration +;## in simpler apps (See bootstrap.php for more). [Account] acct1.ClientId = AYSq3RDGsmBLJE-otTkBtM-jBRd1TCQwFf9RGfwddNXWz0uFU9ztymylOhRS acct1.ClientSecret = EGnHDxD_qRPdaLdZz8iCr8N7_MzF-YHPTkjs6NKYQvQSBngp4PTTVWkPZRbL -## This is an example configuration file for the SDK. -## The sample scripts configure the SDK dynamically -## but you can choose to go for file based configuration -## in simpler apps (See bootstrap.php for more). - - ;Connection Information [Http] http.ConnectionTimeOut = 30 @@ -16,11 +14,11 @@ http.Retry = 1 ;Service Configuration [Service] -mode=sandbox ; can be set to sandbox / live +; can be set to sandbox / live +mode = sandbox ;Logging Information [Log] - log.LogEnabled=true ; When using a relative path, the log file is created @@ -42,4 +40,16 @@ log.LogLevel=FINE ; 'log' : logs the error message to logger only (default) ; 'strict' : throws a php notice message ; 'disable' : disable the validation -validation.level=strict +validation.level=log + +;Caching Configuration +[cache] +; If Cache is enabled, it stores the access token retrieved from ClientId and Secret from the +; server into a file provided in constant $CACHE_PATH in PayPal/Cache/AuthorizationCache. +; If the value is set to 'true', it would try to create a file and store the information. +; For any other value, it would disable it +; Please note, this is a very good performance improvement, and we would encourage you to +; set this up properly to reduce the number of calls, to almost 50% on normal use cases +; PLEASE NOTE: You may need to provide proper write permissions to /var directory under PayPal-PHP-SDK on +; your hosting server +cache.enabled=true