# Protecting access to a specific method of the controller - Cakephp 4

**URL:** <https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944>\
**Category:** Need Help\
**Created:** [February 8, 2023, 1:56pm UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944 "2023-02-08T13:56:02Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Oliv](https://avatars.discourse-cdn.com/v4/letter/o/45deac/32.png) [@Oliv](https://discourse.cakephp.org/u/Oliv)\
**Post date:** [February 8, 2023, 1:56pm UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944/1 "2023-02-08T13:56:02Z")

</div>

I want to create a method in a controller but I want it not to be accessible in the URL.

For exemple, I have a `CheckoutController` with a method to calculate shipping cost.

```php
// in CheckoutController
public function _calculateShippingCost(): ?float
{
	return 8.00;
}

```

I think I’ve found a way to prevent this method from being accessible via its URL `/checkout/calculate-shipping-cost` (but still callable from a `ShoppingCartComponent`) by prefixing the method name with an underscore `_`.

I can’t find confirmation in the docs, is this a way to protect my method ?

Is there still a way to access this method that I would have missed ?

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [February 8, 2023, 4:06pm UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944/2 "2023-02-08T16:06:04Z")

</div>

CakePHP only connects `public` methods inside controllers to URLs automatically (depending on what you have set in your `config/routes.php`)

So a quick fix for your would be to just change the method visibility to `protected` or `private`

BUT I would rather recommend you put that kind of business logic inside a service class so you have an easier time to re-use it wherever you need it.

[![](https://img.youtube.com/vi/z3E_UdH1XeE/maxresdefault.jpg "CakeFest Virtual 2021 Day 2 - How to re use code: Utility Classes and PHP Namespaces - Kevin Pfeifer") ](https://www.youtube.com/watch?v=z3E_UdH1XeE)

---

<div class="post-metadata">

**Author:** ![Oliv](https://avatars.discourse-cdn.com/v4/letter/o/45deac/32.png) [@Oliv](https://discourse.cakephp.org/u/Oliv)\
**Post date:** [February 8, 2023, 4:39pm UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944/3 "2023-02-08T16:39:35Z")

</div>

I first set this method `protected` (as I plan to inheritate my `CheckoutController`) but it couldn’t be called from my `ShoppingCartComponent` anymore.  
That’s why I set it to `public`.

The question is rather : Is there an URL (I hope not) that still can access to my method `CheckoutController::_calculateShippingCost()` as it is (e.g `public` and with underscore at the beginning of its name) ?

I tried `/checkout/calculate-shipping-cost`, `/checkout/-calculate-shipping-cost`, `/checkout/_calculate-shipping-cost`, … none of them is able to access but I might miss something…

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [February 8, 2023, 9:09pm UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944/4 "2023-02-08T21:09:56Z")

</div>

Well if you already have a component why do you not put that method from the controller into the component?  
Components are meant to be used by mutliple controllers so you don’t even have to deal with inheritance when doing that.

---

<div class="post-metadata">

**Author:** ![Oliv](https://avatars.discourse-cdn.com/v4/letter/o/45deac/32.png) [@Oliv](https://discourse.cakephp.org/u/Oliv)\
**Post date:** [February 10, 2023, 7:35am UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944/5 "2023-02-10T07:35:36Z")

</div>

> [@KevinPfeifer](#):
>
> Well if you already have a component why do you not put that method from the controller into the component?

Because all this is inside a `CommerceManager` plugin that I’m creating, and I just need to override the method that calculates the shipping costs in my App.

And it is the easiest/clearest way I found to deal with inheritance.

```php
// in CommerceManager/Controller/Component/ShoppingCartComponent.php
public function calculateShippingCost()
{
    return $this->getController()->_calculateShippingCost();
}

```

As `CommerceManager.ShoppingCartComponent::calculateShippingCost()` calls the current controller’s method `_calculateShippingCost()`, my App just has to inheritate `CommerceManager.CheckoutController` and override `CheckoutController::_calculateShippingCosts()` for rewriting the way the shipping costs are calculated.

If I would choose to put the shipping calculation only in `CommerceManager.ShoppingCartComponent::calculateShippingCost()` I can’t see how Component inheritance could work…

---

<div class="post-metadata">

**Author:** ![KevinPfeifer](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/kevinpfeifer/32/3365_2.png) [@KevinPfeifer](https://discourse.cakephp.org/u/KevinPfeifer)\
**Post date:** [February 10, 2023, 11:58am UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944/6 "2023-02-10T11:58:18Z")

</div>

to come back to your original question: If you

- can’t change the way how you build your app with controller inheritance but
- don’t want those particular methods to be accessible as URLs

you can remove the ` $builder->fallbacks();` from your `config/routes.php` and manually connect each controller method with what URL you want.

Like

```auto
$routes->connect(
    '/users/view/*',
    ['controller' => 'Users', 'action' => 'view']
);

```

or

```auto
$routes->connect('/users/view/*', 'Users::view');

```

See the [routing documentation](https://book.cakephp.org/4/en/development/routing.html) for more details

But I still believe the better solution would be to de-couple your business logic from the whole controller system.

---

<div class="post-metadata">

**Author:** ![Oliv](https://avatars.discourse-cdn.com/v4/letter/o/45deac/32.png) [@Oliv](https://discourse.cakephp.org/u/Oliv)\
**Post date:** [February 10, 2023, 3:12pm UTC](https://discourse.cakephp.org/t/protecting-access-to-a-specific-method-of-the-controller-cakephp-4/10944/7 "2023-02-10T15:12:59Z")

</div>

> [@KevinPfeifer](#):
>
> But I still believe the better solution would be to de-couple your business logic from the whole controller system.

I will think about it, thanks.
