Skip to content

Sanitize Application_Form_URL__c which can be an HTML anchor or plain URL#5575

Open
kevdevlu wants to merge 68 commits intomainfrom
issue/3998-program-apply-url-sanitize
Open

Sanitize Application_Form_URL__c which can be an HTML anchor or plain URL#5575
kevdevlu wants to merge 68 commits intomainfrom
issue/3998-program-apply-url-sanitize

Conversation

@kevdevlu
Copy link
Copy Markdown
Member

@kevdevlu kevdevlu commented May 6, 2026

Subbranch of #5182 .

Sanitize Application_Form_URL__c — extract href when API returns an HTML anchor

Problem

The Trellis /programinfo API returns Application_Form_URL__c inconsistently: most records send a plain URL, but some send a full HTML anchor tag:

<a href="https://forms-a.trellis.arizona.edu/148?acctid=001V400000m5V4L&amp;progcycid=a55V4000015uA1i" target="_blank">Application Link</a>

The migration previously mapped this field directly to field_az_application_link/uri, so anchor-tag values were stored as-is and rendered as Apply now on the frontend.

Solution

Adds a custom migrate process plugin az_extract_url (AZExtractUrl.php) and wires it into the migration pipeline for field_az_application_link/uri.

The plugin:

  • If the value is a plain URL → passes it through unchanged
  • If the value contains an tag → uses Html::load() + DOMXPath to extract the href, then Html::decodeEntities() to decode &amp; → & so the stored URI is valid
  • If an anchor is found but has no usable href, it returns '' so the link field is left empty rather than storing garbage

Testing

Re-run the migration with drush migrate:import az_trellis_opportunities --update to reprocess existing nodes. Verify that records which previously had anchor-tag values now display a working Apply link on the frontend.

zsaenz and others added 30 commits January 9, 2026 09:54
Creates a base Opportunity content type with 3 display views. Uses Smart Title.
Co-authored-by: Joe Parsons <471936+joeparsons@users.noreply.github.com>
It installs properly, but doesn't work. It causes problems with Trellis Event Importer.
zsaenz and others added 23 commits April 8, 2026 13:06
* Update default display

* Update default display of dates (ap date style)

* Update Row content type display

* Update views and content type displays
- Fix AZRecurringImportRule::getQueryParameters() to send `parent_account`
  instead of `parent_account_name` — the Boomi search API does not recognize
  `parent_account_name` and silently returns all results
- Remove Parent ID column from the Trellis import admin results view per
  Dana's feedback
- Relabel "Account ID" filter to "Opportunity ID" with help text per Dana's
  feedback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…zontally

- Adds group_tags field group to move field_az_opportunity_category below
  body and eligibility content, per Dana's feedback
- Adds az_opportunity.module, az_opportunity.libraries.yml, and
  css/az_opportunity.css to load flex styles scoped to the content type,
  following the az_person module pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Matches existing tab titles convention for Content Subtabs

Co-authored-by: Dana Hertzberg <59745109+danahertzberg@users.noreply.github.com>
* Trellis Importer: Rename NetID to "Owner NetID" in results table title
* Entity View Display: Move Category tags into Content Row (`group_content_row`), remove unneeded `group_tags`
1. Add result count, full pager, no-results message, and result summary placement

- Switch import view pager from mini to full so total pages are displayed
- Set pager total_items from search API ID count before slicing, enabling
  accurate page count without a separate count query
- Add result summary header showing "Displaying X-Y of Z results"
- Add template override to render result summary between filters and table
  rather than above the exposed form
- Add empty state message "No results found. Try adjusting your search filters."


2. Add conditional empty state and fix result message for import view

Suppress the "no results" message on initial page load by implementing
hook_views_pre_render — the empty area is only shown when the user has
submitted meaningful filter values. Also updates the empty state text to
"No results found. Try adjusting search filters above."


3. Add ARIA live regions to import view template for screen reader support

The view uses AJAX, so filter submissions silently rewrite the result
count and empty state without notifying assistive technology. Keeps
.view-header persistent in the DOM so its aria-live region fires on
every AJAX update; wraps only the empty state message (not the full
results table) in a second live region to avoid reading the entire
table aloud on each filter change. Also replaces <footer> with
<div class="view-footer"> to match Drupal core Views template conventions.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Results Count Logic correction: the search API gets a count, but the data POST sometimes silently fails, so we get a header saying "Display X of Y" while showing an empty table. This corrects that by committing a result count ONLY after we know the data fetch actually worked.

* Migration Mode: If content admin deletes imported opportunity type, we want to allow them to import it again.
…apping, fix array merge bug

- Add Name and Opportunity ID fields to the recurring import rule form and entity,
  matching all seven exposed filters on the initial search view
- Fix label mismatches: "Owner" → "Owner NetID", "Parent Account" → "Parent Account Name"
- Fix gather_filter_options() to map views exposed filter identifiers (property,
  property_2, parent_account) to entity property names so all fields carry over
  when opening the Create Recurring Import modal
- Fix AZRecurringImportRuleListBuilder to map API param names back to views
  identifiers so View Results pre-fills all fields correctly
- Fix array + operator bug in AZTrellisOpportunitySource that silently dropped
  recurring search results when previously-imported items filled numeric positions;
  replace with array_merge
- Enable update mode on the cron migration so already-imported opportunities
  are re-synced on each scheduled run

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* for recurring and for initial search
… URL

Add AZExtractUrl migrate process plugin that extracts the href from an
<a> tag when the Trellis API returns HTML instead of a bare URL, and
passes plain URLs through unchanged. Wire it into the migration process
pipeline for field_az_application_link/uri.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kevdevlu kevdevlu self-assigned this May 6, 2026
@kevdevlu kevdevlu requested review from a team as code owners May 6, 2026 19:32
@tadean
Copy link
Copy Markdown
Contributor

tadean commented May 6, 2026

I think this should be fixed on the Trellis side by validation, ideally.

@az-digital-bot
Copy link
Copy Markdown
Contributor

Tugboat has finished building the preview for this pull request!

Link:

Dashboard:

Base automatically changed from issue/3998 to main May 7, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants