Не отправлять электронное письмо нового клиента Woocommerce, если условие верно

Если я добавляю нового клиента в Woo с помощью REST API, мне нужно избегать отправки нового клиента по электронной почте. В документации по REST API об этом не говорится, и нет параметра, который нужно установить, чтобы предотвратить отправку электронной почты WC_Email_Customer_New_Account.

Я пробовал около 10 разных вещей, перечислю самые свежие

  • Редактирование исходного кода Woo напрямую class-wc-emails.php. Даже это не работает, потому что, когда я собираю мета пользователя, он все еще пустой и имеет только идентификатор пользователя и красивое имя

  • Создание плагина, который проверяет внешний API, и если условие выполнено, делает ли remove_action('woocommerce_created_customer_notification', array($email_class->emails['WC_Email_Customer_New_Account'], 'trigger'));

  • Обработка всего внутри плагина, но у меня та же проблема, что и у 1.

Как убрать количество товаров в категории WooCommerce
Как убрать количество товаров в категории WooCommerce
По умолчанию WooCommerce показывает количество товаров рядом с категорией, как показано ниже.
1
0
1 400
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуй это

Перейти к:

WooCommerce -> Настройки -> вкладка Электронная почта

Вы можете найти параметры «Новая учетная запись». Нажмите кнопку управления.

Снимите флажок «Включить это уведомление по электронной почте».

Мне нужно сохранить уведомление для регулярных регистраций, но если я создаю нового пользователя с помощью REST API, электронной почты не должно быть.

sdrubish 25.07.2018 12:39
Ответ принят как подходящий

Думаю, мне это удалось. Моя цель состояла в том, чтобы создать пользователя (клиента) через WooCommerce REST API (конечную точку клиентов), а не запускать электронную почту новой учетной записи.

Первый подозреваемый - фильтр woocommerce_email_enabled_customer_new_account. Он дает нам объекты \WP_User и \WC_Email_Customer_Completed_Order. Первая идея, очевидно, состоит в том, чтобы просто запустить get_user_meta() против пользователя.

add_filter( 'woocommerce_email_enabled_customer_new_account', function( $enabled, $user, $email ) {
    /**
     * @var bool $enabled
     * @var \WP_User $user
     * @var \WC_Email_Customer_Completed_Order $email
     */

    $isOurGuy = 'foobar' === get_user_meta( $user->ID, 'meta_key_is_so_meta', true );
    if ( $isOurGuy ) {
        return false;
    }

    return $enabled;
}, 10, 3 );

Как оказалось, обработчик конечной точки REST может отправлять метаданные только после создания пользователя, а уведомление по электронной почте запускается неявно через ловушку в \WC_Emails(). Это означает, что, когда наш код выполняется во время перехвата электронной почты, метаданные еще недоступны.

Следующее, что нужно было проверить, - это перейти к моменту, когда пользователя вообще куда-то выталкивают. Это будет woocommerce_before_data_object_save, на этот раз экшен. Он дает нам два объекта: \WC_Customer и \WC_Customer_Data_Store. У объекта \WC_Customer есть наши метаданные, ура! Вложим существующий код в другой обработчик.

add_action( 'woocommerce_before_data_object_save', function( $customer, $store ) {
    /**
     * @var \WC_Customer $customer
     * @var \WC_Customer_Data_Store $store
     */

    if ( !( $customer instanceof \WC_Customer ) ) { // I guess other object types may end up here, let's make sure we only get to work with customers.
        return;
    }

    $isOurGuy = 'foobar' === $customer->get_meta( 'meta_key_is_so_meta', true );
    if ( !$isOurGuy ) {
        return;
    }

    add_filter( 'woocommerce_email_enabled_customer_new_account', function( $enabled, $user, $email ) use ( $customer ) {
        /**
         * @var bool $enabled
         * @var \WP_User $user
         * @var \WC_Email_Customer_Completed_Order $email
         */
        if ( $customer->get_id() !== $user->ID ) { // Is it our guy?
            return $enabled;
        }

        return false;
    }, 10, 3 );

}, 10, 2 );

Это все еще не работает. Поскольку это перед сохранением объекта, пользователь не существовал в тот момент, когда мы захватили $customer в нашу область видимости. Итак, $customer->get_id() возвращает 0 (ноль). Похоже, мы немного промахнулись - нужно откатиться. woocommerce_created_customer кажется хорошим кандидатом. Он дает нам, среди прочего, новый идентификатор пользователя.

Скомпилируем все вместе.

add_action( 'woocommerce_before_data_object_save', function( $customer, $store ) {
    /**
     * @var \WC_Customer $customer
     * @var \WC_Customer_Data_Store $store
     */

    if ( !( $customer instanceof \WC_Customer ) ) { // I guess other object types may end up here, let's make sure we only get to work with customers.
        return;
    }

    $isOurGuy = 'foobar' === $customer->get_meta( 'meta_key_is_so_meta', true );
    if ( !$isOurGuy ) {
        return;
    }

    /**
     * Hook into the Customer Created event to capture the new customer ID.
     */
    add_action( 'woocommerce_created_customer', function( $customerId ) {
        add_filter( 'woocommerce_email_enabled_customer_new_account', function( $enabled, $user, $email ) use ( $customerId ) {
            /**
             * @var bool $enabled
             * @var \WP_User $user
             * @var \WC_Email_Customer_Completed_Order $email
             */
            if ( $customerId !== $user->ID ) { // Is it our guy?
                return $enabled;
            }

            return false;
        }, 10, 3 );
    }, 1 ); // NB: Email is also hooked here with priority 10.
}, 10, 2 );

А теперь подведем итоги. Мы подключаемся к хранилищу данных и фиксируем момент сохранения объекта \WC_Customer. Мы выполняем настраиваемую логику на основе метаданных, чтобы решить, продолжать ли. Затем мы переходим к моменту, когда создается пользователь для получения своего идентификатора. Затем мы перескочим немного дальше во времени в строке «электронная почта включена?» установите флажок, чтобы фактически отключить уведомление для данного пользователя.

Отличная работа Павла! Для записи я закончил тем, что вручную исправил один из упомянутых вами методов, что является плохой идеей, поскольку каждый раз, когда обновление WC может сломать мой патч, я обязательно реализую ваше гораздо более элегантное решение!

sdrubish 25.10.2019 18:06

Другие вопросы по теме