Answers.Body: <p>In your plugin's main class file you'd set the <a href="https://craftcms.com/docs/plugins/hooks-reference#registerCpRoutes" rel="nofollow">registerCpRoutes</a> method to something like this:</p>
  
  <pre><code>public function registerCpRoutes()
  {
      return array(
          'user/update/(?P&lt;userId&gt;\d+)' =&gt; array('action' =&gt; 'pluginHandleController/updateUserRecordsTest'
          ),
      );
  }
  </code></pre>
  
  <p>The the method in your plugin's <a href="https://craftcms.com/docs/plugins/controllers" rel="nofollow">controller</a> would look something like this:</p>
  
  <pre><code>public function actionUpdateUserRecordsTest(array $variables = array())
  </code></pre>
  
  <p>And <code>$variables</code> will be a collection of all of the named regex patterns captured in your route definition.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-08T14:12:40.750Z
Answers.Text: not for a plug in, just in the UsersController in app/config/controllers in craft.  I am still not sure how I could do things like this within the craft framework.
Answers.UserDisplayName: Rockwell Rice
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-08T17:52:24.277Z
Answers.Text: I'm not following what you're trying to do then. Can you give a little more context in the original question?  You want to be able to hit a page that triggers an action in Craft's UsersController?
Answers.UserDisplayName: Brad Bell
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-11T12:12:44.720Z
Answers.Text: I need to update tables in the users db, as they pass classes.  In laravel I would do this with an ajax call to a page that just triggers some kind of boolean (usually), so when I hit the page (with the users id) it would turn passed from 0 to 1 (for example) to show that user has passed the class.
Answers.UserDisplayName: Rockwell Rice
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-11T18:45:38.057Z
Answers.Text: Gotcha... you'd have to do that though a simple Craft plugin then.
Answers.UserDisplayName: Brad Bell
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-08T01:14:53.923Z
Answers.LastActivityDate: 2016-04-08T01:14:53.923Z
Answers.UserDisplayName: Brad Bell
Answers.Body: <p>You should setup a small plugin for this functionality. This helps you move out business logic and by the way you are helping others implementing stuff in craft.</p>
  
  <p>I would start with the root file for your plugin and there we register a route for the controller.</p>
  
  <pre><code>/* urlbyid/UrlByIdPlugin.php */
  class UrlByIdPlugin extends BasePlugin
  {
      public function getName() { return 'Url by id'; }
      public function getVersion() { return '1.0.0'; }
      public function getDeveloper() { return 'You'; }
      public function getDeveloperUrl() { return 'https://www.yourdomain.com'; }
  
      public function registerSiteRoutes()
      {
          return array(
          'entries/find' =&gt; array('action' =&gt; 'urlById/find'),
          );
      }
  }
  </code></pre>
  
  <p>So <a href="http://www.yourdomain.com/entries/find" rel="nofollow noreferrer">http://www.yourdomain.com/entries/find</a> now routes to a controller UrlByIdController which does the following:</p>
  
  <ul>
  <li>Find the entry by id</li>
  <li>if it has a url -> redirect to it</li>
  </ul>
  
  <p>`</p>
  
  <pre><code>/* urlbyid/controllers/UrlByIdController.php */
  namespace Craft;
  class UrlByIdController extends BaseController
      {
          protected $allowAnonymous = true;
  
      /*
      * Finding entries and redirect if found.
      */
      public function actionFind()
      {
          $requestedId = craft()-&gt;request-&gt;getParam('id');
          // build criteria to find model
          $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
          $criteria-&gt;id = $requestedId;
          $criteria-&gt;limit = 1;
  
          // fire !
          $entries = $criteria-&gt;find();
          $entry = count($entries) &gt; 0 ? $entries[0] : null;
  
          // redirect if possible
          if($entry &amp;&amp; $entry-&gt;url) {
  
              // build new query, but remove id from query path
              $newLocation = $entry-&gt;url . ( craft()-&gt;request-&gt;getParam('L') ? '?L='.craft()-&gt;request-&gt;getParam('L') : '');
  
              header("HTTP/1.1 302 Found"); 
              header("Location: " . $newLocation); 
              exit();
          }else{
              header("HTTP/1.1 404 Not Found");
              header("Location: /404.html"); 
              exit();
          }
  
          craft()-&gt;end();
      }
  
  }
  </code></pre>
  
  <p>You could then implement a variable class to provide a helper for templates:</p>
  
  <pre><code>/* urlbyid/variables/UrlByIdVariable.php */
  namespace Craft;
      /*
      * Helper to generate Url with Id
      */
      class UrlByIdVariable
      {
          public function urlFor($entry)
          {
              if ($entry-&gt;uri !== null)
                  {
                      $url = UrlHelper::getSiteUrl('entries/find', array('id' =&gt; $entry-&gt;id), null, $entry-&gt;locale);
                      return $url;
                  }
          }
    }
  </code></pre>
  
  <p>Use this helper in your layouts:</p>
  
  <pre><code>{{ craft.urlById.urlFor(entry) }}
  </code></pre>
  
  <p>Code improvements: Use craft internal redirector, not php standard</p>
  
  <p>Please have a look at this small plugin I have written: <a href="https://github.com/zauberware/urlbyid/" rel="nofollow noreferrer">UrlById</a></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-10-29T14:06:18.383Z
Answers.LastActivityDate: 2017-10-29T14:06:18.383Z
Answers.UserDisplayName: Simon Franzen
Body: <p>I am trying to create a page I can hit to update a record in the db, something I am used to doing in Laravel, but now have to do in Craft.</p>
  
  <p>The controller method would look something like this:</p>
  
  <pre><code>public function updateUserRecordsTest($userId) {
  
      $user = craft()-&gt;users-&gt;getUserById($userId);
      // $data['status'] = 'asleep';
      // $user-&gt;update($data);
  
  }
  </code></pre>
  
  <p>So I am trying to make a route in <code>craft/config/routes.php</code> like this</p>
  
  <pre><code> route =&gt; user/update/{id} , controller =&gt; UsersController@updateUserRecordsTest;
  </code></pre>
  
  <p>Any suggestions on how to set this route up in Craft would be greatly appreciated.</p>
  
  <p>*Update</p>
  
  <p>So I will try to clear up what I am trying to do.</p>
  
  <p>I need to update the users db when they pass classes.  This will most likely be a boolean, but may end up being an enum.  So what I would usually set up is a page with a controller method like below</p>
  
  <pre><code> // sudo code
  
   public function passedThisClass($id) {
      $user = User::find($id);
      $data['passed'] = 1
      User::update($data);
   });
  </code></pre>
  
  <p>the route would look like</p>
  
  <pre><code> // sudo code
   route::get('updatethisclass/{id} =&gt; UsersController@updateThisClass);
  </code></pre>
  
  <p>When I hit that page it updates the value from 0 to 1 flagging that they passed the class.</p>
  
Tags: <routes>
Title: How do I create an advanced route with an ID that hits a controller method
ThreadText: # How do I create an advanced route with an ID that hits a controller method
  
  (Asked by: username_0 on 2016-04-07)
  
  I am trying to create a page I can hit to update a record in the db, something I am used to doing in Laravel, but now have to do in Craft.
  
  The controller method would look something like this:
  
  ```
  public function updateUserRecordsTest($userId) {
  
      $user = craft()->users->getUserById($userId);
      // $data['status'] = 'asleep';
      // $user->update($data);
  
  }
  
  ```
  
  So I am trying to make a route in `craft/config/routes.php` like this
  
  ```
   route => user/update/{id} , controller => UsersController@updateUserRecordsTest;
  
  ```
  
  Any suggestions on how to set this route up in Craft would be greatly appreciated.
  
  \*Update
  
  So I will try to clear up what I am trying to do.
  
  I need to update the users db when they pass classes. This will most likely be a boolean, but may end up being an enum. So what I would usually set up is a page with a controller method like below
  
  ```
   // sudo code
  
   public function passedThisClass($id) {
      $user = User::find($id);
      $data['passed'] = 1
      User::update($data);
   });
  
  ```
  
  the route would look like
  
  ```
   // sudo code
   route::get('updatethisclass/{id} => UsersController@updateThisClass);
  
  ```
  
  When I hit that page it updates the value from 0 to 1 flagging that they passed the class.
  
  **Tags:** routes
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2016-04-08. Score: 1
  
  In your plugin's main class file you'd set the [registerCpRoutes](https://craftcms.com/docs/plugins/hooks-reference#registerCpRoutes) method to something like this:
  
  ```
  public function registerCpRoutes()
  {
      return array(
          'user/update/(?P<userId>\d+)' => array('action' => 'pluginHandleController/updateUserRecordsTest'
          ),
      );
  }
  
  ```
  
  The the method in your plugin's [controller](https://craftcms.com/docs/plugins/controllers) would look something like this:
  
  ```
  public function actionUpdateUserRecordsTest(array $variables = array())
  
  ```
  
  And `$variables` will be a collection of all of the named regex patterns captured in your route definition.
  
  > **Comments:**
  > **username_0**: not for a plug in, just in the UsersController in app/config/controllers in craft.  I am still not sure how I could do things like this within the craft framework.  
  > **username_1**: I'm not following what you're trying to do then. Can you give a little more context in the original question?  You want to be able to hit a page that triggers an action in Craft's UsersController?  
  > **username_0**: I need to update tables in the users db, as they pass classes.  In laravel I would do this with an ajax call to a page that just triggers some kind of boolean (usually), so when I hit the page (with the users id) it would turn passed from 0 to 1 (for example) to show that user has passed the class.  
  > **username_1**: Gotcha... you'd have to do that though a simple Craft plugin then.  
  
  ---
  
  ### Answer by username_2 on 2017-10-29. Score: 1
  
  You should setup a small plugin for this functionality. This helps you move out business logic and by the way you are helping others implementing stuff in craft.
  
  I would start with the root file for your plugin and there we register a route for the controller.
  
  ```
  /* urlbyid/UrlByIdPlugin.php */
  class UrlByIdPlugin extends BasePlugin
  {
      public function getName() { return 'Url by id'; }
      public function getVersion() { return '1.0.0'; }
      public function getDeveloper() { return 'You'; }
      public function getDeveloperUrl() { return 'https://www.yourdomain.com'; }
  
      public function registerSiteRoutes()
      {
          return array(
          'entries/find' => array('action' => 'urlById/find'),
          );
      }
  }
  
  ```
  
  So <http://www.yourdomain.com/entries/find> now routes to a controller UrlByIdController which does the following:
  
  * Find the entry by id
  * if it has a url -> redirect to it
  
  `
  
  ```
  /* urlbyid/controllers/UrlByIdController.php */
  namespace Craft;
  class UrlByIdController extends BaseController
      {
          protected $allowAnonymous = true;
  
      /*
      * Finding entries and redirect if found.
      */
      public function actionFind()
      {
          $requestedId = craft()->request->getParam('id');
          // build criteria to find model
          $criteria = craft()->elements->getCriteria(ElementType::Entry);
          $criteria->id = $requestedId;
          $criteria->limit = 1;
  
          // fire !
          $entries = $criteria->find();
          $entry = count($entries) > 0 ? $entries[0] : null;
  
          // redirect if possible
          if($entry && $entry->url) {
  
              // build new query, but remove id from query path
              $newLocation = $entry->url . ( craft()->request->getParam('L') ? '?L='.craft()->request->getParam('L') : '');
  
              header("HTTP/1.1 302 Found"); 
              header("Location: " . $newLocation); 
              exit();
          }else{
              header("HTTP/1.1 404 Not Found");
              header("Location: /404.html"); 
              exit();
          }
  
          craft()->end();
      }
  
  }
  
  ```
  
  You could then implement a variable class to provide a helper for templates:
  
  ```
  /* urlbyid/variables/UrlByIdVariable.php */
  namespace Craft;
      /*
      * Helper to generate Url with Id
      */
      class UrlByIdVariable
      {
          public function urlFor($entry)
          {
              if ($entry->uri !== null)
                  {
                      $url = UrlHelper::getSiteUrl('entries/find', array('id' => $entry->id), null, $entry->locale);
                      return $url;
                  }
          }
    }
  
  ```
  
  Use this helper in your layouts:
  
  ```
  {{ craft.urlById.urlFor(entry) }}
  
  ```
  
  Code improvements: Use craft internal redirector, not php standard
  
  Please have a look at this small plugin I have written: [UrlById](https://github.com/zauberware/urlbyid/)
  
  
  ---
  
  