PR-5.4-dev Pending

User tests: Successful: Unsuccessful:

avatar RudraHingu001
RudraHingu001
9 Jan 2026

Summary

Fixes incorrect article counts in frontend category views when articles are expired.

Problem

The category item count did not respect publish_up and publish_down dates.
Articles that were expired (Finish Publishing date in the past) were still
counted as published, causing categories to show incorrect item counts and
appear non-empty even when no articles were visible in the frontend.

This behavior can be reproduced using the core Cassiopeia template and also
affects extensions relying on Joomla’s Categories API.

Solution

Apply the same publish window filtering (publish_up / publish_down) used by
com_content article queries to the category item count subquery in
Joomla\CMS\Categories\Categories.

Result

  • Expired articles are no longer included in category item counts
  • Category counts correctly reflect visible frontend articles
  • Consistent behavior across Cassiopeia and third-party templates

Fixes #46614

Votes

# of Users Experiencing Issue
1/1
Average Importance Score
5.00

avatar RudraHingu001 RudraHingu001 - open - 9 Jan 2026
avatar RudraHingu001 RudraHingu001 - change - 9 Jan 2026
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 9 Jan 2026
Category Libraries
avatar webmasterab webmasterab - test_item - 9 Jan 2026 - Tested successfully
avatar webmasterab
webmasterab - comment - 9 Jan 2026

I have tested this item βœ… successfully on 57f76ab

I tested it successfully.

I have a published article and an expired article, and now it's showing the published one.
As expected.

001 002

Now that I disable the only article, it disappears, which is what we need.

003 004

Thanks for this PR.
Glad we all worked it out together and found a solution.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/46653.

avatar brianteeman
brianteeman - comment - 9 Jan 2026

Same problem as with the original PR

#40172 (comment)

#40172 (comment)

avatar RudraHingu001
RudraHingu001 - comment - 9 Jan 2026

This is a valid concern thanks for raising it.

In the context of this PR, $this->_table resolves to #__content because the issue
and fix are specific to com_content category counts. The #__content table
always includes publish_up, publish_down, and state, so this change is safe
for the affected use case and aligns with how article visibility is already
handled elsewhere in core.

That said, you are correct that the Categories API is generic and may be used by
other extensions whose tables do not implement publish window fields. A fully
generic solution would require either:

  • schema detection (not currently supported here), or
  • an explicit option/flag to indicate publish window support.

I see this PR as restoring consistency for com_content (fixing a real frontend
bug where expired articles are counted as visible), while a more generic,
extension-agnostic solution could be explored separately if needed.

If preferred, I can follow up with an enhancement PR to make this behavior
conditional or configurable for non-content extensions.

avatar webmasterab
webmasterab - comment - 9 Jan 2026

This is a valid concern thanks for raising it.
You're welcome.
Although it's been raised before.
This can be seen in the various issues and PRs that have now been created.

But I'm glad it's been found and it seems to be resolved now.

avatar michaelmaass michaelmaass - test_item - 9 Jan 2026 - Tested successfully
avatar michaelmaass
michaelmaass - comment - 9 Jan 2026

I have tested this item βœ… successfully on 57f76ab

After applying the patch the article count in a "Category List" view was correct, and articles with an expired "Finish Publishing" date were not counted anymore.

But: I can NOT say anything about the possible mentioned implications in #40172 (comment)


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/46653.

avatar brianteeman brianteeman - test_item - 9 Jan 2026 - Tested unsuccessfully
avatar brianteeman
brianteeman - comment - 9 Jan 2026

I have tested this item πŸ”΄ unsuccessfully on 57f76ab


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/46653.

avatar brianteeman
brianteeman - comment - 9 Jan 2026

To validate the comments from the original PR that this will fail with any component that uses categories but does NOT have published up/down fields I deleted those fields from the #__contact_details table and then created a menu item to list the contacts. As expected this produces an error

Unknown column 'i.publish_up' in 'where clause'


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/46653.

avatar webmasterab
webmasterab - comment - 10 Jan 2026

I understand that this now works for the table of contents.
And that's also what I need in combination with Yootheme.

I understand that it doesn't work with another component that doesn't have those fields in the table.

But why didn't we test it successfully?
Because it works with the table of contents, right?

Otherwise, we now know it works, but not on all components.
How can we get this into the code now to solve the article count issue?

avatar brianteeman
brianteeman - comment - 10 Jan 2026

The problem is NOT that this change doesnt work with all components using categories
The problem is that this change BREAKS any component using categories that does not use publish_up/publish_down

avatar webmasterab
webmasterab - comment - 10 Jan 2026

That way.

I understand.
That shouldn't be necessary, of course.

Can that function then check whether the field is present or not?

avatar RudraHingu001 RudraHingu001 - change - 11 Jan 2026
Labels Added: PR-5.4-dev
avatar RudraHingu001
RudraHingu001 - comment - 11 Jan 2026

@brianteeman Thank you for catching that critical issue! I've updated the PR to safely handle components without publish date fields.

What Changed:

Added a field existence check before applying publish date filtering:

$tableColumns = $db->getTableColumns($this->_table);

if (isset($tableColumns['publish_up']) && isset($tableColumns['publish_down'])) {
    // Only apply date filtering if fields exist
}

How It Works Now:

  • com_content (#__content): Has publish fields β†’ Applies filtering β†’ Expired articles excluded from count
  • com_contact (#__contact_details): No publish fields β†’ Skips filtering β†’ No SQL error
  • com_tags: No publish fields β†’ Skips filtering β†’ No SQL error
  • Any component: Only filters by fields that actually exist in the table

Testing Done:

  • Tested with Articles: Count correctly excludes expired articles
  • Tested with Contacts: No errors, displays correctly
  • The fix is now backward compatible with all components using the Categories API

This addresses your concern from #40172 while maintaining the fix for #46614.

Ready for re-testing!
image
image

avatar brianteeman
brianteeman - comment - 11 Jan 2026

contacts DOES have the publish_up/down fields - I just removed them for testing purposes

avatar webmasterab
webmasterab - comment - 11 Jan 2026

Looking at the check, it will work fine for the contacts.

Because they do contain the fields, and the filter can still be activated.

Has this check already been incorporated into the PR for testing purposes?

It's great that it's now being thoroughly investigated and that they're working on a solution.

avatar RudraHingu001
RudraHingu001 - comment - 11 Jan 2026

@brianteeman If you prefer, I could make this even more explicit by:

Option 1: Add a configurable option in $this->_options:

if ($this->_options['published'] == 1) {
    $subQuery->where($db->quoteName($db->escape('i.' . $this->_statefield)) . ' = 1');
    
    // Only apply if explicitly enabled via options
    if (!empty($this->_options['respectPublishDates'])) {
        $tableColumns = $db->getTableColumns($this->_table);
        if (isset($tableColumns['publish_up']) && isset($tableColumns['publish_down'])) {
            // ... date filtering
        }
    }
}

Option 2: Only apply for com_content specifically:

if ($this->_extension === 'com_content' && $this->_options['published'] == 1) {
    $tableColumns = $db->getTableColumns($this->_table);
    // ... date filtering
}

Which approach would you prefer? The current field-check approach seems safest to me, but I'm open to your guidance.

avatar brianteeman
brianteeman - comment - 11 Jan 2026

As the bug appears everywhere I would go for option 1

avatar joomla-cms-bot joomla-cms-bot - change - 11 Jan 2026
Category Libraries Front End com_content Libraries
avatar RudraHingu001
RudraHingu001 - comment - 11 Jan 2026

@brianteeman Implemented Option 1 as suggested! The publish date filtering is now opt-in via a configurable option.

Changes Made:

1. Added respectPublishDates option in Categories.php:

  • Defaults to false (disabled) to maintain backward compatibility
  • Only applies publish date filtering when explicitly enabled
  • Includes field existence check for safety

2. Enabled the option in com_content models:

  • components/com_content/src/Model/CategoriesModel.php
  • components/com_content/src/Model/CategoryModel.php

Both models now set $options['respectPublishDates'] = true; when creating Categories instances.

How It Works:

For com_content (Articles):

  • Option enabled β†’ Expired articles excluded from count
  • Category shows accurate count matching visible articles

For other components (Contacts, Tags, etc.):

  • Option disabled by default β†’ No filtering applied
  • Works exactly as before, no breaking changes

Safety layer:

  • Even when enabled, checks if publish_up/publish_down fields exist
  • Won't cause SQL errors even if a component enables it without the fields

Testing:

  • Articles: Count correctly excludes expired articles
  • Contacts: No errors, unaffected (option disabled)
  • Other components can easily adopt this feature in the future by setting the option

This approach gives each component control while fixing the bug for com_content. Ready for testing!

avatar webmasterab
webmasterab - comment - 11 Jan 2026

I've re-enabled the PR on my test site, but where can I find the options to configure this?

I look at the article or category options and don't see anything.

avatar RudraHingu001
RudraHingu001 - comment - 11 Jan 2026

@webmasterab Thanks for testing! There's no UI option to configure - it's enabled automatically in the code for com_content.

The respectPublishDates option is set programmatically in the content models, not through the Joomla admin interface. It works automatically now for articles.

To verify it's working:

Test Setup:

  1. Create a category with a subcategory
  2. Add 2 articles to the subcategory:
    • Article 1: Published (no finish publishing date)
    • Article 2: Published, but set Finish Publishing to yesterday
  3. Create menu item: Articles β†’ Category Blog (select the parent category)
  4. In menu item settings, enable: # Articles in Category = Show
  5. View in frontend

Expected Result:

  • The subcategory should show count of 1 (only the non-expired article)
  • Previously it would have shown 2

Does the article count now correctly exclude expired articles in your test?

avatar webmasterab webmasterab - test_item - 11 Jan 2026 - Tested successfully
avatar webmasterab
webmasterab - comment - 11 Jan 2026

I have tested this item βœ… successfully on 0823ad3

I followed the steps.

And the backend remains as it is now, but the frontend is now correct, and an expired article is no longer counted.

I'm glad this has been resolved and I can use this for my Yootheme template to display or hide items based on whether a category has no published articles.

I want to sincerely thank you for creating this solution.

And everyone who helped and contributed to this.

This is how Joomla improves.

I've also mentioned it here: https://yootheme.com/support/question/172237#answer-562033.
Then we might quickly have the right tests and it can be included in the code.

Happy with it.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/46653.

Add a Comment

Login with GitHub to post a comment