2

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.

Lindsey D
  • 23,974
  • 5
  • 53
  • 110
Rockwell Rice
  • 509
  • 1
  • 5
  • 16

2 Answers2

1

In your plugin's main class file you'd set the 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 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.

Brad Bell
  • 67,440
  • 6
  • 73
  • 143
  • 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. – Rockwell Rice Apr 08 '16 at 14:12
  • 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? – Brad Bell Apr 08 '16 at 17:52
  • 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. – Rockwell Rice Apr 11 '16 at 12:12
  • Gotcha... you'd have to do that though a simple Craft plugin then. – Brad Bell Apr 11 '16 at 18:45
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

Simon Franzen
  • 119
  • 11