How to create a non-accessible controller action? - php

In one of my controllers, i use codeigniter's form validation helper. One of my validation rules is a custom function that i created that returns true or false.
Problem is, that this validation function is declared inside the controller's class. How do i prevent users from browsing to my validation function as a controller action (mysite/mycontroller/my_callback_func)?
P.S. - Tried to set the function as private but I'm getting an error that it's not accessible for the validation helper.

Just start the function/method name with an underscore.
Straight out of ./system/core/CodeIgniter.php:
/*
* ------------------------------------------------------
* Security check
* ------------------------------------------------------
*
* None of the functions in the app controller or the
* loader class can be called via the URI, nor can
* controller functions that begin with an underscore
*/
$class = $RTR->fetch_class();
$method = $RTR->fetch_method();
if ( ! class_exists($class)
OR strncmp($method, '_', 1) == 0
OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
)
{
show_404("{$class}/{$method}");
}

simply define your function private and put an uderscore befor the function name for example :
class Some_class extends CI_Controller{
private function _some_method(){}
}

I would instead make it a helper function. To do so, put a file in your system/application/myval_helper.php, then add your function in there. Then just call:
$this->load->helper('myval');
And you'll be able to access the function. Another alternative is to simply use .htaccess to block that exact URL.

Related

Method Declerations in Laravel's Facades

I want to know how methods are declared in Laravel's facades. For example, I want to create a user-defined function to index my login page. Firstly, I need to check whether the user is already authenticated. To do that, I will use Laravel's Auth facade.
public function indexLogin() {
if (Auth::check()) {
return redirect('/mainpage');
}
}
But, when I wanted to learn more about this method, the only thing I came across were declarations made in the PHPDoc section.
/*
*
* #method static bool check()
*
*/
For this case, I know what the method does but also want to know how it works. I believe the declarations that were made in PHPDoc sections are not enough to run methods.
I checked Laravel's official documentation but found nothing.
You see at the end of the methods declaration, before the class name declaration there is a PHPDoc :
#see \Illuminate\Auth\AuthManager
#see \Illuminate\Contracts\Auth\Factory
#see \Illuminate\Contracts\Auth\StatefulGuard
#see \Illuminate\Contracts\Auth\Guard
you can check them to know how the method works.
In the documentation, you can see where the methods come from as pointed out by #xenooooo.
by digging a bit, you cas see that check() is using user()
/**
* Determine if the current user is authenticated.
*
* #return bool
*/
public function check()
{
return ! is_null($this->user());
}

Zend 1 php how to get helper and execute it outside of the class?

I need to be able to execute this code in a php debug tool:
$magicStuff = $this->getHelper('magic')->doMagic();
I have a helper, which I need to execute within a PHP debugging tool. For that reason, I need to "call" to this helper to be able to use.
I have tried this but It seems I'mstrong text missing something along the way. I'm pretty new to Zend, I'll appreciate your help.
magic.php
/**
* Helper declared in the actions/helpers/magic.php file
*/
class Magic_Controller_Helper extends Zend_Controller_Action_Helper_Abstract
{
/**
* Do some magic and return data.
*
* #return array
*/
public function doMagic()
{
return $getStuff;
}
}
I have tried with:
$helper = Zend_Controller_Action_HelperBroker::getHelper('magic');
$results= $helper->doMagic();
var_dump($results);
I get back:
Action helper "magic" has not been registered with the helper broker
Exception:
Message: Action helper "magic" has not been registered with the helper broker
Code: 0
You probably missing the registration of your library namespace and actionhelper path.
In your application.ini add the following
resources.frontController.actionhelperpaths.Magic_Controller_Action_Helper = "Magic/Controller/Action/Helper"
autoloadernamespaces.Magic = "Magic_"
The "Magic" library should exists under "library" folder.
If you do not have your helper under the "Action" namespace try to remove it
resources.frontController.actionhelperpaths.Magic_Controller_Helper = "Magic/Controller/Helper"

Laravel 4 - Call to undefined method SomeController::getAfterFilters()

I get
Call to undefined method ContestsCpController::getAfterFilters()
on a specific controller. All other controllers are working fine and I do not remember any change that would cause this breakage. In fact, I haven't touched the code in weeks. The last thing I did was some refactoring.
Route
Route::get("contestscp/home", "ContestsCpController#getHome");
Controller
<?php
class ContestsCpController extends BaseController
{
public function getHome() {
return Redirect::to("contestscp/give_award");
}
...
some other methods
...
}
?>
Debug output
/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php
* #param \Illuminate\Routing\Route $route
* #param \Illuminate\Http\Request $request
* #param string $method
* #return mixed
*/
protected function assignAfter($instance, $route, $request, $method)
{
foreach ($instance->getAfterFilters() as $filter) //fails here
{
// If the filter applies, we will add it to the route, since it has already been
Google and SO suggest that this is caused when controller does not extend BaseController but this is obviously not the case. So I assume that for some reason my class is not being extended. Or.. the class fails to initialize and $instance is null. But I have no idea why and how to debug this.
Any suggestions?
I knew this had to be something stupid.. because it always is.
The problem was my refactoring. I used to have all validators extended in a single file. When I separated the validators into different files I misnamed my ContestsCpValidator class as ContestsCPController (duh..). So I had a second class with the same name with no methods obviously.
So basically, if you happen to have this error and you are indeed extending the BaseController make sure you don't autoload another class with the same name.

Codeigniter: how can i tell if a model is already loaded?

Are there native codeigniter functions I can use to tell if a certain model has already been loaded? Can php's class_exists() be used to tell if a model has already been loaded?
I would be tempted to extend the CI_Loader core class. (See extending Core Class)
class MY_Loader extends CI_Loader {
function __construct()
{
parent::__construct();
}
/**
* Returns true if the model with the given name is loaded; false otherwise.
*
* #param string name for the model
* #return bool
*/
public function is_model_loaded($name)
{
return in_array($name, $this->_ci_models, TRUE);
}
}
You would be checking for a given model with the following:
$this->load->is_model_loaded('foobar');
That strategy is already being used by the CI_Loader class.
This solution supports the model naming feature of CI, where models can have a different name than the model class itself. The class_exists solution wouldn't support that feature, but should work fine if you aren't renaming models.
Note: If you changed your subclass_prefix configuration, it might not be MY_ anymore.
The simplest solution is to use PHP function class_exists
http://php.net/manual/en/function.class-exists.php
For example. if you want to check if Post_model has been defined or not.
$this->load->model('post_model');
/*
a lot of code
*/
if ( class_exists("Post_model") ) {
// yes
}
else {
// no
}
The simplest is the best..
Edited:
You can use the log_message() function.
Put this in your model’s constructor (parent::Model())
log_message ("debug", "model is loaded");
don’t forget to set the log config to debug mode in the config.php file
$config['log_threshold'] = 2;
And set the system/logs directory permission to writable (by default CI will create the log files here)
or set the logs directory in another dir
$config['log_path'] = 'another/directory/logs/';
CI will then create the log file in the directory. monitor the log files as you like. You can get the debug message to see if your model is already loaded or not in the log files.
Riffing off what Maxime Morin & Tomexsans have written, this is my solution:
<?php
class MY_Loader extends CI_Loader {
/**
* Model Loader
*
* Overwrites the default behaviour
*
* #param string the name of the class
* #param string name for the model
* #param bool database connection
* #return void
*/
function model ($model, $name = '', $db_conn = FALSE) {
if (is_array($model) || !class_exists($model)) {
parent::model($model, $name, $db_conn);
}
}
}
?>
This way, you don't ever need to (consciously) check whether a model's loaded or not :)

How can I separate the callback logic in the one single file using codeigniter?

I use the config.php to store all the form_validation rules...But I would like to store the callback function in one single file too, how can I do so? Any ideas? Thank you....
Now my file is something like this:
User_controller
under user controller have many customized callback_valid , but I ready move all the rules in the config.php. I would like to put the _valid callback to one class. Thank you .
By default, the Form_validation lib uses it's $CI property to see if the callback method exists. Normally this looks at the current controller. However, you can change this behavior by extending the validation class and altering the run() method.
class MY_Form_validation extends CI_Form_validation {
/**
* Support for validation callbacks from any object
*
* #access public
* #param object The object to run callbacks from
* #param string Is there a validation rule for the particular URI being accessed?
* #return bool Validation status
*/
function run($obj = '', $group = '')
{
// Assign the callback object
if (is_object($obj)) $this->CI =& $obj;
// Run the validation as normal
return parent::run($group);
}
}
We're just reassigning the $CI property. So to use callbacks from a class called user_validation for instance, you can do this:
$callback_class = $this->user_validation;
if ($this->form_validation->run($callback_class)) {}
Any loaded class will work, so you can store callback rules in models or libraries, just pass the object you want to handle callbacks with to the run() method.
What I would do in this case is just create a MY_Form_validation class to extend CodeIgniter's form validation. Place the "_valid" checks in the newly created MY_Form_Validation file and set the rules for the "_valid" checks the same way that you do for the default form_validation rules.
Something like...
class MY_Form_validation extends CI_Form_validation {
function valid_user($str)
{
}
function valid_password($str)
{
}
}

Categories