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.

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.

  • 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 8 '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 8 '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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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