public function find_ID($post_ID = false) - codeigniter

Can someone explain this code:
Why $post_ID = false being written in the codes:
models/post_model.php
public function find_ID($post_ID = false)
{
}
views/0headers.php
$article = $this->post_model->find_ID(48);

Actually I don't understand why it is in a function inside a model. The code inside that function may explain that.
It means if no $post_ID is passed from controller then take $post_ID as false to use it somewhere inside the function.
Example call would look like this:
$article = $this->post_model->find_ID();

Related

Laravel 6.2 - Dynamically Call a Controller action

I have used a code from Internet to call controller action dynamically. Here is the code for that, and is used in web.php. But I dont fully understand what it does.
Route::match(['get', 'post'], '{controller}/{action?}/{params1?}/{params2?}', function ($controller, $action = 'index', $params1 = '',$params2 = '') {
$params = explode('/', $params1);
$params[1] = $params2;
$app = app();
$controller = $app->make("\App\Http\Controllers\\" . ucwords($controller) . 'Controller');
return $controller->callAction($action, $params);
})->middleware('supadminauth');
Can someone explain?
Route::match(['get', 'post'], '{controller}/{action?}/{params1?}/{params2?}', function ($controller, $action = 'index', $params1 = '',$params2 = '') {
The first line looks at the request to see whether it is a get or post request, if it is some other types of request that means it does not match and will not proceed further. Then the url are separated into 4 parts corresponding by their name and passed into variables with the same name i.e. $controller, $action, $param1 and $params2 where the last 3 variables do not need to be present (with ? at the end of the name).
$params = explode('/', $params1);
$params[1] = $params2;
I believe this is a crude way to create an array of parameters as $params where the following would be more appropriate.
$params = [$params1, $params2];
.
$app = app();
$controller = $app->make("\App\Http\Controllers\\" . ucwords($controller) . 'Controller');
Then load the relevant controller.
return $controller->callAction($action, $params);
And run the corresponding action and passing all the parameters with it.
Hope this makes sense.
This is example of use it:
If you have controller like bellow:
class AdminController extends Controller {
public function index(){ //sample 0, sample 1
...
}
public function view($param1){ //sample2 , sample3
...
}
}
There is some sample route for calling them
sample0: yoursite.com/admin
sample1: yoursite.com/admin/index
sample2: yoursite.com/admin/view
sample3: yoursite.com/admin/view/5
Notice in your question ? in {action?} means it can either have value or not. Other things is simple and clear. Do you need more explaination?

Testing Laravel View Composers with Mockery

I am trying to test my View Composers. Whenever I pass an object to the $view->with('string', $object), my test fails. This is when I do the test like this:
$view
->shouldReceive('with')
->with('favorites', $this->user->favorites(Ad::class)->get())
->once();
I'm pretty sure this is due to strict checking. So I looked around and saw this issue. However, I can't seem to get it working. The closure return true, but the test fails:
Mockery\Exception\InvalidCountException : Method with('favorites',
< Closure===true >) from Mockery_3_Illuminate_View_View should be called
exactly 1 times but called 0 times.
Here is my current test
public function it_passes_favorites_to_the_view()
{
$this->setUpUser(); // basically sets $this->user to a User object
Auth::shouldReceive('user')
->once()
->andReturn($this->user);
$composer = new FavoritesComposer();
$view = Mockery::spy(View::class);
$view
->shouldReceive('with')
->with('favorites', Mockery::on(function($arg) {
$this->assertEquals($this->user->favorites(Ad::class)->get(), $arg);
}))
->once();
$composer->compose($view);
}
FavoritesComposer class:
public function compose(View $view)
{
$user = Auth::user();
$favorites = $user
? $user->favorites(Ad::class)->get()
: collect([]);
$view->with('favorites', $favorites);
}
How do I test object like this?
I fixed the issue by replacing $view->with('favorites', $favorites); with $view->with(['favorites' => $favorites]); and then testing it like this:
$view
->shouldReceive('with')
->with(['favorites' => $this->user->favorites(Ad::class)->get()])
->once();
So, essentially using only one parameter in the with()-method is what fixed it for me.

Loading view inside a Library, issues with cached vars

I am trying to implement a widgets library using load->view. I know I can use include to call directly the file and avoid the vars cache issues but just wondering why it does not work.
Here is how I have structured my code:
My Controller:
class Page extends MY_Controller {
public $data = array();
public function __construct() {
parent::__construct();
...
$this->load->library('widgetmanager');
}
public function index($slug = '') {
echo $this->widgetmanager->show(2);
echo $this->widgetmanager->show(1);
}
}
My Library
class WidgetManager
{
private $CI;
public function __construct()
{
$this->CI = & get_instance();
}
public function show($widget_id) {
$data = array();
$widget_id = (int)$widget_id;
$this->CI->db->select('*');
$this->CI->db->from('widget');
$this->CI->db->where('id', $widget_id);
$query = $this->CI->db->get();
$item = $query->row_array();
$data['widget_title'] = $item['title'];
$data['widget_content'] = $item['content'];
$widget = $this->CI->load->view('widget/'.$item['source'], $data, TRUE);
$data['widget_title'] = '';
$data['widget_content'] = '';
$this->CI->load->view('widget/'.$item['source'], $data);
return $widget;
}
}
widget 1: Calls widget/content
widget 2: Calls widget/banner
What is happening is, the vars set on the first widget call (they are same name as second widget call), get cached, meaning values from the first call are passed to same call. It is weird because are different views.
I have tried:
Using clear_vars(): $this->CI->load->clear_vars(), before and after doing load->view on the library.
Calling load->view with empty array, null, etc
Tried to add a prefix with the widget slug to the vars (that works, but I have to send in some way the prefix to the view, so it is not possible due cache issue)
Any ideas?
Here is what should work.
(I took the liberty of simplifying your database call making it require much less processing.)
public function show($widget_id)
{
$data = array();
$widget_id = (int) $widget_id;
$item = $this->CI->db
->get_where('widget', array('id' => $widget_id))
->row_array();
$data['widget_title'] = $item['title'];
$data['widget_content'] = $item['content'];
$widget = $this->CI->load->view('widget/'.$item['source'], $data, TRUE);
//clear the cached variables so the next call to 'show()' is clean
$this->CI->load->clear_vars();
return $widget;
}
On further consideration The call $this->CI->load->clear_vars(); is probably pointless because each time WidgetManager::show() is called the $data var is recreated with exactly the same keys. When the $data var is passed to load->view the new values of $data['widget_title'] and $data['widget_content'] will replace the values in the cached vars using those keys.

Same model for two tables

I set the name of my table in my model in the constructor:
public function __construct($section, $attributes = array(), $exists = false){
parent::__construct($attributes, $exists);
$this->table = $section;
}
Later on in the class I use this method:
public function getEdit($id){
return $this->find($id);
}
But it fails:
Missing argument 1 for MyModel::__construct()
Any ideas where I'm going wrong?
If you ever override a method that is provided by another class, you should add your own parameters to the end of the parameter list as optional parameters. The reason being that there will likely be code that relies on the old implementation. You can't expect it to know your new implementation, so you must add your own stuff to the end (and optional because the existing implementation won't be supplying it).
As such, change your constructor to:
public function __construct($attributes = array(), $exists = false, $section = null){
parent::__construct($attributes, $exists);
$this->table = $section;
}
And you should find it works. Obviously you'll have to update your code to pass $seciton as the last parameter now, too.

CodeIgniter Controller Method Parameters Issue

I'm using codeigniter 2.1 and I defined a function as follows.
public function reset($email, $hash) {
}
According to MVC architecture and OOPS concept, the function could not execute if I did not pass the parameters in the url. But in codeigniter this function gets executing, So how can i overcome this?. Please help me to find solutions.
Just you need to define null parametra like this:
public function reset($email = null, $hash = null) {
}
If you call function
(controller name)/reset/mail#mail.com/dsadasda
than $email = mail#mail.com & $hash = dsadasda
if you function
(controller name)/reset
than $email and $hash will be null.
Also you can declare default parametre like this.
public function reset($email = mail#mail.com, $hash = dsadasdas) {
}
Hope that I was clear.
If you want to execute function with or without parameters
you can set default values for it.
public function reset($email = '', $hash = '') {
}
This way when there are no parameters function can still execute.
You can use condition for code
public function reset($email = '', $hash = '') {
if(!empty($email) AND !empty($hash)){
//your code here
}
}

Resources