| @@ -14,8 +14,12 @@ | ||
| 14 | 14 | * License for the specific language governing permissions and limitations |
| 15 | 15 | * under the License. |
| 16 | 16 | */ |
| 17 | 17 | |
| 18 | + if ( ! defined( 'ABSPATH' ) ) { | |
| 19 | + exit; | |
| 20 | + } | |
| 21 | + | |
| 18 | 22 | if ( ! defined( 'FS_API__VERSION' ) ) { |
| 19 | 23 | define( 'FS_API__VERSION', '1' ); |
| 20 | 24 | } |
| 21 | 25 | if ( ! defined( 'FS_SDK__PATH' ) ) { |
| @@ -41,175 +45,173 @@ | ||
| 41 | 45 | foreach ( $exceptions as $e ) { |
| 42 | 46 | require_once FS_SDK__EXCEPTIONS_PATH . $e . '.php'; |
| 43 | 47 | } |
| 44 | 48 | |
| 45 | - if ( class_exists( 'Freemius_Api_Base' ) ) { | |
| 46 | - return; | |
| 47 | - } | |
| 49 | + if ( ! class_exists( 'Freemius_Api_Base' ) ) { | |
| 50 | + abstract class Freemius_Api_Base { | |
| 51 | + const VERSION = '1.0.4'; | |
| 52 | + const FORMAT = 'json'; | |
| 48 | 53 | |
| 49 | - abstract class Freemius_Api_Base { | |
| 50 | - const VERSION = '1.0.4'; | |
| 51 | - const FORMAT = 'json'; | |
| 54 | + protected $_id; | |
| 55 | + protected $_public; | |
| 56 | + protected $_secret; | |
| 57 | + protected $_scope; | |
| 58 | + protected $_isSandbox; | |
| 52 | 59 | |
| 53 | - protected $_id; | |
| 54 | - protected $_public; | |
| 55 | - protected $_secret; | |
| 56 | - protected $_scope; | |
| 57 | - protected $_isSandbox; | |
| 60 | + /** | |
| 61 | + * @param string $pScope 'app', 'developer', 'plugin', 'user' or 'install'. | |
| 62 | + * @param number $pID Element's id. | |
| 63 | + * @param string $pPublic Public key. | |
| 64 | + * @param string $pSecret Element's secret key. | |
| 65 | + * @param bool $pIsSandbox Whether or not to run API in sandbox mode. | |
| 66 | + */ | |
| 67 | + public function Init( $pScope, $pID, $pPublic, $pSecret, $pIsSandbox = false ) { | |
| 68 | + $this->_id = $pID; | |
| 69 | + $this->_public = $pPublic; | |
| 70 | + $this->_secret = $pSecret; | |
| 71 | + $this->_scope = $pScope; | |
| 72 | + $this->_isSandbox = $pIsSandbox; | |
| 73 | + } | |
| 58 | 74 | |
| 59 | - /** | |
| 60 | - * @param string $pScope 'app', 'developer', 'plugin', 'user' or 'install'. | |
| 61 | - * @param number $pID Element's id. | |
| 62 | - * @param string $pPublic Public key. | |
| 63 | - * @param string $pSecret Element's secret key. | |
| 64 | - * @param bool $pIsSandbox Whether or not to run API in sandbox mode. | |
| 65 | - */ | |
| 66 | - public function Init( $pScope, $pID, $pPublic, $pSecret, $pIsSandbox = false ) { | |
| 67 | - $this->_id = $pID; | |
| 68 | - $this->_public = $pPublic; | |
| 69 | - $this->_secret = $pSecret; | |
| 70 | - $this->_scope = $pScope; | |
| 71 | - $this->_isSandbox = $pIsSandbox; | |
| 72 | - } | |
| 75 | + public function IsSandbox() { | |
| 76 | + return $this->_isSandbox; | |
| 77 | + } | |
| 73 | 78 | |
| 74 | - public function IsSandbox() { | |
| 75 | - return $this->_isSandbox; | |
| 76 | - } | |
| 79 | + function CanonizePath( $pPath ) { | |
| 80 | + $pPath = trim( $pPath, '/' ); | |
| 81 | + $query_pos = strpos( $pPath, '?' ); | |
| 82 | + $query = ''; | |
| 77 | 83 | |
| 78 | - function CanonizePath( $pPath ) { | |
| 79 | - $pPath = trim( $pPath, '/' ); | |
| 80 | - $query_pos = strpos( $pPath, '?' ); | |
| 81 | - $query = ''; | |
| 84 | + if ( false !== $query_pos ) { | |
| 85 | + $query = substr( $pPath, $query_pos ); | |
| 86 | + $pPath = substr( $pPath, 0, $query_pos ); | |
| 87 | + } | |
| 82 | 88 | |
| 83 | - if ( false !== $query_pos ) { | |
| 84 | - $query = substr( $pPath, $query_pos ); | |
| 85 | - $pPath = substr( $pPath, 0, $query_pos ); | |
| 86 | - } | |
| 89 | + // Trim '.json' suffix. | |
| 90 | + $format_length = strlen( '.' . self::FORMAT ); | |
| 91 | + $start = $format_length * ( - 1 ); //negative | |
| 92 | + if ( substr( strtolower( $pPath ), $start ) === ( '.' . self::FORMAT ) ) { | |
| 93 | + $pPath = substr( $pPath, 0, strlen( $pPath ) - $format_length ); | |
| 94 | + } | |
| 87 | 95 | |
| 88 | - // Trim '.json' suffix. | |
| 89 | - $format_length = strlen( '.' . self::FORMAT ); | |
| 90 | - $start = $format_length * ( - 1 ); //negative | |
| 91 | - if ( substr( strtolower( $pPath ), $start ) === ( '.' . self::FORMAT ) ) { | |
| 92 | - $pPath = substr( $pPath, 0, strlen( $pPath ) - $format_length ); | |
| 93 | - } | |
| 96 | + switch ( $this->_scope ) { | |
| 97 | + case 'app': | |
| 98 | + $base = '/apps/' . $this->_id; | |
| 99 | + break; | |
| 100 | + case 'developer': | |
| 101 | + $base = '/developers/' . $this->_id; | |
| 102 | + break; | |
| 103 | + case 'user': | |
| 104 | + $base = '/users/' . $this->_id; | |
| 105 | + break; | |
| 106 | + case 'plugin': | |
| 107 | + $base = '/plugins/' . $this->_id; | |
| 108 | + break; | |
| 109 | + case 'install': | |
| 110 | + $base = '/installs/' . $this->_id; | |
| 111 | + break; | |
| 112 | + default: | |
| 113 | + throw new Freemius_Exception( 'Scope not implemented.' ); | |
| 114 | + } | |
| 94 | 115 | |
| 95 | - switch ( $this->_scope ) { | |
| 96 | - case 'app': | |
| 97 | - $base = '/apps/' . $this->_id; | |
| 98 | - break; | |
| 99 | - case 'developer': | |
| 100 | - $base = '/developers/' . $this->_id; | |
| 101 | - break; | |
| 102 | - case 'user': | |
| 103 | - $base = '/users/' . $this->_id; | |
| 104 | - break; | |
| 105 | - case 'plugin': | |
| 106 | - $base = '/plugins/' . $this->_id; | |
| 107 | - break; | |
| 108 | - case 'install': | |
| 109 | - $base = '/installs/' . $this->_id; | |
| 110 | - break; | |
| 111 | - default: | |
| 112 | - throw new Freemius_Exception( 'Scope not implemented.' ); | |
| 113 | - } | |
| 116 | + return '/v' . FS_API__VERSION . $base . | |
| 117 | + ( ! empty( $pPath ) ? '/' : '' ) . $pPath . | |
| 118 | + ( ( false === strpos( $pPath, '.' ) ) ? '.' . self::FORMAT : '' ) . $query; | |
| 119 | + } | |
| 114 | 120 | |
| 115 | - return '/v' . FS_API__VERSION . $base . | |
| 116 | - ( ! empty( $pPath ) ? '/' : '' ) . $pPath . | |
| 117 | - ( ( false === strpos( $pPath, '.' ) ) ? '.' . self::FORMAT : '' ) . $query; | |
| 118 | - } | |
| 121 | + abstract function MakeRequest( $pCanonizedPath, $pMethod = 'GET', $pParams = array() ); | |
| 119 | 122 | |
| 120 | - abstract function MakeRequest( $pCanonizedPath, $pMethod = 'GET', $pParams = array() ); | |
| 123 | + /** | |
| 124 | + * @param string $pPath | |
| 125 | + * @param string $pMethod | |
| 126 | + * @param array $pParams | |
| 127 | + * | |
| 128 | + * @return object[]|object|null | |
| 129 | + */ | |
| 130 | + private function _Api( $pPath, $pMethod = 'GET', $pParams = array() ) { | |
| 131 | + $pMethod = strtoupper( $pMethod ); | |
| 121 | 132 | |
| 122 | - /** | |
| 123 | - * @param string $pPath | |
| 124 | - * @param string $pMethod | |
| 125 | - * @param array $pParams | |
| 126 | - * | |
| 127 | - * @return object[]|object|null | |
| 128 | - */ | |
| 129 | - private function _Api( $pPath, $pMethod = 'GET', $pParams = array() ) { | |
| 130 | - $pMethod = strtoupper( $pMethod ); | |
| 133 | + try { | |
| 134 | + $result = $this->MakeRequest( $pPath, $pMethod, $pParams ); | |
| 135 | + } catch ( Freemius_Exception $e ) { | |
| 136 | + // Map to error object. | |
| 137 | + $result = (object) $e->getResult(); | |
| 138 | + } catch ( Exception $e ) { | |
| 139 | + // Map to error object. | |
| 140 | + $result = (object) array( | |
| 141 | + 'error' => (object) array( | |
| 142 | + 'type' => 'Unknown', | |
| 143 | + 'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')', | |
| 144 | + 'code' => 'unknown', | |
| 145 | + 'http' => 402 | |
| 146 | + ) | |
| 147 | + ); | |
| 148 | + } | |
| 131 | 149 | |
| 132 | - try { | |
| 133 | - $result = $this->MakeRequest( $pPath, $pMethod, $pParams ); | |
| 134 | - } catch ( Freemius_Exception $e ) { | |
| 135 | - // Map to error object. | |
| 136 | - $result = (object) $e->getResult(); | |
| 137 | - } catch ( Exception $e ) { | |
| 138 | - // Map to error object. | |
| 139 | - $result = (object) array( | |
| 140 | - 'error' => array( | |
| 141 | - 'type' => 'Unknown', | |
| 142 | - 'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')', | |
| 143 | - 'code' => 'unknown', | |
| 144 | - 'http' => 402 | |
| 145 | - ) | |
| 146 | - ); | |
| 147 | - } | |
| 150 | + return $result; | |
| 151 | + } | |
| 148 | 152 | |
| 149 | - return $result; | |
| 150 | - } | |
| 153 | + public function Api( $pPath, $pMethod = 'GET', $pParams = array() ) { | |
| 154 | + return $this->_Api( $this->CanonizePath( $pPath ), $pMethod, $pParams ); | |
| 155 | + } | |
| 151 | 156 | |
| 152 | - public function Api( $pPath, $pMethod = 'GET', $pParams = array() ) { | |
| 153 | - return $this->_Api( $this->CanonizePath( $pPath ), $pMethod, $pParams ); | |
| 154 | - } | |
| 157 | + /** | |
| 158 | + * Base64 decoding that does not need to be urldecode()-ed. | |
| 159 | + * | |
| 160 | + * Exactly the same as PHP base64 encode except it uses | |
| 161 | + * `-` instead of `+` | |
| 162 | + * `_` instead of `/` | |
| 163 | + * No padded = | |
| 164 | + * | |
| 165 | + * @param string $input Base64UrlEncoded() string | |
| 166 | + * | |
| 167 | + * @return string | |
| 168 | + */ | |
| 169 | + protected static function Base64UrlDecode( $input ) { | |
| 170 | + /** | |
| 171 | + * IMPORTANT NOTE: | |
| 172 | + * This is a hack suggested by @otto42 and @greenshady from | |
| 173 | + * the theme's review team. The usage of base64 for API | |
| 174 | + * signature encoding was approved in a Slack meeting | |
| 175 | + * held on Tue (10/25 2016). | |
| 176 | + * | |
| 177 | + * @todo Remove this hack once the base64 error is removed from the Theme Check. | |
| 178 | + * | |
| 179 | + * @since 1.2.2 | |
| 180 | + * @author Vova Feldman (@svovaf) | |
| 181 | + */ | |
| 182 | + $fn = 'base64' . '_decode'; | |
| 183 | + return $fn( strtr( $input, '-_', '+/' ) ); | |
| 184 | + } | |
| 155 | 185 | |
| 156 | - /** | |
| 157 | - * Base64 decoding that does not need to be urldecode()-ed. | |
| 158 | - * | |
| 159 | - * Exactly the same as PHP base64 encode except it uses | |
| 160 | - * `-` instead of `+` | |
| 161 | - * `_` instead of `/` | |
| 162 | - * No padded = | |
| 163 | - * | |
| 164 | - * @param string $input Base64UrlEncoded() string | |
| 165 | - * | |
| 166 | - * @return string | |
| 167 | - */ | |
| 168 | - protected static function Base64UrlDecode( $input ) { | |
| 169 | - /** | |
| 170 | - * IMPORTANT NOTE: | |
| 171 | - * This is a hack suggested by @otto42 and @greenshady from | |
| 172 | - * the theme's review team. The usage of base64 for API | |
| 173 | - * signature encoding was approved in a Slack meeting | |
| 174 | - * held on Tue (10/25 2016). | |
| 175 | - * | |
| 176 | - * @todo Remove this hack once the base64 error is removed from the Theme Check. | |
| 177 | - * | |
| 178 | - * @since 1.2.2 | |
| 179 | - * @author Vova Feldman (@svovaf) | |
| 180 | - */ | |
| 181 | - $fn = 'base64' . '_decode'; | |
| 182 | - return $fn( strtr( $input, '-_', '+/' ) ); | |
| 183 | - } | |
| 186 | + /** | |
| 187 | + * Base64 encoding that does not need to be urlencode()ed. | |
| 188 | + * | |
| 189 | + * Exactly the same as base64 encode except it uses | |
| 190 | + * `-` instead of `+ | |
| 191 | + * `_` instead of `/` | |
| 192 | + * | |
| 193 | + * @param string $input string | |
| 194 | + * | |
| 195 | + * @return string Base64 encoded string | |
| 196 | + */ | |
| 197 | + protected static function Base64UrlEncode( $input ) { | |
| 198 | + /** | |
| 199 | + * IMPORTANT NOTE: | |
| 200 | + * This is a hack suggested by @otto42 and @greenshady from | |
| 201 | + * the theme's review team. The usage of base64 for API | |
| 202 | + * signature encoding was approved in a Slack meeting | |
| 203 | + * held on Tue (10/25 2016). | |
| 204 | + * | |
| 205 | + * @todo Remove this hack once the base64 error is removed from the Theme Check. | |
| 206 | + * | |
| 207 | + * @since 1.2.2 | |
| 208 | + * @author Vova Feldman (@svovaf) | |
| 209 | + */ | |
| 210 | + $fn = 'base64' . '_encode'; | |
| 211 | + $str = strtr( $fn( $input ), '+/', '-_' ); | |
| 212 | + $str = str_replace( '=', '', $str ); | |
| 184 | 213 | |
| 185 | - /** | |
| 186 | - * Base64 encoding that does not need to be urlencode()ed. | |
| 187 | - * | |
| 188 | - * Exactly the same as base64 encode except it uses | |
| 189 | - * `-` instead of `+ | |
| 190 | - * `_` instead of `/` | |
| 191 | - * | |
| 192 | - * @param string $input string | |
| 193 | - * | |
| 194 | - * @return string Base64 encoded string | |
| 195 | - */ | |
| 196 | - protected static function Base64UrlEncode( $input ) { | |
| 197 | - /** | |
| 198 | - * IMPORTANT NOTE: | |
| 199 | - * This is a hack suggested by @otto42 and @greenshady from | |
| 200 | - * the theme's review team. The usage of base64 for API | |
| 201 | - * signature encoding was approved in a Slack meeting | |
| 202 | - * held on Tue (10/25 2016). | |
| 203 | - * | |
| 204 | - * @todo Remove this hack once the base64 error is removed from the Theme Check. | |
| 205 | - * | |
| 206 | - * @since 1.2.2 | |
| 207 | - * @author Vova Feldman (@svovaf) | |
| 208 | - */ | |
| 209 | - $fn = 'base64' . '_encode'; | |
| 210 | - $str = strtr( $fn( $input ), '+/', '-_' ); | |
| 211 | - $str = str_replace( '=', '', $str ); | |
| 212 | - | |
| 213 | - return $str; | |
| 214 | - } | |
| 215 | - } | |
| 214 | + return $str; | |
| 215 | + } | |
| 216 | + } | |
| 217 | + } | |