I am developing an application in codeigniter containing different modules e.g buyer, seller, public. All these modules use same header file. I want a global variable declared in buyer, seller and public controller so that when I load views of one module this variable should help customizing parts of header for seller depending upon its value. Same goes for buyer and public modules.
I want to ask what is the way to have a variable declared at controller scope and then use its value in its views. I have tried declaring and assigning its value in constructor but I get undefined variable error when loading the views. I also tried this way:
class Seller extends CI_Controller {
public $pagetype="seller";
public function __construct()
{
parent::__construct();
}
But I still get undefined variable error.
I can pass value of page type when loading view but I have to do that for each view, which is bad and cumbersome way because I have around 25-30 views in each controller.
Any help?
in your controller you can make data globally available in the view layer using this
$this->load->vars($data);
where $data is an array of key => values. you could put this in your constructor, or parent constructor
Consider making your own class - look into Singleton or Registry design patterns... but also read this: What is so bad about singletons?
you could assign the main CodeIgniter object to a variable and then use load->get_var($key) to get the view variable.
function something() {
$ci =& get_instance();
$myvar = $ci->load->get_var(‘myvar);
}
Related
I'm newbie in Codeigniter.
I have a table in my database called 'sysConfig' with columns such as title, money unit, license key and ... .
I want to get first line of this table record (it has only one record) to a global variable called '$Config' that it available in all views (If it was possible available in models and controllers).
Edit:
I can select any data from database and I dont have any problem with this. I want to select data on table sysConfig in a variable called $Config and access ti it directly like this <?php echo $Config['Title']; ?> or <?php echo $Config -> Title; ?>.
The best way to do this, if these are system config items is to load them in your own config file.
Create your own config file. Load it manually or in autoload.
$this->config->load('filename');
Access items in it like this
$this->config->item('item_name');
You can also set dynamicallly the config items using this:
$this->config->set_item('item_name', 'item_value');
You can read about it here in the docs: http://www.codeigniter.com/user_guide/libraries/config.html
Alternatively, if this is user based, collect the information into the current session and access that. Although accessing session variables in models or libraries is not a good idea. You should pass the required items as function arguments.
One approach is to add a property to any controller that will need sysConfig data. The name of the variable should not be $config because CI already uses that symbol - it is defined and set by the Config class. So for this answer I will use $sysConfig.
class Some_controller extends CI_Controller
{
protected $sysConfig; //class property with scope to this controller
public function __construct()
{
parent :: __construct();
$this->load->model('sysConfig_model');
}
sysConfig_model (not shown) manages the table you seem to have established. I'm making up functions for that model since you don't show us any code. The model function get($id) retrieves the "user" you want based on $id and returns the data in an array. (The setting of $id with a valid value is not shown.)
The controller can make use of the property as needed by way of $this->sysConfig as in this admittedly trivial made-up controller function.
The class definition continues with...
public function format_title()
{
if(isset($this->sysConfig){
$this->sysConfig['suckup'] = "the most highly regarded "
. $this->sysConfig['title']
. " in the world visit our site!";
}
}
Actually assigning a value to $this->sysConfig happens in this next bit of code. In this example, the controller's index() function can receive an argument that is the "ID" of the user we want to get from the database.
public function index($id = NULL)
{
//assign data to the class property $sysConfig from the model
$this->sysConfig = $this->sysConfig_model->get($id);
The property can be passed to a view quite easily. First we do some sucking up.
$this->format_title();
$data['userStuff'] = $this->sysConfig;
$this->load->view('some_view', $data);
} //end of index()
} //end of class Some_controller
some_view.php
<div>
<h4>Welcome <?php echo $userStuff['firstName']. " " . $userStuff['lastName']; ?></h4>
<p>I cannot say how swell it is to have <?php echo $userStuff['suckup']; ?></p>
</div>
The idea of a "global" is really contrary to OOP methodology in PHP - or any other OOP language.
I have a variable that has the first URL segment. I want to use this as a class on the body tag. It will mainly be used for setting links in my navigation as being active. Is there a way that I can create this variable in one place and use it in all of my controllers? Its not that big of a problem to set it in all of my controllers but I'd like to keep my code as clean as possible. This is what I have in my controllers right now:
$url_segment = $this->uri->rsegment_array(); //get array of url segment strings
$data['url_segment'] = $url_segment[1]; //gets string of first url segment
Is there a way to only have the code above ONCE in my app, instead of inside all of my controllers? If so where should I place it?
I'd extend CI_Controller with a custom subclass that includes that variable, then have all the actual controllers extend that. CodeIgniter makes it easy - just create application/core/MY_Controller.php containing something along these lines:
class MY_Controller extends CI_Controller {
private $cached_url_seg;
function MY_Controller() {
parent::construct();
$url_segment = $this->uri->rsegment_array(); //get array of url segment strings
$this->cached_url_seg = $url_segment[1]; //gets string of first url segment
}
}
And then change your controllers to extend MY_Controller.
You'll still have to add it to $data in each individual controller, but I suppose if you wanted you could add private $data to MY_Controller, too.
You might want to consider making a 1 time library file, with all features you want to be globally accessable, then in your autoload.php add this library there so it initializes automatically..
class my_global_lib {
protected $CI;
public $segment;
public function __construct(){
parent::__construct();
$this->CI =& get_instance();
// Do your code here like:
$this->segment = $this->CI->uri->segment(1);
// Any other things you want to have accessable by default could go here
}
}
This would allow you to call this from your controller like so
echo $this->my_global_lib->segment;
does this help?
I'm trying to access global variables from a model. The global variable is set from a controller:
function sets(){
$value = $this->input->post('current_id');
$anywhere = array('current_id'=>$value);
$this->load->vars($anywhere);
}
But the model doesn't know the value of the current id:
$session_id = $this->load->get_var('current_id');
Unfortunately the CodeIgniter Model doesn't have access to the values that you're looking for. But there is hope! There are a few ways to go about having getting access to the parameters that are loaded from the request, choose your poison, but having a defined contract interface for your model is, in my opinion, something that makes writing code easier and less of a hassle to maintain down the line.
A reference to the CodeIgniter object can be grabbed like so:
$ci =& get_instance();
$session_id = $ci->load->get_var('current_id');
Of course this would be the nasty way to go about getting at your data. A better approach would be to pass it in to the model itself as a parameter. You're not going to be paying for much in doing so, and it gives you a contract signature on the method where you can point and say "Hey, this should be the current_id of the model:
function sets($session_id)
{
...
}
And, of course, you would just pass in the value you wish $current_id to be as an argument in that function call. This gives you the flexibility of not having to rely on the fact that you're populating the model from a POST HTTP request.
The CI_Model class doesn't have a Loader, so $this->load doesn't exist in a model.
$this->load->get_var() is for controllers to use. From the Loader documentation -
This is useful if for any reason a var is set in a library or another controller method using $this->load->vars().
Try this,
$ci =& get_instance();
$ci->load->get_var('current_id');
But my think, this isn't good idea.
You can use input->post() method on model or set variable with model function arguments.
I have a view helper that manages generating thumbnails for images. The images are stored using a unique ID and then linked to a file resource in the database.
I am trying to find out if it is possible for the view helper that generates these images to access the model or controller directly, as it is not possible to load the image data at any other point in the controller work flow.
I know this is a bit of a hack really, but it is easier than trying to rebuild the entire data management stack above the view.
If you had set the data in the model or controller you could access it. So you'd have to think ahead in the controller. As you said you can't load it in the controller, perhaps you need to write a specific controller function, which you can call from the view using $this->requestAction() and pass in the image name or similar as a parameter.
The only disadvantage of this is using requestAction() is frowned upon, as it initiates an entirely new dispatch cycle, which can slow down your app a bit.
The other option, which may work is creating a dynamic element and passing in a parameter into the element and have it create the image for you. Although I'm not too sure how this would work in practise.
How are you generating the thumbnails using the helper in the view if you aren't passing data into it from a controller or model? I mean if it was me, I would be setting the 'database resource' in the controller, and passing it to the view that way, then having the helper deal with it in the view. That way you could bypass this issue entirely :)
$this->params['controller'] will return what you want.
According to the ... you can put this code in a view.ctp file then open the URL to render the debug info:
$cn = get_class($this);
$cm = get_class_methods($cn);
print_r($cm);
die();
You could write a helper and build in a static function setController() and pass the reference in through as a parameter and then store it in a static variable in your helper class:
class FancyHelper extends FormHelper {
static $controller;
public static function setController($controller) {
self::$controller = $controller;
}
... more stuff
}
Then in your Controller class you could import the FancyHelper class and make the static assignment in the beforeFilter function:
App::uses('FancyHelper', 'View/Helper');
class FancyController extends AppController {
public $helpers = array('Fancy');
function beforeFilter() {
FancyHelper::setController($this);
}
... more stuff
}
And then you could access the controller from other public functions inside FancyHelper using self::$controller.
You can check the code(line ☛366 and
line ☛379) of the FormHelper, try with:
echo $this->request->params['controller'];
echo Inflector::underscore($this->viewPath);
I have a controller with different methods, but they all have to set a variable containing a list of items to be shown in a box in the view, I extract data from the DB and set $data['categories'].
Can I set it once and have it visible by all methods?
In addition to this, if you are only using $this->data to get the values into your views, instead of doing:
$this->data->something = 'whatever';
Then doing
$this->load->view('something', $this->data);
You can instead set it with:
$this->load->vars('something', 'whatever');
Then later on use the normal localized $data array (or whatever you like) as the variable will be globally available to all loaded view files.
I'm not suggesting either way is better, just letting you know how else it could be done. I personally use a mix of these methods. :-)
make it a property of the class
class Controller {
protected $data;
and use '$this' to access in in your methods:
class Controller {
function foo() {
$this->data etc...