Reproduce steps:
- Install drupal8.6 and group;1.x-dev and commerce
- Create group_content:commerce_promotion plugin use these code
/** * Provides a content enabler for nodes. * * @GroupContentEnabler( * id = "group_promotion", * label = @Translation("Group promotion"), * description = @Translation("Adds promotion to groups both publicly and privately."), * entity_type_id = "commerce_promotion", * entity_access = TRUE, * reference_label = @Translation("Title"), * reference_description = @Translation("The title of the promotion to add to the group"), * ) */ class GroupPromotion extends GroupContentEnablerBase { }
- Create a group_content-commerce_promotion, when click save, the site crash
The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Drupal\Core\Entity\Exception\UndefinedLinkTemplateException</em>: No link template 'canonical' found for the 'commerce_promotion' entity type in <em class="placeholder">Drupal\Core\Entity\Entity->toUrl()</em> (line <em class="placeholder">224</em> of <em class="placeholder">core/lib/Drupal/Core/Entity/Entity.php</em>). <pre class="backtrace">group_content_entity_submit(Array, Object) call_user_func_array('group_content_entity_submit', Array) (Line: 111) Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 51) Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 589) Drupal\Core\Form\FormBuilder->processForm('commerce_promotion_add_form', Array, Object) (Line: 318) Drupal\Core\Form\FormBuilder->buildForm('commerce_promotion_add_form', Object) (Line: 48) Drupal\Core\Entity\EntityFormBuilder->getForm(Object, 'add', Array) (Line: 361) Drupal\group\Entity\Controller\GroupContentController->createForm(Object, 'group_promotion') call_user_func_array(Array, Array) (Line: 123) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 582) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 67) Drupal\simple_oauth\HttpMiddleware\BasicAuthSwap->handle(Object, 1, 1) (Line: 57) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99) Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 41) Drupal\jsonapi\StackMiddleware\FormatSetter->handle(Object, 1, 1) (Line: 47) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 38) Drupal\webprofiler\StackMiddleware\WebprofilerMiddleware->handle(Object, 1, 1) (Line: 52) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23) Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 665) Drupal\Core\DrupalKernel->handle(Object) (Line: 19) </pre>
The error caused here:
group.module
if ($entity->access('view')) {
$form_state->setRedirectUrl($entity->toUrl());
}
Let's see the code of $entity->toUrl() (\Drupal\Core\Entity\Entity).
public function toUrl($rel = 'canonical', array $options = []) {
if ($this->id() === NULL) {
throw new EntityMalformedException(sprintf('The "%s" entity cannot have a URI as it does not have an ID', $this->getEntityTypeId()));
}
// The links array might contain URI templates set in annotations.
$link_templates = $this->linkTemplates();
// Links pointing to the current revision point to the actual entity. So
// instead of using the 'revision' link, use the 'canonical' link.
if ($rel === 'revision'&& $this instanceof RevisionableInterface && $this->isDefaultRevision()) {
$rel = 'canonical';
}
if (isset($link_templates[$rel])) {
$route_parameters = $this->urlRouteParameters($rel);
$route_name = "entity.{$this->entityTypeId}." . str_replace(['-', 'drupal:'], ['_', ''], $rel);
$uri = new Url($route_name, $route_parameters);
}
else {
$bundle = $this->bundle();
// A bundle-specific callback takes precedence over the generic one for
// the entity type.
$bundles = $this->entityTypeBundleInfo()->getBundleInfo($this->getEntityTypeId());
if (isset($bundles[$bundle]['uri_callback'])) {
$uri_callback = $bundles[$bundle]['uri_callback'];
}
elseif ($entity_uri_callback = $this->getEntityType()->getUriCallback()) {
$uri_callback = $entity_uri_callback;
}
// Invoke the callback to get the URI. If there is no callback, use the
// default URI format.
if (isset($uri_callback) && is_callable($uri_callback)) {
$uri = call_user_func($uri_callback, $this);
}
else {
throw new UndefinedLinkTemplateException("No link template '$rel' found for the '{$this->getEntityTypeId()}' entity type");
}
}
// Pass the entity data through as options, so that alter functions do not
// need to look up this entity again.
$uri
->setOption('entity_type', $this->getEntityTypeId())
->setOption('entity', $this);
// Display links by default based on the current language.
// Link relations that do not require an existing entity should not be
// affected by this entity's language, however.
if (!in_array($rel, ['collection', 'add-page', 'add-form'], TRUE)) {
$options += ['language' => $this->language()];
}
$uri_options = $uri->getOptions();
$uri_options += $options;
return $uri->setOptions($uri_options);
}
If the entity don't have 'canonical' or bundle's uri_callback, then an Exception will be throw out.