PhrictionEditController.php 9.66 KB
Newer Older
1
2
<?php

3
final class PhrictionEditController
4
5
  extends PhrictionController {

6
7
8
  public function handleRequest(AphrontRequest $request) {
    $viewer = $request->getViewer();
    $id = $request->getURIData('id');
9

10
    $max_version = null;
11
    if ($id) {
12
      $is_new = false;
13
      $document = id(new PhrictionDocumentQuery())
14
15
        ->setViewer($viewer)
        ->withIDs(array($id))
16
        ->needContent(true)
17
18
19
20
21
22
        ->requireCapabilities(
          array(
            PhabricatorPolicyCapability::CAN_VIEW,
            PhabricatorPolicyCapability::CAN_EDIT,
          ))
        ->executeOne();
23
24
25
      if (!$document) {
        return new Aphront404Response();
      }
epriestley's avatar
epriestley committed
26

27
      $max_version = $document->getMaxVersion();
28

epriestley's avatar
epriestley committed
29
30
      $revert = $request->getInt('revert');
      if ($revert) {
31
32
33
34
35
        $content = id(new PhrictionContentQuery())
          ->setViewer($viewer)
          ->withDocumentPHIDs(array($document->getPHID()))
          ->withVersions(array($revert))
          ->executeOne();
epriestley's avatar
epriestley committed
36
37
38
39
        if (!$content) {
          return new Aphront404Response();
        }
      } else {
40
41
42
43
44
        $content = id(new PhrictionContentQuery())
          ->setViewer($viewer)
          ->withDocumentPHIDs(array($document->getPHID()))
          ->setLimit(1)
          ->executeOne();
epriestley's avatar
epriestley committed
45
      }
46
47
    } else {
      $slug = $request->getStr('slug');
Bob Trahan's avatar
Bob Trahan committed
48
      $slug = PhabricatorSlug::normalize($slug);
49
50
51
52
      if (!$slug) {
        return new Aphront404Response();
      }

53
      $document = id(new PhrictionDocumentQuery())
54
        ->setViewer($viewer)
55
56
57
        ->withSlugs(array($slug))
        ->needContent(true)
        ->executeOne();
58
59

      if ($document) {
60
61
62
63
64
65
66
        $content = id(new PhrictionContentQuery())
          ->setViewer($viewer)
          ->withDocumentPHIDs(array($document->getPHID()))
          ->setLimit(1)
          ->executeOne();

        $max_version = $document->getMaxVersion();
67
        $is_new = false;
68
      } else {
69
        $document = PhrictionDocument::initializeNewDocument($viewer, $slug);
70
        $content = $document->getContent();
71
        $is_new = true;
72
73
74
      }
    }

75
76
    require_celerity_resource('phriction-document-css');

77
    $e_title = true;
78
79
    $e_content = true;
    $validation_exception = null;
80
    $notes = null;
81
82
    $title = $content->getTitle();
    $overwrite = false;
Chad Little's avatar
Chad Little committed
83
84
    $v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID(
      $document->getPHID());
85

86
87
88
89
90
91
92
93
94
    if ($is_new) {
      $v_projects = array();
    } else {
      $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
        $document->getPHID(),
        PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
      $v_projects = array_reverse($v_projects);
    }

epriestley's avatar
epriestley committed
95
96
    $v_space = $document->getSpacePHID();

97
98
    $content_text = $content->getContent();

99
    if ($request->isFormPost()) {
100

101
      $title = $request->getStr('title');
102
      $content_text = $request->getStr('content');
103
      $notes = $request->getStr('description');
104
      $max_version = $request->getInt('contentVersion');
105
106
      $v_view = $request->getStr('viewPolicy');
      $v_edit = $request->getStr('editPolicy');
107
108
      $v_cc = $request->getArr('cc');
      $v_projects = $request->getArr('projects');
epriestley's avatar
epriestley committed
109
      $v_space = $request->getStr('spacePHID');
110
111
112

      $xactions = array();
      $xactions[] = id(new PhrictionTransaction())
113
        ->setTransactionType(PhrictionDocumentTitleTransaction::TRANSACTIONTYPE)
114
115
        ->setNewValue($title);
      $xactions[] = id(new PhrictionTransaction())
116
117
        ->setTransactionType(
          PhrictionDocumentContentTransaction::TRANSACTIONTYPE)
118
        ->setNewValue($content_text);
119
120
121
122
123
124
      $xactions[] = id(new PhrictionTransaction())
        ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
        ->setNewValue($v_view);
      $xactions[] = id(new PhrictionTransaction())
        ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
        ->setNewValue($v_edit);
epriestley's avatar
epriestley committed
125
126
127
      $xactions[] = id(new PhrictionTransaction())
        ->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
        ->setNewValue($v_space);
Chad Little's avatar
Chad Little committed
128
129
130
      $xactions[] = id(new PhrictionTransaction())
        ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
        ->setNewValue(array('=' => $v_cc));
131

132
133
134
135
136
137
      $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
      $xactions[] = id(new PhrictionTransaction())
        ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
        ->setMetadataValue('edge:type', $proj_edge_type)
        ->setNewValue(array('=' => array_fuse($v_projects)));

138
      $editor = id(new PhrictionTransactionEditor())
139
        ->setActor($viewer)
140
141
142
143
        ->setContentSourceFromRequest($request)
        ->setContinueOnNoEffect(true)
        ->setDescription($notes)
        ->setProcessContentVersionError(!$request->getBool('overwrite'))
144
        ->setContentVersion($max_version);
145
146
147

      try {
        $editor->applyTransactions($document, $xactions);
148

149
        $uri = PhrictionDocument::getSlugURI($document->getSlug());
150
        return id(new AphrontRedirectResponse())->setURI($uri);
151
152
      } catch (PhabricatorApplicationTransactionValidationException $ex) {
        $validation_exception = $ex;
153
        $e_title = nonempty(
154
155
          $ex->getShortMessage(
            PhrictionDocumentTitleTransaction::TRANSACTIONTYPE),
156
157
          true);
        $e_content = nonempty(
158
159
          $ex->getShortMessage(
            PhrictionDocumentContentTransaction::TRANSACTIONTYPE),
160
          true);
161
162
163
164
165
166
167

        // if we're not supposed to process the content version error, then
        // overwrite that content...!
        if (!$editor->getProcessContentVersionError()) {
          $overwrite = true;
        }

168
169
        $document->setViewPolicy($v_view);
        $document->setEditPolicy($v_edit);
epriestley's avatar
epriestley committed
170
        $document->setSpacePHID($v_space);
171
172
173
174
      }
    }

    if ($document->getID()) {
175
      $page_title = pht('Edit Document: %s', $content->getTitle());
176
177
178
179
180
      if ($overwrite) {
        $submit_button = pht('Overwrite Changes');
      } else {
        $submit_button = pht('Save Changes');
      }
181
    } else {
Chad Little's avatar
Chad Little committed
182
      $submit_button = pht('Create Document');
183
      $page_title = pht('Create Document');
184
185
186
187
188
189
    }

    $uri = $document->getSlug();
    $uri = PhrictionDocument::getSlugURI($uri);
    $uri = PhabricatorEnv::getProductionURI($uri);

190
191
    $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());

192
    $policies = id(new PhabricatorPolicyQuery())
193
      ->setViewer($viewer)
194
195
196
197
      ->setObject($document)
      ->execute();
    $view_capability = PhabricatorPolicyCapability::CAN_VIEW;
    $edit_capability = PhabricatorPolicyCapability::CAN_EDIT;
198

199

200
    $form = id(new AphrontFormView())
201
      ->setUser($viewer)
202
      ->addHiddenInput('slug', $document->getSlug())
203
      ->addHiddenInput('contentVersion', $max_version)
204
      ->addHiddenInput('overwrite', $overwrite)
205
206
      ->appendChild(
        id(new AphrontFormTextControl())
Chad Little's avatar
Chad Little committed
207
          ->setLabel(pht('Title'))
208
          ->setValue($title)
209
210
211
212
          ->setError($e_title)
          ->setName('title'))
      ->appendChild(
        id(new AphrontFormStaticControl())
Chad Little's avatar
Chad Little committed
213
          ->setLabel(pht('URI'))
214
215
          ->setValue($uri))
      ->appendChild(
216
        id(new PhabricatorRemarkupControl())
Chad Little's avatar
Chad Little committed
217
          ->setLabel(pht('Content'))
218
          ->setValue($content_text)
219
          ->setError($e_content)
220
          ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
221
          ->setName('content')
222
          ->setID('document-textarea')
223
          ->setUser($viewer))
224
225
      ->appendControl(
        id(new AphrontFormTokenizerControl())
Luke081515's avatar
Luke081515 committed
226
          ->setLabel(pht('Tags'))
227
228
229
          ->setName('projects')
          ->setValue($v_projects)
          ->setDatasource(new PhabricatorProjectDatasource()))
Chad Little's avatar
Chad Little committed
230
231
232
233
234
235
236
      ->appendControl(
        id(new AphrontFormTokenizerControl())
          ->setLabel(pht('Subscribers'))
          ->setName('cc')
          ->setValue($v_cc)
          ->setUser($viewer)
          ->setDatasource(new PhabricatorMetaMTAMailableDatasource()))
237
238
      ->appendChild(
        id(new AphrontFormPolicyControl())
epriestley's avatar
epriestley committed
239
          ->setViewer($viewer)
240
          ->setName('viewPolicy')
epriestley's avatar
epriestley committed
241
          ->setSpacePHID($v_space)
242
243
          ->setPolicyObject($document)
          ->setCapability($view_capability)
244
          ->setPolicies($policies))
245
246
247
248
249
      ->appendChild(
        id(new AphrontFormPolicyControl())
          ->setName('editPolicy')
          ->setPolicyObject($document)
          ->setCapability($edit_capability)
250
          ->setPolicies($policies))
251
252
      ->appendChild(
        id(new AphrontFormTextControl())
Chad Little's avatar
Chad Little committed
253
          ->setLabel(pht('Edit Notes'))
254
          ->setValue($notes)
255
256
          ->setError(null)
          ->setName('description'))
257
258
      ->appendChild(
        id(new AphrontFormSubmitControl())
259
          ->addCancelButton($cancel_uri)
260
261
          ->setValue($submit_button));

262
    $form_box = id(new PHUIObjectBoxView())
263
      ->setHeaderText($page_title)
264
      ->setValidationException($validation_exception)
265
      ->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
Chad Little's avatar
Chad Little committed
266
      ->setForm($form);
267

268
    $preview = id(new PHUIRemarkupPreviewPanel())
269
      ->setHeader($content->getTitle())
270
      ->setPreviewURI('/phriction/preview/'.$document->getSlug())
271
      ->setControlID('document-textarea')
272
      ->setPreviewType(PHUIRemarkupPreviewPanel::DOCUMENT);
273

274
275
    $crumbs = $this->buildApplicationCrumbs();
    if ($document->getID()) {
276
277
278
279
      $crumbs->addTextCrumb(
        $content->getTitle(),
        PhrictionDocument::getSlugURI($document->getSlug()));
      $crumbs->addTextCrumb(pht('Edit'));
280
    } else {
281
      $crumbs->addTextCrumb(pht('Create'));
282
    }
283
    $crumbs->setBorder(true);
284

285
    $view = id(new PHUITwoColumnView())
286
287
288
289
290
      ->setFooter(
        array(
          $form_box,
          $preview,
        ));
291
292
293
294
295

    return $this->newPage()
      ->setTitle($page_title)
      ->setCrumbs($crumbs)
      ->appendChild($view);
296
297
298
  }

}