Welcome Guest, Not a member yet? Register   Sign In
How to prevent a controller to run from web?
#11

[eluser]mddd[/eluser]
Wouldn't that be the other way around?
Show an error if NOT in CLI mode?
#12

[eluser]WanWizard[/eluser]
Eh, oops, yes. Wink
#13

[eluser]paulc010[/eluser]
@mddd Sorry I confused the issue by mentioning modules. I was merely pointing out that the addition of the underscore just prevents "normal" CI routing (and thus prevents the method from being accessible from a web client). In PHP terms the method is still public and callable from outside the class, as opposed to declaring it "private".

Personally I would place the cron script as well as all but main index.php and associated css/js and images above the document root for the site. Cron has no problem running scripts there, and that renders it inaccessible from a browser. I always set CI up that way as I don't see the need to have the system or application folders accessible.

WanWizard's solution will work if indeed the entire controller should only be available via cron which I think is what the OP is trying to do. My case is slightly more complex, as you'll see below.

The "problem" with my method is that we still need the main CodeIgniter.php file to use all of CI's goodness - and that is where the test for the underscore lies. I would suggest that it would be only a slightly naughty hack to create a "cron version" with the test for the underscore removed.... e.g. CodeIgniterCron.php. This can then be included instead of the standard version by our cron script.

I'm looking at it from the point of view of having each controller (and module) contain its own code that I want to execute via cron. That way I can keep the code self-contained, rather than having all the scheduled code lumped into one place. I may also want to only activate the cron elements for a particular controller or module when that part of the site is installed and/or enabled (e.g. from the admin panel). I could use WanWizard's test in every "cron" controller method, but in my opinion that's messy and prone to errors/omissions.

Experimentation required I think....

Paul
#14

[eluser]mddd[/eluser]
Aha, I see. We were thinking about two slightly different things Smile

I agree that the most simple and safe way would be to place the 'cronnable' scripts above document root. But you are right, that loses the whole CI idea.

Using "CI-style private" methods and then "un-privatising" them for the cron seems a bit of a workaround to me. I think checking in each cron-routine would be preferable to making a separate CI-flow without the underscore checking.

Keeping cron code with the rest of the code is absolutely a good idea. If a controller (lets say News) has methods like add_article, remove_article etc. it can also have a method check_for_old_articles which is meant to be run by a cron job. But yes, you would have to check inside that method to see if it really is called by a cron job and not by a user.
#15

[eluser]paulc010[/eluser]
[quote author="mddd" date="1272300352"]
I agree that the most simple and safe way would be to place the 'cronnable' scripts above document root. But you are right, that loses the whole CI idea.
[/quote]

Not sure you understand what I mean. I always move the system and application folders out of the document root, I don't see any reason for them to be there.... it's a fairly trivial change to the index.php file to move them. Cron scripts would also not be in the document root - by definition they aren't intended for public access.

Paul
#16

[eluser]mddd[/eluser]
I meant this:
Even though the script (the controller or model) is outside the document root, the CodeIgniter 'root' index.php is still INSIDE the document root. Otherwise nobody could call it Smile
So, if the cron job is to call that same index.php, the cron model/method whatever can still be called even though the file containing that code is outside the root.
That's the problem: if the 'entry point' is a publicly available index.php file, than web users can always access the same things as your cron script.

Except if you make another 'index.php' especially for the cron, or if you put checks inside the controllers/models, to only let them be executed if the call came from the cron.
#17

[eluser]Sinclair[/eluser]
Hi,

Sorry for not explain well what I need.

I have used this method to run CodeIgniter Controllers from the PHP CLI, Method to Run CI Controllers from PHP CLI.

But this method does not assure that the code could not run from the a Web Browser.

Best Regards,
#18

[eluser]paulc010[/eluser]
@mddd Yes you would use a modified version of the index.php file as the basis for your cron.... which leads nicely on to ....

@sinclair Yes indeed you can use that method. I'm proposing:

1) You "hide" your cron methods in your controllers using the _ technique.
2) Create a modified index.php (cli.php in that article) which has been moved out of the web root (variables need to be adjusted so it can find the system and application folder).
3) in system/codeigniter make a copy of CodeIgniter.php, renamed to CodeIgniterCron.php and modify the following (from line 176 in 1.7.2):
Code:
if ( ! class_exists($class)
    OR $method == 'controller'
    OR strncmp($method, '_', 1) == 0
    OR in_array(strtolower($method), array_map('strtolower', get_class_methods('Controller')))
    )
{
    show_404("{$class}/{$method}");
}

to

Code:
if ( ! class_exists($class)
    OR $method == 'controller'
    OR in_array(strtolower($method), array_map('strtolower', get_class_methods('Controller')))
    )
{
    show_404("{$class}/{$method}");
}

4) At the end of your modified index.php (cli.php) change the following:
Code:
/*
|---------------------------------------------------------------
| LOAD THE FRONT CONTROLLER
|---------------------------------------------------------------
|
| And away we go...
|
*/
require_once BASEPATH.'codeigniter/CodeIgniter'.EXT;

to

Code:
/*
|---------------------------------------------------------------
| LOAD THE FRONT CONTROLLER
|---------------------------------------------------------------
|
| And away we go...
|
*/
require_once BASEPATH.'codeigniter/CodeIgniterCron'.EXT;

You should now be done Smile

Paul
#19

[eluser]loosetops[/eluser]
Elegant hack Paul, I may be using it in the near future.




Theme © iAndrew 2016 - Forum software by © MyBB