0

I am trying to connect users xero accounts with my app and I have that problem

Warning: session_start(): Cannot start session when headers already sent in /storage.php on line 11

my storage.php is like :

<?php
class StorageClass
{
    function __construct() {
        if( !isset($_SESSION) ){
            $this->init_session();
        }
    }

    public function init_session(){
        session_start();
    }

    public function getSession() {
        return $_SESSION['oauth2'];
    }

    public function startSession($token, $secret, $expires = null)
    {
        session_start();
    }

    public function setToken($token, $expires = null, $tenantId, $refreshToken, $idToken)
    {
        $_SESSION['oauth2'] = [
            'token' => $token,
            'expires' => $expires,
            'tenant_id' => $tenantId,
            'refresh_token' => $refreshToken,
            'id_token' => $idToken
        ];
    }

    public function getToken()
    {
        //If it doesn't exist or is expired, return null
        if (empty($this->getSession())
            || ($_SESSION['oauth2']['expires'] !== null
            && $_SESSION['oauth2']['expires'] <= time())
        ) {
            return null;
        }
        return $this->getSession();
    }

    public function getAccessToken()
    {
        return $_SESSION['oauth2']['token'];
    }

    public function getRefreshToken()
    {
        return $_SESSION['oauth2']['refresh_token'];
    }

    public function getExpires()
    {
        return $_SESSION['oauth2']['expires'];
    }

    public function getXeroTenantId()
    {
        return $_SESSION['oauth2']['tenant_id'];
    }

    public function getIdToken()
    {
        return $_SESSION['oauth2']['id_token'];
    }

    public function getHasExpired()
    {
        if (!empty($this->getSession()))
        {
            if(time() > $this->getExpires())
            {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }
}

and I call that class from

<?php
  ini_set('display_errors', 'On');
  require __DIR__ . '/vendor/autoload.php';
  require_once('storage.php');
   // Storage Class uses sessions for storing access token (demo only)
  // you'll need to extend to your Database for a scalable solution
  $storage = new StorageClass();
  $provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => '*********************************',
    'clientSecret'            => '*********************************',
    'redirectUri'             => '*********************************',
    'urlAuthorize'            => 'https://login.xero.com/identity/connect/authorize',
    'urlAccessToken'          => 'https://identity.xero.com/connect/token',
    'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Organisation'
  ]);

It is working fine in my localhost but when I upload the plugin in the host it give me that error.

Thanks for you time.

  • Why would you start a session inside a class? That's something which is normally just at the very first line of your main script (in order to avoid the possibility of the error you're seeing). IMHO I don't think your class ought to be worrying about actually managing the session. It can just add and remove things from the session as needed. If that fails because the session is unitialised, it's the calling code's responsibility to sort that out. – ADyson May 13 '22 at 15:17
  • Essentially a duplicate of [How to fix "Headers already sent" error in PHP](https://stackoverflow.com/questions/8028957/how-to-fix-headers-already-sent-error-in-php) – ADyson May 13 '22 at 15:17
  • It is already working local environment but when it is uploaded it doesn't work – Ahmed Zidan May 13 '22 at 16:15
  • Presumably there is some difference in the environments then, which is causing content to be output before this class is used. We can't tell you what that is since we can't see anything about it. Either work out what's causing it and remove that output, if you can, or do what everyone else does and put session_start() as the first thing in your main script, and nowhere else. – ADyson May 13 '22 at 16:19
  • the storage class is to store the token that I will have when the user login in with his xero account – Ahmed Zidan May 13 '22 at 16:38
  • in the cpanel there is oauth option in php options which is not checked, I don't know if it is dangerous or not to check it . – Ahmed Zidan May 13 '22 at 16:40
  • None of that has anything to do with your error – ADyson May 13 '22 at 16:43
  • It sounds like you need to find out how your host is configured. Is your php.ini file the same on both hosts, and what does the OAuth option in the cpanel do (you need to find that out from your host)? – w. Patrick Gale May 13 '22 at 16:44
  • Php's session stuff is not available to use with WordPress. It has its own session stuff. If you need to store user-specific "session data" use the wp_usermeta subsystem. – O. Jones May 13 '22 at 17:02
  • Maybe your dev machine has buffering enabled by default, but your host does not. – droopsnoot May 13 '22 at 17:04
  • Can you tell me how to find out about buffering thing in my host ? Thanks. – Ahmed Zidan May 13 '22 at 17:14

1 Answers1

2

Thanks for all of you for your interest. the answer was in 'output_buffering' I set it to on in .user.ini file to override php.ini and I put it in the public_html directory. Thanks again @droopsnoot.