是否可以替换WordPress插件的PHP类中的函数?

时间:2014-04-25 15:52:09

标签: php wordpress woocommerce

我读到“除非原始函数被覆盖,否则。这是基本的PHP。”

但是我试图在不编辑插件文件的情况下编辑WooCommerce插件,以便可以在不丢失更改的情况下更新插件。

我已经设置了一个子主题并在functions.php中完成了以下操作,但它不起作用...

functions.php - 子主题

<?php
require_once(WP_PLUGIN_DIR . '/woocommerce/includes/class-wc-form-handler.php');

class child_WC_Form_Handler extends WC_Form_Handler {

    public function process_login() {

        parent::process_login();
       .
       .
       .
       if ( is_email( $_POST['username'] ) && apply_filters( 'woocommerce_get_username_from_email', true ) ) {
           $user = get_user_by( 'email', $_POST['username'] );

           if ( isset( $user->user_login ) ) {
               $creds['user_login']     = $user->user_login;
           } else {
               throw new Exception( '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . __( 'MESSAGE TO BE REPLACED', 'woocommerce' ) );
           }

       } else {
           $creds['user_login']     = $_POST['username'];
       }
       .
       .
       .
    }

}
?>

class-wc-form-handler.php - 原始函数所在的位置

<?php
class WC_Form_Handler {
.
.
.
    public function process_login() {
       .
       .
       .
       if ( is_email( $_POST['username'] ) && apply_filters( 'woocommerce_get_username_from_email', true ) ) {
           $user = get_user_by( 'email', $_POST['username'] );

           if ( isset( $user->user_login ) ) {
               $creds['user_login']     = $user->user_login;
           } else {
               throw new Exception( '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . __( 'A user could not be found with this email address.', 'woocommerce' ) );
           }

       } else {
           $creds['user_login']     = $_POST['username'];
       }
       .
       .
       .
    }
.
.
.
}
?>

这有什么办法吗?我想更改登录错误的异常消息。我已经通过“要更换的消息”突出显示了我想要更改的消息。

2 个答案:

答案 0 :(得分:2)

process_login函数中,您应该能够看到try {} catch {}块,然后像这样调用wc_add_notice

...
wc_add_notice( apply_filters('login_errors', $e->getMessage() ), 'error' );
...

因此,我们应该能够添加一个过滤器并拦截该消息:

function replace_email_error($message) {

    $emailError = '<strong>' . __( 'Error', 'woocommerce' ) . ':</strong> ' . __( 'A user could not be found with this email address.', 'woocommerce');

    if ($message == $emailError) {
        $message = 'MESSAGE TO BE REPLACED';
    }

    return $message;

}

add_filter('login_errors', 'replace_email_error');

我没有对此进行测试 - 请试一试,如果您有任何问题,我很乐意调试。

或者,您应该能够看到错误消息传递给Wordpress的本地化函数 - 因此您还可以向gettext函数添加过滤器,然后检查域和文本以及如果匹配则返回不同的值。

答案 1 :(得分:1)

即使你有答案,这也可以在赛道上派上用场。

根据以下Github线程,它尚未直接在WooCommerce中实现:https://github.com/woothemes/woocommerce/issues/3687

然而,你仍然可以扩展他们的核心类,但很可能必须在他们后面进行清理,这可能很烦人。以下是我根据自己的需求扩展的WC_Form_Handler示例:

class WC_BI_Form_Handler extends WC_Form_Handler {
    public function __construct() {
        parent::__construct();

        remove_filters_for_anonymous_class( 'init', 'WC_Form_Handler', 'process_login', 10 );
        add_action( 'init', array( $this, 'process_login' ) );
    }

    public function process_login() {
        if ( ! empty( $_POST['login'] ) && ! empty( $_POST['_wpnonce'] ) ) {
            # code
        }
    }
}

new WC_BI_Form_Handler;

我使用了以下插件,可以访问remove_filters_for_anonymous_class功能。这使我能够取消特定于课程的特定行动,这是不可能的:https://github.com/herewithme/wp-filters-extras/blob/master/wp-filters-extras.php