I have a list of constants (I'm using them as an enum), some are define statements, and some are just global variables.
Where am I suppose to put them in the MVC framework so I can use them for both my model and my controller that needs to reference it?
I'd rather not stick it into config/constants.php since they shouldn't be called except for by this model and the controllers that use it.
Edit 1: Clarification
To be more specific, I have my message_model model and it has a bunch of constants that I need that are stored in message_model_constants.php. Where should I put message_model_constants.php and is there a way to have it automatically included by the controller that loads message_model when message_model is not (and I don't want it to be) auto-loaded.
Edit 2:
I really don't want to have the constants auto-loaded except for when I use the model
Go to application/config/constants.php and define your constant their and you can use your constants on Model-View-Controller of CI not include "Helper" and "Library"
But in your case I prefer you to create a php file that has your constants and rename it to something like my_constants_helper.php.
In your model or controller __construct just
$this->load->helper('my_constants');
And hooray you can access them =)
You can choose to load a particular config file when you load a particular model in the controller. For instance in your file:
application/controllers/messages.php
You would use a line like this:
$this->config->load('messages');
If you include it at the top of your controller like this
function __construct() {
$this->config->load('messages');
$this->load->model('message_model');
}
Then all of those constants will be available to all the functions and methods in the given controller. You then call each config constant like:
$this->config->item('item name')
And you can name protected $variables; in the construct as well for shorter syntax.
If you are using these config constants and the message model in multiple different controllers you may want make a "Library" file that then loads both the config and the model and declares all variables there.
extending Brennan Novak answer, you can simplify your code by loading your config file in the model constructor. That way, you only have to load the model in your controllers and everything else is done automatically.
Model
class Message_model extends Model {
function __construct()
{
parent::Model();
$this->load->config('message_model_constants');
}
...
}
Controller
class Some_controller extends Controller {
function __construct()
{
parent::Controller();
$this->load->model('message_model');
}
...
}
As already stated, your config files should be application/config/message_model_constants.php
For global configs, add to the config/config.php or create a config/application.php and then load the config, then the item.
$this->config->load('application'); // or autoload this - $autoload['config'] = array('application');
$this->config->item('item name');
Have you considered just adding your constants to your Message_Model Class? You'll then reference them by self::ConstantName inside the Class and Message_Model::ConstantName outside the class. This would also prevent name space collision.
Related
I created a class MyController and put in in core folder. It extends CI_Controller;
Then I created a controller Foo that extends myController. I wanted to do something like exit() in a certain point of the Foo's __construct function.
class Foo extends MyController{
private $formats = array('json');
function __construct(){
parent::__construct();
//do something
exit();
}
}
What I want with this is to stop rendering views in certain cases. But it's not working, if I go to myproject/foo/whatever it still goes to whatever action and renders the 404 default view
How can I achieve this?
The problem is your Controller name. You need to follow Codeigniter's naming convention.
Change the name of the class in the Core folder to start with MY_ such as MY_main_controller, rename your classes, and it should work.
Extending Core Classes
I've now some entities, reposetories and controllers in flow3 and they work very well. In case someone needs a global fluid variable (e.g. a username printed in the default layout) he has to define and use a global controller.
How can I create and use such controllers?
Controllers are classes, so you can extend them and create abstract ones.
Let's assume you have LoveController in My.Relationships package.
You can create some separate base package i.e. My.Life with AbstractLifeController inside (php: abstract class AbstractLifeController extends \TYPO3\Flow\Mvc\Controller\ActionController).
Now there are initialize* methods (where * might be Action, View, AnyAction and so on). In your case use: protected initializeView(\TYPO3\Flow\Mvc\View\ViewInterface $view) in this abstarct controller and there assign some variables i.e. $view->assign('myName', $myName); ...
Then when your LoveController extends \My\Life\Controller\AbstractLifeController, that variable {myName} will be visible in fluid for templates used by its actions.
So instead of extending \TYPO3\Flow\Mvc\Controller\ActionController for all your controllers, just extend this abstract one \My\Life\Controller\AbstractLifeController
I have created a custom class with few method in it. e.g.
class MyClass{
method1 ();
method2();
}
Now I want to create object of this class and use it inside a controller method
class DefaultController{
public function myAction()
{
//here I want to able to create object of MyClass, is it possible?
}
}
Q1. where should I store this class in symfony2 structuere e.g. inside src dir?
Q2. How can I use this class method inside the controller of a bundle?
If you put your class in the src folder, it will be autoloaded, ie: you can simply do:
$foo = new \MyClass();
$foo->method1();
in your Controller.
A good approach would be to put your classes in the Bundle you are likely to use them:
src/YourCompany/YourBundle/MyClass.php
In this way however don't forget to put the namespace declaration on top of your MyClass file:
namespace YourCompany\YourBundle;
class MyClass{
//..
}
You can put your classes on the base folder of your bundle, or use other nested folders to better differentiate a set of classes from each others, for eg:
src/YourCompany/YourBundle/Listener/MyClassListener.php
src/YourCompany/YourBundle/Manager/MyClassManager.php
For more info see the Best practice on Bundles structure of Symfony2
I have a set of functions that are called from 2 different models [ and maybe more in the future ]
What's the best approach to deal with this :
1 - Duplicated in each model
2 - Creating a helper for those functions and loading that helper from each model
Do you suggest any other approach
You can create a base model that your individual models extend, giving them all a shared ancestor of sorts.
Create the file application/core/MY_Model.php
class MY_Model extends CI_Model {
public function common_method($param)
{
// Stuff goes here
}
}
Then, any model that you wish to use the common method(s) in should simply extend MY_Model instead of CI_Model.
Note that the MY_ prefix is the default for CI, but you can change it in the application/config/config.php file.
Its my approach i don't know its a proper one or not.
If you are using this function throughout the site, You can create the class with those functions and add it in a library.
If you like you can do autoload also if require. Based on your usage.
I am using $data in all my views $this->load->view('my_view', $data);
I have also autoload a Controller following this guide Extending Core Controller
But I want to make $data global because in views there is a sidebar which is constant for whole project and displays info fetched through db in autoloaded controller
Currently I have to manually write $data['todo'] for each and fetch info from autoloaded model.
Thank You.
1: Create MY_Controller in application/libraries with following:
class MY_Controller extends Controller {
var $data;
//constructor function
}
2: Replace Controller to MY_Controller in all your controller files and load views with $this->data
class Contact extends Controller { //to.. }
class Contact extends MY_Controller {
$this->load->view('contact_view', $this->data);
}
this way you can perform default functions that are applicable for whole site in MY_Controller like loading settings.
I ran into a similar problem earlier today. I found that an easier way, rather than globals, was to use constants. You can define a constants file that will load from your index.php file:
// Include additional constants
$defines_file = 'includes/defines.php';
if (file_exists($defines_file))
{
require_once($defines_file);
}
Then you can add your constants to the defines.php file:
define(MY_CONSTANT,'my constant info');
This way they will be available in any file throughout the system either directly: echo MY_CONSTANT; or you can assign them to variables.
I decided this way would be easier for me as I would only have 1 location to go to when/if I needed to change the constants.
More: http://codeigniter.com/forums/viewthread/56981/#280205
I used a helper function to call a global function!
eg.
function get_user($userid){
$CI =& get_instance();
$query = $CI->db->get_where('users', array('id' => $userid), 1, 0);
foreach ($query->result() as $row){
// Return a object with userdata!
return $row;
}
}
Now I have access to my userdata everywhere..
Rather than making the view data global, I'd recommend using HMVC to build a module to produce this sidebar view. HMVC is a nice clean way of coding partial views.