'; $ret = strip_tags($source, $allowedTags); return $ret; } //optimizes code, removing all extra space chars function content_optimizer($source) { $source = str_replace("\r","",$source); //$source = str_replace("\n","",$source); $source = preg_replace('/^[ \t\f]+/m','',$source); $source = preg_replace('/[\n]+/',"\n",$source); $source = preg_replace('/[ \t\f]+/',' ',$source); return $source; } //extracts parameters from the template //syntax: {!set_param param_name value1 value2 .... value_n!} function do_template_params($content, &$params) { preg_match_all('/\s*{!\s*?set_param\s*?(.*?)!}\s*/i',$content,$matches); $params = array(); $sect_count = count($matches[0]); for ($i=0;$i<$sect_count;$i++) { preg_match_all('/((")|\s*)((?(2)([^"\\\\]|\\\\.)*|[^"\s]+))(?(2)"|\s*)/ims',$matches[1][$i],$args); $args_count = count($args[3]); //not enoungh args if ($args_count<2) continue; $name = str_replace('\\"','"',$args[3][0]); for ($j=1;$j<$args_count;$j++) { $value = str_replace('\\"','"',$args[3][$j]); $params[$name][$j] = $value; } $content = str_replace($matches[0][$i],$replace_with,$content); } return $content; } //processes cycles in templates //according to index it selects appropriate operand //syntax {!cycle operand1 "operand 2" "operand\"3""!} //operands could be enclosed in quotes to allow whitespaces function do_cycle_temp($content, $index) { preg_match_all('/{!\s*?cycle\s*?(.*?)!}/ims',$content,$matches); $sect_count = count($matches[0]); for ($i=0;$i<$sect_count;$i++) { preg_match_all('/((")|\s*)((?(2)([^"\\\\]|\\\\.)*|[^"\s]+))(?(2)"|\s*)/ims',$matches[1][$i],$args); $args_count = count($args[3]); $replace_with = str_replace('\\"','"',$args[3][$index % $args_count]); $content = str_replace($matches[0][$i],$replace_with,$content); } return $content; } function get_common_template($file, $main_keyword = false, $from_group_scope = false) { global $domain; if (!$main_keyword) $full_name = '../'; if ($from_group_scope) $full_name .= '../'; $full_name .= '_templates/'.$file; if ( !file_exists($full_name) || !filesize($full_name) ) return false; $fp = @fopen($full_name, "r"); if (!$fp) return false; $ret = fread($fp,filesize($full_name)); fclose($fp); $ret = str_replace("{attach_dir}", $domain.'/_images', $ret); $ret = str_replace("{__domain__}", $domain, $ret); return $ret; } function get_template($file) { global $domain; $full_name = $file; if ( !file_exists($full_name) || !filesize($full_name) ) return false; $fp = @fopen($full_name, "r"); if (!$fp) return false; $ret = fread($fp,filesize($full_name)); fclose($fp); $ret = str_replace("{attach_dir}", $domain.'/_images', $ret); $ret = str_replace("{__domain__}", $domain, $ret); return $ret; } function tokenize_results($results) { $results = removeEvilAttributes($results); $results = preg_split('/<\/dl>\s*
/i',$results); for ($i=1;$i<=count($results);$i++) { $result = trim(removeEvilTags($results[$i-1])); $tokens = split("\n",$result); $lexem = 1; for ($j=0;$j',$tok,$match); eregi('"[^"]*"',$match[0],$match); $match = str_replace('"','',$match[0]); $link_url = trim($match); $link_url = trim($link_url,"\xA0"); $ret[$i]["link_url"] = $link_url; break; case 3: $ret[$i]["text"] = strip_tags($tok); break; case 4: $ret[$i]["link"] = strip_tags($tok); break; } $lexem++; } } return $ret; } function form_results($res_arr) { global $main_keyword, $num_results_sections, $results_distr; if( !($result_template = get_common_template(RESULT_TEMPLATE,$main_keyword, GROUP_PART)) ) $result_template = get_template(RESULT_TEMPLATE); //number of results per section (for sequential filling) $results_per_sect = ceil(count($res_arr)/$num_results_sections); for($i=1;$i<=count($res_arr);$i++) { $cur_result = str_replace("{text}",escapeBrackets($res_arr[$i]["text"]),$result_template); $cur_result = str_replace("{index}",$i,$cur_result); $cur_result = str_replace("{link_text}",escapeBrackets($res_arr[$i]["link_text"]),$cur_result); $cur_result = str_replace("{link_url}",escapeBrackets($res_arr[$i]["link_url"]),$cur_result); $cur_result = str_replace("{link}",escapeBrackets($res_arr[$i]["link"]),$cur_result); $cur_result = do_cycle_temp($cur_result,$i-1); //round robin distribution if ($results_distr=="roundrobin") { $sect_index = (($i-1)%$num_results_sections) + 1; //sequential filling distribution } else { $sect_index = foor(($i-1)/$results_per_sect) + 1; } $ret_cnt[$sect_index]++; $cur_result = str_replace("{number}",$ret_cnt[$sect_index],$cur_result); $ret[$sect_index] .= $cur_result; } return $ret; } function get_cached_results($cache_file) { if (!file_exists($cache_file)) return false; clearstatcache(); $fp = @fopen($cache_file,"r"); if (!$fp) return false; flock($fp,LOCK_SH); $serialized_tokens = fread($fp, filesize($cache_file)); flock($fp, LOCK_UN); fclose($fp); $tokens = unserialize($serialized_tokens); return $tokens; } function cache_results($tokens, $cache_file) { $serialized_tokens = serialize($tokens); clearstatcache(); $fp = @fopen($cache_file,"w"); if (!$fp) return false; flock($fp,LOCK_EX); fwrite($fp,$serialized_tokens); flock($fp, LOCK_UN); fclose($fp); touch($cache_file); return true; } function get_results($keyword) { global $index, $main_keyword; global $plugins, $plugins_local, $plugin_context; $keyword = trim($keyword,"\xA0"); if (!$main_keyword) $cache_file = '../'; $cache_file .= '_cache/'.$index; //seeds random number generator srand((double)microtime()*1000000); //number of results calculated for the current request to search-engine.cc $current_num_results = NUM_RESULTS + rand(0,NUM_RESULTS_VARIANCE); $url = "http://".SEARCH_HOST."/cgi-bin/metasearch/metasearch.cgi?page=1&perpage=".$current_num_results."&keywords=".urlencode(strtolower($keyword)); $request = "GET $url HTTP/1.0\r\n"; $request .= "\r\n"; if (CACHE_EXPIRATION_AGE != -1 && file_exists($cache_file) && (time() - filemtime($cache_file)) "Sorry, the content is temporarily unavaliable. Come back soon."); } else { //make cache valid again (to prevent timeouts when doing DNS resolving) touch($cache_file); return form_results($tokens); } } socket_set_timeout($fs,(int)TIMEOUT_DATAREAD); fputs($fs, $request); $content = ''; while (!feof($fs)){ $content .= fread($fs, 4096); } fclose($fs); preg_match('/
.*<\/dl>/ims',$content,$match); //only results $content = $match[0]; //if we don't get anytning - get results from the cache if (!$content) { $tokens = get_cached_results($cache_file); if (!$tokens) { return array(0 => "Sorry, the content is temporarily unavaliable. Come back soon."); } else { //make cache valid again (to prevent timeouts when doing DNS resolving) touch($cache_file); return form_results($tokens); } } //now getting results in the array $tokens = tokenize_results($content); /** applying results plugins to the results set **/ //global plugins if ($plugins) { //setting context call type $plugin_context->SetCallType(PLUGIN_RESULTS_MANGLER); foreach($plugins as $plg) { if ( in_array(PLUGIN_RESULTS_MANGLER,$plg->GetPluginType()) ) { $tokens = $plg->DoAction($tokens,$plugin_context); } } } //local plugins if ($plugins_local) { //setting context call type $plugin_context->SetCallType(PLUGIN_RESULTS_MANGLER); foreach($plugins_local as $plg) { if ( in_array(PLUGIN_RESULTS_MANGLER,$plg->GetPluginType()) ) { $tokens = $plg->DoAction($tokens,$plugin_context); } } } //save retrieved results to cache cache_results($tokens, $cache_file); return form_results($tokens); } //builds {keywords_list} section function get_keywords() { global $keywords, $main_keyword, $main_group_name, $main_group_domain, $num_keywords_sections, $keywords_distr; global $plugins, $plugins_local, $plugin_context; if( !($keyword_template = get_common_template(KWRDLINK_TEMPLATE,$main_keyword,GROUP_PART)) ) $keyword_template = get_template(KWRDLINK_TEMPLATE); $keywords_filtered = $keywords; /** applying keywords plugins **/ //global plugins if ($plugins) { //setting context call type $plugin_context->SetCallType(PLUGIN_KEYWORDS_MANGLER); foreach($plugins as $plg) { if ( in_array(PLUGIN_KEYWORDS_MANGLER,$plg->GetPluginType()) ) { $keywords_filtered = $plg->DoAction($keywords_filtered,$plugin_context); } } } //local plugins if ($plugins_local) { //setting context call type $plugin_context->SetCallType(PLUGIN_KEYWORDS_MANGLER); foreach($plugins_local as $plg) { if ( in_array(PLUGIN_KEYWORDS_MANGLER,$plg->GetPluginType()) ) { $keywords_filtered = $plg->DoAction($keywords_filtered,$plugin_context); } } } //number of keywords per section (for sequential filling) $keywords_per_sect = ceil(count($keywords_filtered)/$num_keywords_sections); for($i=1;$i<=count($keywords_filtered);$i++) { //main group's main keyword if (GROUPPART && GROUP_NAME==$main_group_name && !$keywords_filtered[$i]["dir"] ) $keyword_url = PROJECT_DOMAIN.'/'; else $keyword_url = DOMAIN.'/'.escapeBrackets($keywords_filtered[$i]["dir"]); $keyword_link = str_replace("{keyword_url}",$keyword_url,$keyword_template); $keyword_link = str_replace("{keyword}",escapeBrackets($keywords_filtered[$i]["keyword"]),$keyword_link); $keyword_link = str_replace("{index}","$i",$keyword_link); $keyword_link = do_cycle_temp($keyword_link,$i-1); //round robin distribution if ($keywords_distr=="roundrobin") $sect_index = (($i-1)%$num_keywords_sections) + 1; //sequential filling distribution else $sect_index = floor(($i-1)/$keywords_per_sect) + 1; $keywords_list_cnt[$sect_index]++; $keyword_link = str_replace("{number}",$keywords_list_cnt[$sect_index],$keyword_link); $keywords_list[$sect_index] .= $keyword_link; } return $keywords_list; } //builds {groups_list} section function get_groups() { global $groups, $main_group_name, $main_keyword, $num_groups_sections, $groups_distr; global $plugins, $plugins_local, $plugin_context; if (!GROUP_PART) return false; if( !($group_template = get_common_template(GROUP_TEMPLATE,$main_keyword,GROUP_PART)) ) $group_template = get_template(GROUP_TEMPLATE); //number of goup links per section (for sequential filling) $groups_per_sect = ceil(count($keywords)/$num_groups_sections); $groups_filtered = $groups; /** applying keywords plugins **/ //global plugins if ($plugins) { //setting context call type $plugin_context->SetCallType(PLUGIN_GROUPS_MANGLER); foreach($plugins as $plg) { if ( in_array(PLUGIN_GROUPS_MANGLER,$plg->GetPluginType()) ) { $groups_filtered = $plg->DoAction($groups_filtered,$plugin_context); } } } //local plugins if ($plugins_local) { //setting context call type $plugin_context->SetCallType(PLUGIN_GROUPS_MANGLER); foreach($plugins_local as $plg) { if ( in_array(PLUGIN_GROUPS_MANGLER,$plg->GetPluginType()) ) { $groups_filtered = $plg->DoAction($groups_filtered,$plugin_context); } } } for($i=1;$i<=count($groups_filtered);$i++) { if ($groups_filtered[$i]["name"] != $main_group_name) { if (PROJECT_USE_CHILD_DOMAINS) { $group_url = escapeBrackets($groups_filtered[$i]["domain"]).'/'; } else { $group_url = PROJECT_DOMAIN.'/'.escapeBrackets($groups_filtered[$i]["dir"]).'/'; } } else { $group_url = PROJECT_DOMAIN.'/'; } $group_link = str_replace("{group_url}",$group_url,$group_template); $group_link = str_replace("{group}",escapeBrackets($groups_filtered[$i]["name"]),$group_link); $group_link = str_replace("{index}","$i",$group_link); $group_link = do_cycle_temp($group_link,$i-1); //round robin distribution if ($groups_distr=="roundrobin") { $sect_index = (($i-1)%$num_groups_sections) + 1; //sequential filling distribution } else { $sect_index = floor(($i-1)/$groups_per_sect) + 1; } $groups_list_cnt[$sect_index]++; $group_link = str_replace("{number}",$groups_list_cnt[$sect_index],$group_link); $groups_list[$sect_index] .= $group_link; } return $groups_list; } function get_html_code($index) { global $main_keyword; if( !($html_code = get_common_template($index.'_'.ADD_CODE,$main_keyword)) ) $html_code = get_template($index.'_'.ADD_CODE); return $html_code; } ?>__keyword = $keywords[$index]['keyword']; $this->__is_group_part = GROUP_PART; $this->__group_name = GROUP_NAME; $this->__domain = GROUP_PART ? PROJECT_DOMAIN : DOMAIN; $this->__root_keyword = empty($keywords[$index]['dir']); $this->__root_group = GROUP_PART ? (GROUP_NAME==$main_group_name) : true; $this->__get_params = &$HTTP_GET_VARS; $this->__get_params = &$HTTP_POST_VARS; } //PARAMS: $call_type - here shows what functionality do we need from this plugin function SetCallType($call_type) { $this->__call_type = $call_type; } function GetCallType() { return $call_type; } function GetKeyword() { return $this->__keyword; } function IsGroupPart() { return $this->__is_group_part ; } function GetGroupName () { return $this->__group_name; } function GetRootDomain () { return $this->__domain; } function IsRootKeyword() { return $this->__root_keyword; } function IsRootGroup() { return $this->__root_group; } function IsSiteRoot() { return MWPluginContext::IsRootKeyword() && MWPluginContext::IsRootGroup(); } function GetGetParams() { return $this->__get_params; } function GetPostParams() { return $this->__post_params; } function SetPreviewMode() { $this->__preview_mode = true; } } ?>__unserializer = $unserializer; } //sets writeable dir for plugin function SetWorkDir($work_dir) { $this->__work_dir = $work_dir; } //sets writeable cache dir for plugin function SetCacheDir($cache_dir) { $this->__cache_dir = $cache_dir; } //function loads settings from given xml function LoadSettings($xml) { if ($xml===false) return false; //$options = array('forceEnum' => array('url'),$options); $status = $this->__unserializer->unserialize($xml,false); if (PEAR::isError($status))return false; $this->__plugin_settings = $this->__unserializer->getUnserializedData(); EZRSSPlugin::_validate_settings(); return true; } //load settings from file specified by $path function LoadSettingsFile($path) { //$options = array('forceEnum' => array('url'),$options); $status = $this->__unserializer->unserialize($path.'/'.$this->__config_name,true); if (PEAR::isError($status)) return false; $this->__plugin_settings = $this->__unserializer->getUnserializedData(); EZRSSPlugin::_validate_settings(); return true; } function IsPreviewSupported() { return true; //this plugin supports preview } function SetPreviewMode() { $this->__preview_mode = true; } //return plugin type function GetPluginType() { return array(PLUGIN_PLACEHOLDER_MANAGER); } //returns plugin name function GetPluginName() { return "EZRSSPlugin"; } //performs plugin action function DoAction(&$content_in, &$context) { $content_in = str_replace('{ezrss}',EZRSSPlugin::_get_rssresults($context->GetKeyword(),$context->GetRootDomain()),$content_in); return $content_in; } function _get_rssresults($keyword, $domain) { $keyword = trim(trim($keyword,"\xA0")); $rsscache_file .= $this->__cache_dir.'/EZRSSPlugin_cache-'.$keyword; //number of results calculated for the current request to search-engine.cc srand((double)microtime()*1000000); $current_num_results = $this->__plugin_settings['results_number'] + rand(0,$this->__plugin_settings['results_variance']); $rssurl = "http://metawebs.ezrssfeeds.com/default.asp?d=".urlencode($domain)."&p=".$current_num_results."&k=".urlencode(strtolower($keyword)); $rssrequest = "GET $rssurl HTTP/1.0\r\n"; $rssrequest .= "\r\n"; if (!$this->__preview_mode && $this->__plugin_settings['cache_expiration_age'] != -1 && file_exists($rsscache_file) && (time() - filemtime($rsscache_file))<$this->__plugins_settings['cache_expiration_age'] ) { $rsstokens = EZRSSPlugin::_get_cached_rss($rsscache_file); if ($rsstokens) return EZRSSPlugin::_form_results($rsstokens); } $rssfs = @fsockopen("metawebs.ezrssfeeds.com",80,$errno,$errstr,(double)$this->__plugin_settings['timeout_connection']); if (!$rssfs && $this->__preview_mode) { return $this->__plugin_settings['no_results_text']; } else if (!$rssfs) { $rsstokens = EZRSSPlugin::_get_cached_rss($rsscache_file); if (!$rsstokens) { return $this->__plugin_settings['no_results_text']; } else { //make cache valid again (to prevent timeouts when doing DNS resolving) touch($rsscache_file); return EZRSSPlugin::_form_results($rsstokens); } } socket_set_timeout($rssfs,(int)$this->__plugin_settings['timeout_dataread']); fputs($rssfs, $rssrequest); $rsscontent = ''; while (!feof($rssfs)) { $rsscontent .= fread($rssfs, 4096); } fclose($rssfs); preg_match('/
.*<\/dl>/ims',$rsscontent,$match); //only results $rsscontent = $match[0]; //if we don't get anytning - get results from the cache if (!$rsscontent && $this->__preview_mode) { return $this->__plugin_settings['no_results_text']; } else if (!$rsscontent) { $rsstokens = EZRSSPlugin::_get_cached_rss($rsscache_file); if (!$rsstokens) { return $this->__plugin_settings['no_results_text']; } else { //make cache valid again (to prevent timeouts when doing DNS resolving) touch($rsscache_file); return EZRSSPlugin::_form_results($rsstokens); } } //now getting results in the array $rsstokens = EZRSSPlugin::_tokenize_results($rsscontent); //save retrieved results to cache (not for preview mode) if (!$this->__preview_mode) EZRSSPlugin::_cache_rss($rsstokens, $rsscache_file); return EZRSSPlugin::_form_results($rsstokens); } function _tokenize_results($results) { $results = str_replace(" "," ",$results); $results = preg_split('/<\/dl>\s*
/i',$results); for ($i=1;$i<=count($results);$i++) { $result = trim(strip_tags($results[$i-1], '')); $tokens = split("\n",$result); $lexem = 1; for ($j=0;$j',$tok,$match); eregi('"[^"]*"',$match[0],$match); $match = str_replace('"','',$match[0]); $url = trim($match); $url = trim($url,"\xA0"); $ret[$i]["url"] = $url; break; case 3: $ret[$i]["text"] = strip_tags($tok); break; } $lexem++; } } return $ret; } function _form_results($res_arr) { $ret = ''; $template = $this->__plugin_settings['template']; for($i=1;$i<=count($res_arr);$i++) { $cur_res = str_replace('{ezrssurl}',escapeBrackets($res_arr[$i]['url']),$template); $cur_res = str_replace('{ezrsstitle}',escapeBrackets($res_arr[$i]["title"]),$cur_res); $cur_res = str_replace('{ezrsstext}',escapeBrackets($res_arr[$i]["text"]),$cur_res); $ret .= $cur_res; } return $ret; } function _get_cached_rss($cache_file) { if (!file_exists($cache_file)) return false; clearstatcache(); $fp = @fopen($cache_file,"r"); if (!$fp) return false; flock($fp,LOCK_SH); $serialized_tokens = fread($fp, filesize($cache_file)); flock($fp, LOCK_UN); fclose($fp); $tokens = unserialize($serialized_tokens); return $tokens; } function _cache_rss($tokens, $cache_file) { $serialized_tokens = serialize($tokens); clearstatcache(); $fp = @fopen($cache_file,"w"); if (!$fp) return false; flock($fp,LOCK_EX); fwrite($fp,$serialized_tokens); flock($fp, LOCK_UN); fclose($fp); touch($cache_file); return true; } function _validate_settings() { //defaults if (!isset($this->__settings['timeout_connection'])) $this->__settings['timeout_connection'] = 20; if (!isset($this->__settings['timeout_dataread'])) $this->__settings['timeout_dataread'] = 10; if (!isset($this->__settings['cache_expiration_age'])) $this->__settings['cache_expiration_age'] = 3600; if (!isset($this->__settings['with_links'])) $this->__settings['with_links'] = true; if (!isset($this->__settings['results_number'])) $this->__settings['results_number'] = 5; if (!isset($this->__settings['results_variance'])) $this->__settings['results_variance'] = 2; if (!isset($this->__settings['no_results_text'])) $this->__settings['no_results_text'] = ""; } } function EZRSSPlugin_factory() { global $unserializer; return new EZRSSPlugin($unserializer); } //adding plugin to the plugins list $plugins_factories[] = 'EZRSSPlugin_factory'; ?>