Skip to content

Instantly share code, notes, and snippets.

@atimmer
Created April 12, 2018 09:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atimmer/475fcb4d38e54fb90f22fd77dc05521c to your computer and use it in GitHub Desktop.
Save atimmer/475fcb4d38e54fb90f22fd77dc05521c to your computer and use it in GitHub Desktop.
<?php
namespace Yoast\YoastCom\Core\WordPress\Integration\WooCommerce;
use Yoast\YoastCom\Core\WordPress\Helper\Shop_Helper;
use Yoast\YoastCom\Core\WordPress\Integration;
use Yoast\YoastCom\Core\WordPress\Integration\Dependencies\Dependency;
use Yoast\YoastCom\Core\WordPress\Integration\Dependencies\WooCommerce_Dependency;
final class Customer_On_All_Sites implements Integration {
/**
* Registers hooks to WordPress.
*
* @return void
*/
public function register_hooks() {
$this->add_filter();
}
/**
* Adds the filter that replaces empty capabilities with customer capabilities.
*
* @return void
*/
protected function add_filter() {
add_filter( 'get_user_metadata', [ $this, 'set_default_customer_capability' ], 10, 4 );
}
/**
* Removes the filter that replaces empty capabilities with customer capabilities.
*
* @return void
*/
protected function remove_filter() {
remove_filter( 'get_user_metadata', [ $this, 'set_default_customer_capability' ] );
}
/**
* Filters user metadata to add the customer capability for all sites.
*
* @param null|array|string $data The metadata of a user.
* @param int $object_id The id of the user.
* @param string $meta_key The meta key.
* @param bool $single Whether to return only the first value of the specified $meta_key.
*
* @return mixed
*/
public function set_default_customer_capability( $data, $object_id, $meta_key, $single ) {
if ( ! Shop_Helper::site_is_shop() ) {
return $data;
}
// Only attempt to add capabilities when either retrieving all meta values or just the capability values.
if ( $meta_key !== '' && false === strpos( $meta_key, 'capabilities' ) ) {
return $data;
}
// We want to add the capabilities to the existing meta data (which $data does not contain).
// So, we first need to retrieve the original meta data that was requested.
$actualData = $this->get_unfiltered_meta_data( $object_id, $meta_key, $single );
// When the meta key isn't specified: add the customer capability to each site if none are present.
if ( $meta_key === '' ) {
$capabilities = Shop_Helper::CAPABILITIES;
foreach ( $capabilities as $capability ) {
if ( ! isset( $actualData[ $capability ] ) ) {
if ( $data === null ) {
$data = $actualData;
}
$data[ $capability ] = [ 'customer' => true ];
}
}
}
// When the meta key ends with capabilities (e.g. wp_2_capabilities): Just set the $data to customer capabilities when there's no value already set.
if ( false !== strpos( $meta_key, 'capabilities' ) ) {
if ( empty( $actualData ) && Shop_Helper::capability_is_shop( $meta_key ) ) {
// WordPress will further handle $single. It would fail if we were to return a singular value here.
$data = [ [ 'customer' => true ] ];
// We update the capabilities in the user meta if we changed its value, so we don't have to filter it again.
// Also, in some places, the user meta is queried with WP_User_Query,
// which directly queries the database, not including our capabilities.
$this->remove_filter();
update_user_meta( $object_id, $meta_key, $data[0] );
$this->add_filter();
}
}
return $data;
}
/**
* Gets the metadata without using the set_default_customer_capability function while filtering.
*
* @param $object_id int $object_id The id of the user.
* @param $meta_key string $meta_key The meta key.
* @param $single bool $single Whether to return only the first value of the specified $meta_key.
*
* @return mixed
*/
private function get_unfiltered_meta_data( $object_id, $meta_key, $single ) {
$this->remove_filter();
$actualData = get_metadata( 'user', $object_id, $meta_key, $single );
$this->add_filter();
return $actualData;
}
/**
* Get a list of dependencies which must be met for this integration.
*
* @return Dependency[]
*/
public function get_dependencies() {
return [ new WooCommerce_Dependency() ];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment