| Server IP : 195.130.67.5 / Your IP : 216.73.217.154 Web Server : Microsoft-IIS/10.0 System : Windows NT WEBSERVER1 10.0 build 17763 (Windows Server 2016) i586 User : IUSR ( 0) PHP Version : 7.4.19 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/inetpub/wwwroot/icd/plugins/mobile/scientia/ |
Upload File : |
<?php
/**
* Copyright (c) 2011 ScientiaMobile, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Refer to the COPYING file distributed with this package.
*
* @package WURFL
* @copyright ScientiaMobile, Inc.
* @author Steve Kamerman <steve AT scientiamobile.com>
* @license GNU Affero General Public License
* @version $id$
*/
/**
* Loads the WURFL file from a local file or remote URL into the Tera-WURFL database.
* @package TeraWurfl
*
*/
class TeraWurflLoader{
public static $WURFL_LOCAL = "local";
public static $WURFL_REMOTE = "remote";
public static $WURFL_REMOTE_CVS = "remote_cvs";
public static $WURFL_PATCH = "patch";
public static $PRESERVE_CACHE = true;
// Properties
public $errors;
public $version;
public $last_updated;
protected $table;
protected $file;
protected $wurfl;
protected $devices;
protected $tables;
protected $parser;
public $mainDevices = 0;
public $patchAddedDevices = 0;
public $patchMergedDevices = 0;
/**#@+
* @var int Performance tracking variable
*/
protected $timestart;
protected $timevalidate;
protected $timesort;
protected $timepatch;
protected $timedatabase;
protected $timecache;
protected $timeend;
/**#@-*/
// Constructor
public function __construct(TeraWurfl &$wurfl){
$this->errors = array();
$this->wurfl = $wurfl;
$this->devices = array();
$this->tables = array();
$this->file = TeraWurfl::absoluteDataDir().TeraWurflConfig::$WURFL_FILE;
$this->table = TeraWurflConfig::$TABLE_PREFIX;
$this->parser = TeraWurflXMLParser::getInstance();
}
// Public Methods
/**
* Loads the WURFL and patch files into the database
* @return Bool Success
*/
public function load(){
$this->wurfl->toLog("Loading WURFL",LOG_INFO);
if(!is_readable($this->file)){
$this->wurfl->toLog("The main WURFL file could not be opened: ".$this->file,LOG_ERR);
$this->errors[]="The main WURFL file could not be opened: ".$this->file;
return false;
}
$this->timestart = microtime(true);
// Parse XML data into $this->devices array
$this->parser->open($this->file, TeraWurflXMLParser::$TYPE_WURFL);
$this->parser->process($this->devices);
$this->mainDevices = count($this->devices);
$this->version = $this->parser->wurflVersion;
$this->last_updated = $this->parser->wurflLastUpdated;
$this->wurfl->toLog("Loading Patches",LOG_INFO);
if(!$this->loadPatches()) return false;
$this->wurfl->toLog("Validating WURFL Data",LOG_INFO);
if(!$this->validate()) return false;
$this->wurfl->toLog("Sorting WURFL Data",LOG_INFO);
if(!$this->sort()) return false;
$this->wurfl->toLog("Loading data into DB",LOG_INFO);
if(!$this->loadIntoDB()) return false;
$this->timecache = microtime(true);
if(self::$PRESERVE_CACHE){
$this->wurfl->toLog("Rebuilding cache",LOG_INFO);
$this->wurfl->db->rebuildCacheTable();
}else{
$this->wurfl->db->createCacheTable();
}
$this->timeend = microtime(true);
$this->wurfl->db->updateSetting(TeraWurfl::$SETTING_PATCHES_LOADED,TeraWurflConfig::$PATCH_FILE);
$this->wurfl->db->updateSetting(TeraWurfl::$SETTING_WURFL_VERSION,$this->version);
$this->wurfl->db->updateSetting(TeraWurfl::$SETTING_WURFL_DATE,$this->last_updated);
$this->wurfl->db->updateSetting(TeraWurfl::$SETTING_LOADED_DATE,time());
$this->wurfl->toLog("Finished loading WURFL {$this->version} ({$this->last_updated}) in ".round($this->totalLoadTime(),2)." seconds",LOG_WARNING);
return true;
}
/**
* Validates the data from the WURFL file or Patch file
* @return Bool Vaild
*/
public function validate(){
$this->timevalidate = microtime(true);
$before_errors = count($this->errors);
foreach($this->devices as $id => &$device){
if(!$id == "generic"){
// Must have a valid wurfl ID
if(strlen($id)==0){
$this->wurfl->toLog("Skipping WURFL entry (invalid ID):\n".var_export($device,true),LOG_WARNING);
$this->errors[] = "Skipping WURFL entry (invalid ID):\n".var_export($device,true);
continue;
}
// Must have a valid User Agent unless it's "generic"
if(strlen($device['user_agent'])==0){
$this->wurfl->toLog("Skipping WURFL entry (invalid User Agent):\n".var_export($device,true),LOG_WARNING);
$this->errors[] = "Skipping WURFL entry (invalid User Agent):\n".var_export($device,true);
continue;
}
// Must have a valid fall_back
if(!$this->validID($device['fall_back'])){
$this->wurfl->toLog("Invalid Fallback '".$device['fall_back']."':\n".var_export($device,true),LOG_WARNING);
$this->errors[] = "Invalid Fallback '".$device['fall_back']."':\n".var_export($device,true);
continue;
}
}
}
return ($before_errors == count($this->errors));
}
/**
* Sorts the validated data from $this->devices into their respective UserAgentMatcher tables ($this->tables)
* based on the UserAgentMatcher that matches the device's user agent
* @return Bool Success
*/
public function sort(){
$this->timesort = microtime(true);
foreach($this->devices as $id => &$device){
// This will return something like "Nokia", "Motorola", or "CatchAll"
$matcher = UserAgentFactory::userAgentType($this->wurfl,$device['user_agent']);
// TeraWurfl_Nokia
$uatable = $this->table.'_'.$matcher;
if(!isset($this->tables[$uatable]))$this->tables[$uatable]=array();
$this->tables[$uatable][$device['id']]=$device;
}
// Destroy the devices array
$this->devices = array();
return true;
}
/**
* Loads the WURFL devices into the database.
* @return Bool Completed without error
*/
public function loadIntoDB(){
$this->timedatabase = microtime(true);
if($this->wurfl->db->loadDevices($this->tables)){
return true;
}else{
$this->errors = array_merge($this->errors,$this->wurfl->db->errors);
return false;
}
}
/**
* Loads the patch files from TeraWurflConfig::PATCH_FILE
* @return Bool Success
*/
public function loadPatches(){
if(!TeraWurflConfig::$PATCH_ENABLE) return true;
$this->timepatch = microtime(true);
// Explode the patchfile string into an array of patch files (normally just one file)
$patches = explode(';',TeraWurflConfig::$PATCH_FILE);
foreach($patches as $patch){
$patch_devices = array();
$this->wurfl->toLog("Loading patch: ".$patch,LOG_WARNING);
$patch_parser = TeraWurflXMLParser::getInstance();
$patch_parser->open(TeraWurfl::absoluteDataDir().$patch, TeraWurflXMLParser::$TYPE_PATCH);
$patch_parser->process($patch_devices);
foreach($patch_devices as $id => &$device){
if($this->validID($id)){
// Merge this device on top of the existing device
TeraWurfl::mergeCapabilities($this->devices[$id],$device);
$this->patchMergedDevices++;
}else{
// Add this new device to the table
$this->devices[$id] = $device;
$this->patchAddedDevices++;
}
}
unset($this->parser);
}
return true;
}
public function getParserName(){
return get_class(TeraWurflXMLParser::getInstance());
}
/**#@+
* Get performance information
* @return int Duration in seconds
*/
public function totalLoadTime(){
return ($this->timeend - $this->timestart);
}
public function parseTime(){
return ($this->timepatch - $this->timestart);
}
public function patchTime(){
return ($this->timevalidate - $this->timepatch);
}
public function validateTime(){
return ($this->timesort - $this->timevalidate);
}
public function sortTime(){
return ($this->timedatabase - $this->timesort);
}
public function databaseTime(){
return ($this->timecache - $this->timedatabase);
}
public function cacheRebuildTime(){
return ($this->timeend - $this->timecache);
}
/**#@-*/
/**
* Is WURFL Device ID Valid?
* @param String WURFL ID
* @return Bool
*/
protected function validID($id){
if(strlen($id)==0) return false;
return array_key_exists($id,$this->devices);
}
}