Ferreteria/v0.6/clade/Sys/Data/tree/XML/tags/base/Found
Jump to navigation
Jump to search
| ||||||||||||||||||||||||||||||||||||
Code
as of 2025-10-12
interface iFound extends BaseIface {
// SETUP
static function FromPair(string $sName, string $sValue) : self;
function SubFromXMLNative(SimpleXMLElement $on) : TDataBranchIface;
// ACCESS
function Type() : TypeIface;
function Value() : string;
function Attrs(AttrsIface $o) : AttrsIface;
function SetFTags(FListIface $o) : void;
function GetFTags() : FListIface;
// DIAGS
#function RenderName() : string;
}
abstract class caFound extends BaseClass implements SelfIface {
// ++ CONFIG ++ //
protected function InspectorClass() : string { return DebugClass::class; }
abstract protected function FListClass() : string;
/**
* INSTAR:
* List all supported XML document tags here.
* (TODO: support !DOCTYPE, I guess.)
* Podlings should replace this with a list of subtags they might contain.
*/
static protected function TypeClasses() : array {
return [TagSpace\wuidl\cType::Name() => TagSpace\wuidl\cType::class];
}
// -- CONFIG -- //
// ++ SETUP ++ //
protected function __construct(){} // no direct external construction
// PURPOSE: Callback from Type.
public static function FromType(TypeIface $o) : SelfIface {
$oThis = new static;
$oThis->Type($o);
return $oThis;
}
static public function FromPair(string $sName, string $sValue) : SelfIface {
self::CCreatorMethod_Set();
#self::GotToHere("TAG: [$sName]=[$sValue]");
$oThis = new static;
$oThis->WithPair($sName,$sValue);
return $oThis;
}
// ++ SETUP: internal/common ++ //
protected static function FromXMLCode_Only(string $sXML) : TDataIface {
try {
libxml_use_internal_errors(TRUE); // allow user to handle errors
@$on = new SimpleXMLElement($sXML);
} catch (Throwable $e) {
$this->HandleXMLNativeError();
}
return static::FromXMLNative($on);
}
// ++ SETUP: dynamic ++ //
// DOCS: Root-WithXMLNative.md
protected function WithXMLNative_Only(SimpleXMLElement $on) : void {
$this->Value((string)$on);
$this->SetupAttrsFromXMLNative($on);
$this->SetupTagsFromXMLNative($on); // creates/populates the FTags object
$ofList = $this->GetFTags();
foreach ($on as $onElement) {
$ofSub = static::FromXMLNative($this,$onElement);
$ofList->AddTData($ofSub); // 2025-03-04 I *hope* this is the right thing to do (and the right place to do it).
}
}
protected function SetupAttrsFromXMLNative(SimpleXMLElement $on) : void {
#self::GotToHere("TAG <".$on->getName().'>');
// check for attributes:
$onAttrs = $on->attributes();
$ar = [];
#echo 'TAG '.$this->RenderName().CRLF;
foreach ($onAttrs as $sKey => $onAttr) {
$sVal = (string)$onAttr;
#echo " - ATTR [$sKey] = [$sVal]".CRLF;
$oPair = AttrPairClass::FromData($sKey,$sVal);
$ar[$sKey] = $oPair;
}
$oAttrs = AttrsClass::FromVArray($ar);
$this->Attrs($oAttrs);
}
// 2024-12-20 revised to let list-object handle the collation
protected function SetupTagsFromXMLNative(SimpleXMLElement $on) : void {
// check for podling-tags:
$oFTags = ($this->FListClass())::FromTDataAndXMLNative($this,$on);
$this->SetFTags($oFTags);
}
// ++ SETUP: factory ++ //
// NOTE: *Must* be overridden in Branch to handle Outer stuff
public function SubFromXMLNative(SimpleXMLElement $on) : TDataBranchIface {
$oSub = static::FromXMLNative_Only($on);
/* code as of 2025-03-03; was redundant with FromXMLNative_Only()
$sName = $on->getName();
$oType = static::TypeFromName($sName);
$oSub = $oType->NewTDataBranch();
$oSub->WithXMLNative($this,$on); // iterates through sub-tags
*/
return $oSub;
}
// -- SETUP -- //
// ++ CLASSES ++ //
protected static function TypeClassForName(string $s) : string {
$ar = static::TypeClasses();
if (array_key_exists($s,$ar)) {
$scList = $ar[$s];
} else {
$scThis = get_called_class();
$oScrn = self::Screen();
$ftTag = $oScrn->XMLTagIt($s);
$ftThis = $oScrn->BlueIt($scThis);
self::ThrowHissy("Unexpected tag type $ftTag in $ftThis."); die();
}
return $scList;
}
// -- CLASSES -- //
// ++ OBJECTS ++ //
static protected function TypeFromName(string $sName) : TypeIface {
$sc = static::TypeClassForName($sName);
$ol = ($sc)::FromFound();
return $ol;
}
private $oType;
public function Type(TypeIface $oTType=NULL) : TypeIface { return is_object($oTType) ? ($this->oType = $oTType) : $this->oType; }
private $ofList = NULL;
public function SetFTags(FListIface $o) : void { $this->ofList = $o; }
public function GetFTags() : FListIface { return $this->ofList; }
// -- OBJECTS -- //
// ++ DATA ++ //
private $sVal=NULL; public function Value(string $s=NULL) : string { return $this->sVal ?? ($this->sVal = $s); }
private $oAttr=NULL; public function Attrs(AttrsIface $o=NULL) : AttrsIface { return (is_object($o) ? ($this->oAttr = $o) : $this->oAttr); }
#private $oTag=NULL; public function Tags(TagsIface $o=NULL) : TagsIface { return (is_object($o) ? ($this->oTag = $o) : $this->oTag); }
private $oTerm=NULL; public function Terms() : TermsIface { return $this->oTerm ?? ($this->oTerm = $this->NewTerms()); }
// 2025-03-03 Does not seem to be in use anymore.
#protected function WithAttrsArray(array $ar) : void { $this->oAttrs = new AttrsClass($ar); }
#protected function WithTagsArray(array $ar) : void { $this->oTags = new FListClass($ar); }
protected function WithTerms(TermsIface $o) : void { $this->oTerm = $o; }
protected function NewTerms() : TermsIface { return TermsClass::FromAttrsTags($this->Attrs(),$this->Tags()); }
public function AttrValue(string $sKey) : string {
$os = $this->Attrs()->QryIt($sKey);
if (!$os->HasIt()) {
$ftTag = $this->RenderName();
$this->ThrowHissy("Required attribute '$$sKey not found in tag $ftTag!");
}
return $os->GetIt()->Value();
}
public function FindItQ(string $sKey) : QStrIface {
#$osObj = $this->Attrs()->GetItQ($sKey,QObjClass::class);
// 2025-05-03 QryIt() no longer accepts Q-class as a 2nd argument.
$osObj = $this->Attrs()->QryIt($sKey);
if ($osObj->HasIt()) {
$oAttr = $osObj->GetIt();
$osStr = $oAttr->ValueQ();
} else {
$oSubs = $this->GetFTags();
#$osFT = $oSubs->OSingles()->GetItQ($sKey,QObjClass::class);
// 2025-05-03 QryIt() no longer accepts Q-class as a 2nd argument.
$osFT = $oSubs->OSingles()->QryIt($sKey);
$osStr = QStrClass::AsNew();
if ($osFT->HasIt()) {
$oFTag = $osFT->GetIt();
$oFT = $osFT->GetIt();
$osStr->SetIt($oFT->Value());
}
}
return $osStr;
}
// -- DATA -- //
}