CakePHP extend model from remote directory - php

I'm trying to do something unorthodox. I have 2 cakePHP installations within one directory. Is it possible to extend a model from one of my app installations into another?
This is what my directory structure looks like:
app1
app
model
* app1Model
view
controller
libs
plugins
ventors
app2
app
model
* app2Model (I want to extent this model with app1Model)
view
controller
libs
plugins
ventors
I want my app2Model to extend app1Model.

You sure can! What you're looking for is App::build(). It allows you to let Cake search other directories when you use App::uses(). For example, you could add the additional path to models like so:
// assuming your app is under `/var/www`
App::build(array(
'Model' => array(
'/var/www/app1/app/model'
)
));
You use App::build() to tell Cake "when I use App::uses(), look for classes here as well". You would place the code above in your bootstrap file in app2 to tell cake "also look for models in /var/www/app1/app/model.
Now in app2, when you use:
App::uses('app1Model', 'Model');
It will look both in app2/app/model and /var/www/app1/app/model for models named app1Model. You can use App::build() to point to other things like controllers and plugins as well, as indicated in the doc.
Beware of conflicting names. From the looks of it, you might want to consider building a plugin instead.

Related

Organize controllers in sub-folders

How to organize controllers under /app/controllers in sub-
folders in CakePHP? I want to create a folder like admin inside the controllers folder and I want to create some controller related to admin. If it is possible, then how can i call a controller from a sub folder?
You can use App::build() to let CakePHP know for additional packages/configurations.
App::build(array(
'Controller' => array('/path/to/controllers', '/next/path/to/controllers')
));
You need to re-think your application structure. Cake has something built in called prefix routing that you should probably be using.
This is also available in 1.x
You can't alter the CakePHP file structure "just like that". It would require serious modification of the core to achieve this, but there is almost never a good reason to do so. If you properly follow the naming conventions, everything should be easy to locate.
What you could do (that is still following conventions and comes close to what you're looking for) is create a plugin for all your admin related tasks and then you can put all that logic under app/Plugin/plugin_name/Controller instead. That way it has it's own place, although you will need to load the plugin from you main application for this to work.

How to Extend Controller Class in HMVC Module in Codeigniter to allow for Routing

Question:
How do I extend a controller of an HMVC module and then call that extended class in Codeigniter's URI Router?
Details:
Assuming the following typical Codeigniter file structure as it relates to HMVC:
/
/application
/application/modules
/application/modules/module-name
/application/modules/module-name/controllers
/application/modules/module-name/controllers/controller-name.php
/application/modules/module-name/models
/application/modules/module-name/models/model-name.php
/application/modules/module-name/views
/application/modules/module-name/views/view-name.php
/application/config
/application/config/routes.php
I have a class Events stored in /application/modules/events/controllers/events.php. I would like to extend it to Courses and Conferences which would provide specific functionality to those respective controllers. I would like to store those controllers in the same module folder (ie. /applications/modules/events/controllers/courses.php, etc.) I would like to route users that visit http://www.example.com/courses to the courses controller like so:
$route['courses'] = 'courses/getList';
I would also like to route users that visit http://www.example.com/conferences to the conferences controller like so:
$route['conferences'] = 'conferences/getList';
The Problem:
Unfortunately, I can't seem to get this working because courses isn't contained in it's own module and therefore can't be found by the router. It appears that the router is looking for the course class file at the following file path: /applications/modules/courses/controllers/courses.php. I have tried move that file to the aforementioned path, but I am then asked for the location of the Events controller class that Courses extends from.
A Possible Solution:
One possible solution might be to contain each of the controllers in a single controller file. However, I do not wish to do this because I like to store each class in it's own individual file and grouped with it's extended classes if at all possible. I am looking for a more elegant and altogether correct solution. Even if I were to attempt this technique of a single file, it would need to be contained in /applications/modules/courses/controllers/courses.php to be accessed. This leaves me out of luck when trying to later route to the conferences controller.
It seems that by adding
require APPPATH."modules/events/controllers/events.php";
to the beginning of my extended classes (courses and conferences) I will be able to leave the Events module alone.
Unfortunately, I have to create separate modules for the courses and conferences controllers. Oh well, I guess it can't be perfect.

The use of a modular folder structure?

I'm working with a MVC modular structure, kind of like you can have with Zend (i'm not using Zend). The directory structure is as follows:
/www
/Config
/Modules
/default
/controllers
indexController.php
loginController.php
/models
/views
blog
/controllers
indexController.php
/models
/views
...
I have a few question about this structure. I have a loginController in my "default" folder. Obviously a user goes to that page to login.
A logged in user can then post someting on the blog. But this is where my problem is. How can different modules share data, like user data?
In this scenario the "default" module will also have a "userModel". But the blog also displays a list of 'newest users'. So somehow it needs access to the userModel which is inside the "default" module.
And i could think of more examples where a certain module needs data from another module.
But this means that a 'module' is in a way almost always dependant on another module. So that's why i don't see any use in this structure. Or am i doing something wrong here..??
I would actually rethink what exactly you put in the modules.
The structures from Model layer should be shared between different modules (also .. your naming convention sucks: modules, models, models, modules, module models .. confusing). The modules are there to package the the part related to interaction.
When you work with domain business object representing "article", logic does not magically change from module to module. Instead there are just limits to what each user can do with it. Depending on, if user is authorized to performs some command or not.
You might benefit from reading this SO topic .. while more focused on authorization at controller's level, the same ideas can be applied on domain objects.
Also, you should carefully read M. Fowler's article on GUI Architectures.
It seems that the 'module' approach is the one that doesn't fit here. In MVC you have only three entities: Model View and Controller.
Controllers can load any model, for example as you mentioned: post_controller needs both post and user models so let it be that way. Because models represents data, it is incorrect to have two user models doing the same thing.
So I would get rid of the module approach because it is an anti pattern you notice that when start repeating classes and/or code through all the application.

CodeIgniter HMVC: extend a library or create a global controller?

I've started using HMVC in Codeigniter with Modular Extension and i want to create a set of methods avalaible in the whole application.
For example i've this three methods:
a method to retrieve te app name
a method for getting the right view folder depending on the user agent
a method to load assets
What's the best way to do this:
I'm using a model inside a module which is then requested from all other modules
I may extend or create a library/helper
now i'm using the first solution but I have come to doubt that it can slow down the application.
I would put this one in a base controller. Like this one: https://github.com/jamierumbelow/codeigniter-base-controller

Zend Framework extend module controller

My site structure is currently like this:
/cms/
/data/ - caches etc
/modules/
/public/ - aliases from site public folders
/website1
/images
/layouts, views, scripts, css etc
(no index.php because of the alias)
This works fine, my system looks to the alias folder to run the app. However, I've now got to the point where I would like to extend one of the module controllers.
Ideally my structure would be:
/cms/
.. as above
/CLIENT_ID/
/modules
..extending/overriding scripts
However, this is the problem: the controller to be called must be called according to Zend's file name structure (Module_IndexController etc), so to extend the base classes would be:
Module_IndexController extends Module_IndexController
Which obviously wouldn't work nicely. My thought is that it should be:
CLIENTID_Module_IndexController extends Module_IndexController
But I'm stuck on ideas on how to implement this? I can add the controller directory using: addControllerDirectory on the front controller but I'm guessing I need to change the called class name somewhere?
I can then check if the folder is a directory and run the overriding class rather than the base one.
Any ideas? I'm open to restructuring the folders, but obviously need to keep media files in the public folder.
The problem is that you are not using the conventional directory structure that Zend_Dispatcher, Zend_Autoloader and Zend_Controller are programed to work with.
In my opinion you have two possible solutions:
customize Zend_Autoloader and Zend_Controller and Zend_Dispatcher. You can find possible customizations here, here and here.
modify the directory structure.
In this second case consider theese possible projectual choices:
create independent standalone zend framework projects for all the sites, and create in those the aliases of the CMS folders
like the previous but customizing the module locations with:
http://framework.zend.com/manual/en/zend.controller.modular.html#zend.controller.modular.directories
Use the CMS as a library: you put all the cms files in folder outside the /websiteN and then in websiteN's application.ini you set includePaths.library = /path/to/cms/folder". There are a lot of possible problems in this possibilty, that must be valuated knowing your project. In this way you can call models, extends websites's classes to extend cms's, but you cannot use your cms as the entry point and manager of the user interactions at variuos levels.
As you said, you can tell Zend the base controller directory for each module.
$controller = Zend_controller_Front::getInstance();
$controller->setControllerDirectory(
array("module_name" => "directory_path")
);
I would think Zend would want the naming convention to be ClientId_Module_Controller. But, if you really get stuck with the naming convention, and are using php 5.3 you could use namespaces.

Categories