Managed to fix it via huoxin233/flarum-ext-money-with-history@b2654a8, not sure if the issue in cli is valid and still worth fixing
I ran fl2 upgrade 2.0 on my Money with History extension huoxin233/flarum-ext-money-with-history@e49634e
Got an error half way through:
STEP 12/16 Prepare for JSON:API changes.
=> DONE Flarum 2.0 completely refactors the JSON:API implementation. The way resource CRUD operations,
serialization and extending other resources is done has completely changed.
The tool cannot completely automate this change, but it has added some boilerplate code and TODO comments to help you get started.
You should make whatever changes you can now, then properly test and adapt your code once the upgrade process is over.
Read more: https://docs.flarum.org/2.x/extend/update-2_0#jsonapi
Checkout our additional guide which provides concrete examples for the upgrading process of the JSON:API layer:
https://docs.flarum.org/2.x/extend/update-2_0-api
=> COMMIT chore(2.0): JSON:API changes
STEP 13/16 Intervention Image Library v3
=> WORKING.
Error occurred, and could not complete:
The PHP subsystem returned an invalid value: Syntax error, unexpected '{' on line 15 - #0 /home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php(185): PhpParser\ParserAbstract->doParse()
#1 /home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/php-subsystem/src/Upgrade/Replacement.php(29): PhpParser\ParserAbstract->parse()
#2 /home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/php-subsystem/index.php(37): Flarum\CliPhpSubsystem\Upgrade\Replacement->handle()
#3 {main}
Error: The PHP subsystem returned an invalid value: Syntax error, unexpected '{' on line 15 - #0 /home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php(185): PhpParser\ParserAbstract->doParse()
#1 /home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/php-subsystem/src/Upgrade/Replacement.php(29): PhpParser\ParserAbstract->parse()
#2 /home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/php-subsystem/index.php(37): Flarum\CliPhpSubsystem\Upgrade\Replacement->handle()
#3 {main}
at PhpSubsystemProvider.handlePhpError (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/providers/php-provider.js:48:19)
at PhpSubsystemProvider.run (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/providers/php-provider.js:34:14)
at /home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/steps/upgrade/twopointoh/backend/intervention-image.js:16:35
at InterventionImage.applyReplacements (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/steps/upgrade/twopointoh/base.js:164:34)
at applyOn (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/steps/upgrade/twopointoh/base.js:103:47)
at async InterventionImage.run (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/steps/upgrade/twopointoh/base.js:134:13)
at async StepManager.runStep (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/boilersmith/step-manager.js:179:23)
at async checkAndRun (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/boilersmith/step-manager.js:92:24)
at async StepManager.run (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/boilersmith/step-manager.js:113:21)
at async TwoPointOh.run (/home/huoxin/.nvm/versions/node/v24.15.0/lib/node_modules/fl2/lib/base-command.js:71:21)
Before the error, the following steps were completed:
Saw that at Step 12 Prepare for JSON:API changes, a file src/Api/Resource/MoneyHistoryResource.php is created with syntax error, it is nothing behind the implements:
<?php
namespace Huoxin\MoneyWithHistory\Api\Resource;
use Flarum\Api\Context;
use Flarum\Api\Endpoint;
use Flarum\Api\Resource;
use Flarum\Api\Schema;
use Tobyz\JsonApiServer\Context as OriginalContext;
/**
* @extends Resource\AbstractResource<object>
*/
class MoneyHistoryResource extends Resource\AbstractResource implements
{
...
Review from AI: The Root Cause: A Misplaced Comma
When the Flarum 2.0 migration script (or a user running flarum-cli make api-resource) generates a new Api\Resource without an attached model class, the template logic mistakenly swallows the comma meant to separate the endpoints in the returned PHP array.
Take a look at the original EJS logic for the endpoints() array (lines 36-38):
return [<% if (endpoints.includes('create')) { %>
Endpoint\Create::make()<% if (modelClassName) { %>
->can('create<%= modelClassName %>'),<% } %><% } %><% if (endpoints.includes('update')) { %>
Endpoint\Update::make()
->can('update'),
The trailing comma , for the Endpoint\Create::make() element was placed inside the <% if (modelClassName) { %> conditional block.
If the upgrade script encounters a scenario where it generates an API resource that is not tied to a Flarum Database Model (or if the AST parser failed to extract the model class cleanly from the legacy serializer), modelClassName evaluates to false. This results in the EJS generating the following malformed PHP output:
return [
Endpoint\Create::make()
Endpoint\Update::make()
->can('update'),
];
Because Endpoint\Create::make() lacks a trailing comma, it immediately breaks the PHP array syntax. Flarum CLI uses nikic/php-parser under the hood to perform AST transformations. When the subsequent "Intervention Image Library" upgrade step kicks in, it attempts to parse all .php files in your src/ directory. The parser encounters this malformed array inside your newly generated MoneyHistoryResource.php and crashes the entire upgrade process with a syntax error.
Fix provided from AI
diff --git a/boilerplate/stubs/backend/advanced-api-resource.php b/boilerplate/stubs/backend/advanced-api-resource.php
index be6040d..b27d8b6 100644
--- a/boilerplate/stubs/backend/advanced-api-resource.php
+++ b/boilerplate/stubs/backend/advanced-api-resource.php
@@ -14,7 +14,7 @@ use Tobyz\JsonApiServer\Context as OriginalContext;
/**
* @extends <% if (modelClassName) { %>Resource\AbstractDatabaseResource<<%= modelClassName %>><% } else { %>Resource\AbstractResource<object><% } %>
*/
-class <%= className %> extends <% if (modelClassName) { %>Resource\AbstractDatabaseResource<% } else { %>Resource\AbstractResource<% if (interfaces.length > 0) %> implements <%= interfaces.join(', ') %><% } %>
+class <%= className %> extends <% if (modelClassName) { %>Resource\AbstractDatabaseResource<% } else { %>Resource\AbstractResource<% if (interfaces.length > 0) { %> implements <%= interfaces.join(', ') %><% } %><% } %>
{
public function type(): string
{
@@ -35,13 +35,13 @@ class <%= className %> extends <% if (modelClassName) { %>Resource\AbstractDatab
{
return [<% if (endpoints.includes('create')) { %>
Endpoint\Create::make()<% if (modelClassName) { %>
- ->can('create<%= modelClassName %>'),<% } %><% } %><% if (endpoints.includes('update')) { %>
+ ->can('create<%= modelClassName %>')<% } %>,<% } %><% if (endpoints.includes('update')) { %>
Endpoint\Update::make()
->can('update'),<% } %><% if (endpoints.includes('delete')) { %>
Endpoint\Delete::make()
->can('delete'),<% } %><% if (endpoints.includes('show')) { %>
Endpoint\Show::make()
- ->authenticated(),<% } %><% if (endpoints.includes('list')) { %>
+ ->authenticated(),<% } %><% if (endpoints.includes('list') || endpoints.includes('index')) { %>
Endpoint\Index::make()
->paginate(),<% } %>
];
diff --git a/src/steps/stubs/backend/advanced-api-resource.ts b/src/steps/stubs/backend/advanced-api-resource.ts
index a539aec..9c12c49 100644
--- a/src/steps/stubs/backend/advanced-api-resource.ts
+++ b/src/steps/stubs/backend/advanced-api-resource.ts
@@ -72,6 +72,7 @@ export class GenerateAdvancedApiResourceStub extends BasePhpStubStep {
const interfaceMap: Record<string, string> = {
list: 'Resource\\Contracts\\Listable',
+ index: 'Resource\\Contracts\\Listable', // Add index as an alias for list
show: 'Resource\\Contracts\\Findable',
create: 'Resource\\Contracts\\Creatable',
update: 'Resource\\Contracts\\Updatable',
@@ -79,7 +80,7 @@ export class GenerateAdvancedApiResourceStub extends BasePhpStubStep {
};
params.modelType ||= pluralKebabCaseModel(params.modelClassName as string);
- params.interfaces = (params.endpoints as string[]).map((endpoint) => interfaceMap[endpoint]);
+ params.interfaces = (params.endpoints as string[]).map((endpoint) => interfaceMap[endpoint]).filter(Boolean);
return params;
}
Managed to fix it via huoxin233/flarum-ext-money-with-history@b2654a8, not sure if the issue in cli is valid and still worth fixing
I ran
fl2 upgrade 2.0on my Money with History extension huoxin233/flarum-ext-money-with-history@e49634eGot an error half way through:
Saw that at Step 12
Prepare for JSON:API changes, a filesrc/Api/Resource/MoneyHistoryResource.phpis created with syntax error, it is nothing behind theimplements:<?php namespace Huoxin\MoneyWithHistory\Api\Resource; use Flarum\Api\Context; use Flarum\Api\Endpoint; use Flarum\Api\Resource; use Flarum\Api\Schema; use Tobyz\JsonApiServer\Context as OriginalContext; /** * @extends Resource\AbstractResource<object> */ class MoneyHistoryResource extends Resource\AbstractResource implements { ...Review from AI: The Root Cause: A Misplaced Comma
When the Flarum 2.0 migration script (or a user running
flarum-cli make api-resource) generates a newApi\Resourcewithout an attached model class, the template logic mistakenly swallows the comma meant to separate the endpoints in the returned PHP array.Take a look at the original EJS logic for the
endpoints()array (lines 36-38):The trailing comma
,for theEndpoint\Create::make()element was placed inside the<% if (modelClassName) { %>conditional block.If the upgrade script encounters a scenario where it generates an API resource that is not tied to a Flarum Database Model (or if the AST parser failed to extract the model class cleanly from the legacy serializer),
modelClassNameevaluates to false. This results in the EJS generating the following malformed PHP output:Because
Endpoint\Create::make()lacks a trailing comma, it immediately breaks the PHP array syntax. Flarum CLI usesnikic/php-parserunder the hood to perform AST transformations. When the subsequent "Intervention Image Library" upgrade step kicks in, it attempts to parse all.phpfiles in yoursrc/directory. The parser encounters this malformed array inside your newly generatedMoneyHistoryResource.phpand crashes the entire upgrade process with a syntax error.Fix provided from AI