CODEMemorandum

【WordPress】親テーマで定義されている関数を子テーマで上書きする

親テーマの functions.php で定義されている検索条件を変更したかったのですが、親テーマで定義されている関数を子テーマの functions.php で使おうとすると、

Fatal error: Cannot redeclare

その関数はすでに定義されてるよ!というエラーが出てしまいます。
つまり同じ関数は使えないので、単純に子テーマで親テーマの関数を上書きすることはできないわけです。

親テーマのほうを変更できればよいのですが、このときの親テーマには有料テーマが使われていたので、今後のアップデートを考慮して親テーマには手を入れたくありません。

子テーマ側だけでどうにかならないかと調べた結果、以下の方法でなんとか実現できました。
まず子テーマの functions.php で新しい関数を定義。
override_functions()という関数をつくって、この中で親テーマの関数を削除して、子テーマの関数を実行。

//子テーマで新しい関数 search_filter_child を定義する
function search_filter_child($query) {
  if ( !is_admin() && $query->is_main_query() ) {
    if ( $query->is_search ) {
    $query->set('post_type', array('post','カスタム投稿名') );
    }
  }
}
add_filter( 'pre_get_posts','search_filter_child' );

//親テーマの search_filter を削除して子テーマの search_filter_child を実行
function override_functions() {
  remove_action( 'pre_get_posts','search_filter' );
  add_filter( 'pre_get_posts','search_filter_child' );
}
add_action( 'after_setup_theme', 'override_functions' );

親テーマで定義する関数には function_exists をつけておく

if ( !function_exists( '関数名' ) ) {
  function 関数名() {
    //処理内容
  }
}

そもそも、親テーマで定義した関数に function_exists がつけてあれば子テーマで同じ関数を使っても大丈夫。
この関数がなかったら、という条件が入っているので、子テーマのほうで定義した内容が処理されます。

できればテーマを配布したり販売したりする人はみんなこうしておいてほしい…
結局、カスタマイズするときには子テーマをつくることになるんだからさ…

ちなみに…

プラグインの独自関数をテーマに書き込むときに

<?php if(function_exists('プラグインの独自関数')) { プラグインの独自関数(); } ?>

<?php//WP-PageNavi の独自関数の例
 if(function_exists('wp_pagenavi')) { wp_pagenavi(); } ?>
<?php//Yoast SEO の独自関数の例
 if(function_exists('yoast_breadcrumb')) { yoast_breadcrumb(); } ?>

こういうふうに書くのは、プラグインがインストールされてなかったりアンインストールされたりしたときにエラーになるのを防ぐためなんだね。
function_exists って大事…!