ThemeAvenue /
BetterOptin
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * BetterOptin Provider Aweber |
||
| 4 | * |
||
| 5 | * @package BetterOptin/Provider/Aweber/Settingd |
||
| 6 | * @author ThemeAvenue <[email protected]> |
||
| 7 | * @license GPL-2.0+ |
||
| 8 | * @link http://themeavenue.net |
||
| 9 | * @copyright 2015 ThemeAvenue |
||
| 10 | */ |
||
| 11 | |||
| 12 | // If this file is called directly, abort. |
||
| 13 | if ( ! defined( 'WPINC' ) ) { |
||
| 14 | die; |
||
| 15 | } |
||
| 16 | |||
| 17 | class WPBO_Aweber { |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Aweber authorization code |
||
| 21 | * |
||
| 22 | * @since 2.0 |
||
| 23 | * @var string |
||
| 24 | */ |
||
| 25 | private $auth_code; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * Aweber API key |
||
| 29 | * |
||
| 30 | * @since 2.0 |
||
| 31 | * @var string |
||
| 32 | */ |
||
| 33 | private $api_key; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Aweber API secret key |
||
| 37 | * |
||
| 38 | * @since 2.0 |
||
| 39 | * @var string |
||
| 40 | */ |
||
| 41 | private $api_secret; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * Aweber app access token |
||
| 45 | * |
||
| 46 | * @since 2.0 |
||
| 47 | * @var string |
||
| 48 | */ |
||
| 49 | private $access_token = ''; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * Aweber app access secret |
||
| 53 | * |
||
| 54 | * @since 2.0 |
||
| 55 | * @var string |
||
| 56 | */ |
||
| 57 | private $access_secret = ''; |
||
| 58 | |||
| 59 | /** |
||
| 60 | * Aweber registered app ID |
||
| 61 | * |
||
| 62 | * @since 2.0 |
||
| 63 | * @var string |
||
| 64 | */ |
||
| 65 | public static $app_id = '0cdbc51e'; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * Aweber list ID |
||
| 69 | * |
||
| 70 | * @since 2.0 |
||
| 71 | * @var string |
||
| 72 | */ |
||
| 73 | private $list_id; |
||
| 74 | |||
| 75 | /** |
||
| 76 | * Aweber app authorize URL |
||
| 77 | * |
||
| 78 | * @since 2.0 |
||
| 79 | * @var string |
||
| 80 | */ |
||
| 81 | public static $authorize_url = 'https://auth.aweber.com/1.0/oauth/authorize_app/'; |
||
| 82 | |||
| 83 | /** |
||
| 84 | * Instance of the Aweber class |
||
| 85 | * |
||
| 86 | * @since 2.0 |
||
| 87 | * @var AWeberAPI |
||
| 88 | */ |
||
| 89 | private $aweber; |
||
| 90 | |||
| 91 | /** |
||
| 92 | * Aweber user account |
||
| 93 | * |
||
| 94 | * @since 2.0 |
||
| 95 | * @var |
||
| 96 | */ |
||
| 97 | private $account; |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Holds possible errors if the Aweber class can't be instantiated |
||
| 101 | * |
||
| 102 | * @since 2.0 |
||
| 103 | * @var null|WP_Error |
||
| 104 | */ |
||
| 105 | public $error; |
||
| 106 | |||
| 107 | public function __construct() { |
||
| 108 | |||
| 109 | if ( ! class_exists( 'AWeberAPI' ) ) { |
||
| 110 | require( WPBO_PATH . 'vendor/aweber/aweber/aweber_api/aweber.php' ); |
||
| 111 | } |
||
| 112 | |||
| 113 | $this->auth_code = trim( wpbo_get_option( 'aw_auth_code', '' ) ); |
||
| 114 | $this->api_key = false !== $this->get_credentials() ? $this->get_credentials()['consumerKey'] : ''; |
||
| 115 | $this->api_secret = false !== $this->get_credentials() ? $this->get_credentials()['consumerSecret'] : ''; |
||
| 116 | $this->list_id = wpbo_get_option( 'aw_list_id', '' ); |
||
| 117 | $this->get_tokens(); |
||
| 118 | |||
| 119 | } |
||
| 120 | |||
| 121 | public static function get_authorization_url() { |
||
| 122 | return self::$authorize_url . self::$app_id; |
||
| 123 | } |
||
| 124 | |||
| 125 | /** |
||
| 126 | * Get Aweber authorization tokens |
||
| 127 | * |
||
| 128 | * Try and get the tokens from the database. If no token is found, we query Aweber and request |
||
| 129 | * authorization. |
||
| 130 | * |
||
| 131 | * @since 1.0 |
||
| 132 | * @return bool|WP_Error True if the auth tokens are set, WP_Error otherwise |
||
| 133 | */ |
||
| 134 | private function get_tokens() { |
||
| 135 | |||
| 136 | $tokens = maybe_unserialize( get_option( 'wpbo_aweber_tokens' ) ); |
||
| 137 | |||
| 138 | if ( empty( $tokens ) || ! is_array( $tokens ) ) { |
||
| 139 | $tokens = $this->get_access_tokens(); |
||
| 140 | } |
||
| 141 | |||
| 142 | if ( is_wp_error( $tokens ) ) { |
||
| 143 | return $tokens; |
||
| 144 | } |
||
| 145 | |||
| 146 | $this->access_token = isset( $tokens[0] ) ? trim( $tokens[0] ) : ''; |
||
| 147 | $this->access_secret = isset( $tokens[1] ) ? trim( $tokens[1] ) : ''; |
||
| 148 | |||
| 149 | return true; |
||
| 150 | |||
| 151 | } |
||
| 152 | |||
| 153 | /** |
||
| 154 | * Get access tokens from Aweber. |
||
| 155 | * |
||
| 156 | * @return array Aweber tokens |
||
| 157 | * @since 1.0.0 |
||
| 158 | */ |
||
| 159 | protected function get_access_tokens() { |
||
| 160 | |||
| 161 | if ( is_wp_error( $this->aweber() ) ) { |
||
| 162 | return $this->aweber(); |
||
|
0 ignored issues
–
show
|
|||
| 163 | } |
||
| 164 | |||
| 165 | /* Get credentials from Aweber key */ |
||
| 166 | $credentials = $this->get_credentials(); |
||
| 167 | |||
| 168 | if ( false === $credentials ) { |
||
| 169 | return $this->error = new WP_Error( 'aweber_missing_auth_code', esc_html__( 'Aweber authorization code is missing', 'betteroptin' ) ); |
||
|
0 ignored issues
–
show
The return type of
return $this->error = ne...sing', 'betteroptin')); (WP_Error) is incompatible with the return type documented by WPBO_Aweber::get_access_tokens of type array.
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function Loading history...
|
|||
| 170 | } |
||
| 171 | |||
| 172 | /* Set tokens */ |
||
| 173 | $this->aweber()->adapter->user->requestToken = $credentials['requestToken']; |
||
| 174 | $this->aweber()->adapter->user->tokenSecret = $credentials['tokenSecret']; |
||
| 175 | $this->aweber()->adapter->user->verifier = $credentials['verifier']; |
||
| 176 | |||
| 177 | /* Request access tokens */ |
||
| 178 | try { |
||
| 179 | |||
| 180 | $access_tokens = $this->aweber()->getAccessToken(); |
||
| 181 | $this->access_token = $access_tokens[0]; |
||
| 182 | $this->access_secret = $access_tokens[1]; |
||
| 183 | |||
| 184 | /* Save access tokens */ |
||
| 185 | update_option( 'wpbo_aweber_tokens', $access_tokens ); |
||
| 186 | |||
| 187 | return $access_tokens; |
||
| 188 | |||
| 189 | } catch ( Exception $e ) { |
||
| 190 | return $this->error = new WP_Error( '', esc_html__( 'The Aweber authorization code you provided is incorrect or expired. Please authorize the plugin again.', 'betteroptin' ) ); |
||
|
0 ignored issues
–
show
The return type of
return $this->error = ne...ain.', 'betteroptin')); (WP_Error) is incompatible with the return type documented by WPBO_Aweber::get_access_tokens of type array.
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function Loading history...
|
|||
| 191 | } |
||
| 192 | |||
| 193 | } |
||
| 194 | |||
| 195 | /** |
||
| 196 | * Get the instance of the Aweber class |
||
| 197 | * |
||
| 198 | * @since 2.0 |
||
| 199 | * @return AWeberAPI|WP_Error |
||
| 200 | */ |
||
| 201 | public function aweber() { |
||
| 202 | |||
| 203 | if ( is_object( $this->aweber ) && is_a( $this->aweber, 'AWeberAPI' ) ) { |
||
| 204 | return $this->aweber; |
||
| 205 | } |
||
| 206 | |||
| 207 | /* Make sure we have the tokens */ |
||
| 208 | if ( empty( $this->api_key ) || empty( $this->api_secret ) ) { |
||
| 209 | return $this->error = new WP_Error( 'missing_tokens', __( 'Aweber API keys are missing.', 'betteroptin' ) ); |
||
| 210 | } |
||
| 211 | |||
| 212 | return $this->aweber = new AWeberAPI( $this->api_key, $this->api_secret ); |
||
| 213 | |||
| 214 | } |
||
| 215 | |||
| 216 | /** |
||
| 217 | * Get an account instance. |
||
| 218 | * |
||
| 219 | * @return object User account instance |
||
| 220 | */ |
||
| 221 | public function account() { |
||
| 222 | |||
| 223 | if ( ! is_null( $this->account ) ) { |
||
| 224 | return $this->account; |
||
| 225 | } |
||
| 226 | |||
| 227 | /* Get user account */ |
||
| 228 | try { |
||
| 229 | $this->account = $this->aweber()->getAccount( $this->access_token, $this->access_secret ); |
||
|
0 ignored issues
–
show
$this->access_token is of type string, but the function expects a boolean.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
$this->access_secret is of type string, but the function expects a boolean.
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
| 230 | } catch ( Exception $e ) { |
||
| 231 | return $this->error = new WP_Error( 'aweber_connection_error', __( 'Unable to connect to Aweber', 'betteroptin' ) ); |
||
| 232 | } |
||
| 233 | |||
| 234 | return $this->account; |
||
| 235 | |||
| 236 | } |
||
| 237 | |||
| 238 | /** |
||
| 239 | * Get account credentials. |
||
| 240 | * |
||
| 241 | * Takes the authorization code and extract account credentials. |
||
| 242 | * |
||
| 243 | * @since 1.0.0 |
||
| 244 | * @return array Credentials |
||
| 245 | */ |
||
| 246 | protected function get_credentials() { |
||
| 247 | |||
| 248 | if ( empty( $this->auth_code ) ) { |
||
| 249 | return false; |
||
| 250 | } |
||
| 251 | |||
| 252 | $code = explode( '|', $this->auth_code ); |
||
| 253 | |||
| 254 | $credentials = array( |
||
| 255 | 'consumerKey' => trim( $code[0] ), |
||
| 256 | 'consumerSecret' => trim( $code[1] ), |
||
| 257 | 'requestToken' => trim( $code[2] ), |
||
| 258 | 'tokenSecret' => trim( $code[3] ), |
||
| 259 | 'verifier' => trim( $code[4] ), |
||
| 260 | ); |
||
| 261 | |||
| 262 | return $credentials; |
||
| 263 | |||
| 264 | } |
||
| 265 | |||
| 266 | /** |
||
| 267 | * Subscribe the visitor to a list. |
||
| 268 | * |
||
| 269 | * @since 1.0.0 |
||
| 270 | * |
||
| 271 | * @param array $data Form post data |
||
| 272 | * |
||
| 273 | * @return array Result |
||
| 274 | */ |
||
| 275 | public function subscribe( $data ) { |
||
| 276 | |||
| 277 | if ( is_wp_error( $this->account() ) ) { |
||
| 278 | return $this->account(); |
||
| 279 | } |
||
| 280 | |||
| 281 | $account_id = $this->account()->data['id']; |
||
| 282 | $list_custom = get_post_meta( (int) $data['wpbo_id'], 'wpbo_aw_list', true ); |
||
| 283 | $list_id = ( '' != $list_custom ) ? $list_custom : $this->list_id; |
||
| 284 | $list_url = "/accounts/$account_id/lists/$list_id"; |
||
| 285 | $subscriber = array( 'email' => sanitize_email( $data['email'] ), 'name' => $data['name'] ); |
||
| 286 | |||
| 287 | /* Subscribe the new user */ |
||
| 288 | try { |
||
| 289 | |||
| 290 | $list = $this->account()->loadFromUrl( $list_url ); |
||
| 291 | $newSubscriber = $list->subscribers->create( $subscriber ); |
||
|
0 ignored issues
–
show
$newSubscriber is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the Loading history...
|
|||
| 292 | |||
| 293 | return true; |
||
| 294 | |||
| 295 | } catch ( Exception $exc ) { |
||
| 296 | return false; |
||
| 297 | } |
||
| 298 | |||
| 299 | } |
||
| 300 | |||
| 301 | /** |
||
| 302 | * Get user lists. |
||
| 303 | * |
||
| 304 | * @since 1.0.0 |
||
| 305 | * @return array Array of available lists for this account |
||
| 306 | */ |
||
| 307 | public function get_lists() { |
||
| 308 | |||
| 309 | $lists = maybe_unserialize( get_transient( 'wpbo_aw_lists' ) ); |
||
| 310 | |||
| 311 | if ( is_array( $lists ) ) { |
||
| 312 | return $lists; |
||
| 313 | } |
||
| 314 | |||
| 315 | if ( is_wp_error( $this->account() ) ) { |
||
| 316 | return array(); |
||
| 317 | } |
||
| 318 | |||
| 319 | foreach ( $this->account()->lists as $list ) { |
||
| 320 | $lists[] = array( 'id' => $list->id, 'name' => $list->name ); |
||
| 321 | } |
||
| 322 | |||
| 323 | /* Cache the lists to avoid slow loading */ |
||
| 324 | set_transient( 'wpbo_aw_lists', $lists, 24 * 60 * 60 ); |
||
| 325 | |||
| 326 | return $lists; |
||
| 327 | |||
| 328 | } |
||
| 329 | |||
| 330 | public function is_error() { |
||
| 331 | return $this->error; |
||
| 332 | } |
||
| 333 | |||
| 334 | } |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.