User tests: Successful: Unsuccessful:
AI usage acknowledgement (per Joomla Generative AI policy)
I used an AI tool to assist with this pull request (for drafting parts of the description and for code suggestions), but I have fully reviewed, adapted, and tested the changes myself and I understand how they work. I take responsibility for the correctness, security, licensing and maintainability of this contribution.
Problem
Custom fields are exposed as top‑level properties in the JSON API.
When a custom field has the same name as a core property (for example images on articles, image on contacts, or email on users), the custom field assignment overwrites the core value in the API response.
This causes core data (like article images or contact image) to disappear from the payload, and the custom field value can also become inaccessible.
Root cause
In the JSON API views for components using custom fields:
prepareItem() assigned $item->{$field->name} without checking if that property already existed as a core property on the item.
displayList() / displayItem() registered custom field names directly into fieldsToRenderList / fieldsToRenderItem, again without checking for name collisions.
This was implemented initially only for com_content (articles), so other components remained affected.
Fix
I implemented a consistent, collision‑safe behaviour across the JSON API views which expose custom fields:
Articles (com_content.article)
If a custom field name collides with a core article property, the JSON key is prefixed with cf_ (e.g. cf_images) instead of overwriting the core property.
The effective key (name or cf_name) is also registered in both fieldsToRenderItem and fieldsToRenderList.
Contacts (com_contact.contact)
Same pattern as articles: a custom field named image no longer overwrites the core image property; it is exposed as cf_image.
Users (com_users.user)
Same pattern: a custom field named e.g. email or name is exposed as cf_email / cf_name if there is a collision, leaving the core user properties intact.
Categories (com_content.categories)
Same pattern for content categories, so custom fields cannot overwrite core category properties (like title or description) in the JSON responses.
The general rule is:
Core properties keep their original names.
If a custom field name would collide with a core property, it is exposed as cf_.
Result
Core properties such as article images, contact image, user email / name, and core category fields are preserved in JSON API responses.
Custom fields with colliding names are still available under predictable cf_‑prefixed keys.
Behaviour is consistent between list and single‑item endpoints across the affected components.
Testing
Manually tested scenarios:
Article with custom field images
Set intro/full images in the article and a custom field named images on the same article.
Verified /api/index.php/v1/content/articles/{id} and the list endpoint still return the core images structure and also expose the custom field as cf_images.
Contact with custom field image
Set a core image and a custom field named image on a contact.
Verified /api/index.php/v1/contacts/{id} and /api/index.php/v1/contacts return the core image and expose the custom field as cf_image.
User with custom field email
Added a custom field email to com_users.user.
Verified /api/index.php/v1/users/{id} and /api/index.php/v1/users return the core email and expose the custom field as cf_email.
Category with colliding custom field (e.g. title)
Added a custom field title for com_content.categories.
Verified category JSON responses keep the core title and expose the custom field as cf_title.
Fixes #47301
| Status | New | ⇒ | Pending |
| Category | ⇒ | JavaScript Unit Tests |
Thanks for pointing that out.
you are right currently my fix only handles the issue in com_content I was mainly focused on the article endpoints and didn't think about the fact that custom fields are used in other components as well ... so it probably makes more sense to handle this at a more central level so every component using custom fields gets the fix.
Would it be better to move this logic somewhere like libraries/src/MVC/View/JsonApiView.php, or should it be handled through com_fields (maybe FieldsHelper)?
Happy to refactor the PR and make the solution global. Just wanted to know the preferred place for it.
| Labels |
Added:
Unit/System Tests
PR-5.4-dev
|
||
@Harsh63870 2 things:
@Harsh63870 P.S.: There are already 2 other, older PRs for the same issue. Maybe you should focus on fixing issues where we do not have a PR yet instead of adding a 3rd one for the same issue.
| Title |
|
||||||
Thanks for the heads‑up, @richard67. I’m aware of the two earlier PRs for this issue and I had a look at them before working on this one.
The reason I still opened this PR is that it takes a slightly different, more general approach:
It prevents custom fields from overwriting core properties not only for com_content, but also for other JSON API views which expose custom fields (e.g. users, contacts, categories).
It uses a consistent convention (cf_ prefix) for name collisions so the behaviour is predictable across endpoints.
If maintainers prefer, I’m happy to rework this PR or help adapt the same approach into one of the existing PRs, but from my perspective this solution is more complete and easier to maintain long‑term.
Of course, if the team decides to go forward with one of the older PRs instead, I’m fine to close this and will focus my efforts on issues without existing PRs.
@brianteeman already pointed out that the fix should live at a more central level than just com_content, and my goal with this PR is to follow that guidance and address the collision problem consistently across all relevant JSON API views.
Of course, if the team decides to go forward with one of the older PRs instead, I’m fine to close this and will focus my efforts on issues without existing PRs.
@Harsh63870 If you don't add the acknowledgment of our AI politicy to the top of your PR description like it can be seen in other, current PRs, it will be closed anyway.
@richard67 I’ve added the AI usage acknowledgement to the top of the PR description as requested.
The failing integration job is due to a GHCR pull timeout for ghcr.io/joomla-projects/mirror-bitnami-openldap:latest (network/infra). Re-running failed jobs.
@brianteeman @richard67
I’ve updated this PR to apply the collision-safe cf_ prefix logic not only for com_content but also for other JSON API views using custom fields (users, contacts, categories), and add the AI usage acknowledgement at the top of the description as requested, and update the description to match the current, more general fix.
All style, unit, system tests and most integration tests are passing; the remaining failing integration job was due to a temporary GHCR pull timeout for the OpenLDAP test image, and I’ve re-run the failed jobs.
When you have a moment, could you please have another look and let me know if this approach and placement of the logic are acceptable, or if you’d prefer it to live in a different shared helper?
Changes for articles, contacts, users and content categories are ready and all tests pass. If you’d like, I can refactor the collision logic into shared helpers on JsonApiView, otherwise I’ll wait for your review and further instructions.
i think it should be better to avoid duplicate code
| Title |
|
||||||
| Labels |
Added:
Feature
Webservices
b/c break
|
||
| Category | JavaScript Unit Tests | ⇒ | Libraries JavaScript Unit Tests |
@alikon @richard67 I’ve refactored the custom-field collision handling to avoid duplicate code. The logic for choosing collision-safe keys (name vs cf_name) and assigning custom field values now lives in shared helper methods on JsonApiView, and the JSON API views for articles, contacts, users, and content categories call these helpers. Behaviour is unchanged: core properties keep their original names and colliding custom fields are exposed under a cf_‑prefixed key.
This pull request has been automatically rebased to 6.2-dev.
| Title |
|
||||||
custom fields are also available in many other components. this only addresses com_content