[5.4] Fix: custom field named "images" overrides core article images in API response#47306
[5.4] Fix: custom field named "images" overrides core article images in API response#47306icybersanjay wants to merge 3 commits intojoomla:5.4-devfrom
Conversation
… response When a com_content custom field has the name "images", it was silently overwriting the core article images property during prepareItem(), causing the JSON:API response to return an empty array for images instead of the article's actual intro/fulltext image data. Fix by skipping custom field hydration for any property that already exists on the item object. Also prevent duplicate field names being appended to fieldsToRenderItem/fieldsToRenderList when a custom field name collides with a core field already declared in those arrays. Fixes joomla#47301
|
There is another, a little bit older PR for the same issue: #47304 . |
|
This cannot be the correct solution as the next question would be why isnt the content of my custom field being included in the api response. All you are doing here is silently removing a valid field to solve one part of the problem. |
|
What else should be done to fix the issue @brianteeman ? Renaming the custom field in the response? |
|
Perhaps with a custom field prefix. Simply throwing away the field content silently is just pushing the valid bug to someone else to fix in the future |
Joomla CS rules enforce unqualified native function calls inside a namespace — use `property_exists()` not `\property_exists()`.
|
I have tested this item 🔴 unsuccessfully on 2e34e59 This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/47306. |
…ng it
When a custom field shares a name with a core article property (e.g. "images"),
the previous guard silently dropped the custom field value entirely.
Instead, assign the custom field to a "cf_{name}" key on the item so that:
- The core article property (images, urls, etc.) is preserved as-is.
- The custom field value still appears in the API response as cf_images.
Apply the same prefix logic in displayItem() and displayList() so the
cf_{name} key is included in fieldsToRenderItem / fieldsToRenderList and
therefore serialised into the JSON:API attributes.
|
okay @brianteeman, now I've added prefix 'cf_' in case of field names collision |
|
Does adding a prefix such as “cf_” to custom fields create a problem with all apps that already use APIs and call custom fields by their name without a prefix? |
|
imho it's a wont fix, just choose a non conflicting name for custom fields |

Summary
Fixes #47301
When a
com_contentcustom field has the nameimages, it silently overwrites the core articleimagesproperty duringprepareItem(). This causes the JSON:API response (GET /api/index.php/v1/content/articles/{id}) to return an empty array forimagesinstead of the article's actual intro/fulltext image data.The same collision could occur for any other core field name (e.g.
urls,metadata) if a custom field uses the same name.What was changed
api/components/com_content/src/View/Articles/JsonapiView.phpprepareItem(): Skip custom field hydration when the property already exists on the item object, so core article data is never overwritten by a custom field with a colliding name.displayItem()/displayList(): Guard against appending a custom field name tofieldsToRenderItem/fieldsToRenderListwhen that name is already present (prevents duplicate attribute keys in the JSON:API output).tests/System/integration/api/com_content/Articles.cy.jsAdded a Cypress system test that:
name = "images"scoped tocom_content.articleGET /content/articles/{id}returns the core articleimages.image_introvalue (not an empty array)#__contentand#__fieldsrows after each testTesting instructions
images(any type, e.g. Media).GET /api/index.php/v1/content/articles/{id}with the bearer token.attributes.imagesis[]and the custom field value is also absent.attributes.imagescontains the correctimage_intro/image_fulltextURLs; the custom field is not duplicated.Environment tested
Notes
The fix is intentionally minimal: core properties defined on the item object at the time
prepareItem()is called take precedence over any custom field with a matching name. Custom fields with unique names continue to work exactly as before.