Answers.Body: <p>It turned out that the problem was not in the <code>Controller</code>but inthe <code>Service</code> 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:</p>
  
  <pre><code>// Create new entry to save
  $entry = new EntryModel();
  // Set generic parameters
  $entry-&gt;sectionId = craft()-&gt;sections-&gt;getSectionByHandle('shows')-&gt;id;
  $entry-&gt;typeId    = craft()-&gt;sections-&gt;getSectionByHandle('shows')-&gt;type('show')-&gt;id;
  $entry-&gt;authorId  = craft()-&gt;userSession-&gt;getUser()-&gt;id;
  $entry-&gt;enabled   = true;
  </code></pre>
  
  <p>The key here is the phrase <code>craft()-&gt;userSession-&gt;getUser()-&gt;id</code> which fails, as the user it not logged in when triggering from the <code>cronjob</code>.</p>
  
  <p>Changing the line to test if there is a user made the plugin work:</p>
  
  <pre><code>// If logged in, set author (as apposed to running from cron)
  if ( craft()-&gt;userSession-&gt;getUser() ) {
    $entry-&gt;authorId  = craft()-&gt;userSession-&gt;getUser()-&gt;id;
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-06T08:26:08.900Z
Answers.LastActivityDate: 2017-06-06T08:26:08.900Z
Answers.UserDisplayName: KSP
Answers.Body: <blockquote>
    <p>So my question is – is there anything special to be aware of when calling plugins from the outside? </p>
  </blockquote>
  
  <p>Not particularly.  They're both hitting the same controller endpoint in your plugin, but there are about a million <a href="https://www.gnu.org/software/wget/manual/wget.html" rel="nofollow noreferrer">flags/options</a> you can pass into wget to change it's runtime behaviors you might want to play with.</p>
  
  <p>Personally, I stick with using <a href="https://curl.haxx.se/" rel="nofollow noreferrer">cURL</a> for cronjobs.</p>
  
  <p>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.</p>
  
  <p>If it were Craft generated 500 ISEs, then the underlying error message would be in <code>craft/storage/runtime/logs</code>.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-05T23:24:34.043Z
Answers.Text: 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 …
Answers.UserDisplayName: KSP
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-06T02:21:23.460Z
Answers.Text: 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.
Answers.UserDisplayName: Matt Stein
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-05T21:14:38.563Z
Answers.LastActivityDate: 2017-06-05T21:14:38.563Z
Answers.UserDisplayName: Brad Bell
Body: <p>UPDATE: Question edited to be clearer.</p>
  
  <p>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).</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>Here is the code of the controller:</p>
  
  <pre><code>&lt;?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-&gt;requirePostRequest();
  
      $log = craft()-&gt;updateProgram_program-&gt;update();
  
      // If there are entries in the log, changes have happened
      if ( count($log) ) {
          craft()-&gt;userSession-&gt;setNotice(Craft::t('Program updated.'));
          craft()-&gt;urlManager-&gt;setRouteVariables(array(
             'log' =&gt; $log
          ));
      }
      // Otherwise, give an error message
      else {
          craft()-&gt;userSession-&gt;setNotice(Craft::t('Nothing to update!'));
      }
    }
  }
  </code></pre>
  
  <p>And this is how I'm calling it from the cronjob:</p>
  
  <pre><code>MAILTO=[my.email@address]
  # Run updateProgram every night at 3am
  0 3 * * * wget http://[my.site]/actions/updateProgram/program/update &gt; /dev/null
  </code></pre>
  
  <p>When trying it from the browser, I used the same URL</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-05T03:23:55.173Z
Comments.Text: 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 :)
Comments.UserDisplayName: Matt Stein
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-05T15:36:11.087Z
Comments.Text: 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!
Comments.UserDisplayName: KSP
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-05T19:36:19.350Z
Comments.Text: 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.
Comments.UserDisplayName: Matt Stein
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-05T23:23:17.447Z
Comments.Text: 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?
Comments.UserDisplayName: KSP
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-05T23:30:39.337Z
Comments.Text: 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.
Comments.UserDisplayName: Brad Bell
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-05T23:37:01.227Z
Comments.Text: Both, sort of. It is calling `EntryService->saveEntry() `, but I had set the authorId with `$entry->authorId = craft()->userSession->getUser()->id;`, as I developed the plugin triggering it manually from the CP. But now I added the test `if ( craft()->userSession->getUser() ) {` before trying to set the author, and at least locally, the cronjob now seems to work! I'll do a test on the server now.
Comments.UserDisplayName: KSP
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-05T23:50:15.503Z
Comments.Text: That did the trick. Just not setting the authorId unless one exists. I think the premise for my whole question was a bit off. The sites being inaccessible must have had another cause. I'll update the question accordingly, in case it can be helpful for others. Thank you both!
Comments.UserDisplayName: KSP
Tags: <plugin-development><error><cron>
Title: Calling plugin controller externally fails with 500 error
ThreadText: # Calling plugin controller externally fails with 500 error
  
  (Asked by: username_0 on 2017-06-04)
  
  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
  
  **Tags:** plugin-development, error, cron
  
  > **Comments:**
  > **username_1**: 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 :)  
  > **username_0**: Hi username_1! 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!  
  > **username_1**: That's more helpful @username_0, 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.  
  > **username_0**: 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 @username_2, 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?  
  > **username_2**: 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.  
  > **username_0**: Both, sort of. It is calling `EntryService->saveEntry() `, but I had set the authorId with `$entry->authorId = craft()->userSession->getUser()->id;`, as I developed the plugin triggering it manually from the CP. But now I added the test `if ( craft()->userSession->getUser() ) {` before trying to set the author, and at least locally, the cronjob now seems to work! I'll do a test on the server now.  
  > **username_0**: That did the trick. Just not setting the authorId unless one exists. I think the premise for my whole question was a bit off. The sites being inaccessible must have had another cause. I'll update the question accordingly, in case it can be helpful for others. Thank you both!  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2017-06-06. Score: 2 | Accepted answer
  
  It turned out that the problem was not in the `Controller`but 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;
  }
  
  ```
  
  
  ---
  
  ### Answer by username_2 on 2017-06-05. Score: 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](https://www.gnu.org/software/wget/manual/wget.html) you can pass into wget to change it's runtime behaviors you might want to play with.
  
  Personally, I stick with using [cURL](https://curl.haxx.se/) 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`.
  
  > **Comments:**
  > **username_0**: I added some more info to the comment by @username_1 above! I'm not really sure what the right way to respond is when I'm drawing on two different answers here …  
  > **username_1**: You're doing fine, @username_0! There's only one answer here (username_2'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. username_2 has enough points, so don't worry about that.  
  
  ---
  
  