Im using CI-HMVC stock.
Id like to have a module structure like this:
application
modules
userabc
moduleA
controllers
models
views
moduleB
...
userDEF
moduleC
...
Is this an incorrect way of module organization? Is there another common way of doing something like this?
Im wanting to seperate the users module folders and use them in a URL like this:
userABC.domain.com/module/controller/method
userBCD.domain.com/module/controller/method
You can use that structure if you want, but keep in mind the following:
You must define each user's directory as a module location:
// application/config/config.php
$config['modules_locations'] = array(
// Absolute path // Relative from default application dir
APPPATH.'modules/userABC/' => '../modules/userABC/',
APPPATH.'modules/userDEF/' => '../modules/userDEF/',
APPPATH.'modules/userGHI/' => '../modules/userGHI/',
// etc.
);
You might be able to do this dynamically, but remember that config.php is loaded pretty early so you may need a pre_system hook.
The other thing, which is important if you want all users' modules accessible regardless of which subdomain is active: Order matters!
If userA has a module called "blog" and so does userB, only userA's will ever get loaded (assuming you define userA's module path first). If you're certain no two modules will share the same name, this won't matter as much, but you may suffer a performance hit as the loader will go through the whole stack of module locations until it finds the requested one.
It sounds like you should define a single module_location depending on what user's site is loaded (the subdomain). Something like:
// Get this value dynamically (not sure how you need to do it)
$current_user = 'userABC';
$config['modules_locations'] = array(
APPPATH.'modules/'.$current_user.'/' => '../modules/'.$current_user.'/'
);
Adding submodules in codeigniter you need to defile moudules direcotry in config file like this.
$config['modules_locations'] = array(
APPPATH.'modules/' => '../modules/backend/',
APPPATH.'modules/frontend/' => '../modules/frontend/',
);
Related
I am a Drupal dev and new to code-igniter or any such php frameworks.
Now i have to modify an existing application done on codeigniter and the structure must be as follows:
example.com/motors
example.com/motors/car-for-sale
example.com/motors/car-for-rent etc.
Before it has only one url example.com/motors and i want to create more urls as mentioned above.
In the application\views\content folder i have the following structure:
application\views\content\motors.php
application\views\content\motors
application\views\content\motors\car-for-sale.php
In the application\controller folder i have the following structure:
application\controller\motors.php
application\controller\motors\motors.php
application\controller\motors\car-for-sale.php
I want to get the url example.com/motors & example.com/motors/car-for-sale from the files resides in the motors folder.Also how can i set a default file to load when i open example.com/motors?
You can't have a (controllers) directory that matches the name of a controller class at the same level. That is, since you have a controllers/motors.php, the files under controllers/motors/* will never be reached.
Instead (and this is the answer to your second question), you should set the default_controller name and rename controllers/motors.php to controllers/motors/<default_controller>.php.
Note that the default_controller setting points to a controller name (not a file location) and is applied to all directories. That is, if you set it to 'Default', then controllers/Default.php will be used when you open http://domain.tld/ and controllers/motors/Default.php will be used if you open http://domain.tld/motors/.
Also, your controller names MUST start with a capital letter, so default.php would be incorrect and should be Default.php instead. This might be working for you on Windows right now (because of its case-insensitive file system), but as soon as you upload your site to a Linux (or other UNIX-based) host, any classes with file names that don't start with a capital letter won't work.
It looks like you're trying to build a CodeIgniter site with a completely different paradigm from what it is designed around.
The structure you are after can be set up using the routes.php file within application/config
In there, you can set routes to go to any location needed, so for you, something like:
$routes['motors/cars-for-sale'] => 'motors/cars_for_sale';
$routes['motors/cars-for-rent'] => 'motors/cars_for_rent';
Then in application/controller you'd have a Motors.php file, which starts:
class Motors extends CI_Controller{
And also has the functions cars_for_sale and cars_for_rent
The mappings in routes sets this to link together.
In order to get the views you want for any given route, in the controller function, you'd have:
$this->load->view('path/to/view/file', $array_of_data); // view path does not need the .php extension
I'd recommend having a look and possibly even a follow through of the CodeIgniter tutorial in their documentation
I am working on Codeigniter site and trying to implement User tracking functionality for visitors only (not registered users).
I want to track ( ip address, from_page, to_page, time_stamp) on every page redirect and as I want to track only temporary users I would need to access database too, to check whether account exists or not.
My question is where to write my code, so that Codeigniter automatically checks before each redirect, (keep in mind, that place should have rights to access database or sessions).
Checking in each controller file will make so much redundant code and I don't think htaccess file could do it .
-Thanks
There are multiple ways to do this:
One is to create a helper file, say trackuser_helper.php in the helpers folder. Create a function to do the tracking in this file (say trackUser()). Then autoload this file inside config/autoload.phplike so:
/*
| -------------------------------------------------------------------
| Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['helper'] = array('url', 'file');
*/
$autoload['helper'] = array('trackuser'); //ignore the '_helper.php' portion of the filename
Now you can just call trackUser() in every controller.
The second option which in my opinion is better is to use Hooks provided by CodeIgniter
These are defined inside config/hooks.php like so:
$hook['pre_controller'][] = array(
'class' => 'MyClass',
'function' => 'Myfunction',
'filename' => 'Myclass.php',
'filepath' => 'hooks',
'params' => array('param1', 'param2', 'etc')
);
The array index correlates to the name of the particular hook point you want to use. In the above example the hook point is pre_controller. A list of hook points is found below. The following items should be defined in your associative hook array:
1.Class - The name of the class you wish to invoke. If you prefer to use
a procedural function instead of a class, leave this item blank.
2.Function - The function name you wish to call. filename The file name
containing your class/function.
3.Filepath - The name of the directory
containing your script. Note: Your script must be located in a
directory INSIDE your application folder, so the file path is
relative to that folder. For example, if your script is located in
application/hooks, you will simply use hooks as your filepath. If
your script is located in application/hooks/utilities you will use
hooks/utilities as your filepath. No trailing slash.
4.Params - Any parameters you wish to pass to your script.
This item is optional.
This specifies which function call you want to execute before each controller load. This way you do not even need to add trackuser() to each controller. These hooks can be pre_controller or post_controller. You can read more about hooks at the CI documentation.
My website is divided into separate modules. Every module has it's own specific css or js files in /protected/modules/my_module/assets/css or js for js files. Yiis assets manager creates folder when I first use page that uses my assets.
Unfortunately if I change sth in my files - Yii does not reload my css or js file. I have to manually delete /projects/assets folder. It is really annoying when you are developing the app.
Is there a way to force Yii to reload assets every request?
In components/Controller.php add the following (or adjust an existing beforeAction):
protected function beforeAction($action){
if(defined('YII_DEBUG') && YII_DEBUG){
Yii::app()->assetManager->forceCopy = true;
}
return parent::beforeAction($action);
}
What this does it that before any actions are started, the application will check to see if you are in debug mode, and if so, will set the asset manager to forcibly recopy all the assets on every page load.
See: http://www.yiiframework.com/doc/api/1.1/CAssetManager#forceCopy-detail
I have not tested this, but based on the documentation I believe it should work fine.
Note: The placement of this code within beforeAction is just an example of where to put it. You simply need to set the forceCopy property to true before any calls to publish(), and placing it in beforeAction should accomplish that goal.
If you're using Yii2 there is a much simpler solution through configuration.
Add the following to your 'config/web.php':
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
// ...
$config['components']['assetManager']['forceCopy'] = true;
}
This forces the AssetManager to copy all folders on each run.
An alternatively solution is to publish your module assets like this:
Yii::app()->assetManager->publish($path, false, -1, YII_DEBUG);
The fourth parameter enforces a copy of your assets, even if they where already published.
See the manual on publish() for details.
Re-publishing assets on every request potentially takes a lot of resources and is unnessecary for development.
For development, it's much easier to use the linkAssets feature of
CClientScript. Assets are published as symbolic link directories, and
never have to be regenerated. See:
http://www.yiiframework.com/doc/api/1.1/CAssetManager#linkAssets-detail
For staging/production, you should make clearing the assets/ folder
part of your update routine/script.
Only fall back to one of the other solutions if for some reason you cannot use symbolic links on your development machine (not very likely).
In YII 1 in config we have:
'components'=> [
...
'assetManager' => array(
'forceCopy' => YII_DEBUG,
...
)
...
]
I've looked through all of the CI documentation, and done some Googling of it, but I still can't quite seem to figure out how to create a configuration file for a custom library in codeigniter. If somebody could even just point me in the direction of where in the docs I could find my answer it would be greatly appreciated.
I am creating a library in CI that makes use of several database columns that can vary in name between applications, so I would like the names to be stored in a custom config file. Then I would like to be able to load these values in the construct of the library.
So my two questions are:
1.) How do I name the config file, and how do I name variables within that file so they don't overwrite any other config vars?
2.) How do I get the values from within my library?
When i have questions like this i like to look at other projects that already do this. We utilized Tank_auth in almost all of our ci projects. This is a popular authentication library, which has its own custome config files
It just creates its own config file in application/config directory.
You could prefix your config items with your app name to ensure that they are unique
it then just loads it in the constructor:
$this->ci->load->config('tank_auth', TRUE);
If there is a config/libraryname.php file, it will be automatically loaded, just before library instanciation.
(so, beware of name conflicts with CI's config files)
Side note: this autoloading is disabled if you pass an array as the 2nd argument:
$this->load->library('thelibrary', array('param1' => 'value1'));
in your config /config/your_conf.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config = Array(
'your_conf1' => 'your_conf_val1',
'your_conf2' => 'your_conf_val2',
'your_conf3' => 'your_conf_val3'
);
in your controller:
$this->config->load('your_conf');
var_dump((array)$this->config); //show all the configs including those in the your_conf.php
I've followed the Video store and Jobet examples, and I'm trying to create an Administrator
interface in the ./admin subdirectory. However, I want to use templates and I'm not sure if I need to create a new template directory, i.e. ./admin/templates/ or I can use the default template, i.e. ./templates/default/ which is used by the main API ?
Below is the flow of control of the website:
1) /admin/index.php <- instantiates /admin/lib/AdminFrontend
2) /admin/lib/AdminFrontend <- calls /admin/page/index.php (implicitly) for login of admin.
Inside /admin/page/index.php it sets up a login page and calls the defaultTemplate() function:
function defaultTemplate(){
return array('page/login');
}
However, I get an error "Spot is not found in owner's template".
I've tried to use the addlocation() function inside AdminFrontend to add root template (.template/default/), but I cannot get it to work.
$this->addLocation('../', array( 'template' => array('templates'),
'php' => 'lib' )
)->setParent($this->pathfinder->base_location);
So the login template is not found, but I'm not sure where atk is looking for the template or how I can change it.
From Roman's post, it seems that any new API's, e.g. admin, need a new template directory for security reasons so no pages/templates are shared between the normal users and admin interfaces.
in ATK4 Can I define a different template from frontend to back end?
Thanks for your advice.
Not sure but think you probably wanted to add your subdirectory 'admin' as the first parameter to addLocation something like this
$this->addLocation('admin',array(
'page'=>array(
'page',
),
'template'=>array(
'templates',
),
))
->setParent($this->pathfinder->base_location);
Which should then add /admin/templates to the path searched for templates and /admin/page to the paths it searches for pages.
You could also just install the atk4 folders again under a different atkroot which is only used for admin. Depending on your webhost, you could then point a subdomain e.g. admin.yoursite.com at the admin pages but it keeps it completely separate from your user pages but whether this is viable depends on whether you have a lot of common pages, views and models that will be shared between users and admin or whether you are happy to just copy the ones you need to the admin folders.