call codeigniter API from outside the framework - codeigniter

I have an iPhone application which perform calls to an API developed with codeigniter. Since I am new to the framework, I want to know where such API are normally located ? The url requested from the iPhone application to the API is the following:
http://example.com/site/welcome/admin/api/processingdocuments/
I got a look on the application/libraries folder and there is a bench of php files like rest.php and REST_Controller.php. Are these the files I am looking for? Since the URL above doesn't point to specific file, how to know which API is being called? Thank you in advance.

When using Phil Sturgeon's CodeIgniter Restserver (which is what it seems you are using), you set up a controller within application/controllers directory and extend his class.
Let's say you call your controller Foobar, and it looks like this:
class Foobar extends Rest_Controller {
//... your methods here
}
In this case, you will access this endpoint at http://example.com/foobar
The URL references your controllers, and not the Rest_Controller directly.
URLs look like this:
http://example.com/{controller}/{method}/{param1}/{param2}/.../{paramN}
If method is not specified, it defaults to index()
Further, the Restserver allows you to map methods to HTTP request methods. Such that
GET example.com/foobar will map to the method index_get()
POST example.com/foobar will map to the method index_post()
..and so on.
I highly recommend you read the documentation
In your example, you would expect the controller that is being called to be located at application/controllers/site.
However, this might have been modified using htaccess rewrite rules (check for a .htaccess file), or via redefined CI routes (check application/config/routes.php).
If all else fails:
Under default configurations, that is where you should find them, however, CI is very malleable with routes and it is hard to say where they might be. Your best bet would be to grep the directory for the words extends Rest_Controller since wherever the controllers are, they would be extending that class.

Related

How to attach middleware to an existing named route from a package in laravel 5?

I'm trying to extend an existing application without modifying its source code.
The application has a named route called wizard-add.
Is there a way to register \MyPackage\MyMiddleware with the existing route?
I tried attaching it via Route::getRoutes()->getByName('wizard-add')->middleware(\MyPackage\MyMiddleware::class); but since packages are registered before the routes are read, Route::getRoutes() returns an empty collection.
Thank you!
Since I didn't find a way to solve this, I extended the app's controllers and put my logic inside.
namespace MyPackage\Controllers;
use App\Controllers\WizardController;
class MyPackageWizardController extends WizardController { ... }
and then in my service provider's register() method:
$this->app->bind(WizardController::class, MyPackageWizardController::class);
So everytime the app attempts to instantiate WizardController, it instantiates MyPackageWizardController instead. I don't know if there are any drawbacks but so far this has been working perfectly for me.

Laravel 7 Api incomplete?

I started with Laravel 7 a few weeks ago. It happened to me multiple times that after reading about a topic on the Laravel website, I wanted to check the details of a function, for example:
Illuminate\Support\Facades\Route::group()
So I went to the Laravel API, and could find the Route facade, but not the group function.
What am I doing wrong? Where do you check for example the exact signature of a function?
Thanks!
The method group in Route::group() is inherited from another class, RegistrarGroup.
See the docblock method in the source file, vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php:
#method static \Illuminate\Routing\Router|\Illuminate\Routing\RouteRegistrar group(\Closure|string|array $attributes, \Closure|string $routes)
so, this is what you look for in the API documentation:
https://laravel.com/api/7.x/Illuminate/Contracts/Routing/Registrar.html#method_group
That is because a Facade, by definition, is only an 'interface' to the methods exponed by another object, so you will not find the actual methods available by visiting the facade code.
Usually you can find the actual class that a facade resolves to (when not mocked) by checking the docblock in the source code and navigate to that class.
A very useful tool to overcome this problem and provide autocompletion (and inspection) for facades on your IDE is the package https://github.com/barryvdh/laravel-ide-helper

Can only Use Library in Routes file

I've been testing out the Imagine Library in my Laravel application and have been running the code straight in the Routes file which has worked fine. However, now when I'm trying to use it in a Model or Controller, it can't seem to find the library anymore even though I've included it the same way I did before with use Imagine\Image\Box; and use Imagine\Gd;. The code is also exactly the same as in the Routes file but I still get class 'App\Imagine\Gd\Imagine' not found.
Do I have to do something different when including stuff in a Model or controller?

Generating version specific help documentation pages for ASP.NET Web API application

I am using the WebAPI Versioning package to version my API by the X-Api-Header by using the "VersionHeaderVersionedControllerSelector". I am also using the Microsoft.AspNet.WebApi.HelpPage to autogenerate documentation for the APIs.
In order for controller versionign to work, they need to be namespaced with the VersionXYZ as the suffix in the namespace so that the "VersionHeaderVersionedControllerSelector" is able to route the request to the appropriate version of the controller like so:
namespace WEBAPI.Api.Controllers.Version1
{ public class ProductsController : ApiController {} }
namespace WEBAPI.Api.Controllers.Version2
{ public class ProductsController : ApiController {} }
This works as intended but when I look at the generated help pages the ApiDescription is including the "VersionXYZ" suffix from the namespace in the ID (GETapi/Version1.Products) and RelativePath(api/Version1.Products) properties.
Ideally what I'd like to do is to have a top level help page which just the API Version numbers and drilling in would show the API the normal way i.e. The ApiDescription.ID = GETapi/Products and the ApiDescription.RelativePath = api/Products
Is there a way to achieve this using the Out of the Box APIs or am I going to need to rollout my own implementation of ApiExplorer
Check out this answer Get Help page works with Api Versioning
Make sure you have configure the versioning right, and you need to get a documentation XML file from your project XXXX.Api.v1 project and place it in the bin folder of the XXXX.Api project.
Unfortunately ApiExplorer does not support duplicate controller names. So by implementing controller versioning this way, your (or the package code) doesn't play nicely with the system.
Consider another alternative where you actually change the controller name (and yes you will have to implement your own solution, but honestly its not that complex). For example make the version be part of the controller name itself (rather than its name space).
e.g. Ver1_ProcuctsController
Now these will start showing up on your help page, and since help page is just content package you can change the logic to make the names that start with verxxx_ to mutate.

PHPUnit + CodeIgniter multiple objects with same name

I currently test my CodeIgniter app with phpunit by using CIUnit (https://bitbucket.org/kenjis/my-ciunit). The problem is that I have multiple controllers with the same name. I have a controller in the root controller directory named "Blog" and I have a controller called "Blog" in the controller/ajax/ directory.
The reason is to seperate all ajax requests from the main controller.
When I am running tests on both files, I get the following error:
PHP Fatal error: Cannot redeclare class Blog in ...
Well, I am not suprised I am getting this error.
What are my options to resolve this?
Prefix controllers in ajax directory with "ajax" (looks only a bit stupid url/ajax/ajax_blog)
Use namespaces (I guess I need to namespace codeigniter too then)
Create 3 seperate phpunit.xml files
This aren't really solutions I am looking for. Do I have any other options? Is it somehow possible to run each testsuite seperatly, but still in one command? Can I "clean" objects between testsuites? Anything else?
There are no other options except those you mentioned, as it is impossible to "unload" class definitions in PHP.
Naming two controllers the same is not a problem when you run CI normally, since only one controller is instantiated per request, but something that should be avoided.
If it is just the ajax-url you don't like, maybe override it in a route (in config/routes.php):
$routes['ajax/blog'] = 'ajax/ajax_blog';

Resources