Autodesk-Forge / learn.forge.viewmodels

Learn Forge Tutorial: View your models using 2-legged OAuth. Available in Nodejs, .NET, Go, PHP & Java
http://learnforge.autodesk.io
MIT License
105 stars 85 forks source link

PHP - Failed to get env #57

Open JohnOnSoftware opened 3 years ago

JohnOnSoftware commented 3 years ago

It seems the following code at https://github.com/Autodesk-Forge/learn.forge.viewmodels/blob/php/server/config.php#L14 to get env is not working any more, need to update with latest change.

// load the environment variable from .env into your application $dotenv = Dotenv::create(DIR); $dotenv->load(); $forge_id = getenv('FORGE_CLIENT_ID');

yiskang commented 3 years ago

Just some findings.

With the recent Dotenv change, the Dotenv::create(__DIR__) is supported now. To make it work again, we need to replace it with Dotenv::createUnsafeImmutable(__DIR__).

The Dotenv\Dotenv::createImmutable and Dotenv\Dotenv::createMutable methods no longer call will result in getenv and putenv being called. One should instead use Dotenv\Dotenv::createUnsafeImmutable and Dotenv\Dotenv::createUnsafeMutable methods if one really needs these functions.

<?php
namespace Autodesk\ForgeServices;
use Dotenv\Dotenv;

class ForgeConfig{
    private static $forge_id = null;
    private static $forge_secret = null;
    public static $prepend_bucketkey = true; //toggle client ID prefix to avoid conflict with existing buckets

    public static function getForgeID(){
      $forge_id = getenv('FORGE_CLIENT_ID');
      if(!$forge_id){
        // load the environment variable from .env into your application
        $dotenv = Dotenv::createUnsafeImmutable(__DIR__);
        $dotenv->load();
        $forge_id = getenv('FORGE_CLIENT_ID');
     }
      return $forge_id;
    }

    public static function getForgeSecret(){
      $forge_secret = getenv('FORGE_CLIENT_SECRET');
      if(!$forge_secret){
        // load the environment variable from .env into your application
        $dotenv = Dotenv::createUnsafeImmutable(__DIR__);
        $dotenv->load();
        $forge_secret = getenv('FORGE_CLIENT_SECRET');
     }
      return $forge_secret;
    }

    // Required scopes for your application on server-side
    public static function getScopeInternal(){
      return ['bucket:create', 'bucket:read', 'data:read', 'data:create', 'data:write'];
    }

    // Required scope of the token sent to the client
    public static function getScopePublic(){
      // Will update the scope to viewables:read when #13 of autodesk/forge-client is fixed
      return ['data:read'];
    }
}

However, getting env variables from the getenv looks not the commended way. See Putenv and Getenv, and see the below for the revision code snippet following the suggestion of the owner of the phpdotenv repo.

Using getenv() and putenv() is strongly discouraged due to the fact that these functions are not thread safe, however it is still possible to instruct PHP dotenv to use these functions. Instead of calling Dotenv::createImmutable, one can call Dotenv::createUnsafeImmutable, which will add the PutenvAdapter behind the scenes.

<?php
namespace Autodesk\ForgeServices;
use Dotenv\Dotenv;

class ForgeConfig{
    private static $forge_id = null;
    private static $forge_secret = null;
    public static $prepend_bucketkey = true; //toggle client ID prefix to avoid conflict with existing buckets

    public static function getForgeID(){
      $forge_id = '';
      if(!array_key_exists('FORGE_CLIENT_ID', $_ENV)){
        // load the environment variable from .env into your application
        $dotenv = Dotenv::createImmutable(__DIR__);
        $dotenv->load();
      }
      $forge_id = $_ENV['FORGE_CLIENT_ID'];
      return $forge_id;
    }

    public static function getForgeSecret(){
      $forge_secret = '';
      if(!array_key_exists('FORGE_CLIENT_SECRET', $_ENV)){
        // load the environment variable from .env into your application
        $dotenv = Dotenv::createImmutable(__DIR__);
        $dotenv->load();
      }
      $forge_secret = $_ENV['FORGE_CLIENT_SECRET'];
      return $forge_secret;
    }

    // Required scopes for your application on server-side
    public static function getScopeInternal(){
      return ['bucket:create', 'bucket:read', 'data:read', 'data:create', 'data:write'];
    }

    // Required scope of the token sent to the client
    public static function getScopePublic(){
      // Will update the scope to viewables:read when #13 of autodesk/forge-client is fixed
      return ['data:read'];
    }
}
yiskang commented 2 years ago

Hi @JohnOnSoftware,

I happened to test this repo for another customer. There seems something changed in dotenv again. Now Dotenv::createImmutable() seems not working anymore, but Dotenv::create() work fine.