Override core controller

Permalink 1 user found helpful
Hi,

I used Concrete 5.7.0.4 and I would like to override the SecureimageController in Captcha folder to change the color of displayed captcha.

I tried to copy the SecureimageController.php in application/src/Captcha/SecureimageController.php but it doens't work.

Anyone can help me about overriding core classes ?

Many thanks

 
Korvin replied on at Permalink Best Answer Reply
Korvin
Checking this out, it looks like we have this system pretty tightly coupled to the core.


It looks like we get the class here:https://github.com/concrete5/concrete5-5.7.0/blob/master/web/concret...
That means we'll have to replace the Library AND the Controller, so lets find where Library is referenced.

The Library class is called explicitly here:https://github.com/concrete5/concrete5-5.7.0/blob/master/web/concret... So now we have to replace the Service, Library, and Controller.

That leads us to here:https://github.com/concrete5/concrete5-5.7.0/blob/master/web/concret...
Finally! Something that isn't tightly coupled!

The way to fix this here would be to go into your /application/config/app.php and either override that service provider or add a new service provider to swap out the singleton.

If you want to override the service provider, copy out the providers from /concrete/config/app.php and put them in your application config changing the validation service provider to your own.
<?php
// /application/config/app.php
return array(
    'providers' => array(
        '\Concrete\Core\File\FileServiceProvider',
        '\Concrete\Core\Encryption\EncryptionServiceProvider',
        '\Application\src\Validation\ValidationServiceProvider', // Changed to my application subclass
        '\Concrete\Core\Localization\LocalizationServiceProvider',
        '\Concrete\Core\Feed\FeedServiceProvider',
        '\Concrete\Core\Html\HtmlServiceProvider',
        '\Concrete\Core\Search\PaginationServiceProvider',
        '\Concrete\Core\Mail\MailServiceProvider',
        '\Concrete\Core\Application\ApplicationServiceProvider',
        '\Concrete\Core\Utility\UtilityServiceProvider',
        '\Concrete\Core\Database\DatabaseServiceProvider',


If you want to add your own service provider to take the place of the validation service provider (Note the `append_config()`):

<?php
// /application/config/app.php
return array(
    'providers' => append_config(array(
        '\Application\Src\Validation\ValidationServiceProvider',
    ))
);

and
<?php
namespace Application\Src\Validation;
class ValidationServiceProvider extends \Concrete\Core\Foundation\Service\Provider
{
    public function register()
    {
        $this->app->singleton('helper/validation/captcha', '\Fully\Qualified\Class\Name');
    }
}


Doing either one of these will allow you to replace the tightly coupled core namespace with your own override.

Best wishes,
Korvin
andrew replied on at Permalink Reply
andrew
This will be fixed in the next version of 5.7. This class will be made overridable through the file system, by copying it into application/src/Captcha/SecureImageController.php
iumeo replied on at Permalink Reply
Thanks Korvin for you explanation !
And Thanks to Andrew to include this issue in the next release.

Regards,
swiz replied on at Permalink Reply
Hi andrew, I'm attempting to override a core file (src/StyleCustomizer/Stylesheet.php) using the Application directory structure in 5.7.2 and the references still seem to be tightly coupled. Do you know when we will see this update roll out? Thanks!
andrew replied on at Permalink Reply
andrew
I'm not 100% sure that every single class in the src directory will be overridable via application/src/. Can you explain what you're trying to do ? Maybe we'll be able to find an alternate solution.
illustrationism replied on at Permalink Reply
illustrationism
Hi Andrew.

Similar to these questions, I'm trying to get custom help/tips set up, but the file is /concrete/src/Application/Service/UserInterface/Help.php

I can't seem to override that file. Is there a specific method I should use for that?

Thanks!
andrew replied on at Permalink Reply
andrew
Since this is actually a service we define in the \Concrete\Core\Application\ApplicationServiceProvider class, we have bound it to this pointer:

'helper/concrete/ui/help' => '\Concrete\Core\Application\Service\UserInterface\Help',

Meaning that you can rebind it yourself in application/bootstrap/app.php:

Core::bind('helper/concrete/ui/help', function() {
    return new \Application\Path\To\Your\CustomHelper();
});


which can then extend the original object.
illustrationism replied on at Permalink Reply
illustrationism
Ah, perfect. Thanks for the tips! (Get it? Tips?) Har har...

David
Kienz replied on at Permalink Reply
Kienz
If I copy /concrete/src/Captcha/SecureimageController.php to /application/src/Captcha/SecureimageController I got an error:
eflectionException (-1)
Class \Application\Src\Captcha\SecurimageController does not exist
I'm using Concrete 5.7.3.1.
losttheplot replied on at Permalink Reply
I too am unable to extend/override /concrete/src/Captcha/SecureimageController.php. I get the same error. I can change the namespace about until the system accepts the file but it still does not override the core file, which is not a service defined in the \Concrete\Core\Application\ApplicationServiceProvider class, so that won't work either.

Any help gratefully received!

Using: 5.7.5.8
losttheplot replied on at Permalink Reply
Further to the above, my test file is as follows, and the error I get is 'Class 'Concrete\Src\Captcha\SecurimageController' not found' not found':

<?php
namespace Application\Src\Captcha;
use Loader;
class SecurimageController extends \Concrete\Src\Captcha\SecurimageController
{
    public function label()
    {
        $form = Loader::helper('form');
        print $form->label('ccm-captcha-code', t('Alternate Text.'));
    }
}
losttheplot replied on at Permalink Reply
OK, after hours more fiddling around, I have an answer to my own problem. It would seem that the 'namespace' name for the src directory is 'core', which is confusing to say the least. Thus, this test override file works as expected:

<?php
namespace Application\Src\Captcha;
use Loader;
class SecurimageController extends \Concrete\Core\Captcha\SecurimageController
{
    public function label()
    {
        $form = Loader::helper('form');
        print $form->label('ccm-captcha-code', t('Alternate Text.'));
    }
}