@param array $attr
@param callable|null $callback

@return string
17229
static public function build(array $attr, callable $callback = null): string
    {
        if (!count($attr)) {
            return '';
        }

        $html = array_map(function ($val, $key) use ($callback) {
            if (is_bool($val)) {
                return $val ? self::getKey($key) : '';
            }

            if (isset($val)) {
                if ($val instanceof \Closure) {
                    $val = $val();
                } elseif ($val instanceof \JsonSerializable) {
                    $val = \json_encode($val->jsonSerialize(), (JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
                } elseif (is_callable([$val, 'toArray'])) {
                    $val = $val->toArray();
                } elseif (is_callable([$val, '__toString'])) {
                    $val = strval($val);
                }

                if (is_array($val)) {
                    $val = \json_encode($val);
                }

                if (is_callable($callback)) {
                    $val = call_user_func($callback, $val);
                } else {
                    $val = htmlspecialchars($val, ENT_QUOTES);
                }

                if (is_string($val)) {
                    return sprintf('%1$s="%2$s"', self::getKey($key), $val);
                }
            }

            return self::getKey($key);
        }, $attr, array_keys($attr));

        return implode(' ', $html);
    }
566229
public static function attr( $attr = array() ) {
		$buffer = " ";
		foreach( $attr as $key => $value ) {	
			$buffer .= $key.'="'.$value.'" ';
		}
	
		return substr( $buffer, 0, -1 );
	}
436864
public function attr($attr) {
		if($this->domnode === null)
			return null;
		return $this->domnode->getAttribute($attr);
	}
650545
public function url($attr)
    {
        $data = [];

        foreach ($this->_nodes as $node) {
            $data[] = $this->_document->absolutizeUrl($node->getAttribute($attr));
        }

        return $data;
    }
843797
function attribute( $attr )
    {
        switch( $attr )
        {
            case "uri":
                return $this->uri();
                break;
            case "functions":
                return $this->Functions;
            case "views":
                return $this->Functions;
            case "name":
                return $this->Name;
            case "path":
                return $this->Path;
            case "info":
                return $this->Module;
            case 'aviable_functions':
            case 'available_functions':
                return $this->FunctionList;
            default:
            {
                eZDebug::writeError( "Attribute '$attr' does not exist", __METHOD__ );
                return null;
            }
            break;
        }
    }
5845
private function _serializeCallback( $callback )
    {
        $retVal = $callback;

        if ( is_array( $callback ) && 2 === count( $callback ) )
        {
            $retVal = get_class( $callback[ 0 ] ) . '/' . $callback[ 1 ];
        }

        return $retVal;
    }
992562
public function setCallback($callback = NULL) {

		if (NULL !== $callback) {

			// taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/
			$pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u';

			foreach (explode('.', $callback) as $part) {
				if (!preg_match($pattern, $part)) {
					throw new \InvalidArgumentException(sprintf("The callback name '%s' is not valid.", $part));
				}
			}
		}

		$this->callback = $callback;

		return $this->update();

	}
1163461
public function attr($attribute, $value = null)
    {
        if (is_array($attribute)) return $this->attributes($attribute);
        if ($value) return $this->attributes(array($attribute => $value));
    }
567213
public function attributes(array $attr)
    {
        $attr_string = '';
        foreach ($attr as $name => $value) {
            if (is_array($value)) {
                $attr_string .= ' '.$name.'="'.implode(' ', $value).'"';
            } else {
                $attr_string .= ' '.$name.'="'.$value.'"';
            }
        }

        return $attr_string;
    }
1062482
public function get($attr,$current=true)
    {
        if (!$this->_data || !array_key_exists($attr, $this->_data)) {
            return null;
        }
        return Connection::convertToEncoding($current ? $this->_data[$attr] : $this->_prev_data[$attr]);
    }
587221
public function getAttr($attr)
    {
        $attributeValue = $this->con->evaluateJavascript(sprintf('%s.getAttribute(%s)', $this->getAccessor(), json_encode($attr)));

        if ($attributeValue === false) {
            // see https://github.com/kriswallsmith/Buzz/pull/138 bug
            return '';
        }

        return $attributeValue;
    }
1046804
public function url_first($attr)
    {
        return $this->_nodes ? $this->_document->absolutizeUrl(current($this->_nodes)->getAttribute($attr)) : null;
    }
197360
protected function getFieldValue(array $attr, $field)
    {
        $method = 'set' . ucwords($field);

        if (method_exists($this, $method)) {
            // If there is a setter for this field, use that
            return $this->{$method}($attr[$field]);
        }

        // Otherwise just set the property
        return (isset($attr[$field])) ? $attr[$field] : null;
    }
74553
function getAttribute($attr)
    {
        $attr = strtolower($attr);
        if (isset($this->_attributes[$attr])) {
            return $this->_attributes[$attr];
        }
        return null;
    }
910107
private function normaliseCallbackString(string $callback) : string
    {
        @list($controller, $method) = explode('@', $callback);

        if (class_exists($this->defaultControllerNamespace . $controller)) {
            return $this->defaultControllerNamespace . $callback;
        }

        return $callback;
    }
684965
protected function renderAttr($attributes = false, $params = false)
    {
        $attrStr = '';

        if (isset($attributes['callback'])) {
            $callbackParams = [$this];

            if ($params !== false) {
                array_push($callbackParams, $params);
            }

            call_user_func_array($attributes['callback'], $callbackParams);
        }

        if (is_array($attributes)) {
            foreach ($attributes as $attr => $value) {
                if (is_string($value)) {
                    $attrStr .= ' '.$attr.'="'.$value.'"';
                }
            }
        }

        return $attrStr;
    }
647436
protected function _buildAttribute($attr)
    {
        $string = array();

        foreach ($attr as $key => $value) {
            if (is_array($value)) {
                $value = implode(' ', $value);
            }

            $string[] = $key.'="'.$value.'"';
        }

        return implode(' ', $string);
    }