diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..22b280e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_size = 2 +indent_style = space +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{json,php,xml,xml.dist}] +indent_size = 4 diff --git a/Function.HTML-Build-Attributes.php b/Function.HTML-Build-Attributes.php index 5fd54fa..bcc615c 100644 --- a/Function.HTML-Build-Attributes.php +++ b/Function.HTML-Build-Attributes.php @@ -1,68 +1,83 @@ 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($attr) || !count($attr)) { + return ''; + } - if (is_array($val)) { - if (function_exists('is_blank')) { - $filter = function ($var) { - return !is_blank($var); - }; - } else { - $filter = function ($var) { - return !empty($var) || is_numeric($var); - }; - } - $val = implode(' ', array_filter($val, $filter)); - } + $html = []; + foreach ($attr as $key => $val) { + if (is_null($val)) { + continue; + } - if (is_callable($callback)) { - $val = call_user_func($callback, $val); - } elseif (function_exists('esc_attr')) { - $val = esc_attr($val); - } else { - $val = htmlspecialchars($val, ENT_QUOTES); - } + if (is_string($key)) { + $key = trim($key); - if (is_string($val)) { - return sprintf('%1$s="%2$s"', $key, $val); - } - } - }, - $attr, - array_keys($attr) - ); + if (strlen($key) === 0) { + continue; + } + } - return implode(' ', $html); - } + if (is_object($val)) { + if ($val instanceof Closure) { + $val = $val(); + } elseif ($val instanceof JsonSerializable) { + $val = json_encode($val, (JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)); + } elseif (is_callable([ $val, 'toArray' ])) { + $val = $val->toArray(); + } elseif (is_callable([ $val, '__toString' ])) { + $val = strval($val); + } + } + + if (is_bool($val)) { + $html[] = ($val ? $key : ''); + continue; + } + + if (is_array($val)) { + if (function_exists('is_blank')) { + $filter = function ($var) { + return !is_blank($var); + }; + } else { + $filter = function ($var) { + return !empty($var) || is_numeric($var); + }; + } + $val = implode(' ', array_filter($val, $filter)); + } + + if (is_callable($callback)) { + $val = $callback($val); + } elseif (function_exists('esc_attr')) { + $val = esc_attr($val); + } else { + $val = htmlspecialchars($val, ENT_QUOTES); + } + + if (is_string($val) || is_numeric($val)) { + $html[] = sprintf('%1$s="%2$s"', $key, $val); + continue; + } + } + + return implode(' ', $html); + } } diff --git a/README.md b/README.md index 597e48a..2288d31 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # html_build_attributes -(PHP 5 >= 5.4) +(PHP 5 >= 5.4, PHP 7, PHP 8) `html_build_attributes` — Generate a string of HTML attributes. ## Description @@ -13,17 +13,33 @@ Generate a string of HTML attributes from the associative array provided. ## Parameters -- `attr` — Associative array, or object containing properties, representing attribute names and values. - If `attr` is an object, then only public properties will be incorporated into the result. - If a value is an array, its values will be concatenated and delimited with a space. - Values that cannot be converted into strings will be ignored. If the value is Stringable, Arrayble, or a `Closure`, attempts will be made to parse as a string. -- `callback` — Callback function for escaping the values for the HTML attributes. - If no sanitizer is provided, [`htmlspecialchars()`](http://php.net/htmlspecialchars) is used; - If using WordPress, the [`esc_attr()`](https://developer.wordpress.org/reference/functions/esc_attr/) function is used. +- `attr` — Associative array, or object containing properties, representing + attribute names and values. + + If `attr` is a non-iterable object, then only accessible non-static properties + will be incorporated into the result. + + If a value of `attr` is an array, its values will be concatenated and + delimited with a space. + + If a value of `attr` is a boolean, the value's key will be rendered without + a value. + + If the value is Stringable, Arrayble, or a [`Closure`][class.closure], + attempts will be made to parse as a string. + + Values that cannot be converted into strings will be ignored. + +- `callback` — Callback function for escaping the values for the HTML attributes. + + If no sanitizer is provided, [`htmlspecialchars()`][function.htmlspecialchars] + is used; + + If using WordPress, the [`esc_attr()`][wp.esc_attr] function is used. ## Return Values -Returns a string of HTML attributes. +Returns a string of HTML attributes or a empty string if `attr` is invalid or empty. ## Installation @@ -35,4 +51,10 @@ $ composer require mcaskill/php-html-build-attributes ### Without Composer -Why are you not using [composer](http://getcomposer.org/)? Download `Function.HTML-Build-Attributes.php` from the gist and save the file into your project path somewhere. \ No newline at end of file +Why are you not using [composer](http://getcomposer.org/)? +Download `Function.HTML-Build-Attributes.php` from the gist and save the file +into your project path somewhere. + +[class.closure]: https://php.net/class.closure +[function.htmlspecialchars]: https://php.net/function.htmlspecialchars +[wp.esc_attr]: https://developer.wordpress.org/reference/functions/esc_attr/ diff --git a/composer.json b/composer.json index 9236e54..3dfb32f 100644 --- a/composer.json +++ b/composer.json @@ -1,23 +1,27 @@ { - "name": "mcaskill/php-html-build-attributes", - "version": "1.0.0", - "description": "Generate a string of HTML attributes.", - "license": "MIT", - "authors": [ - { - "name": "Chauncey McAskill", - "email": "chauncey@mcaskill.ca", - "homepage": "https://github.com/mcaskill" + "name": "mcaskill/php-html-build-attributes", + "description": "Generate a string of HTML attributes.", + "license": "MIT", + "authors": [ + { + "name": "Chauncey McAskill", + "email": "chauncey@mcaskill.ca", + "homepage": "https://github.com/mcaskill" + } + ], + "keywords": [ + "function", + "wordpress" + ], + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "require": { + "php": ">=5.4.0" + }, + "autoload": { + "files": [ "Function.HTML-Build-Attributes.php" ] } - ], - "keywords": [ - "function", - "wordpress" - ], - "require": { - "php": ">=5.4.0" - }, - "autoload": { - "files": [ "Function.HTML-Build-Attributes.php" ] - } -} \ No newline at end of file +}