【问题标题】:Is it possible to replace a function within a PHP class of a WordPress plugin?是否可以替换 WordPress 插件的 PHP 类中的函数?
【发布时间】:2014-09-05 15:14:17
【问题描述】:

我读到“除非原始函数要被覆盖,否则不。这是基本的 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'];
       }
       .
       .
       .
    }
.
.
.
}
?>

有没有办法解决这个问题?我想更改登录错误的异常消息。我用“要替换的消息”突出显示了我要更改的消息。

【问题讨论】:

  • 您要覆盖什么功能?您可以采取不同的方法。
  • 我想覆盖异常的输出消息。我应该编辑问题中的代码吗?
  • 嗨,是的,请更新它并在您要更改的消息中包含异常的详细信息。通常可以过滤 Woocommerce 异常消息。
  • 我认为 WC_Form_handler 中的大多数异常都会传递给 wc_add_notice,然后调用 apply_filters 以便更改输出。
  • 哦,对了!真的吗?无论如何,我已将代码添加到我的问题中

标签: php wordpress woocommerce


【解决方案1】:

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 函数添加过滤器,然后检查域和文本,如果它们返回不同的值匹配。

【讨论】:

    【解决方案2】:

    即使你有你的答案,这也可能会派上用场。

    根据以下 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

    【讨论】:

    • 谢谢哥们,方便了解
    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 2011-06-04
    相关资源
    最近更新 更多