generated from jric11/baseProject
ChatGPT's update to harden software and run db updates.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/** Move already-authorized club forms out of summary tables into labelled dialogs. */
|
||||
final class ClubFormModals {
|
||||
public static function render(string $html): string {
|
||||
$titles=['club'=>'Edit or archive club','member'=>'Add member','invite'=>'Invite members',
|
||||
'season'=>'Add season','charge'=>'Record season dues','payment'=>'Record payment',
|
||||
'adjust'=>'Correct dues','reverse'=>'Reverse incorrect payment','revokeInvitation'=>'Revoke invitation'];
|
||||
$doc=new DOMDocument('1.0','UTF-8');$previous=libxml_use_internal_errors(true);
|
||||
try{$loaded=$doc->loadHTML('<?xml encoding="UTF-8">'.$html,LIBXML_NONET);}
|
||||
finally{libxml_clear_errors();libxml_use_internal_errors($previous);}
|
||||
if(!$loaded)throw new RuntimeException('Cannot render club dialogs.');
|
||||
$main=$doc->getElementsByTagName('main')->item(0);
|
||||
if(!$main)throw new LogicException('Club summary container is missing.');
|
||||
$dialogs=[];$index=0;
|
||||
foreach(iterator_to_array($main->getElementsByTagName('form')) as $form){
|
||||
$values=[];foreach($form->getElementsByTagName('input') as $input)$values[$input->getAttribute('name')]=$input->getAttribute('value');
|
||||
$step=$values['step']??'';
|
||||
if(!in_array($values['action']??'',['Roster.workspace','Roster.memberSummary'],true)||!isset($titles[$step]))continue;
|
||||
$title=$step==='member'&&!empty($values['membership_serial'])?'Edit membership':$titles[$step];
|
||||
$id='club-action-'.(++$index);$parent=$form->parentNode;
|
||||
$trigger=$doc->createElement('button');$trigger->appendChild($doc->createTextNode($title));
|
||||
foreach(['type'=>'button','class'=>'btn btn-outline-primary me-2 mb-2','data-bs-toggle'=>'modal','data-bs-target'=>'#'.$id,'data-club-step'=>$step] as $key=>$value)$trigger->setAttribute($key,$value);
|
||||
$dialog=$doc->createElement('div');
|
||||
foreach(['class'=>'modal fade club-action-modal','id'=>$id,'tabindex'=>'-1','aria-labelledby'=>$id.'-title','aria-hidden'=>'true'] as $key=>$value)$dialog->setAttribute($key,$value);
|
||||
$layout=$dialog->appendChild($doc->createElement('div'));$layout->setAttribute('class','modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable');
|
||||
$content=$layout->appendChild($doc->createElement('div'));$content->setAttribute('class','modal-content');
|
||||
$header=$content->appendChild($doc->createElement('div'));$header->setAttribute('class','modal-header');
|
||||
$heading=$header->appendChild($doc->createElement('h2'));$heading->setAttribute('class','modal-title fs-5');$heading->setAttribute('id',$id.'-title');$heading->appendChild($doc->createTextNode($title));
|
||||
$close=$header->appendChild($doc->createElement('button'));$close->setAttribute('type','button');$close->setAttribute('class','btn-close');$close->setAttribute('data-bs-dismiss','modal');$close->setAttribute('aria-label','Close');
|
||||
$body=$content->appendChild($doc->createElement('div'));$body->setAttribute('class','modal-body');
|
||||
// Keep the selected row visible in the dialog so financial/member actions are unambiguous.
|
||||
$row=$parent;while($row&&$row!==$main&&!in_array($row->nodeName,['tr','li'],true))$row=$row->parentNode;
|
||||
if($row&&$row!==$main){
|
||||
$text=$row->textContent;
|
||||
if($row->nodeName==='tr')$text=implode(' · ',array_map(static fn($cell)=>trim($cell->textContent),array_slice(iterator_to_array($row->getElementsByTagName('td')),0,-1)));
|
||||
$context=$body->appendChild($doc->createElement('p'));$context->setAttribute('class','text-secondary');$context->appendChild($doc->createTextNode(trim(preg_replace('/\s+/u',' ',$text))));
|
||||
}
|
||||
if($parent->nodeName==='details'){
|
||||
$parent->parentNode->replaceChild($trigger,$parent);
|
||||
foreach(iterator_to_array($parent->childNodes) as $child)if($child->nodeName!=='summary')$body->appendChild($child);
|
||||
}else{
|
||||
$previous=$form->previousSibling;
|
||||
if($previous&&$previous->nodeName==='h4')$previous->parentNode->removeChild($previous);
|
||||
$following=$form->nextSibling;
|
||||
$parent->replaceChild($trigger,$form);$body->appendChild($form);
|
||||
if($following&&$following->nodeName==='p')$body->appendChild($following);
|
||||
}
|
||||
$error=$doc->createElement('p');$error->setAttribute('class','alert alert-danger club-modal-error');$error->setAttribute('role','alert');$error->setAttribute('tabindex','-1');$error->setAttribute('hidden','hidden');$body->insertBefore($error,$body->firstChild);
|
||||
$footer=$content->appendChild($doc->createElement('div'));$footer->setAttribute('class','modal-footer');
|
||||
$cancel=$footer->appendChild($doc->createElement('button'));$cancel->setAttribute('type','button');$cancel->setAttribute('class','btn btn-outline-secondary');$cancel->setAttribute('data-bs-dismiss','modal');$cancel->appendChild($doc->createTextNode('Cancel'));
|
||||
$dialogs[]=$dialog;
|
||||
if($step==='invite')foreach(iterator_to_array($main->getElementsByTagName('a')) as $link)if($link->getAttribute('href')==='#club-invitations'){$link->parentNode->replaceChild($trigger,$link);break;}
|
||||
}
|
||||
foreach($dialogs as $dialog)$main->appendChild($dialog);
|
||||
$script=$main->appendChild($doc->createElement('script'));$script->setAttribute('src','js/club-modals.js?version='.Base::VERSION);
|
||||
return $doc->saveHTML($main);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user