fetch($url, $referer, $headers); } } public function add_browser_headers() { global $bCurl_headers; $this->add_headers($bCurl_headers); } public function interface_random() { if( self::$interfaces ) { // need to 'seed' the random number generator when threading srand(); $i = self::$interfaces[array_rand(self::$interfaces)]; return $i; } else { // don't run ifconfig everytime $ifaces = bcache('bCurl', 'ifconfig', 60*60*24, function() { exec('/sbin/ifconfig', $output); $output = implode($output, R); preg_match_all('/[\r\n]([^\s\t]{4,10})/', $output, $matches); if( count($matches[1]) ) { $ifaces = $matches[1]; } else { $ifaces = array('eth0'); } return $ifaces; }); self::$interfaces = $ifaces; return $this->interface_random(); } } public function get_info() { return curl_getinfo($this->crl); } public function process_headers($ch, $header) { $this->add_headers($header); } public function get_cookies() { preg_match_all('|Set-Cookie: (.*);|U', $this->response_headers, $results); foreach($results[1] as $flat_cookie) { if($flat_cookie != null && $flat_cookie != '') { $split_cookie = explode('=', $flat_cookie); $cookies[urldecode($split_cookie[0])] = urldecode($split_cookie[1]); } } return $cookies; } public function get_header($name) { if ($name != null) { $matches = array(); preg_match('/'.$name.':(.*?)\n/', $this->response_headers, $matches); //$value = @parse_url(trim(array_pop($matches))); if( isset($matches[1]) ) { $value = $matches[1]; if ( strlen($value) > 0 ) { return $value; } } } return false; } public function add_headers($headers) { if( is_array($headers) && is_array($this->headers) ) { abmerge($this->headers, $headers); } else if( is_array($headers) && !is_array($this->headers) ) { $this->headers = $headers; } else if ( is_string($headers) && is_array($this->headers) ) { array_push($this->headers, $headers); } else if( is_string($headers) && !is_array($this->headers) ) { $this->headers[0] = $headers; } } public function authenticate($user, $pass) { $this->user = $user; $this->pass = $pass; } public function fetch($url=false, $referer=false) { if ($url != false) { if($referer) $this->referer = $referer; $this->url = $url; $this->exec(); return $this->response; } else { return false; } } public function fetch_json($url=false, $referer=false) { $this->decode_json = true; $data = $this->fetch($url, $referer); $this->decode_json = false; return $data; } public function exec() { // if caching is enabled if( $this->cache ) { $cache_key = $this->url; if( $this->postdata ) { $cache_key .= json_encode($this->postdata); } if( $this->headers ) { $cache_key .= json_encode($this->headers); } $bCurl = $this; // check if there is a cached version $cache_status = bcache('bCurl', $cache_key, $this->cachetime, function() use ($bCurl) { return $bCurl->make_request(); }, $cache); // if data was from cache file if( $cache_status ) { $this->response = $cache; $this->last_request_cached = true; return $cache; } } $this->last_request_cached = false; return $this->make_request(); } public function make_request() { // INITIATE CURL if(isset($this->crl)) { @curl_close($this->crl); unset($this->crl); unset($this->response); //curl_setopt($this->crl, CURLOPT_FRESH_CONNECT, 1); $this->crl = curl_init(); } else { $this->crl = curl_init(); } // DEFAULT OPTIONS curl_setopt($this->crl, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($this->crl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($this->crl, CURLOPT_MAXREDIRS, 10); curl_setopt($this->crl, CURLOPT_RETURNTRANSFER, 1); //curl_setopt($this->crl, CURLOPT_HEADERFUNCTION, array(&$this,'process_headers')); // SET INTERFACE $this->iface = $this->interface_random(); if( $this->iface ) { curl_setopt($this->crl, CURLOPT_INTERFACE, $this->iface); } // AUTHENTICATE if( $this->user && $this->pass ) { curl_setopt($this->crl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ; curl_setopt($this->crl, CURLOPT_USERPWD, $this->user.":".$this->pass); } // SET USER AGENT if ( $this->user_agent ) { curl_setopt($this->crl, CURLOPT_USERAGENT, $this->user_agent); } // SET REFERER if ( $this->referer != null ) { curl_setopt($this->crl,CURLOPT_REFERER,$this->referer); } // SET POST METHOD if ( $this->postdata ) { //curl_setopt($this->crl, CURLOPT_POST, 1); curl_setopt($this->crl, CURLOPT_POSTFIELDS, $this->postdata); } // SET COOKIES if ( $this->cookies != null ) { $flat_cookies = ''; foreach ( $this->cookies as $name => $value) { $flat_cookies .= "$name=$value; "; } $flat_cookies = substr( $flat_cookies, 0, -2 ); curl_setopt($this->crl, CURLOPT_COOKIE, $flat_cookies); } // SET HEADERS if ( is_array ($this->headers) ) { curl_setopt ($this->crl, CURLOPT_HTTPHEADER, $this->headers); } // SSL VERIFICATION -- OFF BY DEFAULT FOR SPEED if ( !$this->ssl_verify ) { curl_setopt($this->crl, CURLOPT_SSL_VERIFYPEER, FALSE); } curl_setopt($this->crl, CURLOPT_URL, $this->url); bdebug(tcolor("bCurl : ", "BLUE").tcolor($this->url, "GREEN").tcolor(" on ".$this->iface, "MAGENTA")); $start_time = time(); $return_data = curl_exec($this->crl); $stop_time = time(); if ($return_data === false) bdebug('*** bCurl: Could not get reply: '.curl_error($this->crl), "LIGHT_RED"); $this->response_time = $stop_time - $start_time; curl_close($this->crl); $this->referer = $this->url; bdebug($return_data, "LIGHT_CYAN", 4); // dont cache by returning false if json decode fails if($this->decode_json) { return $this->response = json_decode($return_data, true); } return $this->response = $return_data; } } '.$domain.'', $source); // add the colored domain tag return ''.$wrapped_domain.''; } function render_big_dropdown($button_text, $items, $ident='') { $o = '
'; $o .= '
'.$button_text.'
'; $o .= '
'; return $o; } url_segments = explode('/', preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI'])); // check IP bans if( $this->arg(1) == 'login' && $bans = bdb::fetch_array("SELECT * FROM bans WHERE ip = '{$_SERVER['REMOTE_ADDR']}' AND lifted > '".date("Y-m-d H:i:s", time())."'" ) ) { if( $this->arg(1) != 'banned' ) { $this->redirect('/banned'); } } // load user data once if( !self::$uid ) { require_once INCLUDES . '/api-auth.php'; require_once INCLUDES . '/login.php'; if( isset($_SESSION['uid']) ) { self::$uid = $_SESSION['uid']; self::$user_data = $user_data; if( isset($user_data['active']) ) { // if not active user if( !$user_data['active'] && $this->arg(1) != 'logout' ) { $this->redirect('/logout/?redirect=/inactive'); } } } } // if logged in if( self::$uid ) { $this->uid = $_SESSION['uid']; $this->username = $_SESSION['username']; self::$user_data['subscription'] = 0; $this->user_data = self::$user_data; // if user payment has been confirmed if( $this->user_data['active'] == 2 && $this->user_data['next_payment'] >= date("Y-m-d H:i:s") ) { self::$user_data['subscription'] = 1; } // if user has paid but not required number of confirmations else if( !self::$payments && $this->user_data['active'] == 1 && $this->user_data['next_payment'] >= date("Y-m-d H:i:s") ) { self::$payments = get_payments(self::$uid); $this->payments = self::$payments; self::$user_data['subscription'] = 1; } $this->user_data = self::$user_data; } // not logged in else { $this->uid = 0; } // detect mobile devices /* $detect = new Mobile_Detect(); self::$mobile = $detect->isMobile(); */ self::$mobile = false; } public function get($key) { return self::$$key; } public function set($key, $value) { self::$$key = $value; return $this; } function getv($name) { if( isset($this->vars[$name]) ) { return $this->vars[$name]; } else { return false; } } function setv($name, $var) { $this->vars[$name] = $var; return $this; } function arg($num) { if( isset($this->url_segments[$num]) ) { return $this->url_segments[$num]; } else { return false; } } function load_header($title=false) { global $main_nav; if( $title ) $this->vars['title'] = $title; $this->vars['logged_in'] = $this->uid; $this->vars['main_nav'] = $main_nav; // setup notifications menu /* $unseen = false; if( $this->uid ) $this->vars['notifications'] = get_notifications($_SESSION['uid'], $unseen); if( $unseen ) $this->vars['noticon'] = '/img/notification-on.png'; else $this->vars['noticon'] = '/img/notification-off.png'; */ if( self::$mobile ) { $this->load_tpl('mobile-header'); } else { $this->load_tpl('header'); } } function load_footer() { $this->load_tpl('footer'); } function model($model, $arg=false) { $m = ucfirst($model); $include_model = MODELS."/$m.class.php"; // load and attach model first if( file_exists( $include_model ) ) { require_once($include_model); $class_name = $m."_Model"; $model_object = new $class_name; return $model_object; } return false; } public function load_page($arg=null) { // for testing and logging bdebug(tcolor("* REQUEST ","LIGHT_GREEN").tcolor($_SERVER['REQUEST_URI'],"YELLOW")); // if no arg is passed then use from URL if(!$arg) $arg = $this->arg(1); // if we are controlling subdomains if( !preg_match('/^www\.'.TRACKER_DOMAIN.'/i', $_SERVER['HTTP_HOST']) && !preg_match('/^'.TRACKER_DOMAIN.'/i', $_SERVER['HTTP_HOST']) ) { include(INCLUDES.'/subdomains.handler.php'); } // if nothing then load homepage as default if( !strlen($arg) ) $arg = HOMEPAGE; // clean page argument if( preg_match('/[^a-zA-Z0-9\-\_\.]/', $arg) ) { $arg = preg_replace('/[^a-zA-Z0-9\-\_\.]/', '-', $arg); $this->redirect("/$arg"); } // closed to beta testers /* if( !$this->uid && !in_array($arg, array('homepage', 'login', 'register', 'resetpw', 'request-invite', 'banned', 'inactive') ) ) { $this->throw404(); } */ // closed to dev if ( DEV && $arg != 'logout' && $this->uid && $this->uid != 1 ) { $this->redirect('/logout'); } // subscription /* if( $this->uid && !$this->user_data['active'] && $arg != 'subscription') { $this->redirect('/subscription'); } */ $include_file = CONTROLLERS."/$arg.php"; $include_class_file = CONTROLLERS."/$arg.class.php"; // load controller extention class if( file_exists( $include_class_file ) ) { $class_name = preg_replace('/[^0-9a-zA-Z\_]/', '_', $arg); $subpage = preg_replace('/[^0-9a-zA-Z\_]/', '_', $this->arg(2)); include($include_class_file); $controller = new $class_name; $controller->uid = self::$uid; // attach the associated model if available $controller->m = $this->model($arg); // fire init function if( method_exists($controller, 'init') ) $controller->init(); // if this is a subpage if( strlen($subpage) ) { // this makes sure it is a method of the child class and not the main controller if( method_exists( $controller, $subpage) && !in_array($subpage,get_class_methods('controller')) ) return $controller->$subpage(); } // if this is the main method if( method_exists( $controller, '_main') ) return $controller->_main(); $this->throw404(); } // load simple controller if( file_exists( $include_file ) ) { include($include_file); return true; } /* if( $user = bdb::fetch_row('users', array( 'username' => $arg)) ) { if($user['uid']) { // pass the user array $this->setv('user', $user); $this->load_tpl('user'); return true; } } */ $this->throw404(); } function load_tpl($tpl, $var = false) { if( isset($this->vars) ) { $vars = $this->vars; } if( THEME_FOLDER ) $theme_override = THEME_FOLDER.'/templates/'.$tpl.'.tpl.php'; if( isset($theme_override) && file_exists($theme_override) ) include($theme_override); else include( VIEWS.'/'.$tpl.'.tpl.php' ); } function tpl($tpl, $vars=false) { if( !$vars && isset($this->vars) ) { $vars = $this->vars; } ob_start(); include( VIEWS.'/'.$tpl.'.tpl.php' ); $return = ob_get_contents(); ob_end_clean(); return $return; } function redirect($loc) { header( 'Location: '.$loc ); exit(); } function ban_ip($mod) { bdb::insert('bans', array('ip' => $_SERVER['REMOTE_ADDR'], 'lifted' => date("Y-m-d H:i:s", time()+$mod) ) ); } function ban_user($mod) { bdb::insert('bans', array('uid' => $this->uid, 'lifted' => date("Y-m-d H:i:s", time()+$mod) ) ); } function throw404() { bdebug('*** 404 *** '.$_SERVER['REQUEST_URI'], "LIGHT_RED"); $this->setv('notoolbar', true); $this->setv('noscripts', true); $this->setv('exactostats', true); $this->load_header('Error 404 - File Not Found'); include( VIEWS.'/404.tpl.php' ); $this->load_footer(); exit(); } function ssl_redirect() { if( $_SERVER["SERVER_PORT"] == "80" ) { header ('HTTP/1.1 301 Moved Permanently'); header('Location: https://'.SITE_DOMAIN.$_SERVER['REQUEST_URI']); } } function trailing_slash_redirect() { $location_check = preg_match('/^[^\?]+\/$/', $_SERVER['REQUEST_URI']); if( $location_check ) { header ('HTTP/1.1 301 Moved Permanently'); header('Location: '.substr($_SERVER['REQUEST_URI'], 0, -1)); } } function www_redirect() { $location_check = preg_match('/^www\.'.SITE_DOMAIN.'$/', $_SERVER['HTTP_HOST']); if( $location_check ) { header ('HTTP/1.1 301 Moved Permanently'); header('Location: '.SITE_URL.$_SERVER['REQUEST_URI']); } } } ( $username ? $username : bhash('user-'.microtime(),10) ), 'email' => ( $email ? $email : bhash('email-'.microtime(),10) ), 'password' => mysql_password( ( $password ? $password : bhash('pass-'.microtime(),10) )), 'IP' => $_SERVER['REMOTE_ADDR'], 'is_active' => 3, 'period' => '1Y', 'last_payment' => date('Y-m-d'), 'next_payment' => date('Y-m-d',strtotime(date("Y-m-d", mktime()) . " + 365 day")), ) ); } function activate_user($uid, $plan='1Y') { return true; } function load_site($sid,$uid) { return bdb::fetch_result('sites', array('site_id' => $sid, 'uid' => $uid) ); } function get_keywords($url) { preg_match("/(\&q\=|\?q\=|\&p\=|\?p\=)[A-Za-z0-9\-\_\%\+\.\@\'\\\"]{1,500}/", $url, $matches); $keywords = urldecode( preg_replace('/(\&q\=|\?q\=|\&p\=|\?p\=)/', '', @$matches[0]) ); return strtolower($keywords); } function get_rank($url) { if( preg_match('/(\&cd\=)[0-9]{1,500}/', $url, $matches) ) { $rank = preg_replace('/(\&cd\=)/', '', $matches[0]); return $rank; } return false; } function get_search_data($sid) { $rurls = bdb::fetch_all("SELECT referer FROM visitors WHERE site_id='$sid' && referer REGEXP '([[.ampersand.]]q[[.equals-sign.]]|[[.question-mark.]]q[[.equals-sign.]])[A-Za-z0-9[.hyphen.][.plus-sign.][.underscore.][.percent-sign.][.period.]]+'" ); if( !$rurls ) return array(); $keywords = array(); foreach($rurls as $rurl ) { $k = get_keywords($rurl['referer']); $r = get_rank($rurl['referer']); if( is_array(@$keywords[$k]) && is_numeric(@$keywords[$k]['count']) ) { $keywords[$k]['count']++; } else { $keywords[$k]['count'] = 1; } if( $r ) { $keywords[$k]['rank'] = $r; } } // sorts perfectly using count first and then rank arsort($keywords); return $keywords; } function dec2hex($dec, $digits=false) { $hex = ''; $sign = $dec < 0 ? false : true; while ($dec) { $hex .= dechex(abs(bcmod($dec, '16'))); $dec = bcdiv($dec, '16', 0); } if ($digits) { while (strlen($hex) < $digits) { $hex .= '0'; } } if ($sign) { return strrev($hex); } for ($i = 0; isset($hex[$i]); $i++) { $hex[$i] = dechex(15 - hexdec($hex[$i])); } for ($i = 0; isset($hex[$i]) && $hex[$i] == 'f'; $i++) { $hex[$i] = '0'; } if (isset($hex[$i])) { $hex[$i] = dechex(hexdec($hex[$i]) + 1); } return strrev($hex); } function get_heat_color($c) { // Blue Maxed, Green rises if($c <= 25) { $c = $c*10; $c = round($c, 0); return '00'.dec2hex($c, 2).'FF'; } // green maxed, blue falls if($c > 25 && $c <= 50) { $c = $c - 25; $c = $c*10; $c = 255 - $c; $c = round($c, 0); return '00FF'.dec2hex($c, 2); } //green maxed, red rises if($c > 50 && $c <= 75) { $c = $c - 50; $c = $c*10; $c = round($c, 0); return dec2hex($c, 2).'FF00'; } // red maxed, green falls if($c > 75 && $c <= 100) { $c = $c - 75; $c = $c*10; $c = 255 - $c; $c = round($c, 0); return 'FF'.dec2hex($c, 2).'00'; } } function prorate_days( $next_payment_date ) { $today = getdate(); $current_stamp = mktime ( 0,0,0,$today['mon'], $today['mday'], $today['year'] ); $next_pay = date_parse ( $next_payment_date ); $next_stamp = mktime ( 0,0,0,$next_pay['month'], $next_pay['day'], $next_pay['year'] ); $prorate_days = ($next_stamp - $current_stamp) / (60 * 60 * 24); return round($prorate_days, 0); } function prorate_credit( $next_payment_date, $period, $amount ) { $prorate_days = prorate_days( $next_payment_date ); if( $period == '1 M') { $prorate_credit = $prorate_days * ($amount / 31); } if( $period == '1 Y') { $prorate_credit = $prorate_days * ($amount / 365); } $prorate_credit = round($prorate_credit, 2); return $prorate_credit; } function format_time($seconds, $round = false) { // adjusted for milliseconds $seconds = $seconds/10; $minutes = floor($seconds/60); $seconds = $seconds - ($minutes * 60); if($round == true) { $seconds = round($seconds, 0); } if($minutes != 0) { $formatted_time = $minutes.'m '.ceil($seconds).'s'; } else { $formatted_time = ceil($seconds).'s'; } return $formatted_time; } function domainFromURL($url) { $spliturl = explode('/', $url); $domain = $spliturl[2]; $splitdomain = explode('.', $domain); if($splitdomain[0] == 'www') { $new_splitdomain = array_filter($splitdomain, "www_check"); $domain = implode('.', $new_splitdomain); } return $domain; } function www_check($val) { if($val == 'www' || $val == '' || $val == null) { return false; } else { return true; } } function withQueryChar($location) { $arrayCheck = explode('?', $location); if(count($arrayCheck) > 1) { echo $location . '&'; } else { echo $location . '?'; } } function alternator($class1, $class2) { static $state = 0; if($state == 0) { $state = 1; echo $class1; } else if($state == 1) { $state = 0; echo $class2; } } function getUniquePages($site_id) { //$pages = bdb::fetch_all('pages', array('site_id' => $site_id)); $pages = bdb::fetch_all("SELECT *, COUNT(visit_id) as page_count, SUM(dheight) as dheight, SUM(wheight) as wheight, SUM(scroll) as scroll, SUM(total_time) as total_time FROM pages WHERE site_id='$site_id' GROUP BY location"); $page_count = count($pages); if($page_count > 0) { $unique_pages = array(); // loop through all pages and compare to build an array of unique pages foreach($pages as $page) { // catch google clickthroughs and cut them off $gclid_check = explode('?gclid=', $page['location']); if( count($gclid_check) < 2 ) { $gclid_check = explode('&gclid=', $page['location']); } $gclid_count = count($gclid_check); if($gclid_count > 1) { $page['location'] = $gclid_check[0]; } // check for page location match - if they match then calculate new stat totals if(@$unique_pages[@$page['location']] != null) { // increment the counter for number of like pages $unique_pages[$page['location']]['n'] += $page['page_count']; // add the google clickthrough id if($gclid_count > 1) { $unique_pages[$page['location']]['gc'][] = $gclid_check[1]; $gclid_count = 0; } // calculate average scroll if($page['dheight']) { $scroll = (($page['scroll'] + $page['wheight']) / $page['dheight']) * 100; if($scroll > 100) { $scroll = 100; } $unique_pages[$page['location']]['s'] = ($unique_pages[$page['location']]['s'] + $scroll)/2; } // calculate average time if($page['total_time']) { $unique_pages[$page['location']]['t'] = $unique_pages[$page['location']]['t'] + ($page['total_time'] / $page['page_count']); } } else { //Page is Unique so set it up in the array $unique_pages[$page['location']]['n'] = $page['page_count']; // calculate initial scroll if($page['dheight']) { $unique_pages[$page['location']]['s'] = (($page['scroll'] + $page['wheight']) / $page['dheight']) * 100; if($unique_pages[$page['location']]['s'] > 100) { $unique_pages[$page['location']]['s'] = 100; } } // inital time $unique_pages[$page['location']]['t'] = $page['total_time']; } } } return $unique_pages; } function timeDiff($timestamp,$detailed=false, $max_detail_levels=8, $precision_level='second'){ $now = time(); #If the difference is positive "ago" - negative "away" ($timestamp >= $now) ? $action = 'away' : $action = 'ago'; # Set the periods of time $periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade"); $lengths = array(1, 60, 3600, 86400, 604800, 2630880, 31570560, 315705600); $diff = ($action == 'away' ? $timestamp - $now : $now - $timestamp); $prec_key = array_search($precision_level,$periods); # round diff to the precision_level $diff = round(($diff/$lengths[$prec_key]))*$lengths[$prec_key]; # if the diff is very small, display for ex "just seconds ago" if ($diff <= 10) { $periodago = max(0,$prec_key-1); $agotxt = $periods[$periodago].'s'; return "just $agotxt $action"; } # Go from decades backwards to seconds $time = ""; for ($i = (sizeof($lengths) - 1); $i>0; $i--) { if($diff > $lengths[$i-1] && ($max_detail_levels > 0)) { # if the difference is greater than the length we are checking... continue $val = floor($diff / $lengths[$i-1]); # 65 / 60 = 1. That means one minute. 130 / 60 = 2. Two minutes.. etc $time .= $val ." ". $periods[$i-1].($val > 1 ? 's ' : ' '); # The value, then the name associated, then add 's' if plural $diff -= ($val * $lengths[$i-1]); # subtract the values we just used from the overall diff so we can find the rest of the information if(!$detailed) { $i = 0; } # if detailed is turn off (default) only show the first set found, else show all information $max_detail_levels--; } } # Basic error checking. if($time == "") { return "Error-- Unable to calculate time."; } else { return $time.$action; } } function ScsSerialize( &$params ) { $ret = ''; foreach( $params as $key => $val ) { if ( $ret ) $ret .= ','; $ret .= rawurlencode( $key ); if ( is_array( $val ) ) $ret .= '{' . ScsSerialize( $val ) . '}'; else if ( strlen( $val ) ) $ret .= '=' . rawurlencode( $val ); } return $ret; } function ScsDeserialize( $params, &$last = 0 ) { $arr = array(); $l = strlen( $params ); $s = 0; $e = 0; while ( $e < $l ) { switch( $params[ $e ] ) { case ',' : case '}' : { if ( 1 < $e - $s ) { $a = split( '=', substr( $params, $s, $e - $s ) ); if ( !isset( $a[ 0 ] ) ) $a[ 0 ] = 0; else $a[ 0 ] = rawurldecode( $a[ 0 ] ); if ( !isset( $a[ 1 ] ) ) $arr[ $a[ 0 ] ] = ''; else $arr[ $a[ 0 ] ] = rawurldecode( $a[ 1 ] ); } $s = $e + 1; if ( '}' == $params[ $e ] ) { if ( $last ) $last = $e + 1; return $arr; } } break; case '{' : { $k = rawurldecode( substr( $params, $s, $e - $s ) ); if ( isset( $k ) ) { $end_array = 1; $arr[ $k ] = ScsDeserialize( substr( $params, $e + 1 ), $end_array ); $e += $end_array; } $s = $e + 1; } break; } $e++; } return $arr; } function save_scrap_file($uuid, $html) { $cache_file = FILES."/html/$uuid.html"; bdebug("Saving Scrap File $cache_file"); return file_put_contents($cache_file, $html); } function save_scraps($scraps, $chunk_size) { // save completed scraps foreach( $scraps as $uuid => $parts ) { ksort($parts, true); $data = implode('', $parts); // decompress $lzw = new LZW(127); $html = $lzw->decompress($data, $chunk_size); // debugger output if( DEBUG > 2 ) { bdebug( "compiling '$uuid'"); bdebug( 'Number of Parts:'.count($parts).R.R.print_r($parts, true)); bdebug( "VERIFY LENGTH - ".strlen($data).""); bdebug( "HTML LENGTH - ".strlen($html).""); bdebug( "CHUNK SIZE - ".$chunk_size.""); //bdebug( "$data"); //bdebug("$html"); } // if decompression was successful if($html) { save_scrap_file($uuid, $html); // remove from queue unset($_SESSION['scraps'][$uuid]); } else { bdebug('ERROR WHILE SAVING SCRAP '.$uuid, "LIGHT_RED"); } } } /* classes */ class LZW { function __construct($dictSize=127) { $this->setDictSize($dictSize); } function setDictSize($size) { $this->dictSize = $size; } function compress($uncompressed) { $dictionary = array(); for ($i = 0; $i < $this->dictSize; $i++) { $dictionary[chr($i)] = $i; } $w = ""; $result = ""; for ($i = 0; $i < strlen($uncompressed); $i++) { $c = $this->charAt($uncompressed, $i); $wc = $w.$c; if (isset($dictionary[$wc])) { $w = $wc; } else { if ($result != "") { $result .= ",".$dictionary[$w]; } else { $result .= $dictionary[$w]; } $dictionary[$wc] = $this->dictSize++; $w = "".$c; } } if ($w != "") { if ($result != "") { $result .= ",".$dictionary[$w]; } else { $result .= $dictionary[$w]; } } return $result; } function decompress($full_compressed, $chunk_size = 3) { //$compressed = explode(",", $full_compressed); $split = preg_split('/([0-9a-z]{'.$chunk_size.','.$chunk_size.'})/i', $full_compressed, null, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); $compressed = $split; foreach( $compressed as $key => $value ) { //$sompressed[$key] = base_convert($value,62,10); $sompressed[$key] = base_62_decode($value); } $dictionary = array(); for ($i = 1; $i < $this->dictSize; $i++) { $dictionary[$i] = chr($i); } $w = chr($sompressed[0]); $result = $w; for ($i = 1; $i < count($sompressed); $i++) { $entry = ""; $k = $sompressed[$i]; if (isset($dictionary[$k])) { $entry = $dictionary[$k]; } else if ($k == $this->dictSize) { $entry = $w.$this->charAt($w, 0); } else { return null; } $result .= $entry; $dictionary[$this->dictSize++] = $w.$this->charAt($entry, 0); $w = $entry; } return unescape($result); } function charAt($string, $index){ if($index < mb_strlen($string)){ return mb_substr($string, $index, 1); } else{ return -1; } } }