Support » Plugin: Stormpath » Plugin could not be activated: fatal error

  • When trying to activate the plugin, fatal error:

    Fatal error: Can’t use function return value in write context in /var/www/html/blog/wp-content/plugins/stormpath/includes/stormpath.php on line 186

Viewing 8 replies - 1 through 8 (of 8 total)
  • I also am having this problem

    Thread Starter Techcyclist

    (@techcyclist)

    You might try these, for one thing, there is a problem with their use of ’empty()’ function, and this version, which I had a friend fix, doesn’t uses empty(). These files work for me. New stormpath.php:

    <?php
    /**
     * Stormpath WordPress is a WordPress plugin to authenticate against a Stormpath Directory.
     * Copyright (C) 2016  Stormpath
     *
     * This file is part of Stormpath WordPress.
     *
     * Stormpath WordPress is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 2 of the License, or
     * (at your option) any later version.
     *
     * Stormpath WordPress is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
     *
     * @package Stormpath\WordPress
     */
    
    namespace Stormpath\WordPress;
    use Stormpath\Client;
    use Stormpath\Resource\Application;
    use Stormpath\WordPress\Notices\Error;
    use Stormpath\WordPress\Notices\Success;
    use Stormpath\WordPress\Notices\Warning;
    use Symfony\Component\Yaml\Exception\ParseException;
    use Symfony\Component\Yaml\Yaml;
    
    /**
     * Class Stormpath
     *
     * @category    Stormpath
     * @package     Stormpath\WordPress
     * @author      Stormpath <support@stormpath.com>
     * @license     http://www.gnu.org/copyleft/gpl.html GNU General Public License
     * @link        https://stormpath.com/
     */
    class Stormpath {
    
    	/**
    	 * The Stormpath Client.
    	 *
    	 * @var \Stormpath\Client
    	 */
    	private $client;
    
    	/**
    	 * The Stormpath Applicaiton.
    	 *
    	 * @var \Stormpath\Resource\Application
    	 */
    	private $application;
    
    	/**
    	 * The Authenticate Class
    	 *
    	 * @var Authenticate
    	 */
    	private $authenticate;
    
    	/**
    	 * Stormpath constructor.
    	 *
    	 * @return void
    	 */
    	public function __construct() {
    		$this->settings     = new Settings( $this );
    
    		$this->add_hooks();
    
    		$this->client = $this->create_client();
    
    		if ( $this->client ) {
    			$this->application = $this->application();
    		}
    
    		if ( $this->application ) {
    			$this->replace_auth();
    		}
    
    	}
    
    	/**
    	 * Register Hooks in WordPress
    	 *
    	 * @return void
    	 */
    	private function add_hooks() {
    		add_action( 'admin_init', [ $this->settings, 'register_options' ] );
    		add_action( 'stormpath_admin_error', [ (new Error), 'display' ], 10, 2 );
    		add_action( 'stormpath_admin_warning', [ (new Warning), 'display' ], 10, 2 );
    		add_action( 'stormpath_admin_success', [ (new Success), 'display' ], 10, 2 );
    		add_action( 'admin_menu', [ $this->settings, 'add_options_page' ] );
    
    	}
    
    	/**
    	 * Replace the core authentication
    	 *
    	 * @return void
    	 */
    	public function replace_auth() {
    		if ( null !== $this->client ) {
    
    			$this->authenticate = new Authenticate( $this->application, $this->client );
    
    			add_action( 'user_register', [ $this->authenticate, 'user_registered' ], 10, 1 );
    			add_action( 'profile_update', [ $this->authenticate, 'profile_update' ], 10, 2 );
    			add_action( 'after_password_reset', [ $this->authenticate, 'password_changed' ], 10, 2 );
    			add_filter( 'authenticate', [ $this->authenticate, 'authenticate' ], 10, 3 );
    			add_filter( 'login_errors', [ $this, 'login_errors' ], 10, 1 );
    		} else {
    			do_action( 'stormpath_admin_error', 'could_not_contact_stormpath' );
    		}
    	}
    
    	/**
    	 * Override the login errors.
    	 *
    	 * @param \WP_Error $errors The wp_error object.
    	 * @return string
    	 */
    	public function login_errors( $errors ) {
    		global $errors;
    		$err_codes = $errors->get_error_codes();
    
    		$error = $errors->get_error_message();
    
    		if ( in_array( 'invalid_username', $err_codes ) ) {
    			$error = '<strong>ERROR</strong>: Invalid username or password.';
    		}
    
    		if ( in_array( 'invalid_email', $err_codes ) ) {
    			$error = '<strong>ERROR</strong>: Invalid username or password.';
    		}
    
    		if ( in_array( 'incorrect_password', $err_codes ) ) {
    			$error = '<strong>ERROR</strong>: Invalid username or password.';
    		}
    
    		if ( in_array( 'authentication_failed', $err_codes ) ) {
    			$error = '<strong>ERROR</strong>: Invalid username or password.';
    		}
    
    		if ( in_array( 'stormpath_error', $err_codes ) ) {
    			$error = '<strong>ERROR</strong>: There was an error logging you in. Please let the administrator know you received a ' . $errors->get_error_data()['code'] . ' code during login.';
    		}
    
    		return $error;
    	}
    
    	/**
    	 * Creates a new Stormpath Client
    	 *
    	 * @return null|Client
    	 */
    	private function create_client() {
    		list( $id, $secret ) = $this->resolve_api_keys();
    
    		if ( null === $id || null === $secret ) {
    			do_action( 'stormpath_admin_error', 'api_keys_could_not_be_resolved' );
    			return null;
    		}
    
    		$builder = new \Stormpath\ClientBuilder();
    		$client = $builder->setApiKeyProperties( "apiKey.id={$id}\napiKey.secret={$secret}" )
    			->build();
    
    		return $client;
    
    	}
    
    	/**
    	 * Resolves the API Keys from direct properties, then from properties file.
    	 *
    	 * @return array
    	 */
    	private function resolve_api_keys() {
    		$id = null;
    		$secret = null;
    
    		if ( get_option( 'stormpath_client_apikey_properties' ) ) {
    			$file = get_option( 'stormpath_client_apikey_properties' );
    
    			if ( false === is_file( $file ) && false === is_readable( $file ) ) {
    				do_action( 'stormpath_admin_error', 'api_key_properties_file_invalid' );
    				return [];
    			}
    
    			$content = fopen( $file, 'r' );
    			$content = explode( "\n", fread( $content, 1024 ) );
    			$array = [];
    			foreach ( $content as $line ) {
    				if ( '' === $line ) { continue;
    				}
    				$parts = explode( ' = ', $line );
    				if ( count( $parts ) ) {
    					$array[ $parts[0] ] = $parts[1];
    				}
    			}
    
    			if ( ( ( count( $array ) !== 2 ) || ( ( ! isset( $array['apiKey.id'] )) && ( ! isset( $array['apiKey.secret'] )) ) ) &&
    				( !get_option( 'stormpath_client_apikey_id' ) || !get_option( 'stormpath_client_apikey_secret' )  ) ) {
    				do_action( 'stormpath_admin_error', 'api_key_properties_file_invalid' );
    			}
    
    			$id = $array['apiKey.id'];
    			$secret = $array['apiKey.secret'];
    		}
    
    		if ( get_option( 'stormpath_client_apikey_id', '' )   && get_option( 'stormpath_client_apikey_secret', '' )  ) {
    
    			do_action( 'stormpath_admin_warning', 'api_key_properties_file_should_be_used' );
    
    			$id = get_option( 'stormpath_client_apikey_id' );
    			$secret = get_option( 'stormpath_client_apikey_secret' );
    		}
    
    		return [ $id, $secret ];
    	}
    
    	/**
    	 * Get the Stormpath application.
    	 *
    	 * @return bool|Application
    	 */
    	public function application() {
    		if ( $this->client ) {
    			try {
    				return $this->client->getDataStore()->getResource( get_option( 'stormpath_application' ), '\Stormpath\Resource\Application' );
    			} catch (\Exception $e) {
    				do_action( 'stormpath_admin_error', 'general', $e->getMessage() );
    				return false;
    			}
    		}
    	}
    }
    

    And new authenticate.php:

    <?php
    /**
     * Stormpath WordPress is a WordPress plugin to authenticate against a Stormpath Directory.
     * Copyright (C) 2016  Stormpath
     *
     * This file is part of Stormpath WordPress.
     *
     * Stormpath WordPress is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 2 of the License, or
     * (at your option) any later version.
     *
     * Stormpath WordPress is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
     *
     * @package Stormpath\WordPress;
     */
    
    namespace Stormpath\WordPress;
    
    use Stormpath\Resource\Account;
    use Stormpath\Resource\Application;
    use WP_Error;
    use WP_User;
    
    /**
     * Class Authenticate
     *
     * @category    Stormpath
     * @package     Stormpath\WordPress
     * @author      Stormpath <support@stormpath.com>
     * @license     http://www.gnu.org/copyleft/gpl.html GNU General Public License
     * @link        https://stormpath.com/
     */
    class Authenticate
    {
    	/**
    	 * The Stormpath Client.
    	 *
    	 * @var Client
    	 */
    	private $spClient;
    	/**
    	 * The Stormpath Application.
    	 *
    	 * @var Application
    	 */
    	private $spApplication;
    
    	/**
    	 * Authenticate constructor.
    	 *
    	 * @param Application       $application The Stormpath Application.
    	 * @param \Stormpath\Client $client      The Stormpath Client.
    	 */
    	public function __construct( $application, \Stormpath\Client $client ) {
    		$this->spClient = $client;
    		$this->spApplication = $application;
    
    	}
    
    	/**
    	 * The main authenticate method.
    	 *
    	 * @param null|WP_User|WP_Error $user     The WordPress User.
    	 * @param string                $username Username.
    	 * @param string                $password Password.
    	 * @return bool|WP_Error|WP_User
    	 */
    	public function authenticate( $user, $username, $password ) {
    		remove_action( 'authenticate', 'wp_authenticate_username_password', 20 );
    
    		if ( empty( $username ) || empty( $password ) ) {
    			if ( is_wp_error( $user ) ) {
    				return $user;
    			}
    
    			$error = new WP_Error();
    
    			if ( empty( $username ) ) {
    				$error->add( 'empty_username', __( '<strong>ERROR</strong>: The username field is empty.' ) );
    			}
    
    			if ( empty( $password ) ) {
    				$error->add( 'empty_password', __( '<strong>ERROR</strong>: The password field is empty.' ) );
    			}
    
    			return $error;
    		}
    
    		$authenticationRequest = new \Stormpath\Authc\UsernamePasswordRequest(
    			$username,
    			$password
    		);
    
    		$account = null;
    
    		try {
    			$account = $this->spApplication->authenticateAccount( $authenticationRequest )->account;
    		} catch (\Exception $e) {
    		    if ( 7104 === $e->getCode() ) {
    				$account = $this->attempt_normal_login( $username, $password );
    			} else {
    				return false;
    			}
    		}
    
    		if ( $account instanceof WP_Error ) {
    		    return $account;
    		}
    
    		if ( ! $account instanceof \Stormpath\Resource\Account ) {
    		    return false;
    		}
    
    		$wpUser = $this->get_wp_user( $account );
    
    		if ( 0 === $wpUser->ID ) {
    			$wpUser = $this->create_wp_user( $account, $password );
    		}
    
    		return $this->login_wp_user( $wpUser );
    
    	}
    
    	/**
    	 * Attempt a normal login with WordPress core function.
    	 *
    	 * @param string $username The username of login attempt.
    	 * @param string $password The password of the login attempt.
    	 * @return boolean|\Stormpath\Resource\Account
    	 */
    	private function attempt_normal_login( $username, $password ) {
    		$user = get_user_by( 'login', $username );
    
    		if ( $user && wp_check_password( $password, $user->data->user_pass, $user->ID ) ) {
    			return $this->register_stormpath_user( $user, $password );
    		}
    
    		$user = get_user_by( 'email', $username );
    
    		if ( $user && wp_check_password( $password, $user->data->user_pass, $user->ID ) ) {
    			return $this->register_stormpath_user( $user, $password );
    		}
    
    		return false;
    	}
    
    	/**
    	 * Get a WordPress user based on the account email.
    	 *
    	 * @param Account $account The stormpath account.
    	 * @return WP_User
    	 */
    	private function get_wp_user( Account $account ) {
    		return new WP_User( (new WP_User())->get_data_by( 'email', $account->email )->ID );
    
    	}
    
    	/**
    	 * Create a WordPress User.
    	 *
    	 * @param Account $account  The Stormpath Account.
    	 * @param string  $password The Password.
    	 * @return WP_User
    	 */
    	private function create_wp_user( Account $account, $password ) {
    		$userAccountInfo = [
    			'user_email'    => $account->email,
    			'user_login'    => $account->username,
    			'first_name'    => $account->givenName,
    			'last_name'     => $account->surname,
    			'user_pass'     => wp_hash_password( wp_generate_password( 32 ) ),
    		];
    
    		$newUser = wp_insert_user( $userAccountInfo );
    
    		return new WP_User( $newUser );
    	}
    
    	/**
    	 * Force Login of WordPress User
    	 *
    	 * @param WP_User $wpUser The WordPress User.
    	 * @return WP_User
    	 */
    	public function login_wp_user( $wpUser ) {
    		return wp_set_current_user( $wpUser->ID );
    	}
    
    	/**
    	 * Hook callback for when a user was registered.
    	 *
    	 * @param int $wpUserId The WordPress User Id.
    	 * @return void
    	 */
    	public function user_registered( $wpUserId ) {
    		if ( ! isset( $_REQUEST['_wpnonce_create-user'] ) || ! isset( $_POST['pass1'] ) ) {
    			return;
    		}
    		if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce_create-user'] ) ), 'create-user' ) ) {
    			wp_die( 'nonce not valid' );
    		}
    		$user = new WP_User( $wpUserId );
    		$password = sanitize_text_field( wp_unslash( $_POST['pass1'] ) );
    
    		$account = new \stdClass();
    		$account->email = $user->user_email;
    		$account->password = $password;
    		$account->givenName = $user->user_firstname;
    		$account->surname = $user->user_lastname;
    		$account->username = $user->user_login;
    
    		$accountObj = $this->spClient->getDataStore()->instantiate( 'Account', $account );
    
    		$this->spApplication->createAccount( $accountObj );
    
    		wp_set_password( wp_hash_password( wp_generate_password( 32 ) ), $wpUserId );
    
    	}
    
    	/**
    	 * Register a user from a valid WP_User.
    	 *
    	 * @param WP_User $wpUser   The user being registered.
    	 * @param string  $password The password for the user.
    	 * @return Account|WP_Error|boolean
    	 */
    	public function register_stormpath_user( WP_User $wpUser, $password ) {
    	    try {
    			$account = new \stdClass();
    			$account->email = $wpUser->user_email;
    			$account->password = $password;
    			$account->givenName = $wpUser->user_firstname ?: 'Temp FirstName';
    			$account->surname = $wpUser->user_lastname ?: 'Temp LastName';
    			$account->username = $wpUser->user_login;
    
    			$accountObj = $this->spClient->getDataStore()->instantiate( 'Account', $account );
    
    			return $this->spApplication->createAccount( $accountObj );
    
    		} catch (\Exception $e) {
    			return false;
    		}
    	}
    
    	/**
    	 * Hook callback for when a profile was updated.
    	 *
    	 * @param int    $userId  Id of User.
    	 * @param object $oldData old user data.
    	 * @return void
    	 */
    	public function profile_update( $userId, $oldData ) {
    		$newData = get_userdata( $userId );
    		if ( ! isset( $_REQUEST['_wpnonce'] ) || ! isset( $_POST['pass1-text'] ) ) {
    			return;
    		}
    		if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'update-user_' . $userId ) ) {
    			wp_die( 'nonce not valid' );
    		}
    
    		// Remove the nag if the password has been changed.
    		if ( $newData->user_pass !== $oldData->user_pass ) {
    			$user = new WP_User( $userId );
    			$this->password_changed( $user, sanitize_text_field( wp_unslash( $_POST['pass1-text'] ) ) );
    
    		}
    	}
    
    	/**
    	 * Hook Callback for when a password was changed.
    	 *
    	 * @param WP_User $user     The User.
    	 * @param string  $password The Password.
    	 * @return void
    	 */
    	public function password_changed( $user, $password ) {
    		$accounts = $this->spApplication->accounts->setSearch( [ 'q' => $user->user_email ] );
    		if ( $accounts->size > 0 ) {
    
    			$account = $accounts->getIterator()->current();
    
    			$account->password = $password;
    			$account->save();
    
    			$id = $user->ID;
    			wp_set_password( wp_hash_password( wp_generate_password( 32 ) ), $id );
    		}
    	}
    }

    Both of these are inside the /includes folder in the plugin folder. Once you load these, you should be able to activate.

    • This reply was modified 4 years, 4 months ago by Techcyclist.
    • This reply was modified 4 years, 4 months ago by Techcyclist.
    Plugin Author bretterer

    (@bretterer)

    Sorry for the late reply Techcyclist. I will get this on our issue log to release an update ASAP to fix this.

    Brian

    Plugin Author bretterer

    (@bretterer)

    Hi @techcyclist and @codekrafter. I have patched the issue. The problem was not the use of empty itself, but in versions of PHP prior to 5.5, empty() does not allow use of anything but a variable, which we were using a method to get the value. I will release a patch where it still uses empty, but I extracted the method out to a variable and pass the var into the empty() method. Thank you, and watch for an update in the next day.

    -Brian

    Thread Starter Techcyclist

    (@techcyclist)

    Hi Brian, thanks for taking action. I upgraded the plugin to your version and the whole site would not load while it was activated. So something is wrong there. I ended up reverting to the version we patched with changes above. I didn’t have time to try to figure out why it did that, being the site wasn’t loading, I don’t want to play around.

    Plugin Author bretterer

    (@bretterer)

    @techcyclist. Could you please email support@stormpath.com and direct it to me. I would like to get some more in depth info from you on your setup

    Thread Starter Techcyclist

    (@techcyclist)

    OK sure

    Thread Starter Techcyclist

    (@techcyclist)

    I emailed stormpath support.

    • This reply was modified 4 years, 4 months ago by Techcyclist.
Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘Plugin could not be activated: fatal error’ is closed to new replies.