Identifying the remapped function in a CodeIgniter controller - codeigniter

My controller has a remap function that redirects routed calls for its index method to either methodA or methodB.
From within each of these two methods, an external class instance makes a call to it's own methods, something like this:
methodA(){
$newClass = new newClass();
$newClass->doStuff();
}
in doStuff(), the code does stuff contingent to what segment was referenced. Essentially, I may get data like this
doStuff(){
$data = $assets[$this->ci->router->fetch_class()][$this->ci->router->fetch_method()];
}
But this will fail since $this->ci->router->fetch_method() will return index, not the remapped method. I need to be able to retrieve the remapped method for the correct data corresponding to the remapped method.
I can easily do this by passing the name of the invoking function to this method call, but is there a more CodeIgniter way of doing this ? i.e: Getting the remapped method to which the router method was mapped onto ?
If not, alternate solutions ?

Related

Sending request to a post controller function from another controller function

I have a controller like this.
public function barcode_approve(Request $request)
{
$barcodes = $request->input('barcode_values');
$upload_ids = $request->input('upload_id');
....
}
It is defined as post in route without any problem.
Route::post('my/url','BarcodeScanController#barcode_approve');
I would like to use barcode_approve by sending request from controller like
public function push_approve(){
$request = ['barcode_values' => '23ssdwe','upload_id'=>234234];
$this->barcode_approve($request);
.....
}
But $reqeust->input doesn't give the value when I send it through controller function (push_approve)
How can I send values from another controller function as input in $request?
Your barcode_approve expects a Request object, not an array. While you could instantiate a new Request object and potentially inject your fake inputs, I would consider that a bad practice.
Whenever you find yourself trying to call a controller method from another controller method, it usually means you have logic that can be extracted, either to a model, a trait, or in the case of the same controller, a separate protected function.
The purpose of a controller is to be the transport method, you shouldn't have much business logic in it, extract logic to the models when you can.
Required argument in barcode_approve() method must be instance of Request, not just array even if u call it $request.
So if you realy need your code to work, you must create Request instance at your push_approve method()
$request = new Request(['barcode_values' => '23ssdwe','upload_id'=>234234]);
But better way will be to route Request to push_approve() initially
extends your controller with the controller you want to used
then call the function this->barcode_approve($request)

Laravel core method confusion

I have been digging in the core of Laravel because I would like to understand how it works. But I come up with a method that I just cannot wrap my head around even after 3 days.
In start.php the app is binded to itself. So far so good. But when I check the $app->share method I am lost.
public function share(Closure $closure)
{
return function($container) use ($closure)
{
// We'll simply declare a static variable within the Closures and if
// it has not been set we'll execute the given Closure to resolve
// the value and return it back to the consumers of the method.
static $object;
if (is_null($object))
{
$object = $closure($container);
}
return $object;
};
}
This method returns an anonymous function which when executed returns an instance of the app. Do I see that right? Why is this? Why do you want to return a closure and not just the instance. This seems like a strange way, but I am quite sure that there is a reason ;) ??
UPDATE
The line in start.php:
$app['app'] = $app->share(function($app) { return $app; });
So I would think that $app['app'] is a closure object. However if I do get_class the class is Illuminate\Foundation\Application .
Furthermore there is also no way to execute it as $app'app' will not work obviously.
$app is no normal array, it is actually an instance of Illuminate\Foundation\Application1, an extension of Illuminate\Container\Container2, which implements ArrayAccess. But you know this already, as that's where the share() method lives.
The container binds keys to closures, when the keys are accessed the value is fetched from memory or, on first access, the bound closure is called and the resulting value is returned. When a key is set on the container it is wrapped in a closure unless it is already a closure.
This provides a consistent internal interface for the container, so that the code is not constantly type checking its contents. It will also only load the references you actually use are into memory - it is thought that the footprint of a closure is lighter than that of a fully loaded class instance. But once loaded, you get the benefit of working with the same instance for the rest of the request.
Why the app is not registered on the container using instance() I don't know though - perhaps it produces recursive references in trace and dump output.

CodeIgniter - Use of "new" to create

I have a philosophic question on CodeIgniter, and the role of its model on the utilisation of "new" to instance something.
It looks to me that the idea, is that you use for example to use let say a model of a book
$this->load->model("book_model")
instead of
new book_model
What I mean, is that since you load only once the book_model, you will have only one instance of a book_model, and if you want to model multiple books, you will use a createNewBook function in the book_model, instead of going through the _construct fonction after using "new".
Is it right to see it like this? I mean to consider that I use the same instance of book_model and a function inside it "initiateBook"? Should we consider to never use "new" in CodeIgniter?
Actually when you call $this->load->model("book_model") the CodeIgniter does the job for you, which means CodeIgniter's Loader class has a method public function model(...) which instantiate the model that you've passed as an argument, for example book_model here.
Taken from model function in Loader class (located in system/core)
if (in_array($name, $this->_ci_models, TRUE))
{
return;
}
It checks the _ci_models protected array to see if the requested model is already loaded then it returns and if it's not loaded then it loads it, i.e. (the last segment of model method)
$CI->$name = new $model(); // here $model is a variable which has the name of the requsted model
$this->_ci_models[] = $name; // stores the instantiated model name in the _ci_models[] array
return; // then returns
So, you don't need to use new to instantiate it manually and once a model (same applies with other libraries or classes) is loaded then you can access/use it anywhere in your script.
Since CodeIgniter uses the Singleton (an answer on SO about singleton pattern) design pattern so you have only one super global $CI object (one instance of CodeIgniter) available and it carries everything you've loaded or you'll load.
To load the book_model model and then call the initiateBook() method of that model
$this->load->model("book_model"); // book_model loaded/instantiated
$this->book_model->initiateBook(); // initiateBook() function has been called

With Codeigniter, what's the difference if I wanted to set a method to private?

With callback functions that are within the same class, I can't set the following.
private function check_valid_image
{
...
}
I can get it to work if I do the following.
function _check_valid_image
{
...
}
By placing an underscore in front of the method name, is that the same as placing the word private in front?
It's a convention used with the form validation class for callbacks. It also makes that method not callable via the URL segments.
That being said, it is not the equivalent of making a method private, which has implications in how code can be run outside of the class.

Passing Instance to Shared Method in VB.NET

I have been thrown in at the deep end with an existing VB.NET project at work. I have never used VB.NET before so I am struggling a little. Does anyone know how to solve the following.
I need to pass an instance to client side and then pass it to a shared method in order to access instance methods from when the shared method.
The starting point is a fileupload control within the HTML of my Contacts.aspx file:
<asp:FileUpload ID="DocUpload1" runat="server" onchange="CallMe();" />
The onchange event calls a javascript method, see below, this uses AJAX PageMethods to called a Shared method in my code behind
This is the script code which is in my Contact.aspx file
<script language="javascript">
function CallMe() {
// call server side method
PageMethods.GetContact(0, CallSuccess, CallFailed, null);
}
// set the destination textbox value with the ContactName
function CallSuccess(res, destCtrl) {
}
// alert message on some failure
function CallFailed(res, destCtrl) {
alert(res.get_message());
}
</script>
This is an example class of the type of thing I want to do, I think I need to use the "instance As Contacts" as an input parameter to the WebMethod function but I don't know how to pass the instance into it:
This is the class within my Contacts.aspx.vb file.
Partial Class Contacts
<System.Web.Services.WebMethod()> _
Public Shared Function GetContact(ByVal instance As Contacts) As String
Return instance.GetContactName() 'This is an instance class which I need to call.
End Function
'This is my instance class which I want to call from the Shared Class.
Public Shared Function GetContactName() As String
Return "Fred Bloggs"
End Function
End Class
If anyone knows the solution please could they update the code as I probably won't be able to understand if you just give a description. I just hope I am along the right tracks.
If I understand you correctly, you want to access a class (your instance) created in the ASP.Net page life-cycle from your PageMethod - eg created during initial page load or file upload etc.
This is not directly possible as PageMethods do not go through the full page life-cycle (they are essentially webservices). So you need to pass some sort of identifier to the client that, when passed back to the server in the PageMethod, can be used to re-create or retrieve your instance.
eg During the initial page load:
session("ContactID") = instance
Your PageMethod might look something like:
Public Shared Function GetContact(ByVal key As String) As String
Return HttpContext.Current.Session(key).GetContactName()
End Function
where the parameter key is the same key you used to store your instance in the session state.
In your javascript:
function CallMe() {
// call server side method
PageMethods.GetContact('ContactID', CallSuccess, CallFailed, null);
}

Resources