: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
namespace Yoast\WP\SEO\Integrations\Third_Party;
use Yoast\WP\SEO\Actions\Wincher\Wincher_Account_Action;
use Yoast\WP\SEO\Actions\Wincher\Wincher_Keyphrases_Action;
use Yoast\WP\SEO\Conditionals\Wincher_Automatically_Track_Conditional;
use Yoast\WP\SEO\Conditionals\Wincher_Conditional;
use Yoast\WP\SEO\Conditionals\Wincher_Enabled_Conditional;
use Yoast\WP\SEO\Conditionals\Wincher_Token_Conditional;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Integrations\Integration_Interface;
* Handles automatically tracking published posts with Wincher.
class Wincher_Publish implements Integration_Interface {
* The Wincher enabled conditional.
* @var Wincher_Enabled_Conditional
protected $wincher_enabled;
protected $options_helper;
* The Wincher keyphrases action handler.
* @var Wincher_Keyphrases_Action
protected $keyphrases_action;
* The Wincher account action handler.
* @var Wincher_Account_Action
protected $account_action;
* Wincher publish constructor.
* @param Wincher_Enabled_Conditional $wincher_enabled The WPML WPSEO conditional.
* @param Options_Helper $options_helper The options helper.
* @param Wincher_Keyphrases_Action $keyphrases_action The keyphrases action class.
* @param Wincher_Account_Action $account_action The account action class.
public function __construct(
Wincher_Enabled_Conditional $wincher_enabled,
Options_Helper $options_helper,
Wincher_Keyphrases_Action $keyphrases_action,
Wincher_Account_Action $account_action
$this->wincher_enabled = $wincher_enabled;
$this->options_helper = $options_helper;
$this->keyphrases_action = $keyphrases_action;
$this->account_action = $account_action;
* Initializes the integration.
public function register_hooks() {
* Called in the REST API when submitting the post copy in the Block Editor.
* Runs the republishing of the copy onto the original.
\add_action( 'rest_after_insert_post', [ $this, 'track_after_rest_api_request' ] );
* Called by `wp_insert_post()` when submitting the post copy, which runs in two cases:
* - In the Classic Editor, where there's only one request that updates everything.
* - In the Block Editor, only when there are custom meta boxes.
\add_action( 'wp_insert_post', [ $this, 'track_after_post_request' ], \PHP_INT_MAX, 2 );
* Returns the conditionals based in which this loadable should be active.
* This integration should only be active when the feature is enabled, a token is available and automatically tracking is enabled.
* @return array The conditionals.
public static function get_conditionals() {
Wincher_Conditional::class,
Wincher_Enabled_Conditional::class,
Wincher_Automatically_Track_Conditional::class,
Wincher_Token_Conditional::class,
* Determines whether the current request is a REST request.
* @return bool Whether the request is a REST request.
public function is_rest_request() {
return \defined( 'REST_REQUEST' ) && \REST_REQUEST;
* Sends the keyphrases associated with the post to Wincher for automatic tracking.
* @param WP_Post $post The post to extract the keyphrases from.
public function track_request( $post ) {
if ( ! $post instanceof WP_Post ) {
// Filter out empty entries.
$keyphrases = \array_filter( $this->keyphrases_action->collect_keyphrases_from_post( $post ) );
if ( ! empty( $keyphrases ) ) {
$this->keyphrases_action->track_keyphrases( $keyphrases, $this->account_action->check_limit() );
* Republishes the original post with the passed post, when using the Block Editor.
* @param WP_Post $post The copy's post object.
public function track_after_rest_api_request( $post ) {
$this->track_request( $post );
* Republishes the original post with the passed post, when using the Classic Editor.
* Runs also in the Block Editor to save the custom meta data only when there
* @param int $post_id The copy's post ID.
* @param WP_Post $post The copy's post object.
public function track_after_post_request( $post_id, $post ) {
if ( $this->is_rest_request() ) {
$this->track_request( $post );