Get User configuration from database in a global variable - php

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.

Related

How to use global variables in codeigniter?

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);
}

Global Vars in CodeIgniter

I want to save some global vars to use in the website, like current user id, current user lever, and so on. Where is the best place to do it, or is it possible?
Setting it into constants.php is not working since "$this" is not recognized there.
The principal reason why I want this is because i don't like using sessions (I consider writing strings like $this->session->userdata('session_name') not so practical, writing something like CURR_UID is more easy to do it and read as well)
It's possible, but it isn't the way that Codeigniter was designed. Sessions are really the place for this kind of thing (namely, stuff that persists from one page view to the next), but you could wrap the session calls up in a library for beauty's sake if you wanted. Something like this:
// in libraries/User.php
class User {
protected $ci;
public function __construct() {
$this->ci = &get_instance();
}
public function id() {
return $this->ci->session->userdata('user_id');
}
// etc, etc.
}
Once you've written a few more helpers like id(), you can use them to access the relevant variables elsewhere in your application:
$this->load->library('user');
echo 'Current user ID is: ' . $this->user->id();
What you can do in this case is create a class My_Controller extends CI_Controller. Sort out all the functionality that you would need before actually loading any of the specific controller functionality.
Then any subsequent class you create you can do: class Whatever extends My_Controller.
Edit: I forgot to mention you should put the My_Controller class within the Application > Core folder.

Codeigniter: easiest way to use variables between models and controllers, models and models, controllers and controllers

Is this just impossible?
I thought I would clean up some of my code and put db queries in models only where they belong and put all the other code that belongs in controllers in controllers.
Now I keep getting undefined variable errors. Which is not a problem but I'm trying to work out how to call variables between files.
I would simply like the random hash generated at registration .. stored in a variable because that's the variable I use in the anchor for the "click here to activate account" link that is sent to users email.
I also use that same variable in the method that compares the uri hash that's at the end of the URL in their email with the one stored in the database.. in order for user to confirm their account and update "status" in database to 1(activated).
I would really appreciate some advice. I'm enjoying this learning process. Loosing sleep but enjoying it as it make me think logically.
You cannot access a variable if it's in a seperate file, instead you should set it in your class.
class User_model extends Model {
// Declare the foo variable
public $foo = "";
function blah() {
// You can set variable foo this way from any controller/model that includes this model
$this->foo = "dog";
// You can access variable foo this way
echo $this->foo;
}
}

PHP MVC Best Practice - Pass Session variable to model class from controller or access directly in model

Our development team is debating a general best practice:
Is it better to access a session variable directly from a function in a model class or pass the session variable from the controller as an argument to a function in the model class. Look at the two examples below:
Accessing session variable directly from the model class to use in a query:
class MyModel {
public function getUserPrefs($userID) {
$this->query("SELECT * FROM my_table WHERE id=$_SESSION['userID']");
}
}
Or pass the session variable from the controller to a function in the model class as a function argument:
class MyController {
public function displayUsers() {
$this->model->getUserPrefs($_SESSION['userID']);
}
}
class MyModel {
public function getUserPrefs($userID) {
$this->query("SELECT * FROM my_table WHERE id=$userID");
}
}
The reasoning for passing it to the model from the controller is so all data that is referenced is coming from one point of entry, that being the controller.
What is recognized as a better practice?
The second version (passing $_SESSION['userId'] as an argument to the method) results in a more decoupled class, and therefore more flexible. Go with it.
You NEVER want to have session variables in your model. You should always pass these variables as parameters to the function in the model. This also makes your code more expandable and flexible. Consider a model that gets a user by their id. You may write a function like:
function find_by_id() {
// SELECT * FROM Users WHERE user_id = $_SESSION['user_id'];
}
However, what if you now what to build an admin functionality with a user lookup feature? Your model is hardcoded to use the session's user_id, but you want to be able to pass your own id. You would be better off:
function find_by_id($id) {
// SELECT * FROM Users WHERE user_id = $id
}
and in your controller
$user = Model::find_by_id(1);
//or
$user = Model::find_by_id($_SESSION['user_id']);
//etc
In this case, however, I would really consider making your code even MORE flexible:
function find($ids) {
// this is pseudo code, but you get the idea
if(is_array($ids))
$ids = implode(',', $ids); // if an array of ids was passed, implode them with commas
SELECT * FROM Users WHERE user_id IN ($ids);
}
This allows you to get multiple users in ONE query! Which is way more efficient. Then, in your view:
foreach($users as $user){
// iterate over each user and do stuff
}
You should also consider using a singelton class for a User to limit database load. Create a non-changing instance class called CurrentUser (for example) like:
class CurrentUser {
private static $user;
// we never instantiate it -its singleton
private function __construct() {}
public function user() {
return self::$user;
}
}
This is a really basic example of a singleton class and is missing a lot of stuff. If you want to know more about singleton classes, post another question.
Keep in mind that "session" is just yet another model. However first approach is unacceptable - what if you would like to fetch another users preferences just to compare them with something? Use the second approach.
I agree with Seth re. "You should also consider using a singelton class for a User to limit database load. Create a non-changing instance class called CurrentUser".
In my pseudo-MVC app I have class User (meaning current user) with methods for session, getting user info, roles etc., and class Member (meaning any given user) with methods for registering new users, getting/updating their properties etc but nothing to do with sessions, for example. Also, it is a singleton scenario, so current user is static and does not require much interaction with the DB.
So in my case, my controller and views make calls to User methods, e.g.
User::getId() or User::getGroups().

Passing parameters to controller's constructor

I have a controller which has several methods which should all share common informations. Let's say my URI format is like this:
http://server/users/id/admin/index
http://server/users/id/admin/new
http://server/users/id/admin/list
http://server/users/id/admin/delete
I need to retrieve some informations from the database for id and have them available for all methods instead of writing a line in each of them to call the model. How can I do this?
class users extends Controller {
private $mydata = array();
function users()
{
parent::Controller();
....
$this->mydata = $this->model->get_stuff($this->uri->segment(2));
}
function index()
{
$this->mydata; //hello data!
}
Here I simply hardcoded the array (which probably is a really bad idea). Nevertheless you can store the data in a codeigniter session if you need to. Codeigniter can store this data in a cookie (if it's total is less than 4kb) otherwise you can store bigger blobs of data in the database (see the docs on how to do this).
See: http://codeigniter.com/user_guide/libraries/sessions.html
Subsection: Saving Session Data to a Database
Here's some session exercise:
$this->session->set_userdata('mydata', $mydata);
....
$mydata = $this->session->userdata('mydata');
If this cannot be solved from CodeIgniters Hook mechanism, you could override the constructor method in your controller and call your own. Judging from their SVN repository you'd probably would do something like
class YourController extends Controller
{
function YourController()
{
parent::Controller();
$this->_preDispatch();
}
function _preDispatch()
{
// any code you want to run before the controller action is called
}
Might be that the call to preDispatch has to be before the call to parent. Just try it and see if it works. I didnt know they still use PHP4 syntax. Ugh :(
Based on your url structure, and the fact that codeignitor uses a MVC pattern, I'm assuming you're using mod_rewrite to format the url path into a query string for index.php. If this is the case, the value of "id" should be available at $_REQUEST['id'] at any point in the execution of the script...

Categories