xero-php
xero-php copied to clipboard
getPackageVersion in Helpers causes OutOfBoundsException errors on systems with multiple composer installs
Run into a weird problem with a wordpress build, with the following error:
[22-Oct-2021 08:55:16 UTC] PHP Fatal error: Uncaught OutOfBoundsException: Package "calcinai/xero-php" is not installed in public_html/wp-content/plugins/woocommerce-eu-vat-assistant/src/vendor/composer/InstalledVersions.php:188
That pathing looked odd to me, so i Tracked the issue to here:
public static function getPackageVersion()
{
if (!is_callable('\\Composer\\InstalledVersions::getPrettyVersion')) {
return self::DEFAULT_VERSION;
}
return \Composer\InstalledVersions::getPrettyVersion(self::PACKAGE_NAME);
}
The reference to \Composer is loading the composer namespace instantiated by the woocommerce-eu-vat-assistant plugin, not the custom plugin that is calling it.
For clarity, several plugins have vendor directories included, which means several versions of the \Composer namespace which means that \Composer\InstalledVersions is calling the wrong composer.json for checks, thus is failing (so far as i can tell).
Not sure what the fix is here - i'll provide one if i can work it out. Anyone else run into the same thing?
Hit the same issue.
v2.2.4 didn't have this issue, although the file you reference was still labelled v2.2.1 in the header comments, I reverted back to this and no longer hit the error...
const PACKAGE_VERSION_FILE = '/VERSION';
public static function getPackageVersion()
{
if (!file_exists(self::PACKAGE_VERSION_FILE)) {
return self::DEFAULT_VERSION;
}
return file_get_contents(self::PACKAGE_VERSION_FILE);
}
Oh man. @N1ghteyes did you find a solution to this?
FYI, the reason for this was for Xero to see which versions of the library were bring used during support requests.
@calcinai I hacked it in the end to return a set value (rather than checking against composer), so no not really a fix I'm afraid.
I suspect the actual fix here is to maintain a version constant that can be referenced - it'll just mean a manual update to it every time you push a minor version.
For reference, this is what I ended up doing (based on @N1ghteyes comment above). I created a custom \XeroPHP\Application
subclass and overrode the constructor and just passed it a hardcoded version for the User-Agent
string instead of having it use Helpers::getPackageVersion()
:
class CustomXeroApplication extends \XeroPHP\Application
{
/** @noinspection MagicMethodsValidityInspection
* @noinspection PhpMissingParentConstructorInspection
*/
public function __construct($token, $tenantId)
{
$this->config = static::$_config_defaults;
$transport = new Client([
'headers' => [
'User-Agent' => sprintf(static::USER_AGENT_STRING, 'v2.4.1'),
'Authorization' => sprintf('Bearer %s', $token),
'Xero-tenant-id' => $tenantId,
],
]);
$reflectionProperty = new \ReflectionProperty(\XeroPHP\Application::class, 'transport');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($this, $transport);
}
}
@ValCanBuild I think the best way to do this is just to add a file as part of the build pipeline (and the tag). Just not completely sure how this would work with composer releases in terms of keeping the git tag consistent with the version in the code.