5 array $attributes = array(),
8 if (isset($attributes['sigil']) ||
9 isset($attributes['meta']) ||
10 isset($attributes['mustcapture'])) {
11 foreach ($attributes as $k => $v) {
15 $attributes['data-sigil'] = $v;
17 unset($attributes[$k]);
21 $response = CelerityAPI
::getStaticResourceResponse();
22 $id = $response->addMetadata($v);
23 $attributes['data-meta'] = $id;
25 unset($attributes[$k]);
29 $attributes['data-mustcapture'] = '1';
31 unset($attributes['data-mustcapture']);
33 unset($attributes[$k]);
39 if (isset($attributes['aural'])) {
40 if ($attributes['aural']) {
41 $class = idx($attributes, 'class', '');
42 $class = rtrim('aural-only '.$class);
43 $attributes['class'] = $class;
45 $class = idx($attributes, 'class', '');
46 $class = rtrim('visual-only '.$class);
47 $attributes['class'] = $class;
48 $attributes['aria-hidden'] = 'true';
50 unset($attributes['aural']);
53 if (isset($attributes['print'])) {
54 if ($attributes['print']) {
55 $class = idx($attributes, 'class', '');
56 $class = rtrim('print-only '.$class);
57 $attributes['class'] = $class;
59 // NOTE: Alternative print content is hidden from screen readers.
60 $attributes['aria-hidden'] = 'true';
62 $class = idx($attributes, 'class', '');
63 $class = rtrim('screen-only '.$class);
64 $attributes['class'] = $class;
66 unset($attributes['print']);
70 return phutil_tag($tag, $attributes, $content);
73 function phabricator_form(PhabricatorUser
$user, $attributes, $content) {
76 $http_method = idx($attributes, 'method');
77 $is_post = (strcasecmp($http_method, 'POST') === 0);
79 $http_action = idx($attributes, 'action');
80 $is_absolute_uri = preg_match('#^(https?:|//)#', $http_action);
84 // NOTE: We only include CSRF tokens if a URI is a local URI on the same
85 // domain. This is an important security feature and prevents forms which
86 // submit to foreign sites from leaking CSRF tokens.
88 // In some cases, we may construct a fully-qualified local URI. For example,
89 // we can construct these for download links, depending on configuration.
91 // These forms do not receive CSRF tokens, even though they safely could.
92 // This can be confusing, if you're developing for Phabricator and
93 // manage to construct a local form with a fully-qualified URI, since it
94 // won't get CSRF tokens and you'll get an exception at the other end of
95 // the request which is a bit disconnected from the actual root cause.
97 // However, this is rare, and there are reasonable cases where this
98 // construction occurs legitimately, and the simplest fix is to omit CSRF
99 // tokens for these URIs in all cases. The error message you receive also
100 // gives you some hints as to this potential source of error.
102 if (!$is_absolute_uri) {
103 $body[] = phutil_tag(
107 'name' => AphrontRequest
::getCSRFTokenName(),
108 'value' => $user->getCSRFToken(),
111 $body[] = phutil_tag(
115 'name' => '__form__',
119 // If the profiler was active for this request, keep it active for any
120 // forms submitted from this page.
121 if (DarkConsoleXHProfPluginAPI
::isProfilerRequested()) {
122 $body[] = phutil_tag(
126 'name' => '__profile__',
134 if (is_array($content)) {
135 $body = array_merge($body, $content);
140 return javelin_tag('form', $attributes, $body);