Override concrete5 validation class

Permalink 1 user found helpful
I'm trying to override a c5 class.

/concrete/helpers/validation/captcha.php should look like this:

class ValidationCaptchaHelper {
   private $securimage;
   public function __construct() {
      Loader::library("3rdparty/securimage/securimage");
      $this->securimage = new Securimage();
      $this->securimage->image_bg_color = "#FFFFFF";
      $this->securimage->multi_text_color = "#B88888,#A57575,#CC9090";
      $this->securimage->line_color = "#CCCCCC";
      $this->securimage->arc_line_colors = "#706090";
      $this->securimage->ttf_file = DIR_LIBRARIES_3RDPARTY_CORE . '/securimage/elephant.ttf';


This would be nice because it would allow me to customize the colors of the captcha.

But when I copy this code to the root I get this message:
Fatal error: Cannot redeclare class ValidationCaptchaHelper in /home/usr/concrete5/public_html/helpers/validation/captcha.php on line 37


I could also rewrite the core code and include some constants which would make it possible to define the colors in the config file but I'd need quite a few constants which would probably look a bit ugly.

1. Any ideas how to override a class?
2. Someone else interested in customizing the captcha. Should I create a core patch and add some constants?

Remo
 
Remo replied on at Permalink Reply
Remo
the problem is caused by Loader::helper in libraries/loader.php

public function helper($file, $pkgHandle = false) {
         // loads and instantiates the object
         if ($pkgHandle != false) {
            $dir = (is_dir(DIR_PACKAGES . '/' . $pkgHandle)) ? DIR_PACKAGES : DIR_PACKAGES_CORE;
            require_once($dir . '/' . $pkgHandle . '/' . DIRNAME_HELPERS . '/' . $file . '.php');
            $class = Object::camelcase($pkgHandle . '_' . $file) . "Helper";
            if (!class_exists($class, false)) {
               $class = Object::camelcase($file) . "Helper";
            }
         } else if (file_exists(DIR_HELPERS . '/' . $file . '.php')) {
            // first we check if there's an object of the SAME kind in the core. If so, then we load the core first, then, we load the second one (site)
            // and we hope the second one EXTENDS the first
            if (file_exists(DIR_HELPERS_CORE . '/' . $file . '.php')) {
               require_once(DIR_HELPERS_CORE . '/' . $file . '.php');
               require_once(DIR_HELPERS . '/' . $file . '.php');


The comments explains everything. The non-core file should extend the file but in my case, I'd like to override it..

If I don't override the file, I'd have to modify all the calls to the helper as well. Definitely something I want to avoid.
Ale replied on at Permalink Reply
I ran into very similar situation as I had to modify pagination helper. I copied the file to /helpers directory and made the modifications which led to the error mentioned about redeclaring. My quick solution was to rename the original file in concrete/helpers directory, but that really isn't the best solution considering Concrete upgrades...
Remo replied on at Permalink Reply
Remo
thanks but you're right, this is not really nice..

I want to create an addon where I have the same problem and there I definitely can't and won't rename core files..
ideaday replied on at Permalink Reply 1 Attachment
ideaday
I'm currently working on the same Problem, trying to replace the Captcha with a Mathcaptcha where normally the Captcha would be used. (code is based heavily on yours, Remo. Thanks a lot! It's attached in the packaged alpha version.)

PHP has an extension which COULD solve the problem:
http://de.php.net/manual/en/function.runkit-import.php...

Runkit allows you to redeclare classes. The way I envision it this would work like this:
In your /helpers/validation/captcha.php
you import /helpers/validation/mathcaptcha.php which has the new class definition, but is never included directly by the loader.

Unfortunately the extension does NOT ship regularly with PHP, for Debian Etch it even needs to be compiled, seehttp://www.sebastian.himberger.de/blog/2008/11/23/runkit-with-php-o...

And yes - I'd be interested in a generic solution at core level of this problem!

Perhaps we could define *.override.php files and look for them in the Class loader - i.e. captcha.override.php - thus it would know that the original file should NOT be included.
mose replied on at Permalink Reply
mose
I find myself in a similar situation. I would like to override a helper. We can override most other things, already (models, libraries, etc.). Is there a place where we could request a feature change to allow helpers to be overridden, as well? It would be nice to have that in the final version of 5.4. As with everyone else, I do not want to change the core files. Yucky.
Remo replied on at Permalink Best Answer Reply
Remo
For those who still wonder how to do this, if I replace

ValidationCaptchaHelper
with
SiteValidationCaptchaHelper

it seems to work..
It's actually in the code I've posted above, I just didn't see the "Site" string ):

This also has the benefit that I can extend the core class and not just override it!
terano replied on at Permalink Reply
terano
Thanks, this worked also for me.