XF 2.0 Call \XF Class Outside XenForo && Outside Composer Root

LPH

Well-known member
This one has my head spinning.

I've decided to learn Composer. Everything loads fine except a PHP file above the src/ needs to call the \XF class.

Here is the composer.json

Code:
{
  "name": "TuxReports/XenWord",
  "type": "wordpress-plugin",
  "description": "This configuration file is used for XenWord 2017 using Composer.",

  "autoload"   : {
    "psr-4": {
      "ProjectRoot\\" : "",
      "XenWord\\": "src/"
    }
  }
}

Here is the directory structure:

/xenword
/xenword/composer.json
/xenword/xenword.php
/xenword/assets/
/xenword/framework/
/xenword/src/ <--- namespace root
/xenword/support/
/xenword/vendor/

The main xenword.php file requires the autoload.php as well as the framework/admin-init.php. Everything loads except one part of the framework init file -- the part which has a conditional for the XF class exist. For some reason, the file in the /xenword/framework loads everything except that it cannot find the \XF.

This is the code.

PHP:
if ( class_exists( 'XF' ) ) {

    /** @var \XF\Repository\UserGroup $groupRepo */
    $groupRepo = \XF::app()->repository('XF:UserGroup');
    $usergroups = $groupRepo->getUserGroupTitlePairs();

    return $usergroups;
   }

Before adding composer, this code was not an issue. This is because I was starting the namespace at /xenword rather than /xenword/src/. I've been looking at the composer.json to see if there was a way to add the ability to call \XF but became very confused.

Does anyone have any suggestions on how to get the conditional to work properly?
 
The XF class isn't really autoloadable. You need to manually include it and call XF's initialization routines (which includes XF's autoloader) before working with anything within XF.
 
I’m probably not explaining well. The code above is in an init file for a framework which worked before switching to autoload through composer, the XF class exists for XenForo 2 and the bridge works: login, logout, loading threads externally, pulling stats, etc. The problem is the conditional code in the framework init file doesn’t see XF class. It’s sitting above the anchored namespace. All files in /src see the XF class and work fine.

Code:
|—framework
     |__ init.php
|— src

The directory src is anchored to the namespace, the init file is in a different directory. The framework loads, except for this code checking for the existing XF class.

In other words, this all worked until Composer autoload — anchored to /src.
 
@Mike - Thank you for the help. :D

Based on your post, and thinking about things for a few hours, your point was more clear. I really appreciate the explanation.

It turned out a call to the connector within the init file loaded the \XF class unless the class already exists fixed the issue. Everything now works as it did before starting to use Composer.

Based on your help, as well as @Chris D -- the plugin is nearing an alpha release in a few weeks.

https://www.tuxreports.com/community/threads/xenword-4-news.610502/

PHP:
/**
* Get XenForo UserGroups
* @return mixed
*/
function xenwordGetUGIds() {
   if ( class_exists( '\XenWord\Core\Loader' ) ) {

      if ( ! class_exists('\XF') ) {
         $Connect2 = new \XenWord\Core\Connector();
         $Connect2->getXenForo();
      }

      /** @var \XF\Repository\UserGroup $groupRepo */
      $groupRepo  = \XF::app()->repository( 'XF:UserGroup' );
      $usergroups = $groupRepo->getUserGroupTitlePairs();

      return $usergroups;
   }
}

On a personal note, the reason XenForo 2 is awesome is due to the help. I knew nothing about Composer, autoloading, namespace, entities, finders, etc in May. I didn't speak up much lately because of reading the code and trying to learn. Regardless, XenWord code is far stronger because of XenForo 2.
 
Top Bottom