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

epriestley's avatar
epriestley committed
3
4
5
/**
 * @group phriction
 */
6
final class PhrictionEditController
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  extends PhrictionController {

  private $id;

  public function willProcessRequest(array $data) {
    $this->id = idx($data, 'id');
  }

  public function processRequest() {

    $request = $this->getRequest();
    $user = $request->getUser();

    if ($this->id) {
      $document = id(new PhrictionDocument())->load($this->id);
      if (!$document) {
        return new Aphront404Response();
      }
epriestley's avatar
epriestley committed
25
26
27
28
29
30
31
32
33
34
35
36
37

      $revert = $request->getInt('revert');
      if ($revert) {
        $content = id(new PhrictionContent())->loadOneWhere(
          'documentID = %d AND version = %d',
          $document->getID(),
          $revert);
        if (!$content) {
          return new Aphront404Response();
        }
      } else {
        $content = id(new PhrictionContent())->load($document->getContentID());
      }
38
39
40

    } else {
      $slug = $request->getStr('slug');
Bob Trahan's avatar
Bob Trahan committed
41
      $slug = PhabricatorSlug::normalize($slug);
42
43
44
45
      if (!$slug) {
        return new Aphront404Response();
      }

46
47
48
      $document = id(new PhrictionDocument())->loadOneWhere(
        'slug = %s',
        $slug);
49
50
51
52

      if ($document) {
        $content = id(new PhrictionContent())->load($document->getContentID());
      } else {
53
        if (PhrictionDocument::isProjectSlug($slug)) {
54
55
56
57
58
          $project = id(new PhabricatorProjectQuery())
            ->setViewer($user)
            ->withPhrictionSlugs(array(
              PhrictionDocument::getProjectSlugIdentifier($slug)))
            ->executeOne();
59
60
61
62
          if (!$project) {
            return new Aphront404Response();
          }
        }
63
64
65
66
67
68
        $document = new PhrictionDocument();
        $document->setSlug($slug);

        $content  = new PhrictionContent();
        $content->setSlug($slug);

Bob Trahan's avatar
Bob Trahan committed
69
        $default_title = PhabricatorSlug::getDefaultTitle($slug);
70
71
72
73
        $content->setTitle($default_title);
      }
    }

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
    if ($request->getBool('nodraft')) {
      $draft = null;
      $draft_key = null;
    } else {
      if ($document->getPHID()) {
        $draft_key = $document->getPHID().':'.$content->getVersion();
      } else {
        $draft_key = 'phriction:'.$content->getSlug();
      }
      $draft = id(new PhabricatorDraft())->loadOneWhere(
        'authorPHID = %s AND draftKey = %s',
        $user->getPHID(),
        $draft_key);
    }

89
90
    require_celerity_resource('phriction-document-css');

91
    $e_title = true;
92
    $notes = null;
93
94
95
    $errors = array();

    if ($request->isFormPost()) {
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

      $overwrite = $request->getBool('overwrite');
      if (!$overwrite) {
        $edit_version = $request->getStr('contentVersion');
        $current_version = $content->getVersion();
        if ($edit_version != $current_version) {
          $dialog = $this->newDialog()
            ->setTitle(pht('Edit Conflict!'))
            ->appendParagraph(
              pht(
                'Another user made changes to this document after you began '.
                'editing it. Do you want to overwrite their changes?'))
            ->appendParagraph(
              pht(
                'If you choose to overwrite their changes, you should review '.
                'the document edit history to see what you overwrote, and '.
                'then make another edit to merge the changes if necessary.'))
            ->addSubmitButton(pht('Overwrite Changes'))
            ->addCancelButton($request->getRequestURI());

          $dialog->addHiddenInput('overwrite', 'true');
          foreach ($request->getPassthroughRequestData() as $key => $value) {
            $dialog->addHiddenInput($key, $value);
          }

          return $dialog;
        }
      }


126
      $title = $request->getStr('title');
127
      $notes = $request->getStr('description');
128
129

      if (!strlen($title)) {
Chad Little's avatar
Chad Little committed
130
131
        $e_title = pht('Required');
        $errors[] = pht('Document title is required.');
132
133
134
135
      } else {
        $e_title = null;
      }

136
137
138
139
140
141
      if ($document->getID()) {
        if ($content->getTitle() == $title &&
            $content->getContent() == $request->getStr('content')) {

          $dialog = new AphrontDialogView();
          $dialog->setUser($user);
Chad Little's avatar
Chad Little committed
142
          $dialog->setTitle(pht('No Edits'));
epriestley's avatar
epriestley committed
143
144
          $dialog->appendChild(phutil_tag('p', array(), pht(
            'You did not make any changes to the document.')));
145
146
147
148
          $dialog->addCancelButton($request->getRequestURI());

          return id(new AphrontDialogResponse())->setDialog($dialog);
        }
149
150
151
152
153
154
155
      } else if (!strlen($request->getStr('content'))) {

        // We trigger this only for new pages. For existing pages, deleting
        // all the content counts as deleting the page.

        $dialog = new AphrontDialogView();
        $dialog->setUser($user);
Chad Little's avatar
Chad Little committed
156
        $dialog->setTitle(pht('Empty Page'));
epriestley's avatar
epriestley committed
157
158
        $dialog->appendChild(phutil_tag('p', array(), pht(
          'You can not create an empty document.')));
159
160
161
        $dialog->addCancelButton($request->getRequestURI());

        return id(new AphrontDialogResponse())->setDialog($dialog);
162
163
      }

164
      if (!count($errors)) {
165
        $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))
166
          ->setActor($user)
167
168
          ->setTitle($title)
          ->setContent($request->getStr('content'))
169
          ->setDescription($notes);
170

171
        $editor->save();
172

173
174
175
176
        if ($draft) {
          $draft->delete();
        }

177
        $uri = PhrictionDocument::getSlugURI($document->getSlug());
178
179
180
181
182
        return id(new AphrontRedirectResponse())->setURI($uri);
      }
    }

    if ($document->getID()) {
Chad Little's avatar
Chad Little committed
183
184
      $panel_header = pht('Edit Phriction Document');
      $submit_button = pht('Save Changes');
185
    } else {
Chad Little's avatar
Chad Little committed
186
187
      $panel_header = pht('Create New Phriction Document');
      $submit_button = pht('Create Document');
188
189
190
191
192
193
    }

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

194
195
    $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());

196
197
198
199
200
    if ($draft &&
        strlen($draft->getDraft()) &&
        ($draft->getDraft() != $content->getContent())) {
      $content_text = $draft->getDraft();

201
      $discard = phutil_tag(
202
203
204
205
        'a',
        array(
          'href' => $request->getRequestURI()->alter('nodraft', true),
        ),
Chad Little's avatar
Chad Little committed
206
        pht('discard this draft'));
207
208
209
210

      $draft_note = new AphrontErrorView();
      $draft_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
      $draft_note->setTitle('Recovered Draft');
vrana's avatar
vrana committed
211
212
213
      $draft_note->appendChild(hsprintf(
        '<p>Showing a saved draft of your edits, you can %s.</p>',
        $discard));
214
215
216
217
218
    } else {
      $content_text = $content->getContent();
      $draft_note = null;
    }

219
220
    $form = id(new AphrontFormView())
      ->setUser($user)
221
      ->setWorkflow(true)
222
      ->setAction($request->getRequestURI()->getPath())
223
      ->addHiddenInput('slug', $document->getSlug())
224
      ->addHiddenInput('nodraft', $request->getBool('nodraft'))
225
      ->addHiddenInput('contentVersion', $content->getVersion())
226
227
      ->appendChild(
        id(new AphrontFormTextControl())
Chad Little's avatar
Chad Little committed
228
          ->setLabel(pht('Title'))
229
230
231
232
233
          ->setValue($content->getTitle())
          ->setError($e_title)
          ->setName('title'))
      ->appendChild(
        id(new AphrontFormStaticControl())
Chad Little's avatar
Chad Little committed
234
          ->setLabel(pht('URI'))
235
236
          ->setValue($uri))
      ->appendChild(
237
        id(new PhabricatorRemarkupControl())
Chad Little's avatar
Chad Little committed
238
          ->setLabel(pht('Content'))
239
          ->setValue($content_text)
240
          ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
241
          ->setName('content')
242
243
          ->setID('document-textarea')
          ->setUser($user))
244
245
      ->appendChild(
        id(new AphrontFormTextControl())
Chad Little's avatar
Chad Little committed
246
          ->setLabel(pht('Edit Notes'))
247
          ->setValue($notes)
248
249
          ->setError(null)
          ->setName('description'))
250
251
      ->appendChild(
        id(new AphrontFormSubmitControl())
252
          ->addCancelButton($cancel_uri)
253
254
          ->setValue($submit_button));

255
    $form_box = id(new PHUIObjectBoxView())
Chad Little's avatar
Chad Little committed
256
      ->setHeaderText(pht('Edit Document'))
257
      ->setFormErrors($errors)
Chad Little's avatar
Chad Little committed
258
      ->setForm($form);
259

260
261
262
263
264
    $preview = id(new PHUIRemarkupPreviewPanel())
      ->setHeader(pht('Document Preview'))
      ->setPreviewURI('/phriction/preview/')
      ->setControlID('document-textarea')
      ->setSkin('document');
265

266
267
    $crumbs = $this->buildApplicationCrumbs();
    if ($document->getID()) {
268
269
270
271
      $crumbs->addTextCrumb(
        $content->getTitle(),
        PhrictionDocument::getSlugURI($document->getSlug()));
      $crumbs->addTextCrumb(pht('Edit'));
272
    } else {
273
      $crumbs->addTextCrumb(pht('Create'));
274
275
    }

Chad Little's avatar
Chad Little committed
276
    return $this->buildApplicationPage(
277
      array(
278
        $crumbs,
279
        $draft_note,
Chad Little's avatar
Chad Little committed
280
        $form_box,
281
        $preview,
282
283
      ),
      array(
Chad Little's avatar
Chad Little committed
284
285
        'title'   => pht('Edit Document'),
        'device'  => true,
286
287
288
289
      ));
  }

}