0 ) {
// dirty trick: author is child of authors, contributor is child of contributors
while ($t = each($attr)) {
// example: $thiswurfl["authors"]["author"]["name"]="Andrea Trasatti";
$thiswurfl[$name."s"][$name][$attr["name"]][$t[0]]=$t[1];
}
}
break;
case "device":
if ( ($attr["user_agent"] == "" || ! $attr["user_agent"]) && $attr["id"]!="generic" ) {
die("No user agent and I am not generic!! id=".$attr["id"]." HELP");
}
if ( sizeof($attr) > 0 ) {
while ($t = each($attr)) {
// example: $thiswurfl["devices"]["ericsson_generic"]["fall_back"]="generic";
$thiswurfl["devices"][$attr["id"]][$t[0]]=$t[1];
}
}
$curr_device=$attr["id"];
break;
case "group":
// this HAS NOT to be executed or we will define the id as string and then reuse it as array: ERROR
//$thiswurfl["devices"][$curr_device][$attr["id"]]=$attr["id"];
$curr_group=$attr["id"];
break;
case "capability":
if ( $attr["value"] == 'true' ) {
$value = true;
} else if ( $attr["value"] == 'false' ) {
$value = false;
} else {
$value = $attr["value"];
$intval = intval($value);
if ( strcmp($value, $intval) == 0 ) {
$value = $intval;
}
}
$thiswurfl["devices"][$curr_device][$curr_group][$attr["name"]]=$value;
break;
case "devices":
// This might look useless but it's good when you want to parse only the devices and skip the rest
if ( !isset($thiswurfl["devices"]) )
$thiswurfl["devices"]=array();
break;
case "wurfl_patch":
// opening tag of the patch file
case "wurfl":
// opening tag of the WURFL, nothing to do
break;
case "default":
// unknown events are not welcome
die($name." is an unknown event
");
break;
}
}
function endElement($parser, $name) {
global $wurfl, $wurfl_patch, $curr_event, $curr_device, $curr_group, $wurfl_type;
if($wurfl_type == "main"){
$thiswurfl = &$wurfl;
}elseif($wurfl_type == "patch"){
$thiswurfl = &$wurfl_patch;
}else{
die("Invalid wurfl_type.");
}
switch ($name) {
case "group":
break;
case "device":
break;
case "ver":
case "last_updated":
case "official_url":
case "statement":
$thiswurfl[$name]=$curr_event;
// referring to $GLOBALS to unset curr_event because unset will not destroy
// a global variable unless called in this way
unset($GLOBALS['curr_event']);
break;
default:
break;
}
}
function characterData($parser, $data) {
global $curr_event;
if (trim($data) != "" ) {
$curr_event.=$data;
//echo "data=".$data."
\n";
}
}
function emptyWurflDevTable($tablename){
// version 1.5.2, added KEY on actual device root for sorting
$droptable = "DROP TABLE IF EXISTS ".$tablename;
$createtable = "CREATE TABLE `".$tablename."` (
`deviceID` varchar(128) binary NOT NULL default '',
`user_agent` varchar(255) default NULL,
`fall_back` varchar(128) default NULL,
`actual_device_root` tinyint(1) default '0',
`capabilities` mediumtext,
PRIMARY KEY (`deviceID`),
KEY `fallback` (`fall_back`),
KEY `useragent` (`user_agent`),
KEY `dev_root` (`actual_device_root`)
) TYPE=".DB_TYPE;
$emptytable = "DELETE FROM ".$tablename;
if(DB_EMPTY_METHOD == "DROP_CREATE"){
if(!mysql_query($droptable))return(false);
if(!mysql_query($createtable))return(false);
}else{
if(!mysql_query($emptytable))return(false);
}
return(true);
}
function load_wurfl($filetype="main",$source="local") {
global $wurfl, $wurfl_patch, $curr_event, $curr_device, $curr_group, $fp_cache, $check_patch_params, $checkpatch_result, $wurfl_type, $new_version;
$wurfl_type = $filetype;
if($wurfl_type == "main"){
$devtable = DB_DEVICE_TABLE.DB_TEMP_EXT;
$prodtable = DB_DEVICE_TABLE;
$wurflfile = WURFL_FILE;
$thiswurfl = &$wurfl;
}elseif($wurfl_type == "patch"){
$devtable = DB_PATCH_TABLE.DB_TEMP_EXT;
$prodtable = DB_PATCH_TABLE;
$wurflfile = WURFL_PATCH_FILE;
$thiswurfl = &$wurfl_patch;
}
if(($source == "remote" || $source == "remote_cvs") && $wurfl_type == "main"){
if($source == "remote"){
$dl_url = WURFL_DL_URL;
}elseif($source == "remote_cvs"){
$dl_url = WURFL_CVS_URL;
}
$newfile = DATADIR."dl_wurfl.xml";
echo "Downloading WURFL from $dl_url ...\n
";
flush();
if(!is_writable(DATADIR)){
toLog('update',"no write permissions for data directory",LOG_ERR);
die("Fatal Error: The data directory is not writable. (".DATADIR.")
Please make the data directory writable by the user that runs the webserver process, in Linux this command would do the trick if you're not too concered about security: chmod -R 777 ".DATADIR."
");
}
@ini_set('user_agent', "PHP/Tera-WURFL_$version");
$dl_wurfl = file_get_contents($dl_url);
file_put_contents($newfile,$dl_wurfl);
$size = filesize($newfile);
echo "done ($size bytes)
";
flush();
// ignore this error - I know I'm redefining a constant :P
@define("WURFL_FILE",$newfile);
$wurflfile = $newfile;
}
$thiswurfl = array();
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if ( !file_exists($wurflfile) ) {
toLog('parse', $wurflfile." does not exist",LOG_ERR);
die($wurflfile." does not exist");
}
if (!($fp = fopen($wurflfile, "r"))) {
toLog('parse', "$wurflfile could not be opened for XML input",LOG_ERR);
die("$wurflfile could not opened XML input");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
$errmsg = sprintf("XML error: %s at line %d",xml_error_string(xml_get_error_code($xml_parser)),xml_get_current_line_number($xml_parser));
toLog('parse',$wurflfile." ".$errmsg);
die($wurflfile." ".$errmsg);
}
}
fclose($fp);
xml_parser_free($xml_parser);
$devices = &$thiswurfl["devices"];
// unset($thiswurfl['devices']);
// die("
".var_export($thiswurfl,true).""); $new_version['ver']=$thiswurfl['ver']; $new_version['last_updated']=$thiswurfl['last_updated']; emptyWurflDevTable($devtable); $processedrows = count($devices); $queries = 0; $insertedrows = 0; $maxquerysize = 0; $insert_errors = array(); $insertcache = array(); $used_ids = array(); foreach($devices as $dev_id => $dev_data) { /* * This will detect duplicate device_ids in the WURFL * if they are different cases. This is important for * databases like MySQL where keys are sorted without regard * for case. * * EDIT: I have disabled this by using 'binary' keys in MySQL * which are case sensitive. * if(in_array(strtolower($dev_id),$used_ids)){ $insert_errors[] = "Duplicate ID omitted: \"$dev_id\""; continue; }else{ $used_ids[] = $dev_id; } */ // $wurfl_agents[$one['user_agent']] = $one['id']; // convert device root to tinyint format (0|1) for db $devroot = (isset($dev_data['actual_device_root']) && $dev_data['actual_device_root'])? 1: 0; if(strlen($dev_data['user_agent']) > 255){ $insert_errors[] = "Warning: user agent too long: \"".$dev['user_agent'].'"'; } if(DB_MULTI_INSERT){ $insertcache[] = sprintf("(%s,%s,%s,%s,%s)", sqlPrep($dev_id), sqlPrep($dev_data['user_agent']), sqlPrep($dev_data['fall_back']), sqlPrep($devroot), sqlPrep(serialize($dev_data)) ); if(count($insertcache) >= DB_MAX_INSERTS){ $query = "INSERT INTO ".$devtable." (deviceID, user_agent, fall_back, actual_device_root, capabilities) VALUES ".implode(",",$insertcache); mysql_query($query) or $insert_errors[] = "DB server reported error on id \"$dev_id\": ".mysql_error(); $insertedrows += mysql_affected_rows(); $insertcache = array(); $queries++; $maxquerysize = (strlen($query)>$maxquerysize)? strlen($query): $maxquerysize; } }else{ $query = sprintf("INSERT INTO ".$devtable." (deviceID, user_agent, fall_back, actual_device_root, capabilities) VALUES (%s,%s,%s,%s,%s)", sqlPrep($dev_id), sqlPrep($dev_data['user_agent']), sqlPrep($dev_data['fall_back']), sqlPrep($devroot), sqlPrep(serialize($dev_data)) ); mysql_query($query) or $insert_errors[]=mysql_error(); $insertedrows += mysql_affected_rows(); $queries++; $maxquerysize = (strlen($query)>$maxquerysize)? strlen($query): $maxquerysize; } } // some records are probably left in the insertcache if(DB_MULTI_INSERT && count($insertcache) > 0){ $query = "INSERT INTO ".$devtable." (deviceID, user_agent, fall_back, actual_device_root, capabilities) VALUES ".implode(",",$insertcache); mysql_query($query) or $insert_errors[]=mysql_error(); $insertedrows += mysql_affected_rows(); $queries++; $maxquerysize = (strlen($query)>$maxquerysize)? strlen($query): $maxquerysize; } // perform sanity checks if(count($insert_errors) > 0){ // problem with update - changes will not be applied echo "There were errors while updating the WURFL. No changes have been made to your database.