foldershare-8.x-1.2/src/Form/EditFolderShare.php

src/Form/EditFolderShare.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
<?php
 
namespace Drupal\foldershare\Form;
 
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
use Drupal\foldershare\Constants;
use Drupal\foldershare\ManageLog;
use Drupal\foldershare\Entity\FolderShare;
 
/**
 * Defines a user form for editing folder share entity fields.
 *
 * The form presents the current values of all fields, except
 * for the name and other internal fields. The set of fields
 * shown always includes the description. Additional fields may
 * include the language choice, if the Drupal core Languages module
 * is enabled, plus any other fields a site has added to the folder type.
 *
 * The user is prompted to change any of the presented fields. A 'Save'
 * button triggers the form and saves the edits.
 *
 * <b>Access control:</b>
 * The route to this form must invoke the access control handler to
 * insure that the user is the admin or the owner of the folder subject.
 *
 * <b>Route:</b>
 * The route to this form must include a $foldershare argument.
 *
 * <B>Warning:</B> This class is strictly internal to the FolderShare
 * module. The class's existance, name, and content may change from
 * release to release without any promise of backwards compatability.
 *
 * @ingroup foldershare
 */
final class EditFolderShare extends ContentEntityForm {
 
  /*---------------------------------------------------------------------
   *
   * Form.
   *
   *---------------------------------------------------------------------*/
 
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return str_replace('\\', '_', get_class($this));
  }
 
  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $formState) {
    //
    // Validate.
    // ---------
    // Hidden and disabled items cannot be edited.
    $item = $this->getEntity();
 
    if ($item->isSystemHidden() === TRUE) {
      // Hidden items do not exist.
      throw new NotFoundHttpException(
        FolderShare::getStandardHiddenMessage($item->getName()));
    }
 
    if ($item->isSystemDisabled() === TRUE) {
      // Disabled items cannot be edited.
      throw new ConflictHttpException(
        FolderShare::getStandardDisabledMessage('edited', $item->getName()));
    }
 
    //
    // Setup
    // -----
    // Let the parent class build the default form for the entity.
    // The form may include any editable fields accessible by the
    // current user. This will not include the name field, or other
    // internal fields, which are blocked from being listed by
    // the base field definitions for the Folder entity.
    //
    // The order of fields on the form will honor the site's choices
    // via the field_ui.
    //
    // The EntityForm parent class automatically adds a 'Save' button
    // to submit the form.
    $form = parent::form($form, $formState);
 
    $form['#title'] = $this->t(
      'Edit "@name"',
      [
        '@name' => $item->getName(),
      ]);
 
    //
    // Do NOT acquire a process lock.
    // ------------------------------
    // Normally, edit operations on a FolderShare entity should acquire
    // a process lock on the entity's root folder tree in order to prevent
    // other edit operations from modifying the entity at the same time.
    //
    // However, the edit form requests user input and users can take a
    // long time to edit a description or other fields. They can also
    // abort and close the window or back up to another page. We cannot
    // hold a lock for all of that time.
    //
    // Instead, we do not acquire any locks on presentation of the form.
    // Later, during a save of the form's results, locking will resolve
    // any potential conflicts.
    return $form;
  }
 
  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $formState) {
    // The parent classes handle creating an un-saved entity:
    //
    // - The form controller call's the form's getEntityFromRouteMatch()
    //   to get the entity ID from the URL and load it.
    //
    // - On form submit, submitForm() calls buildEntity() to build
    //   an entity object, which it then sets as the form's entity
    //   available via getEntity().
    //
    // - buildEntity() clones the loaded entity and copies the form's
    //   values into it, but does not save it.
    //
    // - On form submit, after calling submitForm(), save() is called to
    //   save the updated entity. The parent class just calls entity save().
    //
    // If the entity has been deleted by another process during the edit,
    // then getEntityFromRouteMatch() earlier will have failed with a
    // NotFoundHttpException. This doesn't explain much to the user, but
    // it is correct.
    //
    // If the entity has been changed by another process during the edit,
    // then those changes are in the loaded entity. buildEntity() will
    // have overwritten any of those fields that are in this edit form.
    // Since key internal fields cannot be in an edit form, systemhidden,
    // systemdisabled, parentid, rootid, uid, etc., are all unchanged from the
    // loaded entity.
    $item = $this->getEntity();
 
    //
    // Validate.
    // ---------
    // If the entity has been marked as hidden or disabled by another process
    // during the edit, then the edit has to be rejected.
    //
    // Hidden entities are being deleted, so it doesn't make sense to set
    // fields in an entity that is doomed.
    //
    // Disabled entities are being moved, copied, or having their ownership
    // changed. If we save this entity, it could overwrite whatever change
    // is in progress.
    if ($item->isSystemHidden() === TRUE) {
      // Hidden items do not exist.
      throw new NotFoundHttpException(
        FolderShare::getStandardHiddenMessage($item->getName()));
    }
 
    if ($item->isSystemDisabled() === TRUE) {
      // Disabled items cannot be edited.
      throw new ConflictHttpException(
        FolderShare::getStandardDisabledMessage('saved', $item->getName()));
    }
 
    //
    // Lock.
    // -----
    // Another process could be working on the root folder tree that
    // contains this entity. They could be working on this entity itself.
    // If we save the entity without a lock, we could collide.
    //
    // For example, imagine that a change ownership operation is in progress
    // on the folder containing this entity. The loaded entity in hand doesn't
    // have the new owner ID yet. The other process, which has a lock on
    // the root folder tree, traverses down past this entity and sets and
    // saves the owner ID, acting under the belief that it has an exclusive
    // lock on all entities in the folder tree. And now, here, we just save
    // the edited entity back to the database without getting a lock first.
    // We'll overwrite the entity and lose the ownership change just made,
    // causing a file system corruption.
    //
    // So, we MUST lock before saving the changed entity.
    $rootId = $item->getRootItemId();
    if (FolderShare::acquireRootOperationLock($rootId) === FALSE) {
      // Lock failed. There is another operation in progress.
      // We cannot save this entity now. The user can hit their browser's
      // BACK button and most browsers will have saved all field values
      // in the edit form. They can then try to save again and, hopefully,
      // the lock will be done by then.
      throw new ConflictHttpException(
        FolderShare::getStandardLockMessage('saved', $item->getName()));
    }
 
    // Save
    // -----
    // The parent class handles saving the entity.
    parent::save($form, $formState);
 
    //
    // Unlock.
    // -------
    // We're done with the save. Unlock.
    FolderShare::releaseRootOperationLock($rootId);
 
    //
    // Hook & log.
    // -----------
    // Announce the change.
    FolderShare::postOperationHook(
      'edit',
      [
        $item,
        \Drupal::currentUser()->id(),
      ]);
    ManageLog::activity(
      "Edited @kind '@name' (# @id).",
      [
        '@id'      => $item->id(),
        '@kind'    => $item->getKind(),
        '@name'    => $item->getName(),
        'entity'   => $item,
        'uid'      => \Drupal::currentUser()->id(),
      ]);
 
    //
    // Redirect
    // --------
    // Return to the view page for the folder.
    $formState->setRedirect(
      Constants::ROUTE_FOLDERSHARE,
      [
        Constants::ROUTE_FOLDERSHARE_ID => $item->id(),
      ]);
  }
 
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc