Skip to content

Commit 065374e

Browse files
committed
Original formatString function
1 parent 14c12f0 commit 065374e

File tree

1 file changed

+278
-0
lines changed

1 file changed

+278
-0
lines changed

config/vanilla/bootstrap.before.php

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
<?php if (!defined('APPLICATION')) exit();
2+
3+
if (!function_exists('formatString')) {
4+
/**
5+
* Formats a string by inserting data from its arguments, similar to sprintf, but with a richer syntax.
6+
*
7+
* @param string $string The string to format with fields from its args enclosed in curly braces.
8+
* The format of fields is in the form {Field,Format,Arg1,Arg2}. The following formats are the following:
9+
* - date: Formats the value as a date. Valid arguments are short, medium, long.
10+
* - number: Formats the value as a number. Valid arguments are currency, integer, percent.
11+
* - time: Formats the value as a time. This format has no additional arguments.
12+
* - url: Calls url() function around the value to show a valid url with the site.
13+
* You can pass a domain to include the domain.
14+
* - urlencode, rawurlencode: Calls urlencode/rawurlencode respectively.
15+
* - html: Calls htmlspecialchars.
16+
* @param array $args The array of arguments.
17+
* If you want to nest arrays then the keys to the nested values can be separated by dots.
18+
* @return string The formatted string.
19+
* <code>
20+
* echo formatString("Hello {Name}, It's {Now,time}.", array('Name' => 'Frank', 'Now' => '1999-12-31 23:59'));
21+
* // This would output the following string:
22+
* // Hello Frank, It's 12:59PM.
23+
* </code>
24+
*/
25+
function formatString($string, $args = []) {
26+
_formatStringCallback($args, true);
27+
$result = preg_replace_callback('/{([^\s][^}]+[^\s]?)}/', '_formatStringCallback', $string);
28+
29+
return $result;
30+
}
31+
}
32+
33+
if (!function_exists('_formatStringCallback')) {
34+
/**
35+
* The callback helper for {@link formatString()}.
36+
*
37+
* @param array $match Either the array of arguments or the regular expression match.
38+
* @param bool $setArgs Whether this is a call to initialize the arguments or a matching callback.
39+
* @return mixed Returns the matching string or nothing when setting the arguments.
40+
* @access private
41+
*/
42+
function _formatStringCallback($match, $setArgs = false) {
43+
static $args = [], $contextUserID = null;
44+
if ($setArgs) {
45+
$args = $match;
46+
47+
if (isset($args['_ContextUserID'])) {
48+
$contextUserID = $args['_ContextUserID'];
49+
} else {
50+
$contextUserID = Gdn::session() && Gdn::session()->isValid() ? Gdn::session()->UserID : null;
51+
}
52+
53+
return '';
54+
}
55+
56+
$match = $match[1];
57+
if ($match == '{') {
58+
return $match;
59+
}
60+
61+
// Parse out the field and format.
62+
$parts = explode(',', $match);
63+
$field = trim($parts[0]);
64+
$format = trim(($parts[1] ?? ''));
65+
$subFormat = isset($parts[2]) ? strtolower(trim($parts[2])) : '';
66+
$formatArgs = $parts[3] ?? '';
67+
68+
if (in_array($format, ['currency', 'integer', 'percent'])) {
69+
$formatArgs = $subFormat;
70+
$subFormat = $format;
71+
$format = 'number';
72+
} elseif (is_numeric($subFormat)) {
73+
$formatArgs = $subFormat;
74+
$subFormat = '';
75+
}
76+
77+
$value = valr($field, $args, null);
78+
if ($value === null && !in_array($format, ['url', 'exurl', 'number', 'plural'])) {
79+
$result = '';
80+
} else {
81+
switch (strtolower($format)) {
82+
case 'date':
83+
switch ($subFormat) {
84+
case 'short':
85+
$result = Gdn_Format::date($value, '%d/%m/%Y');
86+
break;
87+
case 'medium':
88+
$result = Gdn_Format::date($value, '%e %b %Y');
89+
break;
90+
case 'long':
91+
$result = Gdn_Format::date($value, '%e %B %Y');
92+
break;
93+
default:
94+
$result = Gdn_Format::date($value);
95+
break;
96+
}
97+
break;
98+
case 'html':
99+
case 'htmlspecialchars':
100+
$result = htmlspecialchars($value);
101+
break;
102+
case 'number':
103+
if (!is_numeric($value)) {
104+
$result = $value;
105+
} else {
106+
switch ($subFormat) {
107+
case 'currency':
108+
$result = '$'.number_format($value, is_numeric($formatArgs) ? $formatArgs : 2);
109+
break;
110+
case 'integer':
111+
$result = (string)round($value);
112+
if (is_numeric($formatArgs) && strlen($result) < $formatArgs) {
113+
$result = str_repeat('0', $formatArgs - strlen($result)).$result;
114+
}
115+
break;
116+
case 'percent':
117+
$result = round($value * 100, is_numeric($formatArgs) ? $formatArgs : 0);
118+
break;
119+
default:
120+
$result = number_format($value, is_numeric($formatArgs) ? $formatArgs : 0);
121+
break;
122+
}
123+
}
124+
break;
125+
case 'plural':
126+
if (is_array($value)) {
127+
$value = count($value);
128+
} elseif (stringEndsWith($field, 'UserID', true)) {
129+
$value = 1;
130+
}
131+
132+
if (!is_numeric($value)) {
133+
$result = $value;
134+
} else {
135+
if (!$subFormat) {
136+
$subFormat = rtrim("%s $field", 's');
137+
}
138+
if (!$formatArgs) {
139+
$formatArgs = $subFormat.'s';
140+
}
141+
142+
$result = plural($value, $subFormat, $formatArgs);
143+
}
144+
break;
145+
case 'rawurlencode':
146+
$result = rawurlencode($value);
147+
break;
148+
case 'text':
149+
$result = Gdn_Format::text($value, false);
150+
break;
151+
case 'time':
152+
$result = Gdn_Format::date($value, '%l:%M%p');
153+
break;
154+
case 'url':
155+
if (strpos($field, '/') !== false) {
156+
$value = $field;
157+
}
158+
$result = url($value, $subFormat == 'domain');
159+
break;
160+
case 'exurl':
161+
if (strpos($field, '/') !== false) {
162+
$value = $field;
163+
}
164+
$result = externalUrl($value);
165+
break;
166+
case 'urlencode':
167+
$result = urlencode($value);
168+
break;
169+
case 'gender':
170+
// Format in the form of FieldName,gender,male,female,unknown[,plural]
171+
if (is_array($value) && count($value) == 1) {
172+
$value = array_shift($value);
173+
}
174+
175+
$gender = 'u';
176+
177+
if (!is_array($value)) {
178+
$user = Gdn::userModel()->getID($value);
179+
if ($user) {
180+
$gender = $user->Gender;
181+
}
182+
} else {
183+
$gender = 'p';
184+
}
185+
186+
switch ($gender) {
187+
case 'm':
188+
$result = $subFormat;
189+
break;
190+
case 'f':
191+
$result = $formatArgs;
192+
break;
193+
case 'p':
194+
$result = ($parts[5] ?? ($parts[4] ?? false));
195+
break;
196+
case 'u':
197+
default:
198+
$result = ($parts[4] ?? false);
199+
}
200+
201+
break;
202+
case 'user':
203+
case 'you':
204+
case 'his':
205+
case 'her':
206+
case 'your':
207+
// $Result = print_r($Value, true);
208+
$argsBak = $args;
209+
if (is_array($value) && count($value) == 1) {
210+
$value = array_shift($value);
211+
}
212+
213+
if (is_array($value)) {
214+
if (isset($value['UserID'])) {
215+
$user = $value;
216+
$user['Name'] = formatUsername($user, $format, $contextUserID);
217+
218+
$result = userAnchor($user);
219+
} else {
220+
$max = c('Garden.FormatUsername.Max', 5);
221+
// See if there is another count.
222+
$extraCount = valr($field.'_Count', $args, 0);
223+
224+
$count = count($value);
225+
$result = '';
226+
for ($i = 0; $i < $count; $i++) {
227+
if ($i >= $max && $count > $max + 1) {
228+
$others = $count - $i + $extraCount;
229+
$result .= ' '.t('sep and', 'and').' '
230+
.plural($others, '%s other', '%s others');
231+
break;
232+
}
233+
234+
$iD = $value[$i];
235+
if (is_array($iD)) {
236+
continue;
237+
}
238+
239+
if ($i == $count - 1) {
240+
$result .= ' '.t('sep and', 'and').' ';
241+
} elseif ($i > 0) {
242+
$result .= ', ';
243+
}
244+
245+
$special = [-1 => t('everyone'), -2 => t('moderators'), -3 => t('administrators')];
246+
if (isset($special[$iD])) {
247+
$result .= $special[$iD];
248+
} else {
249+
$user = Gdn::userModel()->getID($iD);
250+
if ($user) {
251+
$user->Name = formatUsername($user, $format, $contextUserID);
252+
$result .= userAnchor($user);
253+
}
254+
}
255+
}
256+
}
257+
} else {
258+
$user = Gdn::userModel()->getID($value);
259+
if ($user) {
260+
// Store this name separately because of special 'You' case.
261+
$name = formatUsername($user, $format, $contextUserID);
262+
// Manually build instead of using userAnchor() because of special 'You' case.
263+
$result = anchor(htmlspecialchars($name), userUrl($user));
264+
} else {
265+
$result = '';
266+
}
267+
}
268+
269+
$args = $argsBak;
270+
break;
271+
default:
272+
$result = $value;
273+
break;
274+
}
275+
}
276+
return $result;
277+
}
278+
}

0 commit comments

Comments
 (0)