I've used codeigniter in the past but on my current project I'm making the switch to Kohana. What is the best practice on constants?
In codeigniter there is the actual constants.php, but going through Kohana's source I'm not seeing something similar.
Never used kohana, but after a quick googling I find that you can use the config API to create your own config that will house the constants you need.
This thread suggests that if you are storing database sensitive items, to place them in the database.php config, etc.. making them relative to the type of data they are storing.
I'm familiar with Kohana, but not CI so much, so I'm guessing a bit to what you mean by 'constants.' I believe the closest thing to this is indeed Kohana's config API. So, if you wanted to make templates aware of some site-wide constant like your site name, that's a great thing to use the config API for.
To accomplish this, you'll need to create a config file under your /config folder, probably in the /application directory. What you call it isn't very important, but since it contains site information, let's call it site.php.
To quickly get going, here is what you'll want to have in that file:
<?php defined('SYSPATH') or die('No direct script access.');
return array(
// Your site name!
'name' => 'Oh me, Oh my',
);
Now, you can bring this in to a template by doing something like:
A better way to do this (using dumb templating) would be to assign this as a template variable in your Controller. So, assuming you have some default controller set up, the code would be:
public function action_index() {
$this->template->site_name = Kohana::config('site.name');
}
And then your template would have something like this:
<title><?php echo $site_name; ?></title>
Kohana's config API is interesting because it is hierarchical, meaning you can override and merge new configuration values on top of existing config structures. When you call Kohana::config('site.name'), the engine looks through all the config files named site.php, runs all of those config files and merges the results in to an array. The application-level config files will overwrite modules, which will overwrite system, etc... Then, based on that result array, Kohana will attempt to find the 'name' key and return it.
Assuming you want global constants...the following worked well for me.
application/config/constants.php:
define('MY_COOL_CONSTANT', 'foo');
return array();
index.php:
Kohana::$config->load('constants');
MY_COOL_CONSTANT should then be available globally.
Related
I have several projects on my host. They have many similarities and I want them to use common node_modules. My folder structure looks something like this:
_CONFIG.php
node_modules/
project1/
index.php
project2/
index.php
project3/
index.php
In all my index.php files, I require_once '../_CONFIG.php' where I've set:
$node_modules = '../node_modules/';
Then in each project, when I need to use a Node module, I have:
<script src="<?= $node_modules; ?>jquery/dist/jquery.min.js"></script>
I do this because I might need to change the path of node_modules. If everything is hardcoded, I'd have a rough time. Let's say I install upgraded node_modules and I want to have a backup. I want to be able to quickly switch between the old and new modules, in case some of the new ones are incompatible with one of my projects.
I have other common things between the projects that I want to be easily configurable via the _CONFIG.php file.
Question
I know that polluting the global scope is not a great thing and that's exactly what I'm doing. Is there a better way to do this? In the same time, I don't want to do a ton of stuff just to output a string in a script tag's src attribute.
What about defining constants? It's quite useful for defining global options, and you do not pollute the global scope at all.
define('NODE_MODULES_DIR', '../node_modules/');
and then later use it there:
<script src="<?= NODE_MODULES_DIR ?>jquery/dist/jquery.min.js"></script>
I'm not aware of a "better" solution.
Keeping configuration outside of your code is the way to go. You put all your connection strings, pwds etc in a config file as suggested by The Twelve-Factor App.
Instead of using global variables, you could add one level of indirection by using a wrapper function that returns values based on a given key-string.
phpdotenv provides these capabilities nicely.
I am trying to give a shot to HMVC in Codeigniter. Here is my folder structure.
-ROOT
--APPLICATION
---MODULES
----Module_Email
-----Controllers
-----Models
-----Views
-----Assets
------JS
------CSS
------IMG
To render the Module i have to use
Module::run('Module_Email');
This method will output the rendered output, an example is given below
<script type="text/javascript" src="PATH/TO/EMAIL_MODULE/JS/JS_FILE.JS"></script>
<div data-module-name="Module_Email" class="Email_wrapper">
//RENDERED HTML CONTENT
</div>
Now here my problem start. Normally i would like to put all my resources to header. So when i call any module, its dependence need to be added in header instead of from where its get called.
I searched a lot but i couldn't find any good methods.
Please help.
Update
Currently i have a function on my header called get_assets() which will output predefined resources to header. But i cant say which modules is going to use in pages, so the system need to check which modules are used in this page, and if its used then its dependencies need to be added on header.
Seems like your main problem then is trying to figure out what modules were used.
Unfortunately as far as I can tell with the default Wiredesignz modular extension there is no way to access the module name unless you write some sort of hack to get at that data. The module being used is stored in the protected variable $module in the MX_Router class, however, there is no public method to allow you to get access to it. So your only choice would be to extend the class and create a public function.
Alternatively you could use a forked version of Wiredesignz implementation which I did which provides numerous other features including a public function to get at the $module variable. Using the forked version I wrote you could then use code such as this:
<?php $module_name = $this->router->fetch_module(); ?>
However, that will only record the last module you loaded, so you would still need to do work to store all the modules, and then have your function use this information to determine what assets to load. If I were doing something like you I would probably fork my version and then create an additional data structure to store every module that was loaded that you could then later get access to.
I don't think this is exactly what you were hoping for, but might be something to get you on the right track to finding a solution.
I added an array to the Module class to store the assets and two functions to store/retrieve the items. Here is the source (updated Modules.php)
# Register your assets
public static function register_asset( $asset )
{
if( in_array($asset,self::$assets) === FALSE )
{
self::$assets[] = $asset;
}
}
public static function assets()
{
return self::$assets;
}
and now you can register your assets like this inside your module
Modules::register_asset('myslider.js');
You can retrieve all your assets using
Modules:assets();
Which will return an array of assets that can be processed depending up on the situation.
I am using codeigniter for a project that is used by a variety of companies.
The default version of our software is up and running and works fine - however some of our customers want slightly different view files for their instance of the system.
Ideally what I would like to do is set a variable (for example VIEW_SUFFIX) and whenever a view file is loaded it would first check if there was a suffix version available if there was use that instead.
For example if the system had a standard view file called 'my_view.php' but one client had a VIEW_SUFFIX of 'client_1' - whenever I called $this->load->view('my_view') if the VIEW_SUFFIX was set it would first check if my_view_client_1 existed (and if it did use that) or if not use the default my_view.php.
I hope that my question is clear enough... If anyone has done this before or can think of a way to do it I would really appreciate it.
EDIT:
Ideally I would like a solution that works without me changing every place that I am calling the view files. Firstly because there are a few files that may want different client versions and also because the view files are called from a lot of controllers
I had a similar requirement for which I created a helper function. Among other things, this function can check for a suffix before loading the specified view file. This function can check for the suffix and check if the file exists before loading it.
Unfortunately, the file checking logic would be a bit brittle. As an alternative, you can implement a MY_Loader class that will override the basic CI_Loader class.
Something like this in your application/core/MY_Loader.php:
class MY_Loader extends CI_Loader {
protected function _ci_load($_ci_data)
{
// Copy paste code from CI with your modifications to check prefix.
}
}
Could you not do this
// some method of creating $client
// probably created at login
$_SESSION['client'] = 'client_1';
$client = (isset($_SESSION['client'])) ? $_SESSION['client'] : '';
$this->load->view("your_view{$client}", $data);
I have just started playing with laravel haveing come from codeigniter and I am trying to work out the best way to define a series of constants.
CI uses a constants folder under app/config and I was largely happy with this approach for most things but wanted advice as to the best way to do this in Laravel.
My constants fall into 3 categories and I would like advice if possible on how best to store and retrieve each (baring in mind I'm completely new to Laravel.
Type 1:
Constants which need to be loaded everytime a controller is called:
e.g. I would like to start by defining a constant to tell me if the user is requesting content via ajax, this is what I used to do in CI constants file:
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
Type 2:
Constants which can be changed by the user:
Are these best stored in a database or would writing to a config file be a better option? Again looking for advice on how to store and retrieve
Type 3:
Constants which are only needed in specific controllers:
Ideally I would like to be able to group constants into arrays or separate files and pull them out in groups as required.
e.g. I could just retrieve my upload settings for my upload controller.
Thanks for any help/advice in advance - examples would be greatly appreciated
Type 1
You can add any constant in Bundle (or application) start.php file.
Type 2 and 3
I would suggest using Config for both these requirement.
My solution is create a file inside app/config folder called "constants.php"
app/config/constants.php
The code inside is in array way.
"some value",
'c2'=>"some value"
);
?>
then inside each controller you can retrieve using
Config::get('constants.c1');
I think is an easy way to do it, it's more scalable.
<?php
//file : app/config/constants.php
return [
'IS_AJAX' => isset($_SERVER['HTTP_X_REQUESTED_WITH']
];
in anywhere:
echo Config::get('constants.IS_AJAX');
Is the proper way to make a few variables available to all my controllers to add a MY_Controller.php file in my /application/libraries/ folder (shown in the docs here)?
I'm working in Kohana 2.3.4 and wondering if there are any better ways to do it, or is this the only recommended method?
Being new to OOP, can you link me to any examples?
I've heard the right answer is to add the vars to your $config[], trying to get more details.
The proper way is to make a custom config file (application/config/foobar.php), and access the data with Kohana::config('foobar.key').
The code igniter way is completely wrong and inappropriate.
See http://docs.kohanaphp.com/core/kohana#methods_config
How does this feel then:
[bootstrap.php]
Kohana::$config->attach(new Kohana_Config_File('global'));
And then, create a new file under application/config called global.php
In it, put (for example):
return (array ('MyFirstVar' => 'Is One',
'MySecondVar' => 'Is Two'));
Anywhere in your code, access these variables with
Kohana::config ('global.MyFirstVar');
As you can see, 'global.' is used to access these variables; the reason for that is that you attached the global.php config file at the beginning.
Was this what you meant? :-)