Separate 3rd party modules - codeigniter

I going to start new Codeigniter application and trying to find a way to separate 3rd party modules source (for example Tank Auth) from my own code,
What i need is to setup a file tree like the following:
/project_root/
/system (framework system - done)
/3rd_party/
/dists/
/application/ (installed 3d party libraries/modules - the question topic)
/application/ ( my application - done)
/site/ (site root, working tree - done)
The /system /application /site done using index.php and application/config/config.php settings.
Is there any correct way to acheive the tree like above using configuration settings ? I new for Codeigniter and have no idea if such is even possible.

For a modular structure with Codeigniter, Modular Extensions - HMVC is the go-to solution:
https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc
For your setup, you would add this to your config.php:
$config['modules_locations'] = array(
// absolute path relative path
APPPATH.'3rd_party/application/' => '../../3rd_party/application/',
);
/project_root/
/system
/3rd_party/
/dists/
/application/
tank_auth
my_module
some_other_third_party_code
/application/
/site/
The "relative path" is relative to any sub directory in your application root, like models, controllers, helpers, etc. For example in CI you can load a "model" from a "view" directory if you use:
$this->load->model('../views/some_model');
...not that's it's something you would normally do - but this is how HMVC's loader works. HVMC can be used to load anything CI normally can but from a "module" directory. You can have as many different modules or module paths as you want.
Modules can (but don't have to) load controller and act like their own mini-application. You can also load dependencies cross-module, or from the default application root.
You can still use your default application directory alongside modules. To specify that you want to load a particular asset from a module path, just include the module name in the path:
// Loads the "tank_auth" library (works from the tank_auth module)
$this->load->library('tank_auth');
// Loads the "tank_auth" library (works from anywhere in your application)
$this->load->library('tank_auth/tank_auth');
This works with models, helpers, etc. as well.
To access a controller in tank_auth/controllers/login you would use the URL http://example.com/tank_auth/login. You can also run a controller within another controller by using the modules::run() method, which could allow you to "wrap" controller methods of modules in your own logic without touching them:
class my_login extends MX_Controller {
function index() {
modules::run('tank_auth/login');
}
}
It's pretty well documented and has been around for years. I have used HMVC in nearly every Codeigniter project I've ever done, I highly recommend it.

The problem is that loader class , that loads the library with $this->load->library("path/to/module") is using hard-coded "library" as folder name (check the source of Loader.php) . So, in other words all your modules and libraries have to reside in library folder
/project_root/
/system (framework system - done)
/library/
/3rd_party/
/application/
and load them then with $this->load->library('3rd_party/application/tankh_auth.php)`
The only way to correct this (and not using library folder) is by overriding Loader class by writing your own. create Loader.php in your application folder , in specific - application/core by overriding library method
class My_Loader extends CI_Loader {
function __construct() {
parent::__construct();
}
public function library($library = '', $params = NULL, $object_name = NULL){
//override this method with your custom loader code
//eg
include_once($filepath."/".$library); //where your $filepath is path to your library,
$this->_ci_loaded_files[] = $filepath;
return $this->_ci_init_class($class, '', $params, $object_name);
//again look at original methods and/or write your own by referencing those
}
}

You don't need to worry yourself with HMVC (Although it is great), and you don't need MY_Loader either.
I would read through http://ellislab.com/codeigniter/user-guide/libraries/loader.html - Namely the section on Application "Packages"
In here, you will see a method called
$this->load->add_package_path()
In which you can specify additional paths for the loader to look for you libraries.

Related

Codeigniter 4 - controllers won't work unless I add them directly to Routes.php

Can anyone tell me:
Do I have to declare all of my controllers in Routes.php in Codeigniter 4?
I can't seem to get a controller to work unless I add it directly to the "Routes.php"
I have created my controllers properly and the Home controller is working after install and setup.
If I add the controller My_page.php :
<?php
namespace App\Controllers;
class My_page extends BaseController{
public function index(){
echo "Controller 'My_page' -> function index() ";
}
}
?>
I get a
: "404 - File Not Found
Sorry! Cannot seem to find the page you were looking for."
If I now add the controller to the rout - i.e.:
$routes->post('my_page', 'My_page::index');
Then my controller works properly and I get the "Controller 'My_page' -> function index() " when I visit www.mydomain.com/my_page
I have also tested:
www.mydomain.com/index.php/my_page
and this makes no difference.
I am using the .htaccess that comes with the download. I have updated the base URL to www.mydomain.com/
The documentation is confusing to me - https://www.codeigniter.com/user_guide/incoming/routing.html#setting-routing-rules ;
it sounds like they are saying have to declare all classes with routes?
Why are my controllers not working without declaring them specifically in Routes.php?
And am I misunderstanding 'setAutoRoute(true)' it also does not seem to work - I expect that I can turn this on and simply create my controllers pretty much like in CI3?
If you don't enable auto-routing you most certainly need to add all routes which you are allowing, anything else will fail with error 404. As #parttimeturtle mentioned - autoroute it is disabled by default since 4.2.
So in short - Yes, you need to add all controllers, their functions and the appropriate http methods. (That includes CLI routes as well)
You can use $route->add(), which will allow all http methods, it's however more secure to explicitly set them with their methods.

HMVC With Multilevel Hierarchy Codeigniter

I am implementing HMVC in codeignter3. I have added all the required file in core and third_party folder.
I have also created modules folder. Inside module I have created frontend folder Inside frontend folder I have created One folder test inside that I have created 3 Folder controllers, models and view. In controllers folder I have created Test.php and in models model created with name Test_model.php and in views one file created index.php
My controller code is
<?php
class Test extends MX_Controller
{
function __construct()
{
parent::__construct();
$this->load->model('test_model');
}
public function index()
{
$data['main_content'] = 'home/index';
$this->load->view('front/layout', $data);
}
}
?>
inside application/config/routes.php
$route['test'] = "frontend/test/Test/index";
When I am accessing it through localhost/myprojectfoldername/test I am getting 404
yes, this gives you an error. because you have created modules folder inside the module folder.
you have to create modules folder in your application folder not to the inside of another folder the path is defined in mx_loader application>modules so the code is not fined the class.
change its directory and refresh it so the error will remove.
further help uses these links:
http://www.dcaulfield.com/how-to-install-codeigniter-hmvc/
Or you can directly download from my gmail drive :
https://drive.google.com/open?id=1Viyo7CQcjJNkBv5ahyiOs5RwwXiOVopg
afer downlad and set up, hit url:
http://localhost/hmvc/home
Use like this:
$route['some-route'] = "yourcontroller/yourmethod";
or in other words:
$route['user'] = 'user/login';
One thing about HMVC Pattern in Codeigniter is, you need to follow the folder structure very well.
In your description you said you have created a Test.php file in your controller which resides in a folder called "frontend" which is in another folder "test" in your modules folder too.
Now the trick here is, If your controller name (Test.php) is equal to the folder name (test), you can simply call it like this:
$route['test'] = "frontend/test/index";
Instead of this:
$route['test'] = "frontend/test/Test/index";
On the other side let's say you have created another file( or controller) in the text folder called User.php then you can set your route as:
$route['test/user'] = "frontend/test/user/index";
Then again in your route code example I noticed you tried to use the Uppercase for the "Test", it does not really matter you can just use a lowercase "test" instead:
$route['test'] = "frontend/test/test/index"; But note this was just to explain whether it is case-sensitive or not.
Try your hands and it and let's see the outcome

Laravel Route to Standalone WebApp

I am trying to build a portal in Laravel to serve some other, standalone web apps (not built in Laravel), but I am struggling to find out how to route to these apps if I want to place them outside the public folder.
In the past, I would use (temporary) symlinks for this kind of things, but I was wondering if Laravel provides another solution.
So, I have a folder:
module
module/index.php
module/js/whatever
module/css/whatever
module/img/whatever
and I want a route /modules/1 to link to index.php in the module-folder in such a way that the resources in this folder (js/css/img) are also accessible.
Any suggestions?
You can include other PHP files with require_once.
web.php
Route::any('/webapp/{assets?}', 'WebAppController#index');
WebAppController
class WebAppController {
public function index(Request $request) {
require_once '../module/index.php';
if ($request->assets) {
// check from session if user is logged in
// require asset as well
// (or download them https://laravel.com/docs/5.5/responses#file-downloads)
}
}
}
http://php.net/manual/en/function.require-once.php

Is it possible to load CI models, libraries, and helpers outside CI application directory?

I am using a REST API outside CodeIgniter application directory and I want to be able to access CI models, libraries, and helpers so I don't have to copy-paste the same function on my REST API folder. I'm hoping not to repeat the functions.
Is there anyway I can do that? I'm using Restler API and I can't make it work within CI so I did it outside CI app folder.
Thanks!
You can use REST library written by Philsturgeon and it would be very easy and you can access anything of the framework. I have used this library in my projects so I know it's very easy to configure and use by my experience.
http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/
https://github.com/philsturgeon/codeigniter-restserver
I'm actually maintaining a codeigniter version that allows to create Rest calls (json) from models methods directly. Here's how I do it:
MODEL
function api_simplearray()
{
return Array(1,2,4,5,6,7);
}
CONTROLLER
public function __construct()
{
parent::__construct();
$this->load->model('MyModel');
}
URL: /index.php/CONTROLLER/api_simplearray/
*Important: The model must be loaded in the constructor.

How to call my model or controller of codeigniter outside application directory?

I have the following doubts:
I have my project in codeigniter which uses Flash. Its structure is as follows:
name_proyect
application /
controller /
model /
view /
audiofiles/
//Here are being saved all audios.
user_guide /
flash /
archivos.swf
save_audio.php
system /
index.php
The flash uses save_audio.php file, which is saving an audio on my server.
However, when I save the physical file on my server also need to save the file path in my database associated with the user.
My question is, I can use the active record in the file of codeigniter save_audio.php? o I can use my model or controller that use the model in my project that saving to database?
NOTE: save_audio.php is a simple script (isn't a class)
Move the current content of the save_audio.php into a CI controller. If you can, edit the flash file so it sends the files/requests to the new place.
If you can't update the flash file, remove the save_audio.php so CI will pick up the request, and use the routes config to make the path routed to your new controller inside CI. In this case you will end up something like this:
application/controllers/upload.php - the newly created controller
class Upload extends CI_Controller {
public function handle_audiofile() {
// the original content of the save_audio.php comes here.
// might need to update some superglobal usage
}
}
application/config/routes.php
$route['application/flash/save_audio.php'] = 'upload/handle_audiofile';

Resources