WritingUtils.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. namespace Knuckles\Scribe\Tools;
  3. use Symfony\Component\VarExporter\VarExporter;
  4. class WritingUtils
  5. {
  6. public static $httpMethodToCssColour = [
  7. 'GET' => 'green',
  8. 'HEAD' => 'darkgreen',
  9. 'POST' => 'black',
  10. 'PUT' => 'darkblue',
  11. 'PATCH' => 'purple',
  12. 'DELETE' => 'red',
  13. 'OPTIONS' => 'grey',
  14. ];
  15. /**
  16. * Print a value as valid PHP, handling arrays and proper indentation.
  17. *
  18. * @param mixed $value
  19. * @param int $indentationLevel
  20. *
  21. * @return string
  22. * @throws \Symfony\Component\VarExporter\Exception\ExceptionInterface
  23. *
  24. */
  25. public static function printPhpValue($value, int $indentationLevel = 0): string
  26. {
  27. if (is_array($value)) {
  28. // Convert any objects to arrays so Symfony serialises them properly
  29. $value = Utils::arrayMapRecursive($value, function ($item) {
  30. return is_object($item) ? json_decode(json_encode($item), true) : $item;
  31. });
  32. }
  33. $output = VarExporter::export($value);
  34. // Padding with x spaces so they align
  35. $split = explode("\n", $output);
  36. $result = '';
  37. $padWith = str_repeat(' ', $indentationLevel);
  38. foreach ($split as $index => $line) {
  39. $result .= ($index == 0 ? '' : "\n$padWith") . $line;
  40. }
  41. return $result;
  42. }
  43. public static function printQueryParamsAsString(array $cleanQueryParams): string
  44. {
  45. $qs = '';
  46. foreach ($cleanQueryParams as $paramName => $value) {
  47. if (!is_array($value)) {
  48. $qs .= "$paramName=" . urlencode($value) . "&";
  49. } else {
  50. if (count($value) == 0) {
  51. continue;
  52. }
  53. if (array_keys($value)[0] === 0) {
  54. // List query param (eg filter[]=haha should become "filter[]": "haha")
  55. $qs .= "$paramName" . '[]=' . urlencode($value[0]) . '&';
  56. } else {
  57. // Hash query param (eg filter[name]=john should become "filter[name]": "john")
  58. foreach ($value as $item => $itemValue) {
  59. $qs .= "$paramName" . '[' . urlencode($item) . ']=' . urlencode($itemValue) . '&';
  60. }
  61. }
  62. }
  63. }
  64. return rtrim($qs, '&');
  65. }
  66. public static function printQueryParamsAsKeyValue(
  67. array $cleanQueryParams,
  68. string $quote = '"',
  69. string $delimiter = ":",
  70. int $spacesIndentation = 4,
  71. string $braces = "{}",
  72. int $closingBraceIndentation = 0,
  73. string $startLinesWith = '',
  74. string $endLinesWith = ','
  75. ): string
  76. {
  77. $output = isset($braces[0]) ? "{$braces[0]}\n" : '';
  78. foreach ($cleanQueryParams as $parameter => $value) {
  79. if (!is_array($value)) {
  80. $output .= str_repeat(" ", $spacesIndentation);
  81. $output .= "$startLinesWith$quote$parameter$quote$delimiter $quote$value$quote$endLinesWith\n";
  82. } else {
  83. if (count($value) == 0) {
  84. continue;
  85. }
  86. if (array_keys($value)[0] === 0) {
  87. // List query param (eg filter[]=haha should become "filter[]": "haha")
  88. $output .= str_repeat(" ", $spacesIndentation);
  89. $output .= "$startLinesWith$quote$parameter" . "[]$quote$delimiter $quote$value[0]$quote$endLinesWith\n";
  90. } else {
  91. // Hash query param (eg filter[name]=john should become "filter[name]": "john")
  92. foreach ($value as $item => $itemValue) {
  93. $output .= str_repeat(" ", $spacesIndentation);
  94. $output .= "$startLinesWith$quote$parameter" . "[$item]$quote$delimiter $quote$itemValue$quote$endLinesWith\n";
  95. }
  96. }
  97. }
  98. }
  99. $closing = isset($braces[1]) ? str_repeat(" ", $closingBraceIndentation) . "{$braces[1]}" : '';
  100. return $output . $closing;
  101. }
  102. /**
  103. * Expand a request parameter into one or more parameters to be used when sending as form-data.
  104. * A primitive value like ("name", "John") is returned as ["name" => "John"]
  105. * Lists like ("filter", ["haha"]) becomes ["filter[]" => "haha"]
  106. * Maps like ("filter", ["name" => "john", "age" => "12"]) become ["filter[name]" => "john", "filter[age]" => 12]
  107. *
  108. * @param string $parameter The name of the parameter
  109. * @param mixed $value Value of the parameter
  110. *
  111. * @return array
  112. */
  113. public static function getParameterNamesAndValuesForFormData(string $parameter, $value): array
  114. {
  115. if (!is_array($value)) {
  116. return [$parameter => $value];
  117. }
  118. // We assume it's a list if its first key is 0
  119. $keys = array_keys($value);
  120. if (count($keys) && $keys[0] === 0) {
  121. if (is_array($value[0])) {
  122. // handle nested arrays/objects
  123. $params = [];
  124. $expanded = self::getParameterNamesAndValuesForFormData('', $value[0]);
  125. foreach ($expanded as $fieldName => $itemValue) {
  126. $paramName = $parameter . '[]' . $fieldName;
  127. $params[$paramName] = $itemValue;
  128. }
  129. return $params;
  130. }
  131. return [$parameter . '[]' => $value[0]];
  132. }
  133. // Transform hashes
  134. $params = [];
  135. foreach ($value as $item => $itemValue) {
  136. if (is_array($itemValue)) {
  137. $expanded = self::getParameterNamesAndValuesForFormData('', $itemValue);
  138. foreach ($expanded as $fieldName => $subItemValue) {
  139. $paramName = $parameter . "[$item]" . $fieldName;
  140. $params[$paramName] = $subItemValue;
  141. }
  142. } else {
  143. $params[$parameter . "[$item]"] = $itemValue;
  144. }
  145. }
  146. return $params;
  147. }
  148. /**
  149. * Convert a list of possible values to a friendly string:
  150. * [1, 2, 3] -> "1, 2, or 3"
  151. * [1, 2] -> "1 or 2"
  152. * [1] -> "1"
  153. * Each value is wrapped in HTML <code> tags, so you actually get "<code>1</code>, <code>2</code>, or
  154. * <code>3</code>"
  155. *
  156. * @param array $list
  157. *
  158. * @return string
  159. */
  160. public static function getListOfValuesAsFriendlyHtmlString(array $list = []): string
  161. {
  162. switch (count($list)) {
  163. case 1:
  164. return "<code>{$list[0]}</code>";
  165. case 2:
  166. return "<code>{$list[0]}</code> or <code>{$list[1]}</code>";
  167. default:
  168. return "<code>"
  169. . implode('</code>, <code>', array_slice($list, 0, -1))
  170. . "</code>, or <code>" . end($list) . "</code>";
  171. }
  172. }
  173. }