@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
3final class AphrontMultiColumnView extends AphrontView {
4
5 const GUTTER_SMALL = 'msr';
6 const GUTTER_MEDIUM = 'mmr';
7 const GUTTER_LARGE = 'mlr';
8
9 private $id;
10 private $columns = array();
11 private $fluidLayout = false;
12 private $fluidishLayout = false;
13 private $gutter;
14 private $border;
15
16 public function setID($id) {
17 $this->id = $id;
18 return $this;
19 }
20
21 public function getID() {
22 return $this->id;
23 }
24
25 public function addColumn(
26 $column,
27 $class = null,
28 $sigil = null,
29 $metadata = null) {
30 $this->columns[] = array(
31 'column' => $column,
32 'class' => $class,
33 'sigil' => $sigil,
34 'metadata' => $metadata,
35 );
36 return $this;
37 }
38
39 public function setFluidlayout($layout) {
40 $this->fluidLayout = $layout;
41 return $this;
42 }
43
44 public function setFluidishLayout($layout) {
45 $this->fluidLayout = true;
46 $this->fluidishLayout = $layout;
47 return $this;
48 }
49
50 public function setGutter($gutter) {
51 $this->gutter = $gutter;
52 return $this;
53 }
54
55 public function setBorder($border) {
56 $this->border = $border;
57 return $this;
58 }
59
60 public function render() {
61 require_celerity_resource('aphront-multi-column-view-css');
62
63 $classes = array();
64 $classes[] = 'aphront-multi-column-inner';
65 $classes[] = 'grouped';
66
67 if ($this->fluidishLayout || $this->fluidLayout) {
68 // we only support seven columns for now for fluid views; see T4054
69 if (count($this->columns) > 7) {
70 throw new Exception(pht('No more than 7 columns per view.'));
71 }
72 }
73
74 $classes[] = 'aphront-multi-column-'.count($this->columns).'-up';
75
76 $columns = array();
77 $i = 0;
78 foreach ($this->columns as $column_data) {
79 $column_class = array('aphront-multi-column-column');
80 if ($this->gutter) {
81 $column_class[] = $this->gutter;
82 }
83 $outer_class = array('aphront-multi-column-column-outer');
84 if (++$i === count($this->columns)) {
85 $column_class[] = 'aphront-multi-column-column-last';
86 $outer_class[] = 'aphront-multi-colum-column-outer-last';
87 }
88 $column = $column_data['column'];
89 if ($column_data['class']) {
90 $outer_class[] = $column_data['class'];
91 }
92 $column_sigil = idx($column_data, 'sigil');
93 $column_metadata = idx($column_data, 'metadata');
94 $column_inner = javelin_tag(
95 'div',
96 array(
97 'class' => implode(' ', $column_class),
98 'sigil' => $column_sigil,
99 'meta' => $column_metadata,
100 ),
101 $column);
102 $columns[] = phutil_tag(
103 'div',
104 array(
105 'class' => implode(' ', $outer_class),
106 ),
107 $column_inner);
108 }
109
110 $view = phutil_tag(
111 'div',
112 array(
113 'class' => implode(' ', $classes),
114 ),
115 array(
116 $columns,
117 ));
118
119 $classes = array();
120 $classes[] = 'aphront-multi-column-outer';
121 if ($this->fluidLayout) {
122 $classes[] = 'aphront-multi-column-fluid';
123 if ($this->fluidishLayout) {
124 $classes[] = 'aphront-multi-column-fluidish';
125 }
126 } else {
127 $classes[] = 'aphront-multi-column-fixed';
128 }
129
130 $board = phutil_tag(
131 'div',
132 array(
133 'class' => implode(' ', $classes),
134 ),
135 $view);
136
137 if ($this->border) {
138 $board = id(new PHUIBoxView())
139 ->setBorder(true)
140 ->appendChild($board)
141 ->addPadding(PHUI::PADDING_MEDIUM_TOP)
142 ->addPadding(PHUI::PADDING_MEDIUM_BOTTOM);
143 }
144
145 return javelin_tag(
146 'div',
147 array(
148 'class' => 'aphront-multi-column-view',
149 'id' => $this->getID(),
150 // TODO: It would be nice to convert this to an AphrontTagView and
151 // use addSigil() from Workboards instead of hard-coding this.
152 'sigil' => 'aphront-multi-column-view',
153 ),
154 $board);
155 }
156}