php WooCommerce管理员设置:add_product_attributes_lookup_table_settings()中的TypeError

lc8prwob  于 2023-06-20  发布在  PHP
关注(0)|答案(1)|浏览(95)

几年前,我创建了一个插件(未公开),在我使用的WooCommerce版本(5.8.1)中运行良好。然而,在某个时候,管理员设置页面停止工作。我现在才注意到它(WC 7.6.0),因为我几乎从来没有使用过那个页面,所以我不知道什么时候改变了。
我的错误是:

Een fout van het type E_ERROR werd veroorzaakt op regelnummer 664 van het bestand <my-document-root>/wp-content/plugins/woocommerce/src/Internal/ProductAttributesLookup/LookupDataStore.php. Foutmelding: Uncaught TypeError: Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore::add_product_attributes_lookup_table_settings(): Argument #1 ($settings) must be of type array, null given in <my-document-root>/wp-content/plugins/woocommerce/src/Internal/ProductAttributesLookup/LookupDataStore.php:664
Stack trace:
#0 [internal function]: Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore->add_product_attributes_lookup_table_settings()
#1 <my-document-root>/wp-content/plugins/woocommerce/src/Internal/Traits/AccessiblePrivateMethods.php(158): call_user_func_array()
#2 <my-document-root>/wp-includes/class-wp-hook.php(308): Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore->__call()
#3 <my-document-root>/wp-includes/plugin.php(205): WP_Hook->apply_filters()
#4 <my-document-root>/wp-content/plugins/woocommerce/includes/admin/settings/class-wc-settings-page.php(130): apply_filters()
#5 <my-document-root>/wp-content/plugins/woocommerce/includes/admin/settings/class-wc-settings-page.php(98): WC_Settings_Page->get_settings_for_section()
#6 <my-document-root>/wp-content/plugins/woocommerce/includes/admin/settings/class-wc-settings-page.php(211): WC_Settings_Page->get_settings()
#7 <my-document-root>/wp-includes/class-wp-hook.php(308): WC_Settings_Page->output()
#8 <my-document-root>/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters()
#9 <my-document-root>/wp-includes/plugin.php(517): WP_Hook->do_action()
#10 <my-document-root>/wp-content/plugins/woocommerce/includes/admin/views/html-admin-settings.php(40): do_action()
#11 <my-document-root>/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-settings.php(153): include('...')
#12 <my-document-root>/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-menus.php(291): WC_Admin_Settings::output()
#13 <my-document-root>/wp-includes/class-wp-hook.php(308): WC_Admin_Menus->settings_page()
#14 <my-document-root>/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters()
#15 <my-document-root>/wp-includes/plugin.php(517): WP_Hook->do_action()
#16 <my-document-root>/wp-admin/admin.php(259): do_action()
#17 {main}
  thrown

我创建了一个很小的无用的插件来复制这个。我想在第83行(return woocommerce_admin_fields($this->getSettings());)出错了。带有管理设置的表单显示正确,但提交按钮没有显示,我确实得到了上面的关键错误。
下面的代码只是在WooCommerce设置->产品-> Foo Bar中添加了一个设置页面

<?php
/**
 * @package Foo_Bar
 * Plugin Name: Foo Bar
 * Description: With this plugin, nothing useful can be done
 * Version: 0.0.0
 * Author URI: http://oveas.com/
 * WC tested up to: 7.6.0
 */
 
if (!defined('ABSPATH')) {
    die;
}

function FooBar_getSettingsId()
{
    return 'foo-bar';
}

function FooBar_Activate()
{
    global $wpdb;

    $settingsId = FooBar_getSettingsId();

    $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE `option_name`=%s", $settingsId);

    $db_result = $wpdb->get_row($query);
    if(is_null($db_result) || $db_result == "" || !isset($db_result)) {
        $query = $wpdb->prepare(
              "INSERT INTO $wpdb->options SET "
            . '  option_name = %s'
            . ', option_value = %s'
            . ', autoload = %s'
            , $settingsId
            , 'a:2:{s:10:"option-one";s:7:"default";s:10:"check-this";s:3:"yes";}'
            , 'yes'
        );
        $wpdb->query($query);
    }
}

function FooBar_Deactivate()
{
}

function FooBar_Uninstall()
{
    global $wpdb;

    $settingsId = FooBar_getSettingsId();

    $query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE `option_name` = '$settingsId'", '');
    $db_result = $wpdb->query($query);
}

class FooBar
{
    public function __construct()
    {
        if (is_admin()) {
            $this->createAdminSettings();
        }

    }

    public function createAdminSettings()
    {
        add_filter('woocommerce_get_sections_products', array($this, 'addSection'), 10, 1);
        add_filter('woocommerce_get_settings_products', array($this, 'adminSettings'), 10, 2);
    }

    public function addSection($sections)
    {
        $sections['foo-bar'] = 'Foo Bar';
        return $sections;
    }

    public function adminSettings($settings, $currentSection)
    {
        if ($currentSection == 'foo-bar' && function_exists('woocommerce_admin_fields')) {
             // This is where it goes wrong: settings are added, but then there's some fatal
            return woocommerce_admin_fields($this->getSettings());
        } else {
            return $settings;
        }
    }

    public function getSettings()
    {
        $settings['section_title'] = array(
              'name'     => 'Foo Bar'
            , 'type'     => 'title'
            , 'desc'     => 'Some useful description'
            , 'id'       => FooBar_getSettingsId() . '[section-title]'
        );

        $settings['option-one'] = array(
              'name' => 'Option one'
            , 'type' => 'select'
            , 'options' => array(
                  'default'        => 'Use WooCommerce default'
                , 'something-else' => 'Something else'
                , 'both'           => 'Both'
            )
            , 'desc' => 'Make a useful selection'
            , 'id'   => FooBar_getSettingsId() . '[option-one]'
        );

        $settings['check-this'] = array(
              'name' => 'Make a selection'
            , 'type' => 'checkbox'
            , 'desc' => 'Enable or disable this'
            , 'id'   => FooBar_getSettingsId() . '[check-this]'
        );

        return apply_filters('foo-bar-settings', $settings);
    }
}

function FooBar_Execute()
{
    if (in_array( 'woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
        $plugin = new FooBar();
    }
}

register_activation_hook( __FILE__, 'FooBar_Activate' );
register_deactivation_hook( __FILE__, 'FooBar_Deactivate' );
register_uninstall_hook( __FILE__, 'FooBar_Uninstall' );

FooBar_Execute();

我找不到add_product_attributes_lookup_table_settings()在哪里以及如何调用,所以欢迎所有建议。插件的其余部分(如产品特定设置-不在此代码示例中)工作正常,只是这个页面。

46scxncf

46scxncf1#

如果其他人遇到同样的问题:我现在发现问题了。
我改变了什么:

  • 第70行上对$this->getSettings()的调用现在将$settings作为参数传递
  • getSettings()的末尾,即返回apply_filters()的结果,我直接返回$settings(原来是118行,现在是122行)。

我还添加了一个section end(第117-120行),但这只是因为保存按钮(以前没有显示)显示在表单上方。
以下是完整的工作代码:

<?php
/**
 * @package Foo_Bar
 * Plugin Name: Foo Bar
 * Description: With this plugin, nothing useful can be done
 * Version: 0.0.0
 * Author URI: http://oveas.com/
 * WC tested up to: 7.7.2
 */
 
if (!defined('ABSPATH')) {
    die;
}

function FooBar_getSettingsId()
{
    return 'foo-bar';
}

function FooBar_Activate()
{
    global $wpdb;

    $settingsId = FooBar_getSettingsId();

    $query = $wpdb->prepare("SELECT * FROM $wpdb->options WHERE `option_name`=%s", $settingsId);

    $db_result = $wpdb->get_row($query);
    if(is_null($db_result) || $db_result == "" || !isset($db_result)) {
        $query = $wpdb->prepare(
              "INSERT INTO $wpdb->options SET "
            . '  option_name = %s'
            . ', option_value = %s'
            . ', autoload = %s'
            , $settingsId
            , 'a:2:{s:10:"option-one";s:7:"default";s:10:"check-this";s:3:"yes";}'
            , 'yes'
        );
        $wpdb->query($query);
    }
}

function FooBar_Deactivate()
{
}

function FooBar_Uninstall()
{
    global $wpdb;

    $settingsId = FooBar_getSettingsId();

    $query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE `option_name` = '$settingsId'", '');
    $db_result = $wpdb->query($query);
}

class FooBar
{
    public function __construct()
    {
        if (is_admin()) {
            $this->createAdminSettings();
        }

    }

    public function createAdminSettings()
    {
        add_filter('woocommerce_get_sections_products', array($this, 'addSection'), 10, 1);
        add_filter('woocommerce_get_settings_products', array($this, 'adminSettings'), 100, 2);
    }

    public function addSection($sections)
    {
        $sections['foo-bar'] = 'Foo Bar';
        return $sections;
    }

    public function adminSettings($settings, $currentSection)
    {
        if ($currentSection == 'foo-bar' && function_exists('woocommerce_admin_fields')) {
            return $this->getSettings($settings);
        } else {
            return $settings;
        }
    }

    public function getSettings($settings)
    {
        $settings['section_title'] = array(
              'name'     => 'Foo Bar'
            , 'type'     => 'title'
            , 'desc'     => 'Some useful description'
            , 'id'       => FooBar_getSettingsId() . '[section-title]'
        );

        $settings['option-one'] = array(
              'name' => 'Option one'
            , 'type' => 'select'
            , 'options' => array(
                  'default'    => 'Use WooCommerce default'
                , 'something-else' => 'Something else'
                , 'both'       => 'Both'
            )
            , 'desc' => 'Make a useful selection'
            , 'id'   => FooBar_getSettingsId() . '[option-one]'
        );

        $settings['check-this'] = array(
              'name' => 'Make a selection'
            , 'type' => 'checkbox'
            , 'desc' => 'Enable or disable this'
            , 'id'   => FooBar_getSettingsId() . '[check-this]'
        );

        $settings[] = array(
              'type' => 'sectionend'
            , 'id'   => FooBar_getSettingsId() . '[section-title]'
        );

        return $settings;
    }
}

function FooBar_Execute()
{
    if (in_array( 'woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
        $plugin = new FooBar();
    }
}

register_activation_hook( __FILE__, 'FooBar_Activate' );
register_deactivation_hook( __FILE__, 'FooBar_Deactivate' );
register_uninstall_hook( __FILE__, 'FooBar_Uninstall' );

FooBar_Execute();

我没有弄清楚为什么和什么时候改变了这一点,但其他人可能会受益于解决方案。

相关问题