1

UPDATE: Question edited to be clearer.

I had an issue where it seems calling a plugin’s controller via an URL caused the site itself to throw a 500 error (i.e. not being accessible at all).

The plugin loads external cinema events (as an XML) and creates entries for films and shows. I’ve made it accessible in the CP, where I hit a button to update, and it will return a log which gets printed out in the CP. Triggering it from the plugins page in the CP works perfectly. Now I wanted to create a cronjob that loads the external data on regular intervals – basically calling the plugin. After some trail and error, I managed to make the plugin’s controller callable from the outside.

So my question is – is there anything special to be aware of when calling plugins from the outside? Is there a difference if it’s called as a cronjob or if it’s done manually through the browser.

Here is the code of the controller:

<?php
namespace Craft;

class UpdateProgram_ProgramController extends BaseController
{
  // Allowing to be called without being logged in
  protected $allowAnonymous = true;

  public function actionUpdate()
  {
  // Disabling having to call the plugin by POST, to access directly by URL
  // this->requirePostRequest();

    $log = craft()->updateProgram_program->update();

    // If there are entries in the log, changes have happened
    if ( count($log) ) {
        craft()->userSession->setNotice(Craft::t('Program updated.'));
        craft()->urlManager->setRouteVariables(array(
           'log' => $log
        ));
    }
    // Otherwise, give an error message
    else {
        craft()->userSession->setNotice(Craft::t('Nothing to update!'));
    }
  }
}

And this is how I'm calling it from the cronjob:

MAILTO=[my.email@address]
# Run updateProgram every night at 3am
0 3 * * * wget http://[my.site]/actions/updateProgram/program/update > /dev/null

When trying it from the browser, I used the same URL

  • 2
    Hi KSP! Can you provide a sample of your controller code and whatever (if anything) you could get out of Craft or system logs? I don't think a blank page has to be a 500 error, and there shouldn't be any difference between hitting something with cron vs. your browser, but it'll be tough to give good feedback without knowing what your code looks like, exactly how you're calling it (via cron at least), and whatever clues (errors) might be related to your blank responses. Don't be afraid though; if you're like me it will absolutely be your fault but you'll learn and be on your way :) – Matt Stein Jun 5 '17 at 3:23
  • Hi Matt! Thanks for your reply! And you're totally right – usually it's my own fault, but I keep learning :) And a lot thanks to helpful people like you willing to share your knowledge. I'll update the post with the controller code, and the code I use to call it from the cronjob! – KSP Jun 5 '17 at 15:36
  • That's more helpful @KSP, thanks! Would there happen to be anything else in the Craft or system logs that could be relevant to the empty response? Your craft()->updateProgram_program->update() could also be related here as well. – Matt Stein Jun 5 '17 at 19:36
  • Thanks for taking your time with this! After some testing on running cronjobs locally, I think I've gotten a bit closer to what can possibly be the issue. Checking the Craft logs, after tip from @brad-bell, I now think the problem may lay in the following code: $entry->authorId = craft()->userSession->getUser()->id; Basically, that I'm trying to set a user, which I guess doesn't exist from the cronjob. This may explain why I can now run it in the browser (and it works), as I'm logged in to the CP. Can I save entries without being logged in? – KSP Jun 5 '17 at 23:23
  • Is craft()->updateProgram_program->update() calling Craft's EntryService->saveEntry()? Or is it using $entry->authorId = craft()->userSession->getUser()->id; directly? Might help to post the contents of that update() method. – Brad Bell Jun 5 '17 at 23:30
2

So my question is – is there anything special to be aware of when calling plugins from the outside?

Not particularly. They're both hitting the same controller endpoint in your plugin, but there are about a million flags/options you can pass into wget to change it's runtime behaviors you might want to play with.

Personally, I stick with using cURL for cronjobs.

Regardless, the behavior you describe sounds like a webserver/Apache crash or segfault. If they are long-running scripts and you inadvertently triggered them multiple times, maybe you hit some hard resource limits. If that's the case, the underlying error message would be in your web server's error logs for the 500 Internal Server Error.

If it were Craft generated 500 ISEs, then the underlying error message would be in craft/storage/runtime/logs.

|improve this answer|||||
  • I added some more info to the comment by @matt-stein above! I'm not really sure what the right way to respond is when I'm drawing on two different answers here … – KSP Jun 5 '17 at 23:24
  • You're doing fine, @KSP! There's only one answer here (Brad's) along with the comments on your post. This has involved a bit of troubleshooting to better understand your issue, where Perfect Form would be a gloriously self-sufficient post that balances thoroughness and brevity to ask a single, concise question. Your instinct is right: edit down the question, include pertinent details from your service, and submit+accept your own answer if it differs from this one. Brad has enough points, so don't worry about that. – Matt Stein Jun 6 '17 at 2:21
2

It turned out that the problem was not in the Controllerbut inthe Service it was calling. There I load external data, and save any updates. The problem was when I was trying to save entries with the following code:

// Create new entry to save
$entry = new EntryModel();
// Set generic parameters
$entry->sectionId = craft()->sections->getSectionByHandle('shows')->id;
$entry->typeId    = craft()->sections->getSectionByHandle('shows')->type('show')->id;
$entry->authorId  = craft()->userSession->getUser()->id;
$entry->enabled   = true;

The key here is the phrase craft()->userSession->getUser()->id which fails, as the user it not logged in when triggering from the cronjob.

Changing the line to test if there is a user made the plugin work:

// If logged in, set author (as apposed to running from cron)
if ( craft()->userSession->getUser() ) {
  $entry->authorId  = craft()->userSession->getUser()->id;
}
|improve this answer|||||

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.