code: protected function saveAndRedirect($data, $form, $redirectLink)
      {
          $new_record = $this->owner->record->ID == 0;
          $controller = Controller::curr();
          $list = $this->owner->gridField->getList();
  
          if ($list instanceof ManyManyList) {
              // Data is escaped in ManyManyList->add()
              $extraData = (isset($data['ManyMany'])) ? $data['ManyMany'] : null;
          } else {
              $extraData = null;
          }
  
          if (!$this->owner->record->canEdit()) {
              return $controller->httpError(403);
          }
  
          try {
              $form->saveInto($this->owner->record);
              $this->owner->record->write();
              $list->add($this->owner->record, $extraData);
          } catch (ValidationException $e) {
              $form->sessionMessage($e->getResult()->message(), 'bad');
              $responseNegotiator = new PjaxResponseNegotiator(array(
                  'CurrentForm' => function () use ($form) {
                      return $form->forTemplate();
                  },
                  'default' => function () use ($controller) {
                      return $controller->redirectBack();
                  }
              ));
              if ($controller->getRequest()->isAjax()) {
                  $controller->getRequest()->addHeader('X-Pjax', 'CurrentForm');
              }
              return $responseNegotiator->respond($controller->getRequest());
          }
  
          return Controller::curr()->redirect($redirectLink);
      }
docs: Oh, the horror! DRY police be advised. This function is a serious offender.
  Saves the form data and redirects to a given link
  
  @param array  $data         The form data
  @param Form   $form         The form object
  @param string $redirectLink The redirect link
  @todo  GridFieldDetailForm_ItemRequest::doSave is too monolithic, making overloading impossible. Most
  of this code is a direct copy.