mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-11-14 19:41:47 +08:00
A CodeIgniter 3 project had no routes in the graph and its flows stopped
at the controller: `$this->users_model->find($id)` goes through a property
nothing declares, so most such calls failed and the rest were guesses by
method name.
The resolver is detected by system/core/CodeIgniter.php, or by a routes
file naming a default controller, at any depth. It makes:
- a route per public method of a controller, implicit-public ones too,
at /<folder>/<class>/<method>, and HMVC modules with the module first;
- a route per $route entry in routes.php, verb-scoped or not, and the
default controller at /. `controller/method/$1` walks to the controller
as CodeIgniter does, and a variable in the method's place binds the
class;
- a `calls` edge for `$this->x->m()`, `$this->CI->x->m()` and
`$CI->x->m()` to the method on the class x holds, its own or inherited.
A class is read by name whatever the case, as PHP and the loader read
it, and an alias comes from the load that gives it;
- a `calls` edge from `$this->load->view('a/b')` to the view's file, where
the calls a template makes are recorded, so a request can be followed
to the end.
Differences from PR #167, each from the real apps: its controller test
is a list of base classes, which misses EA_Controller, Secure_Controller
and every other project's own; its property match is PascalCase only,
which misses `$this->providers_model` and `$this->mdl_invoices`, the form
two of the four apps use throughout; and it stopped at a file-level
`imports` edge to the class, so the flow still ended at the controller.
A reference it made to a method by name could land on a same-named method
in another controller, so a route's reference here names its own file.
Validation:
- codeigniter.test.ts, 21 tests, on the kernel and the wasm path; the 10
on a real index fail with the resolver unregistered.
- A/B on main cd04b21a, real CI3 apps: alextselegidis/easyappointments
f6c8a4c2 +217 routes, +1,229 edges; InvoicePlane e5e2529d (HMVC) +213,
+1,088; opensourcepos 3.3.9 c00ff28d +315, +1,428; ci-bonfire/Bonfire
3eaf6f88 +67, +515. Classes: `+references framework` route to handler,
`+calls framework` property call, and 2 `+calls test-request`. Nothing
removed. Those 2 come from an existing pass: a vendored SimpleTest file
calls `$this->get('http://www.lastcraft.com/')`, read as `/`, which now
exists.
- Every route binds: 217/217, 213/213, 315/315, 67/67.
- Site by site, every framework edge read against its source line and the
class the property holds: 1,012, 875, 1,113 and 446 edges, none wrong.
- A text scan of `->x->m(` where x names a project class: 967 of 967
linked, 855 of 961, 886 of 891, 379 of 420. What's left is methods the
class doesn't declare: InvoicePlane's are `where`, `update` and the like,
which MY_Model forwards to the database through __call.
- Flow: Booking::register -> Appointments_model::save, and
Appointments::store -> save -> validate.
- Controls flask 49943b5a and gin 0f09c3a9 are byte-identical.
- Index CPU, median of 3 interleaved, with a suite running: ospos +6.8%,
easyappointments -8.2%, flask -9.1%, gin -8.8%. The swing is noise; a
project that doesn't use CodeIgniter pays one path scan at detection.
Left out: routes.php entries a helper function adds, which only that
function's code says; CodeIgniter 4, a different layout.
Reimplements PR #167 by @darkspock.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>