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

src/Form/EditFolderShare.php
<?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