Load a library in a model in CodeIgniter - codeigniter

Why won't my model load the encryption library?
class User_model extends Model {
function User_model() {
parent::Model();
$this->check_login();
}
function check_login() {
$this->load->library('encrypt');
$email = $this->encrypt->decode($email);
....
}
}
This giving me a PHP error: Call to a member function decode() on a non-object on line X -- where X is the $this->encrypt->decode($email); line?
Edited to show that the problem was that check_login was called from the constructor

You don't need to load the library in the MODEL, MODELS are always called from the CONTROLLERS so you just have to load the Libraries in the Controller, and the functions will be available in the models called from him!
Regards,
Pedro

Libraries should automatically be assigned to the Model instance so it should work fine.
Remember if you can't access the super-global you can always use $ci =& get_instance() to grab it at no extra cost to your memory.
But still... your code example should work >.<

I was calling check_login from within the constructor, and that was causing the problems.
The solution is to call $this->_assign_libraries(); right after loading a library in a constructor.
Thanks to this codeignitor forum thread:
http://codeigniter.com/forums/viewthread/145537/

I have tried many of them, but in the end, what I did is this in a model:
$this->load->library('mylib');
$mylib= new Mylib();
$mylib->somemethod();
This works for me.

you might want to change the name of the object for the library you are loading
beacause CI also has got the encrypt class
just do
$this->load->library('encrypt',NULL,'myencryptobj');
$this->myencryptobj->yourfunction();
Hope this helps

i was also facing issue about facebook api, then I tried required_once the lib file of facebook in model. it worked for me.
require_once "application/libraries/facebook.php";
then make its object if you need.

Related

Call loadMissing() in a isolated model replica

I have a question maybe a little silly. I'm trying to replicate and store a model instance in a variable to call the loadMissing method. The idea is to call the loadMissing method without being affected by the original model. Let me explain.
I have the following method in my User model:
class User extends Authenticatable
{
...
public function myCustomMethod()
{
$cloned = $this->replicate()
->loadMissing(['roles', 'roles.permissions'])
->getAttribute('roles')
->flatMap(function ($role) {
return $role->permissions
});
return $cloned;
}
The problem is that in this way the original model instance is affected, and it loads in the original instance all the relations that I am loading only in this method.
My question is: is there a way to load and isolate relationships in a replica of the model instance without affecting the original model?
Thanks in advance.
EDIT 1
I have also tried cloning the instance and trying to use the loadMissing method on the cloned instance, but the original instance is also affected. For example:
class User extends Authenticatable
{
...
public function myCustomMethod()
{
$original = $this;
$cloned = clone $original;
$cloned->loadMissing('roles.permissions');
dump($original);
dump($cloned);
die();
}
But in this way, I get the following results. Notice that both the original and the cloned instance are loading the relationships when I'm just trying to load the relationships in the cloned instance:
$original
$cloned
I was wondering if this is normal behavior. If it is a normal behavior, which I suppose it is not, I was wondering if there is any way to use the loadMissing method on a copy, replica or clone of an instance without modifying the original instance. Thank you very much in advance.
EDIT 2
My controller looks like simple like this:
class HomeController extends Controller
{
public function index()
{
dd(User::find(1)->myCustomMethod());
}
}
SOLUTION
After several days looking for documentation, doing tests and pulling my hair a little, I have found the solution to my problem and share it in case someone comes here looking for similar information in the future.
Basically the answer that helped me find the right way was this:
https://stackoverflow.com/a/29787693/13066106
Which is documented in the official PHP documentation:
https://www.php.net/manual/en/language.oop5.cloning.php
I copy and paste verbatim the most relevant here:
When an object is cloned, PHP will perform a shallow copy of all of the object's properties. Any properties that are references to other variables will remain references.
When I got to this point, I understood why it wasn't working ... I was cloning a collection of type Illuminate\Database\Eloquent\Collection and this collection contained multiple objects of type Role, but according to the documentation, it is normal behavior that when I modify any property in the cloned instance, the changes will be reflected back to me in the original instance.
From here, I looked for more documentation about it and I found an article that definitely helped me solve my problem:
Don't clone your php objects, DeepCopy them
The article is quite descriptive and basically what it does is advise the use of the package DeepCopy
Fortunately, the package is already a Laravel dependency by default, so I didn't have to install it with composer. I just used the deep_copy method to clone the instance.
Thank you very much to everyone who helped me in some way. I hope that the links to the documentation that I have shared will be of use to those who come here looking for similar information.
Why don't you just get the permissions collection (outside of model):
$userId = $user->id;
$premissions = Permissions::whereHas('users', function($userQuery) use ($userID) {
$userQuery->where('id',$userId);
})
->get();
Or do the flatmap:
$result = Roles::with('permissions')
->whereHas('users', function($userQuery) use ($userID) {
$userQuery->where('id',$userId);
})
->get()
->flatMap(function ($role) {
return $role->permissions
});

How to use $this in another file on Codeigniter?

I have a file named fn.php in my view, then I create a function to post data, like this
function post($input_name){
return $this->input->post($input_name);
}
In my controller I call it like this,
public function myFunc(){
$this->input->load('fn.php');
// then I use the function that I have created like this
post('myinputname');
}
But... I got error, how I can solve this problem? thank you so much
You should take some time to try and understand the MVC architecture. It is, after all, one of the main points of using a framework.
You can't put functions in a view and expect to load them somehow and access them. You can put functions in a model, controller, library or helper. In you case I would suggest a helper:
application/helpers/some_file_helper.php
function post($input_name){
$CI = &get_instance();
return $CI->input->post($input_name);
}
The get_instance() part is only used when $this (CI context) isn't available. This only happens in helpers and libraries. In views, controllers, and models $this is always available.
Model or controller:
$this->load->helper('some_file');
print_r(post('somevar'));
However if all you want to do is access the post variable use $this->input->post('somevar') directly and don't introduce an extra layer.

Trying to understand the view method and general method calling in laravel

I am a new to laravel and trying to understand where the view method comes from and what mechanism allows it to be shown in the web.php folder in laravel.
For example :
Route::get('/', function () { return view('welcome'); })
I guess the view function is defined in some class. Bu which class is it and where is that class made reference to in order to access its method?
Thanks a lot if you can help me understanding this!
In most IDEs you can hold CTRL and left-click the function to view it's definition. view() is not defined in a class. It comes from a file called helpers.php.
This file is included at the beginning, so its functions can be used afterwards.
PHP is not only object oriented. Procedural and object oriented programming can be mixed together.
What I do usually in these cases is to search in the whole project (and remember to include vendor directory in your search) for: "function YOUR_FUNCTION_NAME" because somewhere in PHP there must be that function declared, whether is in a class or in a simple .php file.
view() method is a helper method inside src/Illuminate/Foundation/helpers.php. All the methods that declare here will be available everywhere inside Laravel application. You can check view() method here

How to load more than one controller in another controller in CodeIgniter

How to load more than one controller in another controller in CodeIgniter. The below code is i'm using. But it doesn't working. Only the controller which specified at first was work the second one is not working.
class A extends CI_Controller{
function __construct(){
parent::__construct();
$this->load->controller('B');
$this->load->controller('C');
}
}
You shouldn't be loading other controllers. Each request should be handled by a single controller. If you require common behaviour you have the following options:
/application/core/MY_Controller.php and extend that class
Move the behaviour to a model
Move the behaviour to a library or helper
If you are unfamiliar with the MVC pattern, this forum post might help you. It's from an old thread, but the principles still apply.
There are various methods to do that.
One of them: you can try this.
//Load the controller you want
$this->load->library('../controllers/controller_name');
//and can call functions of that controller
$this->controller_name->function_name();
I hope this is helpful!

Why does code igniter not segregate class types?

When you are using code igniter you load a library or model like so
$this->load->library('mylibrary');
$this->load->model('mymodel');
So, in a real world example, lets say you have a controller called user.
So, to login a user you send them to http://example.com/user/login
Now the login function loads a form that submits to http://example.com/user/login_do
You do some simple checks, and then send it over to your model to do the database check for you.
So you call
$this->load->model('user');
if($this->user->validate($email, $pass)){...}
UH OH!
Fatal error: Cannot redeclare class
User in
/var/www/unity/src/application/models/User_Model.php
on line ...
So what happened? Well, Code igniter does not segregate the classes, so your model now conflicts with your controller,
sure you can use
$this->load->model('user_model', '', 'user_m');
if($this->user_m->validate($email, $pass)){...}
So, Onto my question.
Why does code igniter not segregate the classes,
e.g. so you would call
$this->load->model('user');
if($this->model->user->validate($email, $pass)){...}
Sure it's slightly longer, but hell it would make things heaps nicer to user.
is it possible to extend code igniter so it works in this way?
It's not exactly the solution you're asking for (or a great idea), but there's nothing stopping you from doing this:
class Users extends CI_Controller {
private $model;
private $m;
public function __construct()
{
parent::__construct();
$this->load->model('user_model');
$this->model->users = $this->user_model;
$this->m = $this->user_model;
}
function index()
{
// Here's that syntax you wanted
$this->model->users->get_many();
// Even shorter
$this->m->get_many();
}
}
You can really just assign anything to any property of the controller you want, as long as it's not the name of a loaded class or property (session, router, etc.). It can save you some typing if your model names are really long, but otherwise it's pointless and may conflict with things in the future.
Here's what I do if I'm not using *_model for model names:
Controller name: Users (plural)
Model name: User (singular)
No conflict, short syntax, sensible naming, it just doesn't work for some names like "news".
As I mentioned, it would be nice to see controller names using something like Controller_User or User_Controller to clear up the namespace issues a bit for the classes that we actually do have to call frequently, like models and libraries, but keep our urls as normal. I'm sure it can be done, something for a rainy day...
You missing the main point, PHP doesn't allow two classes with the same name, basically that's what Cannot redeclare class User says.

Resources