CakePHP Extending Controllers and Overriding Methods - php

I'm working on an Application, and most of the code will be returning in future project. So my idea was to create a structure such as this:
App/
- controllers
- models
- ...
Cake/
My_Custom_Folder/
- controllers
- models
- ..
Basically I want to add another folder next to the normal App folder and use App::build() to set the paths of the extra folder controllers, models, etc.
Now the goal is to only use the App layer when my project requires custom work, I have succeeded in that and CakePHP takes the controllers in the App over the ones in My_Custom_Folder if they are there.
For example: If i have a pages_controller.php in My_Custom_Folder AND one in my App folder, it will use the one in the App folder. If there is none in the App folder, then it uses the one in My_Custom_Folder.
However that is not how I want it to be working, what I want to do is extend the controllers from My_Custom_Folder so I can override methods and/or add new ones.
So far I have tried the following:
/My_Custom_Folder/pages_controller.php
Class PagesController Extends AppController {
Public $name = 'Pages';
Public Function home(){
echo 'default home';
}
}
/App/pages_controller.php
require_once(ROOT . DS . 'My_Custom_Folder' . DS . 'controllers' . DS . 'pages_controller.php');
Class AppPagesController Extends PagesController {
Public Function home(){
echo 'Override default home';
}
}
Unfortunately this doesn't work, it still loads the default home. Basically what i want is for it to load all methods from the My_Custom_Folder and allow the App folder to override methods and/or add methods the same way as you would by extending the Appcontroller. It does load both files, but it's not overriding any functions.
A structure like this would be great to maintain the same code over many projects and allow me to easily add new functionality for all projects by just updating the My_Custom_Folder and it would not break projects that have some customized code.
Any help on this would be greatly appreciated.

Take a look at plugin or behaviors or components or helpers. With plugins you can put them in one common folder for all apps (just like your My_Custom_Folder).

Related

Change default controller directory of Codeigniter

I want to have two folders where save codeigniter's controllers:
/application/controllers
/application/buckets
i'm a order paranoic person and i want to separate two types of my controllers.
In bucket folders the structure app was this:
/application/buckets/example/index.php
/application/buckets/example2/index.php
/application/buckets/example3/index.php
¿Maybe extending the router class?
A working example:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
Extended the core Router class to allow for sub-sub-folders in the controllers directory.
*/
class App_Router extends CI_Router {
function __construct()
{
parent::__construct();
}
function _validate_request($segments)
{
if (count($segments) == 0)
{
return $segments;
}
if (file_exists(APPPATH.'buckets/'.$segments[0].'/index.php'))
{
$this->set_directory(APPPATH.'buckets/'.$segments[0]);
$this->set_class(ucfirst($segments[0]));
$this->set_method(isset($segments[1]) ? $segments[1] : 'index');
return $segments;
}
}
}
You can use Hierarchical MVC(HMVC) with Codeigniter to accomplish this.
For reference, see Modular Extensions - HMVC
You may want to look into parent-child controller ...one extending another. To be more clear you can make as many controller you want.
I Agreed with #Brian Gottier : "what does changing their location do?"
You can perform anything if you have core functionalities in your hands.
You can play around with hooks (CodeIgniter's Hooks feature provides a means to tap into and modify the inner workings of the framework without hacking the core files. When CodeIgniter runs it follows a specific execution process, diagramed in the Application Flow page.)
Create "Base"/"Admin"/"Public"/"XYZ" Controllers in
application/core/MY_Controller.php
and keep rest of your controllers in same application/controller folder
MY_Controller is a basic core library extension. Whenever you create a class with the MY_ prefix the CodeIgniter Loader class will load this after loading the core library.
All we have done here is create a base class that all of our Controllers and "controller types" will inherit. Anything we put in here and assign to $this will be available to anything that extends this class.
Base Controllers are a nice simple way to give you global data, logic and shared code which can be specific to a certain part of your site. They can do all sorts of crazy stuff which I will leave for you to think about.
I Hope this help.

Write common methods in laravel 5.2

To develop a project where I am creating some methods which are common in all the controllers.
Before this I have used codeigniter and there I wrote MY_Controller class in core directory and then I extended the controller in all the controllers in controller directory.
Same I want to do inside Laravel. But I am confused that where should I write the common methods like send_email, validate_captcha, ajax_file_upload and other common methods which remains same across whole application.
So please suggest me a good way to define such a class or middleware.. What should one do to create that?
OK. Let me suggest some stuffs
Need to write methods which is apply to all Controllers. You
can/should modify App\Http\Controllers\Controller.php. Because all
Controllers in Laravel extend it
Need to write class that available across whole application. It is
never easier
Step 1: Write any class you want in app folder. And follow psr-4 convention
Step 2: Register to Laravel application
In App\Providers\AppServiceProvider. In register() method. Add
$this->app->bind('bindname', function ($app) {
return new \App\YourClass;
// If you want to inject other class to YourClass contructor
// return new \App\YourClass($app->make('otherbindname'));
});
Step 3: Use it. There are several ways to access YourClass in your whole application:
app()->make('bindname');
app('bindname');
app()['bindname'];
\App::make('bindname');
//etc

Front-end and admin panel setup in single CodeIgniter 3 installation [duplicate]

What is the best way to separate admin and front-end for a website in codeigniter where as I was to use all libraries, models, helpers etc. in common, but only controllers and Views will be separate.
I want a more proper way, up for performance, simplicity, and sharing models and libraries etc.
I highly suggest reading the methods outlined in this article by CI dev Phil Sturgeon:
http://philsturgeon.co.uk/blog/2009/07/Create-an-Admin-panel-with-CodeIgniter
My advice: Use modules for organizing your project.
https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home
Create a base controller for the front and/or backend. Something like this:
// core/MY_Controller.php
/**
* Base Controller
*
*/
class MY_Controller extends CI_Controller {
// or MX_Controller if you use HMVC, linked above
function __construct()
{
parent::__construct();
// Load shared resources here or in autoload.php
}
}
/**
* Back end Controller
*
*/
class Admin_Controller extends MY_Controller {
function __construct()
{
parent::__construct();
// Check login, load back end dependencies
}
}
/**
* Default Front-end Controller
*
*/
class Public_Controller extends MY_Controller {
function __construct()
{
parent::__construct();
// Load any front-end only dependencies
}
}
Back end controllers will extend Admin_Controller, and front end controllers will extend Public_Controller. The front end base controller is not really necessary, but there as an example, and can be useful. You can extend MY_Controller instead if you want.
Use URI routing where needed, and create separate controllers for your front end and back end. All helpers, classes, models etc. can be shared if both the front and back end controllers live in the same application.
I use a very simple approach: file folders. Check out the CI User Guide section, Organizing Your Controllers into Sub-folders.
I have my public-facing website built as any other would be built with CodeIgniter. Then I have two additional folders, controllers/admin and views/admin.
The admin controllers are accessed via http://[hostname]/admin/controller, and behave just as any other controller except they have specific authentication checks. Likewise, the views are simply called with the folder name included: $this->load->view('admin/theview');.
I haven't found a reason to do anything more complicated than that.
You all can find complete solution over here, https://github.com/bhuban/modular
Module separation for admin and front-end using HMVC and template separation using template libraries
I am using two third party libraries, you can find it in zip file.
HMVC for modular developed by wiredesignz
Template engine for templating by Phil Sturgeon
Just unzip it into your webserver root directory and run
localhost/modular for front-end
and
localhost/modular/admin for back-end
application/back-modules, it is for the back-end modules
application/front-modules, it is for the front-end modules
similarly
templates/admin for the back-end templates
templates/front for the front-end templates
themes/admin for the back-end themes
themes/front for the front-end themes
Nothing hacked in original code just configured using config.php and index.php

How to namespace in a front controller situation using PHP

Alright I have a tiny framework that I hope to open source soon and I'm trying to implement namespacing so that controllers and models don't need appended text. Here's the basic code logic:
url request
htaccess reroutes to index.php which initiates the framework
framework parses route & determines which controller/action to instantiate & fire
the framework's front controller is 'Controller' & project controllers extend 'Controller'
So in order to allow for controllers to be named for example:
class Foo extends Controller {}
and later a model be:
class Foo extends Model {}
My directory structure is like so:
project/
controllers/
foo.php
models/
foo.php
So, I'm obviously needing to implement namespacing. (And yes, I'm running php 5.3). So my question is, how exactly would I implement namespacing where the front Controller and Model is extended by other controllers and models?
One way to do it would be to manually prepend the namespace assuming your controllers are living in the same space. Take the following example.
public function __construct( $controller, $model )
{
$this->controller = 'Application\Controllers\\' . $controller;
$this->model = 'Application\Models\\' . $model;
}
There may be a more autoload-ish way of doing it but I think this will suffice in most cases. Don't quote me but perhaps you could use Reflection and get the namespace of the called object. However, this may still require a more unique naming convention otherwise the autoloader still wouldn't know if you were calling Controllers\Index.php or Views\Index.php.
Always check php.net... http://php.net/namespace

Correct Location for Custom Zend_Action_Controller

The ZF Docs reference 'Subclassing the Action Controller' (bottom of the page), but don't reference a standard place to put the new Action_Controller class.
Application_Module_Autoloader sets up pats for a bunch of things, but never controllers. I guess putting it on library/APPNAMESAPCE/Action/Contoller would work. But that seems a bit odd since every other application specific file is stored under application/.
The class gets autoloaded like any other class, there isn't a 'standard' place for it as such. So the question becomes, where do you want it to live?
The convention I usually follow in modular applications is to have most stuff in the modules, but register an app namespace and use application/models for 'core' type classes. So in your case, say your app namespace was Wordpress, you'd have:
class Wordpress_Controller_Action extends Zend_Controller_Action
{
}
and the file would live in application/models/Wordpress/Controller/Action.php.
To make this work you'll need application/models on your include path, and you'll want to init the standard autoloader with something like this (in your bootstrap class):
protected function _initAutoloader()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('Wordpress_');
return $autoloader;
}
alternatively you could setup the above in application.ini.

Categories