XML <RepeatTag>

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

@return void
545002
private function repeatTagStartHandler(array $attrs): void
    {
        $this->process_repeats++;
        if ($this->process_repeats > 1) {
            return;
        }

        $this->repeats_stack[] = [$this->repeats, $this->repeat_bytes];
        $this->repeats         = [];
        $this->repeat_bytes    = xml_get_current_line_number($this->parser);

        $tag = $attrs['tag'] ?? '';
        if (!empty($tag)) {
            if ($tag === '@desc') {
                $value = $this->desc;
                $value = trim($value);
                $this->current_element->addText($value);
            } else {
                $tag   = str_replace('@fact', $this->fact, $tag);
                $tags  = explode(':', $tag);
                $temp  = explode(' ', trim($this->gedrec));
                $level = $temp[0];
                if ($level == 0) {
                    $level++;
                }
                $subrec = $this->gedrec;
                $t      = $tag;
                $count  = count($tags);
                $i      = 0;
                while ($i < $count) {
                    $t = $tags[$i];
                    if (!empty($t)) {
                        if ($i < ($count - 1)) {
                            $subrec = Functions::getSubRecord($level, "$level $t", $subrec);
                            if (empty($subrec)) {
                                $level--;
                                $subrec = Functions::getSubRecord($level, "@ $t", $this->gedrec);
                                if (empty($subrec)) {
                                    return;
                                }
                            }
                        }
                        $level++;
                    }
                    $i++;
                }
                $level--;
                $count = preg_match_all("/$level $t(.*)/", $subrec, $match, PREG_SET_ORDER);
                $i     = 0;
                while ($i < $count) {
                    $i++;
                    // Privacy check - is this a link, and are we allowed to view the linked object?
                    $subrecord = Functions::getSubRecord($level, "$level $t", $subrec, $i);
                    if (preg_match('/^\d ' . Gedcom::REGEX_TAG . ' @(' . Gedcom::REGEX_XREF . ')@/', $subrecord, $xref_match)) {
                        $linked_object = GedcomRecord::getInstance($xref_match[1], $this->tree);
                        if ($linked_object && !$linked_object->canShow()) {
                            continue;
                        }
                    }
                    $this->repeats[] = $subrecord;
                }
            }
        }
    }
496898
protected function checkAttr($values, $attr)
    {
        if (!is_array($values)) $values = array($values);

        foreach ($values as $value) {
            if (!@in_array($value, $this->get_value($attr, 'all'))) {
                return false;
            }
        }
        return true;
    }
581612
public function prepare(&$attrs)
    {
        $attrs['id'] = $this->getAttribute('id', $this->getId());
        $attrs['class'] = $this->getAttribute('class');
    }
246257
protected function inputStartHandler(array $attrs): void
    {
        $this->text  = '';
        $this->input = [
            'name'    => $attrs['name'] ?? '',
            'type'    => $attrs['type'] ?? '',
            'lookup'  => $attrs['lookup'] ?? '',
            'options' => $attrs['options'] ?? '',
            'default' => '',
            'value'   => '',
        ];

        if (isset($attrs['default'])) {
            if ($attrs['default'] === 'NOW') {
                $this->input['default'] = Carbon::now()->format('d M Y');
            } else {
                $match = [];
                if (preg_match('/NOW([+\-]\d+)/', $attrs['default'], $match) > 0) {
                    $this->input['default'] = Carbon::now()->addDays((int) $match[1])->format('d M Y');
                } else {
                    $this->input['default'] = $attrs['default'];
                }
            }
        } elseif ($attrs['name'] === 'pageSize') {
            $this->input['default'] = app(LocaleInterface::class)->territory()->paperSize();
        }
    }
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));
                }
            }
        }
    }
1371417
protected function reportStartHandler(array $attrs): void
    {
        $this->data['access'] = $attrs['access'] ?? Auth::PRIV_PRIVATE;

        $this->data['icon'] = $attrs['icon'] ?? '';
    }
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;
        }
    }
1219527
public function buildTagAttributes(array $attributes)
	{
		$html = array();

		foreach ($attributes as $key => $value)
		{
			if (is_null($value))
				continue;

			if (is_numeric($key))
				$key = $value;

			$html[] = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"';
		}

		return (count($html) > 0) ? ' ' . implode(' ', $html) : '';
	}
993746
public function updateAttributes(array $attrs) {
        $url = "entities/{$this->_id}/attrs";

        if ($this->_type) {
            $url .= "?type={$this->_type}";
        }

        $updateEntity = new ContextFactory($attrs);
        return $this->_orion->patch($url, $updateEntity);
    }
384069
public function setAttrs(array $attrs) {
		foreach ($attrs as $attr => $value) {
			$this->setAttr($attr, $value);
		}
		
		return $this;
	}
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;
    }
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');
    }
71161
private function factsStartHandler(array $attrs): void
    {
        $this->process_repeats++;
        if ($this->process_repeats > 1) {
            return;
        }

        $this->repeats_stack[] = [$this->repeats, $this->repeat_bytes];
        $this->repeats         = [];
        $this->repeat_bytes    = xml_get_current_line_number($this->parser);

        $id    = '';
        $match = [];
        if (preg_match('/0 @(.+)@/', $this->gedrec, $match)) {
            $id = $match[1];
        }
        $tag = '';
        if (isset($attrs['ignore'])) {
            $tag .= $attrs['ignore'];
        }
        if (preg_match('/\$(.+)/', $tag, $match)) {
            $tag = $this->vars[$match[1]]['id'];
        }

        $record = GedcomRecord::getInstance($id, $this->tree);
        if (empty($attrs['diff']) && !empty($id)) {
            $facts = $record->facts([], true);
            $this->repeats = [];
            $nonfacts      = explode(',', $tag);
            foreach ($facts as $fact) {
                if (!in_array($fact->getTag(), $nonfacts, true)) {
                    $this->repeats[] = $fact->gedcom();
                }
            }
        } else {
            foreach ($record->facts() as $fact) {
                if (($fact->isPendingAddition() || $fact->isPendingDeletion()) && $fact->getTag() !== 'CHAN') {
                    $this->repeats[] = $fact->gedcom();
                }
            }
        }
    }
508587
protected function varStartHandler(array $attrs): void
    {
        if (preg_match('/^I18N::number\((.+)\)$/', $attrs['var'], $match)) {
            $this->text .= I18N::number((int) $match[1]);
        } elseif (preg_match('/^I18N::translate\(\'(.+)\'\)$/', $attrs['var'], $match)) {
            $this->text .= I18N::translate($match[1]);
        } elseif (preg_match('/^I18N::translateContext\(\'(.+)\', *\'(.+)\'\)$/', $attrs['var'], $match)) {
            $this->text .= I18N::translateContext($match[1], $match[2]);
        } else {
            $this->text .= $attrs['var'];
        }
    }
451673
private function appendAttributes(array $attrs)
    {
        foreach ($attrs as $key => $value) {
            $this->appendAttribute($key, $value);
        }
    }
720627
public function setAttrArray(array $attributes)
    {
        foreach ($attributes as $attribute => $value) {
            $this->setAttr($attribute, $value);
        }
    }
1361059
public static function newRow(array $attrs = array()) {
        if (!empty(self::$row_data))
            self::$rows[count(self::$rows) - 1][] = self::$row_data;
        self::$row_data = array();
        self::$rows[][] = $attrs;
        return count(self::$rows);
    }