# Router usage

**URL:** https://forums.concretecms.org/t/router-usage/4476
**Category:** Developing with Concrete
**Created:** [November 18, 2022, 3:32am UTC](https://forums.concretecms.org/t/router-usage/4476 "2022-11-18T03:32:35Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 18, 2022, 3:32am UTC](https://forums.concretecms.org/t/router-usage/4476/1 "2022-11-18T03:32:35Z")

</div>

I’m creating an addon that **must** POST to a specific php file and function within it. I have no idea how to do this.  
The front end is JavaScript (I must be and it’s not my choice. There is no changing this requirement). The JS script needs to POST to the backend in PHP. (the php file is going to be a method file in the package. For the example say it’s here:…/package/PackageName/scr/Complete/finish.php  
The function inside the method file is called Completed()

This is the part of the JS that is a must;

```auto
try {
   const response = await fetch('finish.php', {
     method: 'POST',
     headers: {
       'Content-Type': 'application/json'
     },
     body: dataJsonString
   });

```

I’m pretty sure I need to set up a ROUTER in the controller.php of the package but I don’t understand how to do this properly. I need help please.  
Keep in mind that while I’m fairly good a writing small simple apps, I’m really a newbie so you’ll need to spell it out for me. Oh, and if Router isn’t what I should do, please tell me (keeping in mind that the JS needs to be done something like that).  
I’ve tried to make the example as simple as possible for you all so that I can get a response.

---

<div class="post-metadata">

### Author: ![JohntheFish](https://forums.concretecms.org/user_avatar/forums.concretecms.org/johnthefish/32/3767_2.png) [@JohntheFish](https://forums.concretecms.org/u/JohntheFish)
#### Post date: [November 18, 2022, 9:59am UTC](https://forums.concretecms.org/t/router-usage/4476/2 "2022-11-18T09:59:29Z")

</div>

From a package controller on\_start() method, you can do something like:

```auto
use Concrete\Core\Support\Facade\Route;
  
function on_start() {

  // maps a route (any in-site url you like) to a class::method
  Route::register('/ccm/system/dialogs/block/button_nav/submit',
                              'ButtonNav\ButtonNavDialogController::submit');
  
  // maps a route to an anonymous function with parameters from the route
  Route::register('jl_form_reform/submit_form/{bID}/{cID}',
              function ($bID, $cID) { }
  );
}

```

The first is from my Button Nav addon, the second from Form Reform. There are variations to map routes to any callable.

> **[Button Nav - Concrete CMS](https://marketplace.concretecms.com/marketplace/addons/button-nav/)**
>
> The ultimate dropdown, slide in and lightbox button maker.

> **[Form Reform - Concrete CMS](https://marketplace.concretecms.com/marketplace/addons/form-reform/)**
>
> Reform the way forms are built. Build forms with blocks. Manage how forms are processed and how the data is stored.

---

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 18, 2022, 6:00pm UTC](https://forums.concretecms.org/t/router-usage/4476/3 "2022-11-18T18:00:47Z")

</div>

Thank you @JohntheFish but I’m still confused. That’s different than [Concrete router](https://documentation.concretecms.org/developers/framework/routing/including-routes-in-packages) instructions but yours makes more sense so let’s stick with how you explained it.

I’m having a as lot of trouble understanding the actual route. The actual route I’m working on is quite long so for simplicity let’s say this instead;  
/packages/payment/src/payments/method/Payment.php  
And inside that php there is MakePayment class and paynow() method  
Is this my route:

```auto
Route::register('/packages/MyPayment/src/payments/method/Payment’
                              ‘MakePayment::paynow');

```

I’m pretty sure I have the directory structure starting in the wrong place.

But even after that, how do I point to that route in the JavaScript.

Thanks

---

<div class="post-metadata">

### Author: ![JohntheFish](https://forums.concretecms.org/user_avatar/forums.concretecms.org/johnthefish/32/3767_2.png) [@JohntheFish](https://forums.concretecms.org/u/JohntheFish)
#### Post date: [November 18, 2022, 6:29pm UTC](https://forums.concretecms.org/t/router-usage/4476/4 "2022-11-18T18:29:22Z")

</div>

You could be confusing 2 separate mappings:

**(1) Namespace mapping**. This is which directory path within a package maps to a namespace for classes within that package. Namespace mapping provides instructions to php’s autoloader about which file to load for classes provided by your package. For example, I could map

directory =\> namespace  
src/JtF/FormReform =\> \JtF\FormReform

This kind of namespace mapping is a modern php thing. Concrete has its own interface to such configuration, but underneath its the same as you would get in any OO php application.

**(2) Route mapping**. This maps a url sub-path to the code that handles it. **My previous examples are for this only** and had nothing to do with (1). This is a convention that Concrete has adopted from underlying framework libraries and provides instructions to Concrete about which code to run for a specific incoming url. You just code the route as a full url into your javascript and Concrete then uses the mapping to run the associated php.

The core URL class can help you turn a route into a full url.

Both the above have their own sections in the documentation.

---

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 18, 2022, 6:46pm UTC](https://forums.concretecms.org/t/router-usage/4476/5 "2022-11-18T18:46:16Z")

</div>

I think I might be getting it. I’ll try and get back here once I’ve had time. I will clarify though that I cannot find anywhere the Router documentation the way you’ve explained it. The link I sent from Concrete Documentation is completely different. But then I’ve always found the Concrete documentation very confusing. It feel like the person wrote it with an idea in their head but failed to share the idea. Lol. It’s probably just me because I’m a weak coder. But just to clarify, Concrete “Router Basic” [https://documentation.concretecms.org/developers/framework/routing/routing-basics](https://documentation.concretecms.org/developers/framework/routing/routing-basics)  
Show it like:

```auto
$router->get(‘/api/customer/{customerId}, function($customerId) {
    return ‘The customer ID is: ‘ . $customerId;
});

```

---

<div class="post-metadata">

### Author: ![JohntheFish](https://forums.concretecms.org/user_avatar/forums.concretecms.org/johnthefish/32/3767_2.png) [@JohntheFish](https://forums.concretecms.org/u/JohntheFish)
#### Post date: [November 18, 2022, 7:43pm UTC](https://forums.concretecms.org/t/router-usage/4476/6 "2022-11-18T19:43:57Z")

</div>

Route::register is just a convenience static method that registers -\>get and -\>post. Otherwise it is the same. The following few pages cover mapping directly to a class::method, expanding from anonymous functions.

Or you can use an anonymous function to then call your class::method. That is what I do (stripped out) in the form\_reform example above, with a bit of data checking first in the anonymous function.

---

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 18, 2022, 8:37pm UTC](https://forums.concretecms.org/t/router-usage/4476/7 "2022-11-18T20:37:49Z")

</div>

You’ve been lots of help but I’m still confused. Im feeling a bit stupid here. I’m not understanding the class part of the route.  
Is it the namespace: at the top of the method file plus the name of the class in that file???

Also, do I need to do anything special since the JS is POSTing json  
I do have:

```auto
$json = file_get_contents(‘php://input’);

```

in the method that I’m trying to call. Maybe I’ve done the route correctly but did something else wrong.

---

<div class="post-metadata">

### Author: ![JohntheFish](https://forums.concretecms.org/user_avatar/forums.concretecms.org/johnthefish/32/3767_2.png) [@JohntheFish](https://forums.concretecms.org/u/JohntheFish)
#### Post date: [November 18, 2022, 9:32pm UTC](https://forums.concretecms.org/t/router-usage/4476/8 "2022-11-18T21:32:53Z")

</div>

For the handling code, $json = file\_get\_contents(‘php://input’) looks like a misdirection from code designed to work elsewhere, reading an input stream, not within a framework. Best to forget it. I don’t think it will work here.

The Concrete router works with an anonymous function or a fully qualified classname::methodname, which would be something like

“Your\Configured\Namespace\YourClass::YourMethod”

The Concrete router will then call that class::method and from within that method you can read the post data.

In the handling code, you would do one of:

(1) Dirty - look directly at the $\_POST superglobal

Or the Concrete way using a Symfony parameter bag  
(2) If your receiving class is a controller, you can do $this-\>request-\>request-\>all() or $this-\>request-\>request-\>get() for a specific parameter name  
(3) Otherwise, you make an instance of the request object and get the parameter from that. $request = $app-\>make(Request::class);

---

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 19, 2022, 12:08am UTC](https://forums.concretecms.org/t/router-usage/4476/9 "2022-11-19T00:08:51Z")

</div>

John, I sent you a private email explaining what I’m trying to do. Disregard the stuff about the router. I got that figured out. Thanks for your help on that.  
I’m having trouble with the symfony $request now though. I’ll keep trying.

---

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 20, 2022, 4:28pm UTC](https://forums.concretecms.org/t/router-usage/4476/10 "2022-11-20T16:28:34Z")

</div>

I’m having another issue and I think it’s related to how the json data gets routed.  
The JavaScript “fetch” sends the json (I know it’s being sent) but I can see that when it gets to the place it’s supposed to go, it’s empty. I can’t find anything on concrete but I googled and found other frameworks require an extra step. Am I missing a step sending and receiving JSON?  
Thanks.

---

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 21, 2022, 1:36am UTC](https://forums.concretecms.org/t/router-usage/4476/11 "2022-11-21T01:36:27Z")

</div>

Ok so I think I figured out another way to get done what I needed to do, but still wouldn’t mind seeing an explanation as to how this json thing should happen. I’d like to learn.

---

<div class="post-metadata">

### Author: ![JohntheFish](https://forums.concretecms.org/user_avatar/forums.concretecms.org/johnthefish/32/3767_2.png) [@JohntheFish](https://forums.concretecms.org/u/JohntheFish)
#### Post date: [November 21, 2022, 10:43am UTC](https://forums.concretecms.org/t/router-usage/4476/12 "2022-11-21T10:43:58Z")

</div>

Some diagnostic tips to see what the data is:

(A). Keep the browser developer console open on the Network tab. You can then look at any communication between the browser and the server and examine the query (get) parameters, payload (post) parameters and response.

(B) At the top of your route, or later in your processing:

```auto
echo "<pre>"
echo h(print_r($_POST,true)); // or $_REQUEST or $_GET
echo "</pre>"
die(); // optional, can be useful to just end here to prevent 
       // further output confusing things.

```

(C) As per B, wrapped in a `<pre>`, not as easy to read but safe against data containing objects that could be recursive.

```auto
var_dump_safe($_POST, true, 3); // '3' is the depth to dump to. 
                               // Adjust for more/less data

```

(D) Configure xdebug to follow what is happening in php . A complex topic in itself, both setting it up and understanding the output.

---

<div class="post-metadata">

### Author: ![baxterdmutt](https://forums.concretecms.org/user_avatar/forums.concretecms.org/baxterdmutt/32/5178_2.png) [@baxterdmutt](https://forums.concretecms.org/u/baxterdmutt)
#### Post date: [November 21, 2022, 8:02pm UTC](https://forums.concretecms.org/t/router-usage/4476/13 "2022-11-21T20:02:02Z")

</div>

Thank you so much for all your help John. People learning (like me) need people like you, to give valuable examples. Everyone learns differently and people that learn but examples need examples that show a complete process. It helped so much. Thanks again.
