/** * Returns the timezone for an IP address. * * @param string $ip IP address to check (defaults to <get_ip_address>) * @return string Timezone identifier or false on error */ function get_timezone_by_ip($ip = false) { if ($ip === false) { $ip = $GLOBALS['current_ip_addr']; } if (starts_with($ip, "1.1 ") || starts_with($ip, "192.168.")) { return false; } $key = "get_timezone_by_ip." . getAppVersion('nc') . "-" . $ip; $ret = cache_get($key); if ($ret) { return $ret; } /* // new url with api key: $url = "https://api.ipinfodb.com/v3/ip-city/?key=ae4dea477cd8a36cc678c582c3f990fb57a5aae696f878b4e0eee70afa53bf1e&ip=".$GLOBALS['current_ip_addr']."&format=xml"; try { $xml = downloadData($url, false, false, 60 * 60, 2); }catch(Exception $ex){ WdfException::Log("Unable to get Timezone for ".$ip." ($url)",$ex); return false; } if( preg_match_all('/<timeZone>([^<]*)<\/timeZone>/', $xml, $zone, PREG_SET_ORDER) ) { $zone = $zone[0]; if($zone[1] != "") { cache_set($key,$zone[1], 24 * 60 * 60); return $zone[1]; } } // log_error("No timezone found for ".$GLOBALS['current_ip_addr']." via ipinfodb.com"); */ $url = "http://ip-api.com/php/" . $ip; try { $data = @unserialize(downloadData($url, false, false, 60 * 60, 2)); } catch (Exception $ex) { WdfException::Log("Unable to get Timezone for " . $ip . " ({$url}) " . $ex->getMessage(), $ex); return false; } if ($data && $data['status'] == 'success') { $zone = $data['timezone']; cache_set($key, $zone, 24 * 60 * 60); return $zone; } log_error("No timezone found for " . $ip . " via ip-api.com"); $coords = get_coordinates_by_ip($ip); if ($coords === false) { log_error("No timezone found for IP " . $ip . " (missing coordinates)"); // disaster-fallback: use our timezone: return "Etc/GMT+2"; } // ALTERNATIVE 1: // ws.geonames.org had only timeouts on 2/10/2010... // $url = "http://ws.geonames.org/timezone?lat=".$coords['latitude'].'&lng='.$coords['longitude']; $url = "http://api.geonames.org/timezone?lat=" . $coords['latitude'] . '&lng=' . $coords['longitude'] . "&username=scavix"; try { $xml = downloadData($url, false, false, 60 * 60, 2); } catch (Exception $ex) { WdfException::Log("Unable to get Timezone for " . $ip . " ({$url}) " . $ex->getMessage(), $ex); return false; } if (preg_match_all('/<timezoneId>([^<]*)<\\/timezoneId>/', $xml, $zone, PREG_SET_ORDER)) { $zone = $zone[0]; cache_set($key, $zone[1], 24 * 60 * 60); return $zone[1]; } log_error("No timezone found for " . $ip . " via geonames.org"); // ALTERNATIVE 2: $url = "http://www.earthtools.org/timezone/" . $coords['latitude'] . '/' . $coords['longitude']; try { $xml = downloadData($url, false, false, 60 * 60, 2); } catch (Exception $ex) { WdfException::Log("Unable to get Timezone for " . $ip . " ({$url})", $ex); return false; } if (preg_match_all('/<offset>([^<]*)<\\/offset>/', $xml, $zone, PREG_SET_ORDER)) { $zone = $zone[0]; $zone[1] = round($zone[1], 0); $ret = "Etc/GMT" . ($zone[1] < 0 ? $zone[1] : "+" . $zone[1]); cache_set($key, $ret, 24 * 60 * 60); return $ret; } log_error("No timezone found for " . $ip . " via earthtools.org"); // disaster-fallback: use our timezone: return "Etc/GMT+2"; }
private function Unser_Inner() { $orig_line = array_shift($this->Lines); if ($orig_line == "") { return null; } $type = $orig_line[0]; $line = substr($orig_line, 2); if ($type == 'k' || $type == 'f' || $type == 'v') { $type = $line[0]; $line = substr($line, 2); } try { switch ($type) { case 's': return str_replace("\\n", "\n", $line); case 'i': return intval($line); case 'a': $res = array(); for ($i = 0; $i < $line; $i++) { $key = $this->Unser_Inner(); $res[$key] = $this->Unser_Inner(); } return $res; case 'd': if (!$line) { return null; } return new DateTime($line); case 'x': if (!$line) { return null; } return new DateTimeEx($line); case 'y': return new WdfReflector($line); case 'z': return simplexml_load_string(stripcslashes($line)); case 'o': list($id, $len, $type, $alias) = explode(':', $line); $datasource = $alias ? model_datasource($alias) : null; $this->Stack[$id] = new $type($datasource); for ($i = 0; $i < $len; $i++) { $field = $this->Unser_Inner(); if ($field == "") { continue; } $this->Stack[$id]->{$field} = $this->Unser_Inner(); } if (system_method_exists($this->Stack[$id], '__wakeup')) { $this->Stack[$id]->__wakeup(); } return $this->Stack[$id]; case 'r': if (!isset($this->Stack[intval($line)])) { WdfException::Raise("Trying to reference unknown object."); } if ($this->Stack[intval($line)] instanceof DataSource) { return model_datasource($this->Stack[intval($line)]->_storage_id); } return $this->Stack[intval($line)]; case 'm': return model_datasource($line); case 'n': return null; case 'f': return floatval($line); case 'b': return $line == 1; default: WdfException::Raise("Unserialize found unknown datatype '{$type}'. Line was {$orig_line}"); } } catch (Exception $ex) { WdfException::Log($ex); return null; } }
/** * Ensures object validity * * Calls <store_object> for every <Renderable> object in the object store to ensure that the stored * objects really match the serialized ones. This is needed because fields/properties can change after * the initial save and our caching will hide that from system. * * No need to call this manually, ScavixWDF will do! * @return void */ function Update() { global $CONFIG; $_SESSION[$CONFIG['session']['prefix'] . "session_lastaccess"] = time(); foreach ($GLOBALS['object_storage'] as $id => &$obj) { try { if ($obj instanceof Renderable) { store_object($obj, $id); } } catch (Exception $ex) { WdfException::Log("updating session storage for object {$id} [" . get_class($obj) . "]", $ex); } } }
/** * @internal Performs JavaScript minifying */ function minify_js($paths, $target_file) { require_once __DIR__ . "/minify/jsmin.php"; $files = minify_collect_files($paths, 'js'); log_debug("JS files to minify: ", $files); //die("stopped"); $code = ""; foreach ($files as $f) { if (starts_with($f, "/") && !starts_with($f, "//")) { $f = (isSSL() ? "https" : "http") . "://{$_SERVER['SERVER_NAME']}" . $f; } $js = sendHTTPRequest($f, false, false, $response_header); if (mb_detect_encoding($js) != "UTF-8") { $js = mb_convert_encoding($js, "UTF-8"); } if (stripos($response_header, "404 Not Found") !== false) { continue; } $js = "/* FILE: {$f} */\n{$js}"; if (!isset($GLOBALS['nominify'])) { try { $code .= jsmin::minify($js) . "\n"; } catch (Exception $ex) { WdfException::Log("EXCEPTION occured in jsmin::minify ({$js})", $ex); $code .= $js . "\n"; } } else { $code .= $js . "\n"; } } global $ext_resources; foreach (array_unique($ext_resources) as $ext) { $code .= "\$.getScript('{$ext}', function(){ wdf.debug('external script loaded:','{$ext}'); });"; } file_put_contents($target_file, $code); }
/** * Sends an email. * * @param mixed $recipient Email recipient as string. If $recipient is <PHPMailer> will ignore all other arguments and use this. * @param string $subject The subject * @param string $message The message (may be HTML formatted) * @param string $plainmessage Optional plain message (may differ from $message) * @param array $attachments Array of filenames to attach * @return boolean true on success or string on error */ function mail_send($recipient, $subject = "", $message = "", $plainmessage = "", $attachments = array()) { if (is_object($recipient) && $recipient instanceof PHPMailer) { $mail = $recipient; } else { $mail = mail_prepare($recipient, $subject, $message, $plainmessage, $attachments); } $res = false; try { $res = $mail->Send(); } catch (Exception $ex) { WdfException::Log($ex); $res = false; } if (!$res) { log_trace("mail_send({$subject},{$message}): " . $mail->ErrorInfo, $recipient); return $mail->ErrorInfo; } return true; }
/** * Gets a list of all keys in the cache. * * @return array list of all keys */ function globalcache_list_keys() { if (!hook_already_fired(HOOK_POST_INIT)) { return array(); } global $CONFIG; switch ($CONFIG['globalcache']['CACHE']) { case globalcache_CACHE_DB: $ds = model_datasource($CONFIG['globalcache']['datasource']); try { $rs = $ds->ExecuteSql("SELECT full_key FROM wdf_cache WHERE (valid_until IS NULL OR valid_until>=" . $ds->Driver->Now() . ")"); return $rs->Enumerate('full_key'); } catch (Exception $ex) { } return array(); case globalcache_CACHE_APC: $ret = array(); $cacheinfo = apc_cache_info('user'); $keyprefixlen = strlen($GLOBALS["globalcache_key_prefix"]); foreach ($cacheinfo['cache_list'] as $cacheentry) { $ret[] = substr($cacheentry['info'], $keyprefixlen); } return $ret; break; default: WdfException::Log("globalcache_list_keys not implemented for handler {$CONFIG['globalcache']['CACHE']}"); break; } return array(); }
/** * Called whenever a class shall be instanciated but there's no definition found * * See http://www.php.net/manual/de/function.spl-autoload-register.php * @param string $class_name Name of the class to load * @return void */ function system_spl_autoload($class_name) { if ($class_name == "" || $class_name[0] == "<") { return; } // it's html try { if (strpos($class_name, '\\') !== false) { $orig = $class_name; $class_name = array_pop(explode('\\', $class_name)); } $file = __search_file_for_class($class_name); if ($file && is_readable($file)) { $pre = get_declared_classes(); require_once $file; $post = array_unique(array_diff(get_declared_classes(), $pre)); foreach ($post as $cd) { $d = explode("\\", $cd); if (count($d) > 1) { create_class_alias($cd, array_pop($d)); } } $def = array_pop($post); if (!isset($orig) && !$def) { foreach (array_reverse($pre) as $c) { if (!ends_with($c, $class_name)) { continue; } log_info("Aliasing previously included class '{$c}' to '{$class_name}'. To avoid this check the use statements or use a qualified classname."); create_class_alias($c, $class_name, true); break; } } else { $class_name = isset($orig) ? $orig : $class_name; if (strtolower($def) != strtolower($class_name) && ends_iwith($def, $class_name)) { log_info("Aliasing class '{$def}' to '{$class_name}'. To avoid this check the use statements or use a qualified classname."); create_class_alias($def, $class_name, true); } } } } catch (Exception $ex) { WdfException::Log("system_spl_autoload", $ex); } }
/** * Converts a datetime value to this objects timezone * * @param mixed $date Date as string, integer or <DateTime> * @return int Converted time */ function GetTimezoneDate($date) { $date = $this->_ensureTimeStamp($date); if (!isset($this->TimeZone) || !$this->TimeZone) { return $date; } $dt = new DateTime(date('Y-m-d H:i:s', $date)); try { $tz = new DateTimeZone($this->TimeZone); $dt->setTimezone($tz); } catch (Exception $ex) { $this->TimeZone = ""; WdfException::Log($ex); } return strtotime($dt->format('Y-m-d H:i:s')); }
private function __toTypedValue($column_name, $value) { if (isset(self::$_typeMap[$this->_cacheKey][$column_name])) { $t = self::$_typeMap[$this->_cacheKey][$column_name]; } else { $t = $this->__typeOf($column_name); } switch ($t) { case 'int': case 'integer': return intval($value); case 'float': case 'double': return floatval($value); case 'date': case 'time': case 'datetime': case 'timestamp': try { return Model::EnsureDateTime($value); } catch (Exception $ex) { WdfException::Log("date/time error with value '{$value}'", $ex); } break; } return $value; }
/** * Get a value/object from the global cache. * * @param string $key the key of the value * @param mixed $default a default return value if the key can not be found in the cache * @return mixed The object from the cache or `$default` */ function globalcache_get($key, $default = false) { if (!hook_already_fired(HOOK_POST_INIT)) { return $default; } global $CONFIG; try { if (!isset($CONFIG['globalcache']) || !isset($CONFIG['globalcache']['CACHE'])) { return $default; } switch ($CONFIG['globalcache']['CACHE']) { case globalcache_CACHE_OFF: return $default; break; case globalcache_CACHE_APC: $ret = apc_fetch($GLOBALS["globalcache_key_prefix"] . $key, $success); return $success ? $ret : $default; break; case globalcache_CACHE_ZEND: $ret = $GLOBALS["zend_cache_object"]->load(globalcache_cleanupkey($GLOBALS["globalcache_key_prefix"] . $key)); return $ret === false ? $default : $ret; break; case globalcache_CACHE_EACCELERATOR: $ret = eaccelerator_get($GLOBALS["globalcache_key_prefix"] . md5($key)); return is_null($ret) ? $default : $ret; break; case globalcache_CACHE_MEMCACHE: $ret = $GLOBALS["memcache_object"]->get($GLOBALS["globalcache_key_prefix"] . md5($key)); return $ret === false ? $default : $ret; break; case globalcache_CACHE_DB: $ds = model_datasource($CONFIG['globalcache']['datasource']); try { $ret = $ds->ExecuteScalar("SELECT cvalue FROM wdf_cache WHERE ckey=? AND (valid_until IS NULL OR valid_until>=" . $ds->Driver->Now() . ")", array(md5($key))); } catch (Exception $ex) { return $default; } if ($ret === false) { return $default; } return session_unserialize($ret); break; } } catch (Exception $ex) { WdfException::Log($ex); die($ex->__toString()); } return $ret; }
/** * Returns the timezone for an IP address. * * @param string $ip IP address to check (defaults to <get_ip_address>) * @return string Timezone identifier or false on error */ function get_timezone_by_ip($ip = false) { if ($ip === false) { $ip = $GLOBALS['current_ip_addr']; } if (starts_with($ip, "1.1 ") || starts_with($ip, "192.168.1.")) { return false; } $key = "get_timezone_by_ip." . getAppVersion('nc') . "-" . $ip; $ret = cache_get($key); if ($ret) { return $ret; } // new url with api key: $url = "http://api.ipinfodb.com/v2/ip_query.php?key=6a6ef9d4d82491036a4f3dbd465d52d2e2d5253d1285a3dda02b65752b5474f8&ip=" . $GLOBALS['current_ip_addr'] . "&timezone=true"; try { $xml = downloadData($url, false, false, 60 * 60, 2); } catch (Exception $ex) { WdfException::Log("Unable to get Timezone for " . $ip . " ({$url})", $ex); return false; } if (preg_match_all('/<TimezoneName>([^<]*)<\\/TimezoneName>/', $xml, $zone, PREG_SET_ORDER)) { $zone = $zone[0]; if ($zone[1] != "") { cache_set($key, $zone[1], 24 * 60 * 60); return $zone[1]; } } // log_error("No timezone found for ".$GLOBALS['current_ip_addr']." via ipinfodb.com"); $coords = get_coordinates_by_ip($ip); if ($coords === false) { log_error("No timezone found for IP " . $ip . " (missing coordinates)"); // disaster-fallback: use our timezone: return "Etc/GMT+2"; } // ALTERNATIVE 1: // ws.geonames.org had only timeouts on 2/10/2010... // $url = "http://ws.geonames.org/timezone?lat=".$coords['latitude'].'&lng='.$coords['longitude']; $url = "http://api.geonames.org/timezone?lat=" . $coords['latitude'] . '&lng=' . $coords['longitude'] . "&username=scendix"; try { $xml = downloadData($url, false, false, 60 * 60, 2); } catch (Exception $ex) { WdfException::Log("Unable to get Timezone for " . $ip . " ({$url}) " . $ex->getMessage(), $ex); return false; } if (preg_match_all('/<timezoneId>([^<]*)<\\/timezoneId>/', $xml, $zone, PREG_SET_ORDER)) { $zone = $zone[0]; cache_set($key, $zone[1], 24 * 60 * 60); return $zone[1]; } log_error("No timezone found for " . $ip . " via geonames.org"); // ALTERNATIVE 2: $url = "http://www.earthtools.org/timezone/" . $coords['latitude'] . '/' . $coords['longitude']; try { $xml = downloadData($url, false, false, 60 * 60, 2); } catch (Exception $ex) { WdfException::Log("Unable to get Timezone for " . $ip . " ({$url})", $ex); return false; } if (preg_match_all('/<offset>([^<]*)<\\/offset>/', $xml, $zone, PREG_SET_ORDER)) { $zone = $zone[0]; $zone[1] = round($zone[1], 0); $ret = "Etc/GMT" . ($zone[1] < 0 ? $zone[1] : "+" . $zone[1]); cache_set($key, $ret, 24 * 60 * 60); return $ret; } log_error("No timezone found for " . $ip . " via earthtools.org"); // disaster-fallback: use our timezone: return "Etc/GMT+2"; }
/** * Checks if a vat number is valid * * @param type $vat_number VAT number to be checked * @return bool true if valid, else false */ function check_vat_number($vat_number) { $vat = strtoupper(str_replace(array(" ", "-", ",", ".", "/", "\\"), "", $vat_number)); if (preg_match("/^(AT|BE|BG|CY|CZ|DE|DK|EE|EL|ES|FI|FR|GB|HU|IE|IT|LT|LU|LV|MT|NL|PL|PT|RO|SE|SI|SK)(.*)/i", $vat, $matches)) { $country_code = strtoupper($matches[1]); $vat = $matches[2]; } if (!isset($country_code)) { return false; } $regex = array('AT' => '/(U[0-9]{8})/i', 'BE' => '/(0[0-9]{9})/i', 'BG' => '/([0-9]{9,10})/i', 'CY' => '/([0-9]{8}[a-z])/i', 'CZ' => '/([0-9]{8}|[0-9]{9}|[0-9]{10})/i', 'DE' => '/([0-9]{9})/i', 'DK' => '/([0-9]{8})/i', 'EE' => '/([0-9]{9})/i', 'EL' => '/([0-9]{9})/i', 'ES' => '/([a-z][0-9]{8}|[0-9]{8}[a-z]|[a-z][0-9]{7}[a-z])/i', 'FI' => '/([0-9]{8})/i', 'FR' => '/([a-z0-9]{2}[0-9]{9})/i', 'GB' => '/([0-9]{9}|[0-9]{12}|GD[0-9]{3}|HA[0-9]{3})/i', 'HU' => '/([0-9]{8})/i', 'IE' => '/([0-9][a-z0-9\\+\\*][0-9]{5}[a-z])/i', 'IT' => '/([0-9]{11})/i', 'LT' => '/([0-9]{9}|[0-9]{12})/i', 'LU' => '/([0-9]{8})/i', 'LV' => '/([0-9]{11})/i', 'MT' => '/([0-9]{8})/i', 'NL' => '/([0-9]{9}B[0-9]{2})/i', 'PL' => '/([0-9]{10})/i', 'PT' => '/([0-9]{9})/i', 'RO' => '/([0-9]{2,10})/i', 'SE' => '/([0-9]{12})/i', 'SI' => '/([0-9]{8})/i', 'SK' => '/([0-9]{10})/i'); if (!isset($regex[$country_code])) { return false; } if (!preg_match($regex[$country_code], $vat, $m)) { return false; } // only ask service is syntax-check is ok if ($m[1] == $vat) { try { $res = cache_get("vat_check_{$country_code}_{$vat}"); if (!$res) { $sc = new SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl"); $test = $sc->checkVat(array('countryCode' => $country_code, 'vatNumber' => $vat)); if (!$test->valid) { log_debug("VAT syntax ok, but SOAP says not", $vat_number, $country_code, $vat, $test); } $res = $test->valid ? "valid" : "invalid"; cache_set("vat_check_{$country_code}_{$vat}", $res); } elseif ($res != "valid") { log_debug("VAT syntax ok, but CACHE says not", $vat_number, $country_code, $vat); } return $res == "valid"; } catch (Exception $ex) { WdfException::Log($ex); } return true; // ignore service exceptions } return false; }
/** * Converts a string to a unix timestamp. * * Tries all KnownDateTimePatterns() and uses the best match. * Known Bugs: * - Culture cs-CZ Format dd MMMM * - Culture mt-MT Format dddd, d' ta\' 'MMMM yyyy * - Culture mt-MT Format dddd, d' ta\' 'MMMM yyyy HH:mm:ss * - Culture vi-VN Format dd MMMM * * @param string $str Input string in one of the KnownDateTimePatterns() * @return int The timestamp or FALSE on error */ public function StringToTime($str) { $apm1 = substr($this->AM, 0, 1) . '|' . substr($this->PM, 0, 1); $regex_data = array("d5" => '(\\d(|st|nd|rd))', "d4" => '(' . $this->_regexEscapeArray($this->DayNames) . ')', "d3" => '(' . $this->_regexEscapeArray($this->ShortDayNames) . ')', "d2" => '(\\d\\d)', "d1" => '(\\d|\\d\\d)', "h2" => '(\\d|\\d\\d)', "h1" => '(\\d|\\d\\d)', "H2" => '(\\d\\d)', "H1" => '(\\d|\\d\\d)', "m2" => '(\\d\\d)', "m1" => '(\\d\\d)', "M4" => '(' . $this->_regexEscapeArray($this->MonthNames) . ')', "M3" => '(' . $this->_regexEscapeArray($this->ShortMonthNames) . ')', "M2" => '(\\d\\d)', "M1" => '(\\d|\\d\\d)', "s2" => '(\\d\\d)', "s1" => '(\\d\\d)', "y4" => '(\\d{4})', "y3" => '(\\d{4})', "y2" => '(\\d\\d)', "y1" => '(\\d\\d)', "t2" => '(' . $this->AM . '|' . $this->PM . ')', "t1" => '(' . $apm1 . ')'); $replacements = array_values($regex_data); $rep_keys = array_keys($regex_data); $pattern = self::$PatternPlaceholders; $formats = $this->KnownDateTimePatterns(); $found = array(); $semantics = array(); foreach ($formats as $format) { $tmp_s = array(); for ($iter = 0; $iter < strlen($format); $iter++) { foreach ($pattern as $k => $p) { if (substr($format, $iter, strlen($p)) == $p) { $tmp_s[] = $rep_keys[$k]; $format = substr_replace($format, $replacements[$k], $iter, strlen($p)); $iter += strlen($replacements[$k]); break; } } } $format = str_replace('.', '\\.', $format); $format = str_replace('/', '\\/', $format); $format = str_replace(' ', '\\s', $format); $format = '/' . $format . '/iU'; try { if (preg_match($format, $str, $match)) { if (count($found) < count($match)) { $found = $match; $semantics = $tmp_s; } } } catch (Exception $ex) { WdfException::Log("Invalid RegEx: {$format}", $ex); } } if (count($found) < 1) { return false; } $d = 1; // because 0 would mktime return the last day of the previous month, so patterns like MMMM, YYYY would return prev month $m = 0; $y = 0; $h = 0; $i = 0; $s = 0; $apm = $this->AM; $fcnt = count($found); for ($iter = 1; $iter < $fcnt; $iter++) { switch ($semantics[$iter - 1]) { case "d5": case "d4": case "d3": break; case "M4": for ($mn = 0; $mn < count($this->MonthNames); $mn++) { if ($this->MonthNames[$mn] == $found[$iter]) { $m = $mn + 1; break; } } break; case "M3": $m = array_search($found[$iter], $this->ShortMonthNames); $m++; break; case "d2": case "d1": $d = $found[$iter]; break; case "h1": case "h1": $h2 = $found[$iter]; break; case "H2": case "H1": $h = $found[$iter]; break; case "m2": case "m1": $i = $found[$iter]; break; case "M2": case "M1": $m = $found[$iter]; break; case "s2": case "s1": $s = $found[$iter]; break; case "y4": case "y3": $y = $found[$iter]; break; case "y2": case "y1": $y2 = $found[$iter]; break; case "t2": case "t1": $apm = $found[$iter]; break; default: log_debug("Unknown semantic for {$iter} -> " . $semantics[$iter - 1]); break; } } if ($h == 0 && isset($h2)) { $add = $apm == $this->AM ? 0 : ($apm == substr($this->AM, 0, 1) ? 0 : 12); $h = intval($h2) + intval($add); } if ($y == 0 && isset($y2)) { $y = intval(substr(date("Y"), 0, 2) . $y2); } return mktime($h, $i, $s, $m, $d, $y); }