Problem/Motivation

ALinks needs to implement TrustedCallbackInterface.

Steps to reproduce

When displaying a page with ALink content on a Drupal 8.9 or 9.0 site, the #post_render is blocked because ALinkPostRenderer does not implement the TrustedCallbackInterface documented in https://drupal.org/node/2966725.

Drupal\Core\Security\UntrustedCallbackException: Render #post_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was Drupal\alinks\AlinkPostRenderer::postRender. See https://www.drupal.org/node/2966725 in Drupal\Core\Render\Renderer->doTrustedCallback() (line 96 of core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php)

https://www.drupal.org/project/alinks/issues/3171893#

Proposed resolution

Implement that interface.

Remaining tasks

User interface changes

None;

API changes

None.

Data model changes

None.

CommentFileSizeAuthor
#2 3171893-trustedcallbackinterface.patch816 bytesfgm

Issue fork alinks-3171893

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

    1 hidden branch
  • 2.x Comparechanges, plain diff MR !4

Comments

fgm created an issue. See original summary.

fgm’s picture

Status: Active » Needs review
StatusFileSize
new816 bytes

Suggested callback, working on 9.0.6 for us.

fgm’s picture

fgm’s picture

Suggested patch, working on 9.0.6.

osopolar’s picture

Fixes the error for me too, on Drupal 9.2

mikogotyk’s picture

hi, any progress on making this official? I can't implement this fix you provided - apparently it has problem with Wamania\Snowboll\English stuff?

fgm’s picture

@mikogotyk can you be more specific regarding the problem you encounter ? I have it in production on Drupal 9.3.12, and there is no Wamania\Snowbol\English class in that site.

Searching a bit further, that does not seem to actually exist, although there is a wamania/php-snowball which is a "Native PHP5 Stemmer" (which requires PHP7.3 per its composer.json ?). Maybe that's what you are referring to. If so, why is it on your site (`composer why wamani? And what is the problem ? At first sight, there does not seem to be any reason for that code to interfere with this patch.

mikogotyk’s picture

Hey, I will try to explain further. I am using Hostinger and Auto-Installer for Drupal so everything is working on host site.

I will try to insert some code here.

So I get this message same as yours:
Drupal\Core\Security\UntrustedCallbackException: Render #post_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was Drupal\alinks\AlinkPostRenderer::postRender. See https://www.drupal.org/node/2966725 in Drupal\Core\Render\Renderer->doTrustedCallback() (line 96 of core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php).

Okay, so I want to fix this. I go to AlinkPostRenderer.php. As you can see below there is Wamania stuff in the code.

namespace Drupal\alinks;

use Drupal\alinks\Entity\Keyword;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\taxonomy\Entity\Term;
use Wamania\Snowball\English;

/**
 * Class AlinkPostRenderer.
 */
class AlinkPostRenderer {

  protected $content;

  protected $keywords;

  protected $existingLinks;

  /**
   * Stemmer.
   *
   * @var \Wamania\Snowball\Stem
   */
  protected $stemmer;

  protected $stemmerCache = [];

  protected $xpathSelector = "//text()[not(ancestor::a) and not(ancestor::script) and not(ancestor::*[@data-alink-ignore])]";

  /**
   * AlinkPostRenderer constructor.
   *
   * @param \Drupal\Core\Render\Markup $content
   *    The content of the current page.
   * @param array $context
   *    The current page context.
   * @param null $xpathSelector
   *    The selector rule for the html.
   */
  public function __construct($content, $context = NULL, $xpathSelector = NULL) {

    if (!empty($context['#entity_type']) && !empty($context['#' . $context['#entity_type']])) {
      $entity = $context['#' . $context['#entity_type']];
      $class = 'Wamania\Snowball\\' . $entity->language()->getName();
      if (class_exists($class)) {
        $this->stemmer = new $class();
      }
      else {
        $this->stemmer = new English();
      }
    }

    $this->content = $content;
    if ($xpathSelector) {
      $this->xpathSelector = $xpathSelector;
    }
  }

As I implemented your solution I get error like this:
The website encountered an unexpected error. Please try again later.
Error: Class 'Wamania\Snowball\English' not found in Drupal\alinks\AlinkPostRenderer->__construct() (line 53 of modules/alinks/src/AlinkPostRenderer.php).

Also in your solution posted 2 years ago there is use case of Wamania.

fgm’s picture

Issue summary: View changes

Ah, I see: wamania\Snowball is a non-standard namespace used by wamania/php-stemmer (probably because wamania\php-stemmer would be invalid for PSR-4), and that appears to break the deployment technique which you are using. Most likely, the autoloader configuration is missing that directory after install.

As you can see, that patch does not change this: that line was already there previously and it did not trigger only because the other error happened first.

Can you try to deploy (at least locally) using a plain Composer deployment ? That should fix your problem.

If you cannot use a normal deployment, you might ask Hostinger for a fix. Since they self-describe as "cutting-edge web hosting provider with over a decade of experience", they should be able to help you with their hosting.

If that still doesn't work, you might try to register the vendor/wamania/php-stemmer/src in the autoloader in your web/sites/default/settings.local.php file with something like this:

$class_loader->addPsr4('Wamania\\Snowball', [ realpath("${app_root}/../vendor/wamania/php-stemmer/src") ]);

Adjust the exact path according to where your vendor directory really is. This example assumes vendor is a sibling of web but it may be located in a different place in a non-standard deployment, maybe under web instead of beside it.

mikogotyk’s picture

Thank you, I will try your solutions out :)

higherform’s picture

I ran into this error message again just now on a D9.4.2 + Alinks 2.0.0 dev install.

Patch from #2 seems to have cured the error.

Any ETA for a release containing this patch?

Thanks

samk11’s picture

After applying the Patch from #2, this error is gone, but a new error appeared for D9.5.10 with latest dev version of Alinks:

TypeError: Drupal\alinks\AlinkPostRenderer::__construct(): Argument #1 ($entity_type_manager) must be of type Drupal\Core\Entity\EntityTypeManagerInterface, Drupal\Core\Render\Markup given, called in /modules/alinks/src/AlinkPostRenderer.php on line 289 in Drupal\alinks\AlinkPostRenderer->__construct() (line 79 of /modules/alinks/src/AlinkPostRenderer.php)

Any ideas?

eeyorr made their first commit to this issue’s fork.

frank.dev’s picture

#12 - same

frank.dev’s picture

Version: 8.x-1.x-dev » 2.x-dev
Issue tags: +Drupal 10

I hope the changes to the metadata are OK. :-)

drupaldope’s picture

same as #12 on Drupal 10.1.6

upgrade bug severity to critical since website becomes inaccessible with this error.

drupaldope’s picture

Priority: Major » Critical
Status: Needs review » Needs work
drupaldope’s picture

okay, so I fixed the security error by changing AlinkPostRenderer.php a little:

TrustedCallbackInterface

...
use Drupal\Core\Security\TrustedCallbackInterface;
...
class AlinkPostRenderer implements TrustedCallbackInterface {

  public static function trustedCallbacks() {
      return ['postRender'];
  }

the security error goes away.

but I now get the error:
Uncaught PHP Exception TypeError: "Drupal\alinks\AlinkPostRenderer::__construct(): Argument #1 ($entity_type_manager) must be of type Drupal\Core\Entity\EntityTypeManagerInterface, Drupal\Core\Render\Markup given, called in C:\wamp64\www\website\web\modules\contrib\alinks\src\AlinkPostRenderer.php on line 294" at C:\wamp64\www\website\web\modules\contrib\alinks\src\AlinkPostRenderer.php

what seems to be the problem ?

drupaldope’s picture

resolved in the current dev release
https://www.drupal.org/project/alinks/issues/3412674

drupaldope’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.