0

I am converting a simple module from Drupal 7 to Drupal 8 and I used the Drupal Module Upgrader to do this. The code has been reformatted and some @FIXME notes have been added, I have no experience developing modules though and I'm not sure what to do.

When I search for more info concerning my problem I found this link https://www.drupal.org/node/2346779 but I'm not sure how to rewrite my code snippet exactly.

This is the .module file.

/**
 * @file
 * The littlurl module does little urls.
 */

/**
 * Implements hook_menu().
 */
function littlurl_menu() {
  $items['n'] = array(
    'title' => 'Forward n to node',
    'access arguments' => array('access content'),
    'page callback' => 'littlurl_forward',
    'type' => MENU_CALLBACK,
  );

  $items['u'] = array(
    'title' => 'Forward u to user',
    'access arguments' => array('access user profiles'),
    'page callback' => 'littlurl_forward',
    'type' => MENU_CALLBACK,
  );

  $items['t'] = array(
    'title' => 'Forward t to taxonomy/term',
    'access arguments' => array('access content'),
    'page callback' => 'littlurl_forward',
    'type' => MENU_CALLBACK,
  );

  return $items;
}


/**
 * Page callback to forward people along their merry way.
 */
function littlurl_forward() {
  // Get the elements of the URL.
  $args = explode('/', $_GET['q']);

  // Get the elements of the query string.
  $query_string = $_GET;
  unset($query_string['q']);

  if (count($args) > 1) {
    switch ($args[0]) {
      case 'u':
        $args[0] = 'user';
        break;

      case 't':
        $args[0] = 'taxonomy/term';
        break;

      case 'n':
      default:
        $args[0] = 'node';
        break;
    }
    // It's easier to use url than deal with drupal_goto's arguments.
    // @FIXME
// url() expects a route name or an external URI.
// $destination_url = url(implode('/', $args), array('query' => $query_string, 'absolute' => TRUE));

    drupal_goto($destination_url);
  }
  else {
    // This should never happen.
    drupal_goto('<front>');
  }
}

This is the Controller.php file. It has the same code the .module file has. Should I remove the redundant code snipped from the .module file?

/**
 * @file
 * Contains \Drupal\littlurl\Controller\DefaultController.
 */

namespace Drupal\littlurl\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Default controller for the littlurl module.
 */
class DefaultController extends ControllerBase {

  public function littlurl_forward() {
    // Get the elements of the URL.
    $args = explode('/', $_GET['q']);

    // Get the elements of the query string.
    $query_string = $_GET;
    unset($query_string['q']);

    if (count($args) > 1) {
      switch ($args[0]) {
        case 'u':
          $args[0] = 'user';
          break;

        case 't':
          $args[0] = 'taxonomy/term';
          break;

        case 'n':
        default:
          $args[0] = 'node';
          break;
      }
      // It's easier to use url than deal with drupal_goto's arguments.
      // @FIXME
      // url() expects a route name or an external URI.
      // $destination_url = url(implode('/', $args), array('query' => $query_string, 'absolute' => TRUE));

      drupal_goto($destination_url);
    }
    else {
      // This should never happen.
      drupal_goto('<front>');
    }
  }

}

This is a routing.yml file. It seems to be linking to the controller.

littlurl.forward:
  path: /t
  defaults:
    _title: 'Forward t to taxonomy/term'
    _controller: '\Drupal\littlurl\Controller\DefaultController::littlurl_forward'
  requirements:
    _permission: 'access content'
1
  • I rolled back a set of edits to the question, as it changed the meaning after it was answered.
    – mpdonadio
    Commented Dec 28, 2016 at 21:06

2 Answers 2

2

The hooks/functions you shown for the .module file can be removed, since Drupal 8 doesn't use hook_menu(); therefore, Drupal will not use the littlurl_forward() function defined from the module.

The code in the Controller.php file needs to be rewritten for Drupal 8, since:

  • It should not access $_GET['q']
  • Instead of drupal_goto(), it should use the redirect() method of the controller

The first point means you should have three different methods you assign to the three different paths, which makes also more sense. It doesn't sense to assign the same method to three different paths, and the method then still need to understand for which path is being called.

As side notes, keep in mind that:

  • If you are editing a module that is already installed, or any of its files, you need to uninstall it first, since Drupal keep in a cache the list of hooks the module is implementing

  • The method of a class should not be named like lower_case(), but camelCase()

  • From the code you are showing, it seems you are redirecting from n to node; if that is the case, then you can simply use a path alias

  • If instead you are redirecting from /n/node-id to /node/node-id, then it is probably better to use the Pathauto module which creates path aliases for nodes, taxonomy terms, and users (and lets you decide which pattern to use for those path aliases)

  • If the routes you are defining get arguments, you should define them in the routes, such as /n/{node}

  • If all the routes are doing is allowing to use /n/node-id instead of /node/node-id, I don't see much of a reason to write the code just for that

2
  • My code is almost working taking into account the things you recommended to me, I still get a small error when trying to use the path I defined though. Symfony\Component\Routing\Exception\RouteNotFoundException: Route "node" does not exist. in Drupal\Core\Routing\RouteProvider->getRouteByName() (line 187 of C:\Users\SAMUEL\Sites\devdesktop\Module3\core\lib\Drupal\Core\Routing\RouteProvider.php). This is because of the string I put in the url option most likely, but reading the documentation I'm not sure what else to do Commented Dec 28, 2016 at 19:50
  • Btw you can find the updated code under EDIT 1 if you are willing to take a look at it, I would appreciate it a lot Commented Dec 28, 2016 at 20:46
0

You need to replace the calls to drupal_goto().

Write this line at top of the file.

use \Symfony\Component\HttpFoundation\RedirectResponse;

Replace the call to drupal_goto() with the following code.

$response = new RedirectResponse($url); // $url = '<front>';
$response->send();
8
  • Ok, so I removed the $destination_url from comments and should now be compiled, and I got $destination_url = url(implode('/', $args), array('query' => $query_string, 'absolute' => TRUE)); //drupal_goto($destination_url); $response = new RedirectResponse($destination_url); // $url = '<front>'; $response->send(); I added this in both the controller.php file and .module file, should I remove the function from the .module file? Commented Dec 24, 2016 at 15:04
  • Yes, do the same in .module file. Commented Dec 24, 2016 at 15:06
  • This didn't fix it unfortunately, this is what I currently got prntscr.com/dnfqdx Sorry for the bad formatting on my previous comment Commented Dec 24, 2016 at 15:19
  • which function are you talking about to remove from .module file? Commented Dec 24, 2016 at 15:21
  • The littlurl_forward() function, since it seems reduntant Commented Dec 24, 2016 at 15:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.