[ "endpoint" => $appContext . "/wp-json/fiftyonedegrees/v4/json", "host" => isset($_SERVER['HTTP_HOST']) ? sanitize_text_field($_SERVER['HTTP_HOST']) : $url, "protocol" => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? "https" : "http", "minify" => false ] ]); $error = null; try { $cloud = new CloudRequestEngine(array("resourceKey" => $resourceKey)); } catch (Exception $e) { $error = $e->getMessage(); return array( "pipeline" => null, "available_engines" => null, "error" => $error); } // Get engines available with the Resource Key $engines = array_keys($cloud->flowElementProperties); // Add CloudRequestEngine to the pipeline. $builder->add($cloud); // Add all the engines, accessible via provided // resourceKey, to the pipeline foreach ($engines as $engine) { $cloudEngine = new CloudEngine(); $cloudEngine->dataKey = $engine; $builder->add($cloudEngine); } // Build the pipeline $pipeline = $builder->build(); return array( "pipeline" => $pipeline, "available_engines" => $engines, "error" => $error); } /** * Process function sets the evidence from web request in flowData and * runs the process function on each attached FlowElement * * @return void */ public static function process() { // Only process if the data has not already been populated. if (Pipeline::$data === null) { // Fetch the data from the session if it's enabled and is already // there. if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION["fiftyonedegrees_data"]) && Pipeline::session_is_invalidated() === false) { Pipeline::$data = $_SESSION["fiftyonedegrees_data"]; return; } require_once dirname(__DIR__) . "/lib/vendor/autoload.php"; // Get the preconstructed pipeline from the cached option. $cachedPipeline = get_option(Options::PIPELINE); if (!$cachedPipeline) { // There is no pipeline, so return null. return; } if (isset($cachedPipeline["error"])) { error_log("Error occurred while initializing the 51Degrees " . "plugin: '" . $cachedPipeline["error"] . "'"); return; } // Get pipeline and available engines from cache $pipeline = $cachedPipeline["pipeline"]; $engines = $cachedPipeline["available_engines"]; // Create flowData object in the pipeline. $flowData = $pipeline->createFlowData(); // Set evidence from web request. $flowData->evidence->setFromWebRequest(); // Process flowData with evidence supplied $flowData->process(); // Some browsers require that extra HTTP headers are explicitly // requested. So set whatever headers are required by the browser // in order to return the evidence needed by the pipeline. // More info on this can be found at // https://51degrees.com/blog/user-agent-client-hints Utils::setResponseHeader($flowData); // Get properties for each engine from pipeline. $properties = array(); foreach ($engines as $engine) { $properties[$engine] = $pipeline->getElement($engine)->getProperties(); } Pipeline::$data = array( "flowData" => $flowData, "properties" => $properties, "errors" => $flowData->errors, "createdAt" => time()); // If session cache is enabled then store the result in it. if (session_status() == PHP_SESSION_ACTIVE) { $_SESSION["fiftyonedegrees_data"] = Pipeline::$data; } } } /** * Retrieves property by engine and property key. If there is no flow data * available, or it contains errors, then null is returned. * * @param string $engine FlowElementDataKey e.g. device * @param string $key Property Key e.g. browsername * @return string|null Property Value */ public static function get($engine, $key) { $data = Pipeline::$data; if (!$data) { // There is no processed flow data. return null; } if(isset($data["errors"]) && count($data["errors"])) { // There were errors from processing. error_log("Errors processing Flow Data" . $data["errors"]); return null; } $flowData = $data["flowData"]; try { if ($flowData->{$engine}->{$key}->hasValue) { return $flowData->{$engine}->{$key}->value; } else { error_log($flowData->{$engine}->{$key}->noValueMessage); return null; } } catch (\Exception $e) { error_log($e->getMessage()); return null; } } /** * Retrieves processed flow data as a JSON object. * * @return object|null flow data as a JSON Object */ public static function getJSON() { $data = Pipeline::$data; if (!$data) { return null; } if (isset($data["errors"]) && count($data["errors"])) { error_log("Errors processing Flow Data" . $data["errors"]); return null; } $flowData = $data["flowData"]; try { return $flowData->jsonbundler->json; } catch (\Exception $e) { error_log($e->getMessage()); return null; } } /** * Retrieves a properties list for the specified category. * * @param string $category the category name to get properties for * @return array|null the list of properties */ public static function getCategory($category) { $data = Pipeline::$data; if (!$data) { return null; } if (isset($data["errors"]) && count($data["errors"])) { error_log("Errors processing Flow Data" . $data["errors"]); return null; } $flowData = $data["flowData"]; $categoryResults = $flowData->getWhere("category", $category); $output = array(); foreach ($categoryResults as $key => $property) { $value = null; if($property->hasValue) { $value = $property->value; } else { $value = null; } $output[$key] = $value; } return $output; } /** * Gets client side javascript from FlowData. * * @return string|null the Javascript for the requesting device */ public static function getJavaScript() { $data = Pipeline::$data; if (!$data) { return null; } if (isset($data["errors"]) && count($data["errors"])) { error_log("Errors processing Flow Data" . $data["errors"]); return null; } $flowData = $data["flowData"]; try { return $flowData->javascriptbuilder->javascript; } catch (\Exception $e) { error_log($e->getMessage()); return ""; } } /** * Gets AppContext from the URL * @param string $url * @return string the app context */ public static function getAppContext($url) { $urlParts = explode( "/", str_replace("https://", "", str_replace("http://", "", $url))); if (count($urlParts) > 1) { $appContext = "/" . end($urlParts); } else { $appContext = ""; } return $appContext; } /** * Returns true if the data in the session has been invalidated by * another process updating the pipeline. * * @return bool */ static function session_is_invalidated() { $createdAt = $_SESSION["fiftyonedegrees_data"]['createdAt']; $invalidatedAt = get_option(Options::SESSION_INVALIDATED); return $createdAt < $invalidatedAt; } }