Ferreteria/v0.6/clade/Sys/Data/tree/XML/tags/base/Found

From Woozle Writes Code
< Ferreteria‎ | v0.6‎ | clade‎ | Sys‎ | Data‎ | tree
Revision as of 18:07, 12 October 2025 by Woozle (talk | contribs) (Created page with "{{page/clade/v2 |fam= {{!}} align=right {{!}} {{l/ver/clade|Aux|StandardBase}} {{!}} align=center {{!}} → {{l/ver/clade|Sys\Data\tree\XML\tags\base|Found}} → {{!}} align=left {{!}} {{l/ver/clade|Sys\Data\tree\XML\tags\base\Found|Branch}}<br> {{l/ver/clade|Sys\Data\tree\XML\tags\base\Found|Root}} |alia= {{!}}- {{!}} '''Base'''* [c,i] {{!!}} {{l/ver/clade/full|p=ferreteria|Aux|StandardBase}} {{!}}- {{!}} '''QObj'''* [c] {{!!}} {{l/ver/clade/full|p=ferreteria|Dat...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
clade: Sys\Data\tree\XML\tags\base\Found
Clade Family
StandardBase Found

Branch
Root

Clade Aliases
Alias Clade
Base* [c,i] Aux\StandardBase
QObj* [c] Data\Mem\QVar\Obj
QStr* [c,i] Data\Mem\QVar\Str
Attrs* [c,i] Sys\Data\tree\XML\list\Attrs
ForAttr* [c] Sys\Data\tree\XML\list\Pair\ForAttr
Debug* [c] Sys\Data\tree\XML\tags\view\Found
Tag [s] Sys\Data\tree\XML\tags
Self [i] Sys\Data\tree\XML\tags\base\Found (=TData)
TData [i] Sys\Data\tree\XML\tags\base\Found (=Self)
FList [c,i] Sys\Data\tree\XML\tags\base\FoundList
TDataBranch [i] Sys\Data\tree\XML\tags\base\Found\Branch
Type[Maker,Iface] Sys\Data\tree\XML\tags\base\Type
Subpages

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 -- //
}