@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3/**
4 * View which renders down to a single tag, and provides common access for tag
5 * attributes (setting classes, sigils, IDs, etc).
6 */
7abstract class AphrontTagView extends AphrontView {
8
9 private $id;
10 private $classes = array();
11 private $sigils = array();
12 private $style;
13 private $metadata;
14 private $mustCapture;
15 private $workflow;
16
17 /**
18 * @param bool $workflow
19 * @return $this
20 */
21 public function setWorkflow($workflow) {
22 $this->workflow = $workflow;
23 return $this;
24 }
25
26 /**
27 * @return bool
28 */
29 public function getWorkflow() {
30 return $this->workflow;
31 }
32
33 public function setMustCapture($must_capture) {
34 $this->mustCapture = $must_capture;
35 return $this;
36 }
37
38 public function getMustCapture() {
39 return $this->mustCapture;
40 }
41
42 final public function setMetadata(array $metadata) {
43 $this->metadata = $metadata;
44 return $this;
45 }
46
47 final public function getMetadata() {
48 return $this->metadata;
49 }
50
51 final public function setStyle($style) {
52 $this->style = $style;
53 return $this;
54 }
55
56 final public function getStyle() {
57 return $this->style;
58 }
59
60 final public function addSigil($sigil) {
61 $this->sigils[] = $sigil;
62 return $this;
63 }
64
65 final public function getSigils() {
66 return $this->sigils;
67 }
68
69 public function addClass($class) {
70 $this->classes[] = $class;
71 return $this;
72 }
73
74 public function getClasses() {
75 return $this->classes;
76 }
77
78 public function setID($id) {
79 $this->id = $id;
80 return $this;
81 }
82
83 public function getID() {
84 return $this->id;
85 }
86
87 protected function getTagName() {
88 return 'div';
89 }
90
91 protected function getTagAttributes() {
92 return array();
93 }
94
95 protected function getTagContent() {
96 return $this->renderChildren();
97 }
98
99 final public function render() {
100 $this->willRender();
101
102 // A tag view may render no tag at all. For example, the HandleListView is
103 // a container which renders a tag in HTML mode, but can also render in
104 // text mode without producing a tag. When a tag view has no tag name, just
105 // return the tag content as though the view did not exist.
106 $tag_name = $this->getTagName();
107 if ($tag_name === null) {
108 return $this->getTagContent();
109 }
110
111 $attributes = $this->getTagAttributes();
112
113 $implode = array('class', 'sigil');
114 foreach ($implode as $attr) {
115 if (isset($attributes[$attr])) {
116 if (is_array($attributes[$attr])) {
117 $attributes[$attr] = implode(' ', $attributes[$attr]);
118 }
119 }
120 }
121
122 if (!is_array($attributes)) {
123 $class = get_class($this);
124 throw new Exception(
125 pht("View '%s' did not return an array from getTagAttributes()!",
126 $class));
127 }
128
129 $sigils = $this->sigils;
130 if ($this->workflow) {
131 $sigils[] = 'workflow';
132 }
133
134 $tag_view_attributes = array(
135 'id' => $this->id,
136
137 'class' => implode(' ', $this->classes),
138 'style' => $this->style,
139
140 'meta' => $this->metadata,
141 'sigil' => $sigils ? implode(' ', $sigils) : null,
142 'mustcapture' => $this->mustCapture,
143 );
144
145 foreach ($tag_view_attributes as $key => $value) {
146 if ($value === null) {
147 continue;
148 }
149 if (!isset($attributes[$key])) {
150 $attributes[$key] = $value;
151 continue;
152 }
153 switch ($key) {
154 case 'class':
155 case 'sigil':
156 $attributes[$key] = $attributes[$key].' '.$value;
157 break;
158 default:
159 // Use the explicitly set value rather than the tag default value.
160 $attributes[$key] = $value;
161 break;
162 }
163 }
164
165 return javelin_tag(
166 $tag_name,
167 $attributes,
168 $this->getTagContent());
169 }
170}