recall the construct in codigniter - codeigniter

How to recall the construct as it contains all the required data for the page?
class Abc extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('xyz_m');
$this->data['info'] = $this->xyz_m->get(); //get data
}
public function 123()
{
/*view page code*/
}
public function 456()
{
/*insert code here*/
$this->123(); // redirect, need to load 123() with updated data from construct.
}
}
So, how do you make the __construct initiate again so you get a new updated results from database?

You should name your methods with letter first i.e. there is convention for method names uses descriptive words getProducts() or get_books or you will get PHP error for using numbers as method names. So in your case method names should be like a123() or b_456().
Second thing, regarding your need in question, since you assign data from DB using model to array $this->data, you would use it like:
class Abc extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('xyz_m');
$this->data['info'] = $this->xyz_m->get(); //get data
}
public function a123()
{
$this->load->view('a123_view', $this->data);//loading file APPPATH . 'a123_view.php' and passing created array to it
}
public function b_456()
{
/*insert code here*/
$this->a123(); // redirect, need to load 123() with updated data from construct.
}
}
In your APPPATH . 'a123_view.php':
<?php var_dump($info);//here you would call key of array you passed from controller as variable ?>
Check basics in CodeIgniter documentations. All this is described in General Topics section.

Related

Laravel How not to Rewrite the Same code again

I have a model, called Tours and controller ToursController which uses restful methods (index, show, store, edit, update etc).
Now I have this code:
$names = request()->get('names');
$lastnames = request()->get('lastnames');
$hotels = request()->get('hotel');
both in Store and Update. So i duplicate the same code twice. And this is only one exmaple of duplicated code.
I want to create a function "getEverythingFromRequest()"
which I can use in both Store and Update methods. Something like:
public function store (Request $request) {
getEverythingFromRequest();
dd($names[3];
}
public function store (Request $request) {
getEverythingFromRequest();
dd($hotels[2];
}
How can I do it? Globally, how can I avoid re-writing the same code in Controller?
There are a bunch of ways to solve this. One way would be to create a repo that extracts the arrays from your request. (I updated my code to use injection).
Controller
public function store (GuestsRepository $repo, Request $request) {
dd($repo->names);
}
Repository
<?php
namespace App;
class GuestsRepository
{
public $names;
public $lastnames;
public $hotels;
public function __construct(){
$this->names = request()->get('names');
$this->lastnames = request()->get('lastnames');
$this->hotels = request()->get('hotel');
}
}

Laravel 4: Reference controller object inside filter

I have a controller in Laravel 4, with a custom variable declared within it.
class SampleController extends BaseController{
public $customVariable;
}
Two questions: Is there any way I can call within a route filter:
The controller object where the filter is running at.
The custom variable from that specific controller ($customVariable).
Thanks in advance!
as per this post:
http://forums.laravel.io/viewtopic.php?pid=47380#p47380
You can only pass parameters to filters as strings.
//routes.php
Route::get('/', ['before' => 'auth.level:1', function()
{
return View::make('hello');
}]);
and
//filters.php
Route::filter('auth.level', function($level)
{
//$level is 1
});
In controllers, it would look more like this
public function __construct(){
$this->filter('before', 'someFilter:param1,param2');
}
EDIT:
Should this not suffice to your needs, you can allways define the filter inside the controller's constructor. If you need access to the current controller ($this) and it's custom fields and you have many different classes you want to have that in, you can put the filter in BaseController's constructor and extend it in all classes you need.
class SomeFancyController extends BaseController {
protected $customVariable
/**
* Instantiate a new SomeFancyController instance.
*/
public function __construct()
{
$ctrl = $this;
$this->beforeFilter(function() use ($ctrl)
{
//
// do something with $ctrl
// do something with $ctrl->customVariable;
});
}
}
EDIT 2 :
As per your new question I realised the above example had a small error - as I forgot the closure has local scope. So it's correct now I guess.
If you declare it as static in your controller, you can call it statically from outside the controller
Controller:
class SampleController extends BaseController
{
public static $customVariable = 'test';
}
Outside your controller
echo SampleController::$customVariable
use:
public function __construct()
{
$this->beforeFilter('auth', ['controller' => $this]);
}

CodeIgniter - Replace redunant JSON conversion

I recently started using Codeigniter after having a structural problem in one of my Ajax-heavy applications. (You can read up on it if you want in my previous question)
I have a fairly short question. Currently I am making a lot of Ajax requests to different controllers. I open the controllers like this:
public function __construct()
{
parent::__construct();
$this->output->set_content_type('application/json');
}
And at the end of every function I do the following:
$this->returnValue['result'] = "ReturnedInfo";
$this->returnValue = json_encode($this->returnValue);
$this->output->set_output($this->returnValue);
The code is pretty clear in itself, but I don't want to keep repeating myself. The codeigniter manual says to do the following:
$this->output
->set_content_type('application/json')
->set_output(json_encode(array('foo' => 'bar')));
But I would still be repeating myself. Also, I don't want to add a function to every controller that does this, even if it does decrease redundancy.
Since all of my controllers return JSON, is there a way to set this globally in a config file maybe, or in any other way?
TL;DR I have this same piece of code in every controller/function. Since the output type is always the same, just not the result, is there a way to automate this process across every controller/function?
Create an Ajax_Controller that extends MY_Controller that extends CI_Controller.
The Ajax Controller will then inherit from both Controllers.
class Ajax_Controller extends MY_Controller
{
public function __construct()
{
parent::__construct();
if(!$this->input->is_ajax_request()) return show_error('Invalid Request');
}
public function jsonOutput($json)
{
//some data checking here....
return $this->output
->set_content_type('application/json')
->set_header("HTTP/1.1 200 OK")
->set_output($json);
}
}
-
class User extends Ajax_Controller
{
public function __construct()
{
parent::__construct();
}
public function userMethod()
{
$json = json_encode(array(
'' => ''
));
$this->jsonOutput($json);
}
}
Extend your controllers from your own base class rather than CI_Controller and put your repeatedly-used function(s) and constructor code in there. Something like:
class BaseController extends CI_Controller {
protected function index() {
$this->returnValue['result'] = "ReturnedInfo";
$this->returnValue = json_encode($this->returnValue);
$this->output->set_output($this->returnValue);
}
}
class Specific extends BaseController {
public function index() {
//do controller-specific stuff
parent::index();
}
}
I abstract this further if I have groups of controllers with shared code; for example, if I had a bunch of controllers that require the user to be logged-in I create AuthenticatedController, which extends BaseController and add session checks etc.

Codeigniter updating records in db table

I want to change a specific record in the database using codeigniter. The url should be like this mysite.com/users/edit/10.
Here the user having id=10 is being edited
users is the controller name and edit is a method.
Usually I do in this way
//code of the rest of controller
.....
function edit(){
$uid =$_REQUEST['uid'];
//database update code
}
...
Where a form is being posted deliberately to change the record
You're not clear at all on what you want, I just can give you some pointers.
In CI, you don't need (don't have to) use superglobals to access url parameters. It has a native system to manage uri segments, which became automatically accessible without the need to call them; they're available as arguments of the method you're accessing.
So, in a url like yours, mysite.com/users/edit/10, you'll have
Controller:
class Users extends CI_Controller {
public function edit($uid)
{
// $uid is automatically passed to this method and is already available
// here you do your operations
//for. ex.
$this->load->model('user_model');
$this->user_model->update_user($uid);
}
}
Model:
class User_model extends CI_Model {
function __construct()
{
parent::__construct();
}
function update_user($id)
{
$this->db->where('id',$id);
$fields = array('field1' => 'value1','field2' => 'value2'...);
$this->db->update('users',$fields);
}
}
If you provide further information I could expand my answer.

Convenient Way to Load Multiple Databases in Code Igniter

I've added the appropriate configuration arrays to database.php and they work, however, I would like an easier way to access the different databases. Right now I have to do something like this in every controller method:
function index(){
$BILLING = $this->load->database('billing', TRUE);
$INVENTORY = $this->load->database('inventory', TRUE);
$data['billing'] = $BILLING->get('stuff');
$data['inventory'] = $INVENTORY->get('stuff');
}
I'd like to be able to put those first two lines in some sort of before filter or pre_controller hook.
You could simply load the database instances globally in your constructor, then they would be available to all controller methods...
example controller
class Example extends CI_Controller {
//declare them globally in your controller
private $billing_db;
private $inventory_db;
function __construct() {
parent::__construct();
//Load them in the constructor
$this->billing_db = $this->load->database('billing', TRUE);
$this->inventory_db = $this->load->database('inventory', TRUE);
}
function index() {
//Then use them in any controller like this
$data['billing'] = $this->inventory_db->get('stuff');
$data['inventory'] = $this->billing_db->get('stuff');
}
}
And if these same databases are used across multiple controllers, you might consider extending the base controller to include these global variables and load them in the constructor of your base controller in MY_Controller.php
example MY_Controller.php
class DB_Controller extends CI_Controller {
//declare them globally in your controller
private $billing_db;
private $inventory_db;
function __construct() {
parent::__construct();
//Load them in the constructor
$this->billing_db = $this->load->database('billing', TRUE);
$this->inventory_db = $this->load->database('inventory', TRUE);
}
}
Then you'd use it like this...
class Example extends DB_Controller {
function __construct() {
parent::__construct();
}
function index() {
//Then use them in any controller like this
$data['billing'] = $this->inventory_db->get('stuff');
$data['inventory'] = $this->billing_db->get('stuff');
}
}

Resources