web-dev-qa-db-ja.com

カスタムプラグインでプラグインのWidgetクラスをオーバーライドする

私は現在、それが機能するために必要なプラグインがいくつかあるクライアント用に購入したテーマを変更しています。必要なプラグインの1つは、投稿タイプを表示するウィジェットを作成し、クライアントは表示されたフィールドのいくつかを削除したいと思います。

プラグインにアクセスして編集するのは簡単、問題は解決しました。それはもちろん、良い習慣ではありません。必要なプラグインの機能のいくつかをオーバーすることができるカスタムプラグインを作成する方法かどうか知りたいのですが。それは合理的な種類の行動であるべきだが、ベストプラクティスが少し失われるように思われる。いくつか質問があります。

これは上書きする必要があるクラスの始まりです:

add_action('widgets_init', 'gdlr_lms_recent_course_widget');
if( !function_exists('gdlr_lms_recent_course_widget') ){
    function gdlr_lms_recent_course_widget() {
        register_widget( 'Goodlayers_Lms_Recent_Course' );
    }
}

if( !class_exists('Goodlayers_Lms_Recent_Course') ){
    class Goodlayers_Lms_Recent_Course extends WP_Widget{

        // Initialize the widget
        function __construct() {
            parent::WP_Widget(
                'gdlr-lms-recent-course-widget',
                __('Goodlayers Recent Course Widget','gdlr-lms'),
                array('description' => __('A widget that shows latest courses', 'gdlr-lms')));
        }

        // Output of the widget
        function widget( $args, $instance ) {
            global $gdlr_lms_option;

            $title = apply_filters( 'widget_title', $instance['title'] );
            $category = $instance['category'];
            $num_fetch = $instance['num_fetch'];

            // Opening of widget
            echo $args['before_widget'];

            // Open of title tag
            if( !empty($title) ){
                echo $args['before_title'] . $title . $args['after_title'];
            }

            // Widget Content
            $current_post = array(get_the_ID());
            $query_args = array('post_type' => 'course', 'suppress_filters' => false);
            $query_args['posts_per_page'] = $num_fetch;
            $query_args['orderby'] = 'post_date';
            $query_args['order'] = 'desc';
            $query_args['paged'] = 1;
            $query_args['course_category'] = $category;
            $query_args['ignore_sticky_posts'] = 1;
            $query_args['post__not_in'] = array(get_the_ID());
            $query = new WP_Query( $query_args );

            if($query->have_posts()){
                echo '<div class="gdlr-lms-course-widget">';
                while($query->have_posts()){ $query->the_post();
                    echo '<div class="recent-course-widget">';
                    gdlr_lms_print_course_thumbnail('thumbnail');

                    echo '<div class="recent-course-widget-content">';
                    echo '<div class="recent-course-widget-title"><a href="' . get_permalink() . '" >' . get_the_title() . '</a></div>';
                    echo '<div class="recent-course-widget-info blog-info">';
                echo '<span class="gdlr-head">' . __('Created on', 'gdlr-lms') . '</span> ';
                    echo get_the_time($gdlr_lms_option['date-format']);
                    echo '</div>';
                    echo '</div>';
                    echo '<div class="clear"></div>';
                    echo '</div>';
                }
                echo '<div class="clear"></div>';
                echo '</div>';
            }
            wp_reset_postdata();

            // Closing of widget
            echo $args['after_widget'];
        }

いくつかの質問:if(!class_exists(...の目的は、クラスを他の場所に作成してオーバーライドできるようにすることであると考えていましたが、それはうまくいかないようです。クラスが既に定義されているというエラーが出ますか?

このクラスを自分自身で拡張し、add_actionステートメントに対してremoveアクションを使用してから自分自身を追加する正しい方法はありますか?

私は以前の手続き型プログラマーで、最初のカスタムクラスのセットに入るだけです。クラスを拡張しても、コンストラクタは依然として親の親を呼び出すのでしょうか。それとも、コンストラクタにparent::__constructを追加する必要があるのでしょうか。

私はこのための例をいくつか見つけましたが、それらはかなり古く、すべてを完全に説明しているわけではありません。この機能は、クライアントサイトを完全にカスタマイズしたくない場合にクライアントサイトに変更を加えるときに非常に役立つので、私はこの問題に頭を悩ませたいと思います。

3
Robert Wilde

あなたは実際にあなた自身の質問に答えるのにかなり近いです。あなたのプラグインは プラグインがアクティブであるかどうかをチェックすることから始めなければならないでしょう (これはfunction_existsでもできます)。

あなたは実際に remove_action を使って関数やクラスが起動されないようにすることができます。これらの関数が未定義になるわけではありません。

そのため、カスタマイズしたい場合は、 クラスを拡張する必要があります 。カスタマイズしたクラスでコンストラクタを定義しない場合は、親のコンストラクタが使用されます。

1
cjbj