loadHTML('' . $content . ''); $xpath = new \DOMXPath($doc); $nodes = $xpath->query('//div[contains(@class, "' . $id . '")]'); if (sizeof($nodes) === 0) { return ''; } $content = $doc->saveHTML($nodes[0]); if ($charset === 'UTF-8') { return utf8_decode($content); } return $content; } private function pickVariant($variants, $testId, $variantId) { $abTestManager = new ABTestManager(); $cookieData = []; $hasCookieData = CookieManager::isAvailable($testId); $pickedVariant = false; if ($hasCookieData) { $cookieData = CookieManager::getData($testId); } // try to find variant based on given id if (isset($variantId)) { foreach ($variants as $variant) { if ($variant['id'] === $variantId) { $pickedVariant = $variant; if ($hasCookieData && $cookieData['variant'] !== $pickedVariant['id']) { // if not already tracked as converted if ($cookieData['tracked'] !== 'C') { // swap participation $abTestManager->addTracking($cookieData['variant'], 'S'); $abTestManager->addTracking($pickedVariant['id'], 'P'); } // save to cookie with new variant and old tracked state CookieManager::setData($testId, $pickedVariant['id'], $cookieData['tracked']); } } } } if (!$pickedVariant) { // see if variant is in cookies if (CookieManager::isAvailable($testId)) { // make sure variant is still in variants foreach ($variants as $variant) { if ($variant['id'] === $cookieData['variant']) { return $variant; } } } // pick a random one instead $pickedVariant = $this->pickVariantAt($variants, $this->randomTestDistributionPosition($variants)); } if (!$hasCookieData) { // add tracking and cookie $abTestManager->addTracking($pickedVariant['id'], 'P'); CookieManager::setData($testId, $pickedVariant['id'], 'P'); } return $pickedVariant; } private function getControlVariant($variants, $testId, $control) { // get control variant version foreach ($variants as $variant) { if ($variant['id'] === $control) { return $variant; } } // when all else fails... return the first variant return $variants[0]; } private function wrapData($testId, $controlContent) { return '
' . $controlContent . '
'; } public function resolveVariant($request) { if (!$request->get_param('test')) { return new \WP_Error('rest_invalid_request', 'Missing test parameter.', ['status' => 400]); } $testId = $request->get_param('test'); $variantId = $request->get_param('variant'); $forcedVariant = isset($variantId); if (DoNotTrack::isEnabled($request)) { return rest_ensure_response([ 'id' => $variantId ]); } $testManager = new ABTestManager(); $postId = $testManager->getTestPostId($testId); // get contents of the post to extract gutenberg block $content_post = get_post($postId); $content = $content_post->post_content; // find the json data of the test in the post $testData = ABTestContentParser::findTestInContent($content, $testId); if (!$testData) { return new \WP_Error('rest_invalid_request', 'Could not find test data on post.', ['status' => 400]); } // extract data $isEnabled = isset($testData['isEnabled']) && $testData['isEnabled']; $variants = $testData['variants']; $control = $testData['control']; $skipVariation = $testData['control']; // find out if already in a variant if (CookieManager::isAvailable($testId)) { $cookieData = CookieManager::getData($testId); $skipVariation = $cookieData['variant']; } // get control variant of the test $controlVariant = $this->getControlVariant($variants, $testId, $control); // parse referer $refererQuery = parse_url($request->get_header('referer'))['query']; parse_str($refererQuery, $parsedQuery); // check if conditions are in query string foreach ($variants as $variant) { if ( !$forcedVariant && isset($variant['conditions']) && count($variant['conditions']) > 0 ) { foreach ($variant['conditions'] as $condition) { if ( isset($parsedQuery[$condition['key']]) && $parsedQuery[$condition['key']] == $condition['value'] ) { $variantId = $variant['id']; break; } } } } // skip picking variant if provided in request if (!$forcedVariant) { // pick a variant of the test $pickedVariant = $isEnabled ? $this->pickVariant($variants, $testId, $variantId) : $controlVariant; $variantId = $pickedVariant['id']; } // skip parsing HTML if variation already picked or control and variant not provided if ($variantId === $skipVariation && !$forcedVariant) { return rest_ensure_response([ 'id' => $variantId ]); } // parse HTML of the test and send $variantContent = apply_filters('the_content', $this->getVariantContent($content, $variantId)); return rest_ensure_response([ 'id' => $variantId, 'html' => $variantContent, ]); } public function renderTest($attributes, $content) { $variants = $attributes['variants']; $testId = $attributes['id']; $control = $attributes['control']; $isEnabled = isset($attributes['isEnabled']) ? $attributes['isEnabled'] : false; $controlVariant = $this->getControlVariant($variants, $testId, $control); if (!isset($controlVariant)) { return ''; } $variantId = $controlVariant['id']; if (CookieManager::isAvailable($testId)) { $cookieData = CookieManager::getData($testId); $variantId = $cookieData['variant']; } return $this->wrapData($testId, $this->getVariantContent($content, $variantId)); } public function renderInsertedTest($attributes) { $content_post = get_post($attributes['id']); $content = $content_post->post_content; return apply_filters('the_content', $content); } }