diff --git a/administrator/components/com_content/src/Model/ArticlesModel.php b/administrator/components/com_content/src/Model/ArticlesModel.php index d526d9699acbe..f8fb9e9b6d718 100644 --- a/administrator/components/com_content/src/Model/ArticlesModel.php +++ b/administrator/components/com_content/src/Model/ArticlesModel.php @@ -504,6 +504,22 @@ protected function getListQuery() ->bind(':tag', $tag, ParameterType::INTEGER); } + // Filter by date after modified date. + $modifiedStartDateTime = $this->getState('filter.modified_start'); + + if (!empty($modifiedStartDateTime)) { + $query->where($db->quoteName('a.modified') . ' >= :startDate') + ->bind(':startDate', $modifiedStartDateTime); + } + + // Filter by date before modified date. + $modifiedEndDateTime = $this->getState('filter.modified_end'); + + if (!empty($modifiedEndDateTime)) { + $query->where($db->quoteName('a.modified') . ' <= :endDate') + ->bind(':endDate', $modifiedEndDateTime); + } + // Add the list ordering clause. $orderCol = $this->state->get('list.ordering', $defaultOrdering); $orderDirn = $this->state->get('list.direction', 'DESC'); diff --git a/api/components/com_content/src/Controller/ArticlesController.php b/api/components/com_content/src/Controller/ArticlesController.php index a5226eb00e390..9b9ea84c38196 100644 --- a/api/components/com_content/src/Controller/ArticlesController.php +++ b/api/components/com_content/src/Controller/ArticlesController.php @@ -82,6 +82,14 @@ public function displayList() $this->modelState->set('filter.language', $filter->clean($apiFilterInfo['language'], 'STRING')); } + if (\array_key_exists('modified_start', $apiFilterInfo)) { + $this->modelState->set('filter.modified_start', $filter->clean($apiFilterInfo['modified_start'], 'STRING')); + } + + if (\array_key_exists('modified_end', $apiFilterInfo)) { + $this->modelState->set('filter.modified_end', $filter->clean($apiFilterInfo['modified_end'], 'STRING')); + } + $apiListInfo = $this->input->get('list', [], 'array'); if (\array_key_exists('ordering', $apiListInfo)) { diff --git a/tests/System/integration/api/com_content/Articles.cy.js b/tests/System/integration/api/com_content/Articles.cy.js index d1a31b94160cd..7e56609e4b90a 100644 --- a/tests/System/integration/api/com_content/Articles.cy.js +++ b/tests/System/integration/api/com_content/Articles.cy.js @@ -9,6 +9,18 @@ describe('Test that content API endpoint', () => { .should('include', 'automated test article')); }); + it('can deliver a list of articles filtered by the modified start and end filter', () => { + cy.db_createArticle({ title: 'automated test article before', modified: '2025-03-15 10:00:00' }) + .then(() => cy.db_createArticle({ title: 'automated test article within', modified: '2025-03-15 15:00:00' })) + .then(() => cy.db_createArticle({ title: 'automated test article after', modified: '2025-03-15 20:00:00' })) + .then(() => cy.api_get('/content/articles?filter[modified_start]=2025-03-15 14:00:00&filter[modified_end]=2025-03-15 16:00:00')) + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('title') + .should('include', 'automated test article within') + .should('not.include', 'automated test article before') + .should('not.include', 'automated test article after')); + }); + it('can deliver a single article', () => { cy.db_createArticle({ title: 'automated test article' }) .then((article) => cy.api_get(`/content/articles/${article.id}`))