web-dev-qa-db-ja.com

Functions.php内でrequire_once()を使用している間だけ問題

私は私の子供のテーマのfunctions.php内でadd_theme_page()を次のように実装しています...

// other functions located here that create a custom options page in the Dashboard.
// THIS IS NOT A FILE PATH ISSUE ->  THE CUSTOM PAGE IS CREATED IN BOTH CASES.

function my_menu() {
    ...
    if ( 'save' == $_REQUEST['action'] ) {
        echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions.php&saved=true">';
        die;
    }
    add_theme_page(...)
}

add_action('admin_menu', 'my_menu');

WordPressのドキュメントのとおり

注: を実行している場合は、このページにアクセスするための十分な権限がありません。" メッセージがwp_die()画面に表示された場合は、早すぎます。あなたが使うべきフックはadmin_menuです。

これは、オプションを保存した直後に発生するエラーです。ただし、推奨されているとおりに正しいフックを使用しました。

このエラーは、関数を新しいファイルに移動し、require_once内でfuntions.phpを使用した場合にのみ発生します。 この答え のようにコードを整理していました。

require_once('includes/functions-theme-options.php');

なぜこれが単に関数を外部ファイルに移動することによって壊れるのですか?多分それは配置と関係があると思いましたが、require_once()は元のコードが配置された正確な位置にあります。

  • コードがfunctions.phpの内側にあるとき、それはうまく働きます。

  • コードを外部ファイルに移動してrequire_once()で参照すると、コードは壊れます( 上記の参照されたドキュメントのように保存時にエラーメッセージ )。

明らかに、今のところ、私はそれをfunction.php内に保っていますが、動かすとなぜ壊れるのか説明できる人もいるでしょう。


編集

これはファイルパスの問題ではありませんrequire_once()で参照されているすべてのファイルが見つかってインクルードされています。問題はそれがどのように実行されているかにあるようです。

この答えを読んでください: https://wordpress.stackexchange.com/a/1406/11092


EDIT 2 - 2013年1月16日改訂

これは問題を完全に実証するために検証された削除バージョンです。このコードは、「外観」の下に「テーマオプション」というサブメニューページを作成します。 [保存オプション]ボタンをクリックすると、ページにリロードして "your-theme settings saved" というメッセージが表示されます。ただし、代わりにWordPressのエラーページが表示されます。 "このページにアクセスするための十分な権限がありません。" 最後の関数をfunctions.phpに移動するだけで、このパーミッションの問題は解決します。なぜそしてどうやってそれを修正できるのか知りたいのですが。

functions.phpファイル内:

<?php

require_once('includes/functions-test.php');

私のchild-theme-directoryにあるincludes/functions-test.phpファイル

<?php

$themename = wp_get_theme();

function mytheme_admin() {

    global $themename;

    if ( $_REQUEST['saved'] ) echo '<div id="message" class="updated fade"><p><strong>'.$themename.' settings saved.</strong></p></div>';

    ?>

    <div class="wrap">
        <h2><?php echo $themename; ?> Options</h2>
        <div style="border-bottom: 1px dotted #000; padding-bottom: 10px; margin: 10px;">Options specfic to this theme.</div>
        <form method="post">
            <p class="submit">
                <input name="save" type="submit" class="button button-primary" value="Save Options" />    
                <input type="hidden" name="action" value="save" />
            </p>
        </form>
    </div>

<?php               
}


function wp_initialize_the_theme_load() {
    if (!function_exists("wp_initialize_the_theme")) { 
        wp_initialize_the_theme_message();
        die;
    }
}

add_action('admin_menu', 'mytheme_add_admin');


/*  move only the following function to 'functions.php' and the problem is gone
__________________________________________________________________________*/ 

function mytheme_add_admin() {
    global $themename, $shortname;  
    if ( $_GET['page'] == basename(__FILE__) ) {    
        if ( 'save' == $_REQUEST['action'] ) {
            echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions.php&saved=true">';
            die;
        } 
    }
    add_theme_page($themename." Options", "Theme Options", 'edit_theme_options', basename(__FILE__), 'mytheme_admin');
}
1
Sparky

カスタムダッシュボードページのURLがこれだと気付きました….

themes.php?page=functions-test.php

pageincludes/functions-test.php内の私の外部関数の名前であることに注意してください。

問題はこの行にあります、それは許可エラーの直前にページを更新するものです...

echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions.php&saved=true">';

今ではとても明白なようです。 URLのpageパラメータを見てください。これはfunctions.phpで、インクルードファイルの名前(functions-test.php)になります。

これは修正です...

echo '<meta http-equiv="refresh" content="0;url=themes.php?page=functions-test.php&saved=true">';

ハードコード化されたファイル名を持つよりも堅牢な解決策があるのでしょうか。

EDIT:

そして、ハードコードされたファイル名なしで...言い換えれば、代わりにbasename(__FILE__)を使って、頭痛なしでどこでもこのコードを動かすことができたかもしれません。

echo '<meta http-equiv="refresh" content="0;url=themes.php?page=' . basename(__FILE__) . '&saved=true">';

@ChipBennettによるトラブルシューティングの提案をありがとうございます。

編集2:

さらに一歩進めて、metarefresh;、およびdie;を完全に削除することができました。代わりに、意図したとおりにactionエレメントのformを使用します。これはデフォルトのWordPressの外観ページで使われているのと同じ形式のactionです。

<form action="<?php echo esc_url( add_query_arg( 'saved', true ) ) ?>" method="post">

add_query_arg( 'saved', true )は、フォーム送信時にページが自分自身にリダイレクトされるときに、クエリ文字列に&saved=1が追加されることを意味します。これは、このコードが"options saved"メッセージを表示するために必要な唯一の部分です。非常にずさんなmeta refresh; dieそのハードコードされたURLを含む、元の問題の根本は、完全に根絶されました。

FYI:これは私が彼らの "カスタム"テーマからクライアントの元々のオプションと機能性を抽出し、それらをTwenty 13の子テーマに移動しなければならないプロジェクトです。これらのずさんなコーディング慣習を使用する最初の壊れたテーマは デリケート と呼ばれます。

1
Sparky