RCA Feed Factory Changelog
RcaFeedFactorySocialEmbedAssets not found on com_content article pages. Social embed WAM registration now lives in plg_system_rca_feedfactory (always autoloaded with the system plugin). The component class remains a thin delegate for backward compatibility.<p> blocks to fulltext instead of cutting mid-sentence. In-paragraph splits retreat to the last sentence end when possible, with slight budget slack to finish a sentence.<p> tags in fulltext (e.g. "this" / "week") merge when they clearly continue the same sentence.extractTrailingSourceLink() now strips only the I2C footer anchor whose link text matches “Source link”, with a byte cap. Fixes Fox-style syndication where inline anchors caused the old regex to treat the whole story as suffix, leaving empty fulltext and no Joomla read-more.<a> counts toward the character limit again (anchors stay atomic). Syndicated bodies split at the configured teaser length instead of stuffing link-heavy HTML into intro.invento / ry across intro and fulltext.fulltext after split are counted per batch and shown as an admin warning.splitParagraphElement() no longer recurses when intro exceeds the read-more budget with an empty remainder. Oversize single tokens (no whitespace) now use a one-shot visible-character split instead of keeping the whole token in intro.ReadMoreResplitService releases large strings and runs gc_collect_cycles() so DOM/HTML from prior rows is not retained for the rest of the HTTP request.DisplayController; the admin cron dispatcher is no longer loaded on the site client. Added Site\Service\Router so SEF URLs preserve view and request keys.<p> tags).introtext and a leading system-readmore marker before the story. Intro is now guaranteed when remainder exists; word splits honor the budget at the character level.<a> link text no longer counts toward the visible-character limit; anchors stay atomic and are not broken across intro/fulltext.<hr id="system-readmore" /> into parsed HTML (Joomla introtext/fulltext fields own the split).blockquote markup is present (import path strips inline scripts by design).div.pmc-paywall, div.a-content, layout grids) no longer keeps the entire story in introtext because paragraphs were nested one level too deep for the splitter. Passive layout containers are unwrapped before counting; oversized blocks are not forced into the intro fallback path.fulltext: Strips paywall placeholders, ad shells, empty Trinity/audio widgets, and article-tag blocks before split so re-split does not leave a non-empty fulltext that is only chrome (which made Joomla show “Read more” at the bottom of a full intro on category blogs).RcaFeedFactoryReadMoreAssembly: Central I2C pipeline for read-more limits, prepend/append (excluded from the visible-character budget), and source link placement at the end of fulltext (or intro when there is no remainder).<p> blocks split at word boundaries with a closed </p> on introtext and a new <p> opening on fulltext so category layouts do not inherit mangled markup.introtext + fulltext before save. ContentTable::addReadMore() uses the same assembly on check (idempotent re-split).i2c_readmore_char_limit overrides the global value when set.script/style, and attribute text such as alt/title are excluded). Splits at safe HTML boundaries (block-complete default; word-boundary fallback inside a single oversized block). Replaces the legacy word-based addReadMore() split that could leave unclosed tags in introtext.RcaFeedFactoryIntroSplit helper (same visible-character rules as global I2C read more).RcaFeedFactoryHtml.php file header was broken after J7 annotation insertion (syntax error, unexpected token "--"), which blocked Feed Factory categories and other admin screens that boot com_rca_feedfactory. Restored a valid GPL docblock header.COM_RCA_FEEDFACTORY_* language keys that exist in en-GB INI (replaces legacy lowercase keys).site/helpers/refresh.php no longer reads $_GET (query parsed via RcaFeedFactoryRefreshBootstrap::getQueryParameters()).#id (…): N stories showed empty parentheses when refresh used poll-driven admin slices. Summaries now include the feed URL (or title if URL is empty) in admin flash messages and HTTP cron HTML output.nrfeeds < 1 are upgraded to 15 on install/update (6.0.54.sql).0 → 15 fallback; uses the saved minimum of 1 (defensive max(1, …) at parse time).index.php (edge proxy/FPM returned 503/504) while Import2Content full-article work can exceed a single request budget even for 25 stories. Detached refresh no longer uses loopback after redirect.feed.refreshJobStatus poll runs a short in-administrator slice (default 25s, configurable admin_refresh_slice_seconds) via Parser::parse2cacheResumable() and FeedModel::refreshFeedResumable() until all stories/feeds complete. No browser navigation to the site front end; no self-HTTP through the public vhost.fastcgi_finish_request), then run refresh on the site application via server-side loopback HTTP (return=loopback JSON). The browser never navigates to the site front end; administrator URL and session stay in place. Completion is delivered via ff_refresh_job polling and cache-backed ff_cron_flash (same pattern as 6.0.48 site handoff, without browser redirect).adminfeed token auth on site:runAdminFeedsRefresh() accepts one-time cache token authorization so loopback runs do not require a site login session.index.php front-end hop). The 6.0.49+ site handoff caused “You don't have permission to access this” on Joomla 5 when the site app handled adminfeed/adminbatch without a valid admin session context.applyRefreshRuntimeEnvironment() is called before list/single feed refresh in admin (session lock release, time limit, memory) — same helper used by HTTP cron.getShortLivedCache() remains CacheController + output handler for any legacy site cron URLs only.getShortLivedCache() was typed to return legacy Joomla\CMS\Cache\Cache while Factory::getCache() returns a CacheController (OutputController when handler is empty). PHP 8+ throws before store/get of admin batch/feed tokens. Return type is now CacheController with explicit output handler (same as AboutHelper), J4/5/6 compatible.administrator/index.php?...runCronbatch or feed refresh tasks. 6.0.48 auto mode still ran ≤2 feeds inline, so maxm’s 2-feed scheduled test and every single-feed refresh on the Feeds list/edit screen still hit the admin worker until timeout.site: Scheduled Run now, Feeds list refresh, and feed edit refresh hand off to sitetask=cron.run (adminbatch / new adminfeed) unless the site is explicitly set to Always in administrator. Auto mode max-inline default is 1 feed.adminfeed cron type: Site HTTP handler for admin-initiated feed refresh with cache token + return URL (preserves feed edit tab, e.g. import2content_rules).task=cron.run&type=adminbatch) when feeds per run exceed max inline feeds (default 2); smaller batches stay inline in administrator (Showcase J4 with 2 feeds). Component options: Admin Run now dispatch (auto / inline / site) and Max feeds for inline admin run.ff_cron_flash query param (admin session was never reliable from site redirect).CronBatchService::runAdminBatchTest() — same application context as per-feed refresh (which already worked on Showcase J4). Removed the admin→site HTTP redirect (adminbatch / task=cron.run), which failed across J4 subdirectory installs, empty live_site, cross-client routers, and admin/site session splits.index.php?option=com_rca_feedfactory&task=cron.run&type=cronjob (and legacy helpers/refresh.php redirect) remain the supported path for wget/cron-job.org/production timers. applyRefreshRuntimeEnvironment() still releases the session lock and extends limits for long runs.Route::link() (requires the other client’s router from admin) with Uri-based absolute URLs via getSiteRootAbsolute() — works on J4/5/6, subdirectory installs, and subdomain hosts (live_site or derived from the current request)./j4/): Cron and admin test-run URLs now use Route::link('site', …) instead of Uri::root() . 'index.php', so requests hit the correct index.php when live_site is empty.adminbatch auth no longer requires a matching site frontend session user; it validates the one-time key and core.manage for the admin user id stored when Run now was clicked.helpers/refresh.php: HTTP cron now runs through index.php?option=com_rca_feedfactory&task=cron.run (full Joomla bootstrap). Legacy refresh.php only 302-redirects to that URL so old cron bookmarks keep working.CronbatchesController now resolves Cronbatch AdminModel for delete.configuration.php + includes/ are found (fixes legacy site/helpers/ depth and non-standard host layouts). Installer mirrors refresh.php + refresh_bootstrap.php to site/helpers/ on upgrade.type=adminbatch with a one-time session key (core.manage on the component) instead of password= in the URL. External cron URLs unchanged.administrator/index.php and were killed by admin PHP-FPM/proxy timeouts on strict hosts (e.g. maxm.news). Run now redirects to the site refresh.php cron endpoint (same as scheduled cron), then returns to Scheduled refresh with a summary. Shared applyRefreshRuntimeEnvironment() sets memory, time limit, system plugins, and releases the session lock for all batch runs.DisplayController called non-existent getMVCFactory() on BaseController. Cron batch save/list tasks now pass injected $this->factory (Joomla admin controller pattern).404 View not found … cronbatch): Cron batch edit form posted with empty option= so admin did not dispatch com_rca_feedfactory on Save. Cronbatch HtmlView now sets $option; edit template includes hidden option (same pattern as other admin views).404 View not found … cronbatch: Custom FeedFactoryMVCFactory resolves cron HtmlView classes when core MVCFactory::createView() returns null; controllers use ResolvesCronAdminViews fallback. Dispatcher normalizes compound display.saveCronbatch tasks before routing.cronbatch view: Admin dispatcher now remaps legacy cronbatch.* / cronbatches.* tasks and controller=cronbatch display URLs to DisplayController (same path as display.saveCronbatch). CronbatchController / CronbatchesController preload cron HtmlView in getView() when those controllers are still hit.cronbatch.save after upgrade.CronBatchService, helpers) plus site helpers/refresh.php. Postflight verifies admin MVC and site refresh endpoint; package postflight checks the same paths. Use this release when upgrading from pre–6.0.21 component trees that never received cron batch files.refresh.php install errors.404 View not found … cronbatch when admin/src/View/Cronbatch/HtmlView.php was missing after a partial component upgrade. Installer force-sync now includes AdminViewNames.php; package postflight verifies cron HtmlView files and cronbatch.xml on disk. Admin boot and DisplayController preload cron views; schedule redirect fails with a clear message instead of a 404 when views are still absent.Invalid controller class: feeds — cron batch tasks now use display.saveCronbatch (and related display.* tasks) on DisplayController, the default admin entry controller. Dispatcher falls back to Display when feeds / cronbatch / cronbatches controllers cannot be instantiated (legacy bookmarks).postflight verifies the full scheduled-refresh contract on disk (CronbatchTaskRunner.php, updated FeedsController.php with saveCronbatch, cron MVC, dispatcher helper)—not only CronbatchController.php.view so feeds.publish / feeds.unpublish delegate correctly on POST.Invalid controller class: cronbatch) — permanent routing: all scheduled-refresh POST/AJAX tasks use feeds.saveCronbatch, feeds.applyCronbatch, and related feeds.* handlers on FeedsController (via CronbatchTaskRunner). Joomla no longer has to resolve a separate cronbatch controller name for save/apply/list actions.install/update scripts force-sync critical admin files (including CronbatchTaskRunner.php and updated FeedsController.php) as soon as the package source is available.Invalid controller class: cronbatch): admin dispatcher now loads CronbatchController via explicit require_once, falls back to FeedsController delegation when MVCFactory cannot instantiate the class, and component postflightoverwrites critical cron-batch MVC files from the package (not only missing-file reconcile). Service provider.php preloads custom Dispatcher.php when present.postflight used legacy $parent->get('manifest') on PackageAdapter (undefined method). Use PackageAdapter::getManifest() so pkg upgrades complete without fatal error.Invalid controller class: cronbatch): root cause is missing CronbatchController.php (and related admin MVC) on the site after upgrade — not MVC naming alone. Installer postflight now copies any missing files from the package source into administrator/components/com_rca_feedfactory/ and shows an explicit error if cron-batch MVC is still absent.postflight (install and update): verify component version matches package and CronbatchController.php exists; enqueue actionable errors when not.CronbatchController on admin boot and in the component dispatcher so task=cronbatch.save resolves when PSR-4 autoload lags after upgrade (Invalid controller class: cronbatch).controller=cronbatch on POST.language/en-GB/ inside the component, load on boot, and sync to administrator/language/en-GB on install/update so new strings (feeds toolbar, list columns, scheduled refresh titles, last-refresh messages) resolve after upgrade instead of showing raw constants.refresh.php), and pseudo-cron are the documented paths.Dispatcher maps cronbatch / cronbatches tasks to the correct PSR-4 controller classes (fixes Invalid controller class: cronbatch on save).CronBatches (was Cronbatch).CRON-AND-REFRESH.html): clarify helpers/refresh.php as the runtime entry point; cron-job.org URL jobs and optional REST API for hosts without crontab.addfieldprefix on cronbatch.xml so RcaFeedFactoryFeedsList and RcaFeedFactoryCronUrl load (without it Joomla fell back to text and htmlspecialchars() failed on pre-selected feed_ids arrays).cronbatch.add.cronbatch.add no longer discards pre-filled session data before the batch edit form loads.feed_ids as an integer array so the edit form does not throw htmlspecialchars(): array given when feeds are pre-selected.DisplayController resolved the wrong model name (CronBatch vs Cronbatch), so the batch form never loaded (getFieldset() on null).images JSON), remove only that assigned image from article HTML. Other inline images are preserved. Matching uses normalized media path, filename, and on-disk byte size (under images/ paths, different date folders require an exact path match).i2c_strip_hero_from_body, default Yes) and per-feed override (Use global / No / Yes).refresh.php URL (batch= id) for server cron or cron-job.org. Site-wide lock prevents concurrent batch runs. List view warns on feed overlap and matching stagger minutes.FeedModel::refresh() accepts options order (stale) and limit for batch rotation.$sidebar properties.feed.js and factoryajaxlink.js refactored off j