Setting upp or changing variables in the XML
The XML variable name and value is stored in $this->vars

@param string[] $attrs an array of key value pairs for the attributes

@return void
198108
private function setVarStartHandler(array $attrs): void
    {
        if (empty($attrs['name'])) {
            throw new DomainException('REPORT ERROR var: The attribute "name" is missing or not set in the XML file');
        }

        $name  = $attrs['name'];
        $value = $attrs['value'];
        $match = [];
        // Current GEDCOM record strings
        if ($value === '@ID') {
            if (preg_match('/0 @(.+)@/', $this->gedrec, $match)) {
                $value = $match[1];
            }
        } elseif ($value === '@fact') {
            $value = $this->fact;
        } elseif ($value === '@desc') {
            $value = $this->desc;
        } elseif ($value === '@generation') {
            $value = (string) $this->generation;
        } elseif (preg_match("/@(\w+)/", $value, $match)) {
            $gmatch = [];
            if (preg_match("/\d $match[1] (.+)/", $this->gedrec, $gmatch)) {
                $value = str_replace('@', '', trim($gmatch[1]));
            }
        }
        if (preg_match("/\\$(\w+)/", $name, $match)) {
            $name = $this->vars["'" . $match[1] . "'"]['id'];
        }
        $count = preg_match_all("/\\$(\w+)/", $value, $match, PREG_SET_ORDER);
        $i     = 0;
        while ($i < $count) {
            $t     = $this->vars[$match[$i][1]]['id'];
            $value = preg_replace('/\$' . $match[$i][1] . '/', $t, $value, 1);
            $i++;
        }
        if (preg_match('/^I18N::number\((.+)\)$/', $value, $match)) {
            $value = I18N::number((int) $match[1]);
        } elseif (preg_match('/^I18N::translate\(\'(.+)\'\)$/', $value, $match)) {
            $value = I18N::translate($match[1]);
        } elseif (preg_match('/^I18N::translateContext\(\'(.+)\', *\'(.+)\'\)$/', $value, $match)) {
            $value = I18N::translateContext($match[1], $match[2]);
        }

        // Arithmetic functions
        if (preg_match("/(\d+)\s*([\-\+\*\/])\s*(\d+)/", $value, $match)) {
            // Create an expression language with the functions used by our reports.
            $expression_provider  = new ReportExpressionLanguageProvider();
            $expression_cache     = new NullAdapter();
            $expression_language  = new ExpressionLanguage($expression_cache, [$expression_provider]);

            $value = (string) $expression_language->evaluate($value);
        }

        if (strpos($value, '@') !== false) {
            $value = '';
        }
        $this->vars[$name]['id'] = $value;
    }
508392
protected function setAttributes(\DOMNode &$node, array $attrs = array())
	{
		$attrs = array_filter('is_string', $attrs);
		if (! is_array($attrs) or empty($attrs)) {
			return;
		}
		array_map(
			[$node, 'setAttribute'],
			array_keys($attrs),
			array_values($attrs)
		);
	}
777053
private function _index_attribs($attrs)
    {
        $this->attr_idx = $this->attrs = $aix = $six = $iix = $iax = self::$_ar_;
        $i              = 0;
        $ian            = self::$_index_attribs;
        foreach ($ian as $atn) {
            if (!isset($iax[$atn])) {
                $iax[$atn] = self::$_ar_;
            }
        }

        foreach ($attrs as $str => $v) {
            $a = self::html_parseAttrStr($str, true, false);
            unset($attrs[$str]); // free mem
            foreach ($ian as $atn) {
                if (isset($a[$atn])) {
                    // href attribute has a separate index
                    if (is_array($v)) {
                        foreach ($v as $e) {
                            $iax[$atn][$e] = $a[$atn];
                        }

                    } else {
                        $iax[$atn][$v] = $a[$atn];
                    }
                    unset($a[$atn]);
                }
            }
            if (empty($a)) {
                continue;
            }

            $str = self::html_attr2str($a);
            $aid = $i;
            if (isset($six[$str])) {
                $aid = $six[$str];
                if (!is_array($iix[$aid])) {
                    $iix[$aid] = array($iix[$aid]);
                }

                if (is_array($v)) {
                    foreach ($v as $v_) {
                        $iix[$aid][] = $v_;
                    }
                } else {
                    $iix[$aid][] = $v;
                }

            } else {
                $six[$str] = $aid;
                $aix[$aid] = $a;
                $iix[$aid] = $v;
                ++$i;
            }
        }
        unset($six, $attrs, $i); // free mem
        foreach ($aix as $aid => $a) {
            $v = $iix[$aid];
            if (is_array($v)) {
                if (count($v) == 1) {
                    $v = reset($v);
                } elseif ($v) {
                    $u = array();
                    foreach ($v as $e) {
                        $u[$e]           = $this->ids[$e];
                        $this->attrs[$e] = $aid;
                    }
                    $v = $u;unset($u);
                }
            }
            if (!is_array($v)) {
                $this->attrs[$v] = $aid;
            }

            $this->attr_idx[$aid] = $v; // ids for this attr
        }
        foreach ($iax as $atn => $v) {
            if (!$v) {
                unset($iax[$atn]);
            }
        }

        $this->idx_attr = $iax;
        $this->attribs  = $aix;

        return $this->attr_idx;
    }
938826
public function set($attr, $value)
    {
        $pk = self::getPK();
        // can't change the primary key of an existing record
        if (!$this->_new_rec && $attr == $pk) {
            return;
        }
        $this->_data[$attr] = $value;
    }
424218
public function setAttributeArray(array $attributes = null)
    {
        if (!is_array($attributes) || empty($attributes)) {
            return;
        }

        foreach ($attributes as $name => $value) {
            $this->setAttribute($name, $value);
        }
    }
1003076
public function assign($attrs)
    {
        foreach ($attrs as $key => $val) {
            if (property_exists($this, $key)) {
                $this->$key = $val;
            }
        }
    }
403520
protected function addValidAttributes( $attrs ) {
        foreach( $attrs as $attr ) {
            //add if string
            if( is_string( $attr ) ) {
                $this->validAttributes[] = $attr;
            }
        }
    }
599521
private function footnoteStartHandler(array $attrs): void
    {
        $id = '';
        if (preg_match('/[0-9] (.+) @(.+)@/', $this->gedrec, $match)) {
            $id = $match[2];
        }
        $record = GedcomRecord::getInstance($id, $this->tree);
        if ($record && $record->canShow()) {
            $this->print_data_stack[] = $this->print_data;
            $this->print_data         = true;
            $style                    = '';
            if (!empty($attrs['style'])) {
                $style = $attrs['style'];
            }
            $this->footnote_element = $this->current_element;
            $this->current_element  = $this->report_root->createFootnote($style);
        } else {
            $this->print_data       = false;
            $this->process_footnote = false;
        }
    }
671605
public function addElement($attrs)
    {
        if (!$this->getPrefix($attrs['type'])) {
            $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
        }
        $this->elements[$attrs['name']] = $attrs;
        $this->elements[$attrs['name']]['typeClass'] = 'element';

        $this->xdebug("addElement " . $attrs['name']);
        $this->appendDebug($this->varDump($this->elements[$attrs['name']]));
    }
218229
private function docStartHandler(array $attrs): void
    {
        $this->parser = $this->xml_parser;

        // Custom page width
        if (!empty($attrs['customwidth'])) {
            $this->wt_report->page_width = (int) $attrs['customwidth'];
        } // Get it as int to ignore all decimal points or text (if any text then int(0))
        // Custom Page height
        if (!empty($attrs['customheight'])) {
            $this->wt_report->page_height = (int) $attrs['customheight'];
        } // Get it as int to ignore all decimal points or text (if any text then int(0))

        // Left Margin
        if (isset($attrs['leftmargin'])) {
            if ($attrs['leftmargin'] === '0') {
                $this->wt_report->left_margin = 0;
            } elseif (!empty($attrs['leftmargin'])) {
                $this->wt_report->left_margin = (int) $attrs['leftmargin']; // Get it as int to ignore all decimal points or text (if any text then int(0))
            }
        }
        // Right Margin
        if (isset($attrs['rightmargin'])) {
            if ($attrs['rightmargin'] === '0') {
                $this->wt_report->right_margin = 0;
            } elseif (!empty($attrs['rightmargin'])) {
                $this->wt_report->right_margin = (int) $attrs['rightmargin']; // Get it as int to ignore all decimal points or text (if any text then int(0))
            }
        }
        // Top Margin
        if (isset($attrs['topmargin'])) {
            if ($attrs['topmargin'] === '0') {
                $this->wt_report->top_margin = 0;
            } elseif (!empty($attrs['topmargin'])) {
                $this->wt_report->top_margin = (int) $attrs['topmargin']; // Get it as int to ignore all decimal points or text (if any text then int(0))
            }
        }
        // Bottom Margin
        if (isset($attrs['bottommargin'])) {
            if ($attrs['bottommargin'] === '0') {
                $this->wt_report->bottom_margin = 0;
            } elseif (!empty($attrs['bottommargin'])) {
                $this->wt_report->bottom_margin = (int) $attrs['bottommargin']; // Get it as int to ignore all decimal points or text (if any text then int(0))
            }
        }
        // Header Margin
        if (isset($attrs['headermargin'])) {
            if ($attrs['headermargin'] === '0') {
                $this->wt_report->header_margin = 0;
            } elseif (!empty($attrs['headermargin'])) {
                $this->wt_report->header_margin = (int) $attrs['headermargin']; // Get it as int to ignore all decimal points or text (if any text then int(0))
            }
        }
        // Footer Margin
        if (isset($attrs['footermargin'])) {
            if ($attrs['footermargin'] === '0') {
                $this->wt_report->footer_margin = 0;
            } elseif (!empty($attrs['footermargin'])) {
                $this->wt_report->footer_margin = (int) $attrs['footermargin']; // Get it as int to ignore all decimal points or text (if any text then int(0))
            }
        }

        // Page Orientation
        if (!empty($attrs['orientation'])) {
            if ($attrs['orientation'] === 'landscape') {
                $this->wt_report->orientation = 'landscape';
            } elseif ($attrs['orientation'] === 'portrait') {
                $this->wt_report->orientation = 'portrait';
            }
        }
        // Page Size
        if (!empty($attrs['pageSize'])) {
            $this->wt_report->page_format = strtoupper($attrs['pageSize']);
        }

        // Show Generated By...
        if (isset($attrs['showGeneratedBy'])) {
            if ($attrs['showGeneratedBy'] === '0') {
                $this->wt_report->show_generated_by = false;
            } elseif ($attrs['showGeneratedBy'] === '1') {
                $this->wt_report->show_generated_by = true;
            }
        }

        $this->wt_report->setup();
    }
451673
private function appendAttributes(array $attrs)
    {
        foreach ($attrs as $key => $value) {
            $this->appendAttribute($key, $value);
        }
    }
693493
protected function add_autovalues(&$attrs)
    {
        if (empty($this->prop['autovalues'])) {
            return;
        }

        $attrvals = array();
        foreach ($attrs as $k => $v) {
            $attrvals['{'.$k.'}'] = is_array($v) ? $v[0] : $v;
        }

        foreach ((array)$this->prop['autovalues'] as $lf => $templ) {
            if (empty($attrs[$lf])) {
                if (strpos($templ, '(') !== false) {
                    // replace {attr} placeholders with (escaped!) attribute values to be safely eval'd
                    $code = preg_replace('/\{\w+\}/', '', strtr($templ, array_map('addslashes', $attrvals)));
                    $res  = false;

                    try {
                        $res = eval("return ($code);");
                    }
                    catch (ParseError $e) {
                        // ignore
                    }

                    if ($res === false) {
                        rcube::raise_error(array(
                            'code' => 505, 'file' => __FILE__, 'line' => __LINE__,
                            'message' => "Expression parse error on: ($code)"), true, false);
                        continue;
                    }

                    $attrs[$lf] = $res;
                }
                else {
                    // replace {attr} placeholders with concrete attribute values
                    $attrs[$lf] = preg_replace('/\{\w+\}/', '', strtr($templ, $attrvals));
                }
            }
        }
    }
242588
function variableAttribute( $var, $attrs )
    {
        foreach( $attrs as $attr )
        {
            if ( is_object( $var ) )
            {
                if ( $var->hasAttribute( $attr ) )
                {
                    $var = $var->attribute( $attr );
                }
                else
                {
                    return null;
                }
            }
            else if ( is_array( $var ) )
            {
                if ( isset( $var[$attr] ) )
                {
                    $var = $var[$attr];
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }
        if ( isset( $var ) )
        {
            return $var;
        }

        return null;
    }
738985
public function startElement($name, $attrs)
    {
        $tmp = new ElementHandler($this->parser, $this, $this->configurator, null, null, $this->target);
        $tmp->init($name, $attrs);
    }
1128076
public function addAttrs(array $attrs)
    {
        foreach ($attrs as $attr => $val) {
            $this->addAttr($attr, $val);
        }

        return $this;
    }
356889
public function prepare(&$attrs)
    {
        parent::prepare($attrs);

        $attrs['max'] = $this->getAttribute('max');
        $attrs['min'] = $this->getAttribute('min');
        $attrs['step'] = $this->getAttribute('step');
        $attrs['patten'] = $this->getAttribute('pattern');
    }
958997
function SetOverride ( $attrname, $attrtype, $values )
    {
        assert ( is_string ( $attrname ) );
        assert ( in_array ( $attrtype, array ( SPH_ATTR_INTEGER, SPH_ATTR_TIMESTAMP, SPH_ATTR_BOOL, SPH_ATTR_FLOAT, SPH_ATTR_BIGINT ) ) );
        assert ( is_array ( $values ) );

        $this->_overrides[$attrname] = array ( "attr"=>$attrname, "type"=>$attrtype, "values"=>$values );
    }