<? // в этом файле собраны все функции, непосредствеено не относящиеся к работе движка, но необходимые в повседневной жизни



//---------------------------------------------------------------------------------------------------------------------
//
// класс - выгрузка в XML
//
//---------------------------------------------------------------------------------------------------------------------

// класс obj_XML - дополнительный интерфейс между PHP и XML

class obj_XML
{ public $tag_name ;
  public $value ;
  public $props ;
  public $childs ;
  public $href ;
  public $parent ;

  function __construct($tag_name,$value='',$props=array())
  {
  	$this->tag_name=$tag_name ;
  	if ($value) $this->value=$value ;
  	if (_sizeof($props)) $this->props=$props ;
  	//damp_array($this) ;
  }

  function add_child($tag_name,$value='',$props=array())
  { $obj = new obj_xml($tag_name,$value,$props) ;
    $obj->parent=&$this ;
    $this->childs[]=&$obj ;
    return($obj) ;
  }

  function add_value(&$obj,$val_name)
  { global ${$val_name} ;
    $obj->add_child('param','',array('id'=>$val_name,'value'=>${$val_name})) ;
  }

  function to_XML(&$doc,&$root,$debug)
  { //include_once(_DIR_TO_ENGINE.'/admin/i_XML.php') ;
    if ($this->tag_name!='_space_') $parent=add_element($doc,$root,$this->tag_name,$this->value,$this->props) ;
    if (_sizeof($this->childs)) foreach($this->childs as $obj) $obj->to_XML($doc,$parent,$debug) ;
    if ($doc==$root) echo $doc->saveXML() ;
  }

  function to_HTML()
  {
    if ($this->tag_name=='offers')
     { ?><h1>Выгружаемый товар</h1>
       <strong class=green>Всего выгружается: <?echo _sizeof($this->childs)?> позиций</strong><br><br>
       <?if (_sizeof($this->childs))
        {?><table><tr><?
	       list($indx,$obj)=each($this->childs) ;
	       if (_sizeof($obj->childs)) foreach($obj->childs as $fields)
	       {?><td><? echo $fields->tag_name ?></td><?}
	       reset($this->childs) ;
	    }
       ?></tr><?
     }

    if ($this->tag_name=='offer')
    {?><tr><?
      if (_sizeof($this->childs)) foreach($this->childs as $obj)
      {?><td class=left><?
         switch ($obj->tag_name)
         { case 'picture': 	if ($obj->value) echo '<img src="'.$obj->value.'" border="0">' ; break;
           case 'url': 		echo '<a href="'.$obj->value.'">'.$this->href.'</a>' ; break;
           default: 		echo $obj->value ;
         }
       ?></td><?
      }

      ?></tr><?
    } else if (_sizeof($this->childs)) foreach($this->childs as $obj) $obj->to_HTML() ;
    if ($this->tag_name=='offers') {?></table><?};
  }
}

// класс  xml_doc - для быстрой генерации XML
// $xml_doc = new  xml_doc('order','',array('status'=>'DELIVERY')) ;
// $text_xml=$xml_doc->getXML() ;

class xml_doc
{  private $doc ;

   function __construct($root_name,$root_value='',$root_attr=array())
   {
       $imp = new DOMImplementation; // Creates an instance of the DOMImplementation class
       $this->doc = $imp->createDocument("",""); // Creates a DOMDocument instance
       $this->doc->encoding = 'utf-8';
       $this->doc->formatOutput = false;
       $this->add_element($this->doc,$root_name,$root_value,$root_attr) ;
   }

   function add_element(&$obj,$name,$value='',$attribute=array())
    { $element=$this->doc->createElement($name) ;// DOMAttr Object ( )
      //if ($value) $element->appendChild($this->doc->createTextNode(iconv('windows-1251','utf-8',$value)));
      if ($value) $element->appendChild($this->doc->createTextNode($value));
      if (is_array($attribute) and _sizeof($attribute)) $this->add_attribute($element,$attribute) ;
      $obj->appendChild($element) ;
      return($element) ;
    }

   function add_attribute(&$obj,$arr)
    { if (_sizeof($arr)) foreach($arr as $name=>$value)
        { $obj->appendChild($this->doc->createAttribute($name)) ;
          //$obj->setAttribute($name,iconv('windows-1251','utf-8',$value)) ;
          $obj->setAttribute($name,$value) ;
        }
    }

    function getXML()
    {
      return $this->doc->saveXML() ;
    }

}

//*************************************************************************************************************************************/
//
// фукции XML
//
//*************************************************************************************************************************************/

 function add_attribute(&$doc,&$obj,$arr)
 { if (_sizeof($arr)) foreach($arr as $name=>$value)
   { $obj->appendChild($doc->createAttribute($name)) ;
     //$obj->setAttribute($name,iconv('windows-1251','utf-8',$value)) ;
     $obj->setAttribute($name,$value) ;
   }
 }

function add_element(&$doc,&$obj,$name,$value='',$attribute=array())
 {
     $element=$doc->createElement($name) ;// DOMAttr Object ( )
   //if ($value) $element->appendChild($doc->createTextNode(iconv('windows-1251','utf-8',$value)));
   if ($value) $element->appendChild($doc->createTextNode($value));
   if (is_array($attribute) and _sizeof($attribute)) add_attribute($doc,$element,$attribute) ;
   $obj->appendChild($element) ;
   return($element) ;
 }

 function get_XML_node_value(&$prop_xml)
 { //$value=trim(iconv('utf-8','windows-1251',$prop_xml->nodeValue)) ;
   $value=trim($prop_xml->nodeValue) ;
   return($value) ;
 }

function get_XML_node_attr(&$prop_xml)
 { if (!$prop_xml->hasAttributes()) return(array()) ;
   $elementarray = array();
   $attributes = $prop_xml->attributes;
   //foreach ($attributes as $index => $domobj) $elementarray[$domobj->name] = trim(iconv('utf-8','windows-1251',$domobj->value));
   foreach ($attributes as $index => $domobj) $elementarray[$domobj->name] = trim($domobj->value);
   return($elementarray) ;
 }

 function get_XML_node_attr2($item)
 { $rec=array() ;
   $length = $item->attributes->length;
   for ($i = 0; $i < $length; ++$i) $rec[$item->attributes->item($i)->name]=$item->attributes->item($i)->value;
   return($rec) ;

 }


 // <order id="11123" fake="true" currency="RUR">
 // $dom = new DomDocument();
 // if (!$dom->loadXML($XML_source)) return ;
 // $order=get_attr_tag_by_name($dom,'order') ;
 function get_attr_tag_by_name($dom,$tag_name)
 { $rec=array() ;
   $items=$dom->getElementsByTagName($tag_name);
   if (_sizeof($items)) foreach ($items as $item) $rec=get_XML_node_attr($item) ;
   return($rec) ;
 }

 // <notes>прим</notes>
 // $dom = new DomDocument();
 // if (!$dom->loadXML($XML_source)) return ;
 // $notes=get_value_tag_by_name($dom,'notes') ;
 function get_value_tag_by_name($dom,$tag_name)
 { $value='' ;
   $items=$dom->getElementsByTagName($tag_name);
   if (_sizeof($items)) foreach ($items as $item) $value=trim($item->nodeValue) ;
   return($value) ;
 }

function convert_XML_to_ARR($XML_source,$tagname)
{ $dom = new DomDocument();
  $rec=array() ;
  if ($dom->loadXML($XML_source))
   { $objs_xml=$dom->getElementsByTagName($tagname);
     if (_sizeof($objs_xml)) foreach ($objs_xml as $obj_xml)
       {   // собираем в массив все свойства объекта
           foreach($obj_xml->childNodes as $prop_xml)
           { //$value=trim(iconv('utf-8','windows-1251',$prop_xml->nodeValue)) ;
             $value=trim($prop_xml->nodeValue) ;
             $rec[$prop_xml->nodeName]=$value ;
           }
       }
   }
  return($rec) ;
}

//*************************************************************************************************************************************/
//
// функции получения web-станиц
//
//*************************************************************************************************************************************/

//http://docs.php.net/manual/en/function.fsockopen.php
//echo http_request('GET', 'www.php.net');
//echo http_request('GET', 'www.php.net', 80, '/manual/en/function.phpinfo.php');
//echo http_request('GET', 'www.php.net', 80, '/manual/en/function.phpinfo.php', array('get1' => 'v_get1'), array(), array('cookie1' => 'v_cookie1'), array('X-My-Header' => 'My Value'));
function exec_http_request(
    $verb = 'GET',             /* HTTP Request Method (GET and POST supported) */
    $ip,                       /* Target IP/Hostname */
    $port = 80,                /* Target TCP port */
    $uri = '/',                /* Target URI */
    $getdata = array(),        /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $postdata = array(),       /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $cookie = array(),         /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */
    $timeout = 1000,           /* Socket timeout in milliseconds */
    $req_hdr = false,          /* Include HTTP request headers */
    $res_hdr = false           /* Include HTTP response headers */
    )
{
    $ret = '';
    $verb = strtoupper($verb);
    $cookie_str = '';
    $getdata_str = count($getdata) ? '?' : '';
    $postdata_str = '';

    foreach ($getdata as $k => $v) $getdata_str .= urlencode($k) .'='. urlencode($v);
    foreach ($postdata as $k => $v) $postdata_str .= urlencode($k) .'='. urlencode($v) .'&';
    foreach ($cookie as $k => $v) $cookie_str .= urlencode($k) .'='. urlencode($v) .'; ';

    $crlf = "\r\n";
    $req = $verb .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf;
    $req .= 'Host: '. $ip . $crlf;
    $req .= 'User-Agent: Mozilla/5.0 Firefox/3.6.12' . $crlf;
    $req .= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' . $crlf;
    $req .= 'Accept-Language: en-us,en;q=0.5' . $crlf;
    $req .= 'Accept-Encoding: deflate' . $crlf;
    $req .= 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' . $crlf;

    foreach ($custom_headers as $k => $v) $req .= $k .': '. $v . $crlf;

    if (!empty($cookie_str)) $req .= 'Cookie: '. mb_substr($cookie_str, 0, -2) . $crlf;

    if ($verb == 'POST' && !empty($postdata_str))
    {   $postdata_str = mb_substr($postdata_str, 0, -1);
        $req .= 'Content-Type: application/x-www-form-urlencoded' . $crlf;
        $req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf;
        $req .= $postdata_str;
    }
    else $req .= $crlf;

    if ($req_hdr) $ret.=$req;
    if (($fp = @fsockopen($ip, $port, $errno, $errstr)) == false) return "Error $errno: $errstr\n";
    stream_set_timeout($fp, 0, $timeout * 1000);
    fputs($fp, $req);
    while ($line = fgets($fp)) $ret .= $line;
    fclose($fp);
    if (!$res_hdr) $ret = mb_substr($ret, strpos($ret, "\r\n\r\n") + 4);
    return $ret;
}

// получаем страницу из веба по сокету
// $host                - домен:
// $res                 - запрос: /index.php
// $options['IP']       - IP домена, если необходимо сделать запрос прямо на сервер без DNS
// $options['charset']  - кодировка получаемой страницы
//
// пример вызова функции: list($page,$error)=get_page_by_sock('www.as-com.ru','/',array('IP'=>'77.221.130.37','charset'=>'utf-8')) ;

function  get_page_by_sock($host,$req,$options=array())
{   $IP=($options['IP'])? $options['IP']:gethostbyname($host);
    $fp = fsockopen($IP, 80,$errno,$errstr,1000000);
    if (!$fp) return(array('',"Unable to open $host ($IP)  ERROR: $errno - $errstr"));
    else {  $request = "GET $req HTTP/1.0\r\n";
            $request .= "Host: $host\r\n";
            $request .= "Accept: text/html, application/xml;q=0.9, */*;q=0.1\r\n";
            $request .= "Accept-Charset: windows-1251, utf-8;q=0.6, *;q=0.1\r\n";
            $request .= "Accept-Encoding: deflate, identity, *;q=0\r\n"; // добавить gzip для получения в виде архива
            $request .= "Accept-Language: ru\r\n";
            $request .= "Connection: close\r\n";
            $request .= "Keep-Alive: 300\r\n";
            $request .= "Expires: Thu, 01 Jan 1970 00:00:01 GMT\r\n";
            $request .= "Cache-Control: no-store, no-cache, must-revalidate\r\n";
            $request .= "Pragma: no-cache\r\n";
            $request .= "Cookie: income=1\r\n";
            $request .= "Referer: http://$host/\r\n";
            $request .= "User-Agent: Mozilla/5.0 (compatible; MSIE 6.0; Windows 98)\r\n";
            //$request .= "Authorization: Basic YWRtaW46NTIwNzQwMw==\r\n";
            $request .= "\r\n";
            $out='' ; $fest='' ;
            fwrite ($fp,$request);
            stream_set_timeout($fp,60);
            //while ($line = fgets ($fp)) if ( preg_match ("/?[\r]?\n$/i",$line)) $fest='yes'; elseif ($fest=='yes'){$out.=$line;}
            //$cont = fread($fp, 2000);
            while ($line = fgets($fp)) $out.=$line;
            $info = stream_get_meta_data($fp);
            fclose($fp);
            if ($options['charset']) $out=iconv($options['charset'],'utf-8',$out) ;
            if ($info['timed_out']) return(array('',$host.' ('.$IP.') ERROR: Connection timed out!'));
            else return(array($out,'')) ;
     }
}


// проверяет, изменилось ли значение форма по сравнению с ранее сохраненным текстом
// выведено в отдельюу функцию, так как результат зависит от  get_magic_quotes_gpc
function check_nochange_form_value($form_value,$saved_value)
{ $check_value=(get_magic_quotes_gpc())? stripslashes($form_value):$form_value ;
  return($check_value==$saved_value) ;
}


// готовим заголовк для запроса
function prepare_request_options($host,$return_header=1,$use_proxi='')
{   //global $arr_proxi ;
    $options=array() ;
    // выбираем прокси через который будем работать
    //if (!$use_proxi) $use_proxi=$arr_proxi[rand(1,_sizeof($arr_proxi))-1] ;
    //damp_array($arr_proxi,1,-1) ;
    //echo '�?спользуем прокси '.$use_proxi.'<br>' ;
    // формируя заголовки, воспользуемся пользовательским user-agent
    //$options['referer']=$_SERVER['HTTP_USER_AGENT'] ;
    //$options['proxi']='faonj:xivuxztgzbm@'.$use_proxi.':4974' ;
    $options['header']=array() ;
    $options['header'][]="Host: ".$host ;
    $options['header'][]="Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    $options['header'][]="Accept-Encoding: gzip,deflate,sdch";
    $options['header'][]="Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4";
    $options['header'][]="Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3";
    $options['return_header']=$return_header ;
    return ($options) ;

}


// получить страницу
function get_page($url,$options=array())
{    global $cookie_file_name ;
     $debug=$options['debug'] ;
     $ch=curl_init();
     curl_setopt($ch, CURLOPT_URL, $url);
     curl_setopt($ch, CURLOPT_HEADER, $options['return_header']); //если данная опция установлена не в 0, то будут отображены заголовки ответа сервера. Если нужны заголовки ответа, то нужно обязательно установить в 1, ибо по умолчанию данная опция установлена в 0;
     curl_setopt($ch, CURLOPT_NOBODY, $options['return_only_code']);
    //if (!$cookie)
    //{ curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_name);
    //  curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_name);
    //} //else curl_setopt($ch, CURLOPT_COOKIE,$cookie);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // если эта опция установлена не в 0, то функция curl_exec() (см. ниже) вернет результат, а не выведет его. По умолчанию, функция curl_exec() выводит результат запроса;
    $agent=($_GET['agent'])? rawurldecode($_GET['agent']):"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7" ;
    curl_setopt($ch, CURLOPT_USERAGENT,$agent);
    curl_setopt($ch, CURLOPT_PROXY,$options['proxi']);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);   // отключение сертификата
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // отключение сертификата

    // отправка логина и пароля
    if ($options['login'] and $options['password'])
    { //curl_setopt($ch, CURLOPT_HEADER, 1);
      //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      //curl_setopt($ch, CURLOPT_POST, 1);
      //curl_setopt($ch, CURLOPT_POSTFIELDS, "LOGIN=".$options['login']."&PASSWD=".$options['password']."&submit=Login");
      curl_setopt($ch, CURLOPT_HTTPHEADER,array("Authorization: Basic ".base64_encode($options['login'].":".$options['password'])));
    }

    //curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate");
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    if ($options['referer']) curl_setopt($ch, CURLOPT_REFERER,$options['referer']);
    if ($options['header']) curl_setopt($ch, CURLOPT_HTTPHEADER, implode("\n",$options['header']));
    $res=curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    //echo 'error='.curl_error($ch)."<br>";
    curl_close($ch);
    if ($debug) echo $url.' <span class=green>'.$http_code."</span><br/>";
    if ($debug) echo '<hr>'.$res.'<hr>';
    list($res_header,$body) = explode("\n\n", $res, 2);
    if ($http_code == 301 || $http_code == 302)
	{	$matches = array();
		preg_match_all('/Location:(.*?)\n/is', $res_header, $matches); //damp_array($matches) ;
		if ($debug) echo "<strong>Relocation...</strong><br>";
		$new_url=trim($matches[1][0]) ;
        //echo 'new_url='.$new_url.'<br>' ; damp_array($options) ; echo '<br>' ;
        $res=get_page($new_url,$options) ;

        return $res;
	}
    else  if ($options['return_only_code']) return($http_code) ;
    //else  if ($options['return_only_header']) return() ;
    else return $res;
}

//*************************************************************************************************************************************/
//
// функции извлечения данных из web-станиц
//
//*************************************************************************************************************************************/

function get_first_img_of_content($text)
{
  $arr_img=pc_image_extractor($text) ;
  $img_url='' ;
  if (_sizeof($arr_img)) $img_url=$arr_img[0][0] ;
  return($img_url) ;
}


// извлекает заголовки из страницы сайта
function pc_title_extractor($s)
{ $arr = array();
  //echo $s ;
  if (preg_match_all('/<title>(.+?)<\/title>/is',$s,$matches,PREG_SET_ORDER)) foreach($matches as $match) array_push($arr,array($match[1],$match[2]));
  if ($arr[0][0]) $res['title']=$arr[0][0] ;
  $arr = array();
  if (preg_match_all('/<meta name=\"(.+?)\"(.+?)content=\"(.*?)\"(.+?)>/is',$s,$matches,PREG_SET_ORDER)) foreach($matches as $match) array_push($arr,array($match[1],$match[3]));
  if (_sizeof($arr)) foreach($arr as $rec) $res[$rec[0]]=$rec[1] ;
  if (preg_match_all('/<h1>(.+?)<\/h1>/is',$s,$matches,PREG_SET_ORDER)) $res['h1']=$matches[0][1] ;
  return $res;
}

function pc_image_extractor($s)
{ $a = array();
  /*if (preg_match_all('/<img [^>]+? src\s*=\s*[\"\']?([^\'\ ">]+?)[\"\']? [^>]+?>/is',$s,$matches,PREG_SET_ORDER)) {*/
  /*if (preg_match_all('/<img\s+.*?src\s*=\s*[\"\']?([^\'\ ">]+?)[\"\']? [^>]+?>/is',$s,$matches,PREG_SET_ORDER)) foreach($matches as $match) array_push($a,array($match[1],$match[2])); */
  // редакция март 2011 - после правок на linetest
  if (preg_match_all('/<img\s+.*?src\s*=\s*[\"\']([^\'\">]+?)[\"\'][^>]*?>/is',$s,$matches,PREG_SET_ORDER)) foreach($matches as $match) array_push($a,array($match[1],$match[2]));
  //damp_array($matches) ;
  return $a;
}

function pc_ext_image_extractor($s)
{ $a = array();
  /*if (preg_match_all('/<img [^>]+? src\s*=\s*[\"\']?([^\'\ ">]+?)[\"\']? [^>]+?>/is',$s,$matches,PREG_SET_ORDER)) {*/
  /*if (preg_match_all('/<img\s+.*?src\s*=\s*[\"\']?([^\'\ ">]+?)[\"\']? [^>]+?>/is',$s,$matches,PREG_SET_ORDER)) foreach($matches as $match) array_push($a,array($match[1],$match[2])); */
  // редакция март 2011 - после правок на linetest
  if (preg_match_all('/<img\s+.*?src\s*=\s*[\"\'](http[^\'\">]+?)[\"\'][^>]*?>/is',$s,$matches,PREG_SET_ORDER)) foreach($matches as $match) array_push($a,array($match[1],$match[2]));
  //damp_array($matches) ;
  if (_sizeof($a)) foreach($a as $i=>$rec)
     { //убираем все переносы строк
       $url=preg_replace('/\n/','',$rec[0]) ;
       $url=preg_replace('/\r/','',$url) ;
       $arr=parse_url($url) ;
       $host=$arr['host'] ;
       //echo $host.'<br>' ;
       if ($host==_MAIN_DOMAIN or $host==_BASE_DOMAIN) unset($a[$i]) ;
     }
  return $a;
}

function pc_base_extractor($s)
{ $arr = array();
  if (preg_match_all('/<BASE HREF=\"(.+?)\" \/>/is',$s,$matches,PREG_SET_ORDER)) foreach($matches as $match) array_push($arr,array($match[1]));
  return $match[1]; // почему не arr?
}

function pc_link_extractor($s)
{
  $a = array();
  if (preg_match_all('/<a\s+.*?href=[\"\']?([^\"\' >]*)[\"\']?[^>]*>(.*?)<\/a>/i',$s,$matches,PREG_SET_ORDER)) {
    foreach($matches as $match) { array_push($a,array($match[1],$match[2],$match[0]));}
  }
  return $a;
}

// получаем список шаблонов, используемых в скрипте
function analize_class_file_to_templates($file)
{ global $install_options ;
  $file=hide_server_dir($file) ;
  if (_sizeof($install_options) and !$install_options['install_copy_templates']) return ;
  $cont=file_get_contents(_DIR_TO_ROOT.$file) ;
  if (!$cont) {echo 'Не удалось открыть файл '.$file ; }
  //echo nl2br($cont) ;
  $arr = array(); $func=array() ;
  if (preg_match_all('/show_list_section\((.+?)\)/is',$cont,$matches,PREG_SET_ORDER)) foreach($matches as $match) $arr[]=$match[1];
  if (preg_match_all('/show_list_items\((.+?)\)/is',$cont,$matches,PREG_SET_ORDER)) foreach($matches as $match) $arr[]=$match[1];
  if (preg_match_all('/print_template\((.+?)\)/is',$cont,$matches,PREG_SET_ORDER)) foreach($matches as $match) $arr[]=$match[1];
  //damp_array($arr,1,0) ;
  if (_sizeof($arr)) foreach($arr as $rec) list($agr1,$func[],$options)=explode(',',$rec) ;
  if (_sizeof($func)) foreach($func as $i=>$func_name)
  { $func_name=str_replace('\'','',$func_name) ;
    $func_name=str_replace('\"','',$func_name) ;
    $func[$i]=$func_name ;
  }
  $func=array_unique($func) ;
  return($func) ;
}

//*************************************************************************************************************************************/
//
// функции форматированного вывода данных
//
//*************************************************************************************************************************************/

function byte_to_kbyte($byte) { return(round($byte/1024)) ; }

function show_size($value){return(format_size($value));}
function format_size($value)
 { 	if ($value<1) return('0 байт') ;
    if ($value<1024) return($value.' байт') ;
   	$value=round($value/1024) ;
 	if ($value<1024) return($value.' кБ') ;
   	$value=round($value/1024) ;
 	if ($value<1024) return($value.' МБ') ;
   	$value=round($value/1024) ;
 	if ($value<1024) return($value.' ГБ') ;
   	$value=round($value/1024) ;
 	return($value.' ТБ') ;
 }

function show_time($value)
 { 	if ($value<60) return($value.' сек') ;
   	$value=round($value/60) ;
 	if ($value<60) return($value.' мин') ;
   	$value=round($value/60) ;
 	if ($value<60) return($value.' час') ;
   	$value=round($value/24) ;
 	return($value.' дней') ;
 }

function get_month_year($time=0,$mode='month year',$options=array())
{ if (!$time) $time=time() ;  $text='' ;
  $year_word=($options['no_year_word'])? '':' г. ' ;
  switch ($mode)
  { case 'year'	:       $text=date('Y',$time) ;	break;
    case 'day month'	: $text=date('d',$time).' '.$_SESSION['list_mon_short_names'][date('n',$time)] ;	break;
    case 'month year'	: $text=$_SESSION['list_mon_names'][date('n',$time)].' '.date('Y',$time) ;	break;
    case 'year - month': $text=date('Y',$time).' - '.$_SESSION['list_mon_names'][date('n',$time)] ;	break;
    case 'day month year': $text=date('d',$time).' '.$_SESSION['list_mon_short_names'][date('n',$time)].' '.date('Y',$time).$year_word ;	break;   // $arr_data=getdate($rec['c_data']) ; $arr_data['mday'].' '.$list_mon_short_names[$arr_data['mon']].' '.$arr_data['year'].' г.' ;
    case 'day month year time': $text=date('d',$time).' '.$_SESSION['list_mon_short_names'][date('n',$time)].' '.date('Y',$time).' '.$year_word.date('H:i',$time) ;	break;   // $arr_data=getdate($rec['c_data']) ; $arr_data['mday'].' '.$list_mon_short_names[$arr_data['mon']].' '.$arr_data['year'].' г.' ;
    case 'd_m_y': $text=date('d',$time).'_'.date('n',$time).'_'.date('Y',$time) ; break ;
    case 'd_m_y_h_i_s': $text=date('d_n_Y_H_i_s',$time);
    case 'd.m': $text=date('d',$time).'.'.date('m',$time) ; break ;
    case 'd.m.y': $text=date('d',$time).'.'.date('m',$time).'.'.date('Y',$time) ; break ;
  }
  return($text) ;
}

// проеобразование даты из строки
// !!! найсить понимать время в формате 2010-08-27 22:45:04

function StrToData($str)
  {   if ($str)
      {  //echo 'Передано: '.$str.' --> ' ;
         // разбиваем строку на группу цифр
         if (preg_match_all('/(\d+)/is',$str,$matches,PREG_SET_ORDER))
         { // по умолчанию отсутствующие данные о времени равны текущему времени
           $arr=getdate(time()) ;
           $year=$arr['year'] ; $mon=$arr['mon'] ; $mday=$arr['mday'] ; $h=$arr['hours'] ; $m=$arr['minutes'] ; $s=$arr['seconds'] ; //echo $year.' '.$mday.' '.$mon.' '.$h.' '.$m.' '.$s ;

           // анализируем группы цифр
            // первым идет год
           if (strlen($matches[0][0])==4)  { $year=$matches[0][0] ; $mon=$matches[1][0] ; $mday=$matches[2][0] ; }
           else if(strlen($matches[2][0])==4) { $year=$matches[2][0] ; $mon=$matches[1][0] ; $mday=$matches[0][0] ; }

           $h=$matches[3][0] ; $m=$matches[4][0] ; $s=$matches[5][0] ;

           $data=mktime($h,$m,$s,$mon,$mday,$year);

           //damp_array($matches) ;
         }
         /*
         $tm=explode(' ',$str) ;
         $tm_date=explode('.',$tm[0]) ;
         if (!$tm_date[2]) $tm_date[2]=date('Y',time()) ;
         $tm_time=explode(':',$tm[1]) ;
         if (!$tm_time[2]) $tm_time[2]=0 ;
         if ($tm[0] and $tm[1]) $data=mktime($tm_time[0], $tm_time[1], $tm_time[2],$tm_date[1],$tm_date[0],$tm_date[2]);
         else $data=mktime(0,0,0,$tm_date[1],$tm_date[0],$tm_date[2]);
         //echo $data.' --> '.date("M-d-Y",$data).'<br>' ;
         */
         return($data) ;
      } else return(0) ;
  }

function check_preview_image($otn_dir,$file_name)
 { global $abs_root_upload_patch,$abs_root_upload_dir ;
   $preview_dir=$abs_root_upload_dir.$otn_dir.$file_name ;
   $preview_patch=$abs_root_upload_patch.$otn_dir.$file_name ;
   //echo $preview_dir.'<br>' ;
   if (is_file($preview_dir))
   { $preview_patch=$abs_root_upload_patch.$otn_dir.$file_name ;
     $size_prev=@getimagesize($preview_dir) ;
     $preview_element='<img src="'.$preview_patch.'" width='.$size_prev[0].' height='.$size_prev[1].' alt="" border="0">' ;
   }
   else $preview_element='' ;
   return($preview_element) ;
 }

 function check_preview_file($otn_dir,$file_name)
 { global $abs_root_upload_patch,$abs_root_upload_dir ;
   $preview_dir=$abs_root_upload_dir.$otn_dir.$file_name ;
   $preview_patch=$abs_root_upload_patch.$otn_dir.$file_name ;
   if (is_file($preview_dir)) return($preview_patch) ;
 }


function generate_flvplayer_code($file_patch,$width,$height)
{  $flv_player=_PATH_TO_SITE.'/AddOns/flvplayer.swf' ;
   $rand_id='div_'.rand() ;
   $embed_str='<div id="'.$rand_id.'"></div><script type="text/javascript">var so = new SWFObject("'.$flv_player.'","mpl","'.$width.'","'.$height.'","7");so.addParam("allowfullscreen","true");so.addParam("allowscriptaccess","always");so.addVariable("displayheight","'.$height.'");so.addVariable("file","'.$file_patch.'");so.addVariable("height","'.$height.'");so.addVariable("width","'.$width.'");so.write("'.$rand_id.'");</script>' ;
   return($embed_str) ;
}



//*************************************************************************************************************************************/
//
// функции работы с директориями и файлами
//
//*************************************************************************************************************************************/

// $dir_name - путь к создаваемой директории
// можно передавать в относииельно корня сайта так и абсллюьный путь
function create_dir($dir_name)
{ global $install_options ;
  $result=0 ;
  // для опциональной установки при запуске инсталяции через админки
  if (_sizeof($install_options) and !$install_options['install_copy_script'] and !$install_options['install_copy_images'] and !$install_options['install_copy_css_js']) return(-1) ;
  $dir_name=hide_server_dir($dir_name) ; // добавлено для совместимости с любой формой $dir_name
  $abs_dir_name=_DIR_TO_ROOT.$dir_name ;
  if (is_dir($abs_dir_name)) echo '<span class=red>Директория <strong>'.$dir_name.'</strong> уже существует</span>' ;
  else if (mkdir($abs_dir_name,_CREATE_DIR_PERMS))
       { $result=1 ;
         echo '<span class=green>Создана директория <strong>'.$dir_name.'</strong></span>' ;
         if (!chmod($abs_dir_name,_CREATE_DIR_PERMS))  echo ' <span class=red>не удалось изменить права доступа на <strong>'.decoct(_CREATE_DIR_PERMS).'</strong></span>' ;
       }
       else echo '<span class=red>Не удалось создать директорию <strong>'.$dir_name.'</strong></span>' ;
  echo '<br>' ;
  return($result) ;
}

function delete_dir($dir_name,$options=array())
{ if ($options['debug']) echo 'удалеям директорию '.$dir_name.'<br>'."\n" ;
  $list=get_all_files($dir_name) ; if ($options['debug']) print_r($list) ;
  if (_sizeof($list)) foreach($list as $fname) if (file_exists($fname) and is_file($fname)) unlink($fname) ;
  $list=get_all_files($dir_name) ; if ($options['debug']) echo 'ПОСЛЕ DELETE FILES '.print_r($list,true) ;

  $list=get_all_files($dir_name,array('include_dir'=>1)) ; if ($options['debug']) echo 'ВСЕ ДИРЕКТОРИИ: '.print_r($list,true) ;
  if (_sizeof($list)) foreach($list as $fname) if (is_dir($fname)) @rmdir($fname) ;
  $list=get_all_files($dir_name,array('include_dir'=>1)) ; if ($options['debug']) echo 'ПОСЛЕ DELETE 1: '.print_r($list,true) ;
  if (_sizeof($list)) foreach($list as $fname) if (is_dir($fname)) rmdir($fname) ;
  $list=get_all_files($dir_name,array('include_dir'=>1)) ; if ($options['debug']) echo 'ПОСЛЕ DELETE 2: '.print_r($list,true) ;
  if (_sizeof($list)) foreach($list as $fname) if (is_dir($fname)) rmdir($fname) ;
  $list=get_all_files($dir_name,array('include_dir'=>1)) ; if ($options['debug']) echo 'ПОСЛЕ DELETE 3: '.print_r($list,true) ;
  rmdir($dir_name) ;
}

function delTree($dir)
{
   $files = array_diff(scandir($dir), array('.','..'));
    foreach ($files as $file) {
      (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
    }
    return rmdir($dir);
}

function convert_path_to_dir($path)
{ $arr=parse_url($path) ;
  return(_DIR_TO_ROOT.$arr['path']) ;
}


function create_file($file_name,$cont)
{ $abs_file_name=_DIR_TO_ROOT.'/'.$file_name ;
  if (is_file($abs_file_name)) echo 'Файл <strong>/'.$file_name.'</strong> уже существует<br>' ;
  else if (file_put_contents($abs_file_name,$cont)) echo 'Создан файл <strong>/'.$file_name.'</strong><br>' ; else echo 'Не удалось создать файл <strong>/'.$file_name.'</strong><br>' ;
}

function create_page($dir,$fname,$cont,$obj=' cкрипт страницы сайта')
{  $fdir=_DIR_TO_ROOT.$dir.$fname ;
   $fpatch=_PATH_TO_SITE.$dir.$fname ;
   $cnt=0 ;
   ob_start() ;
   if (file_exists($fdir)) echo '<span class=red>'.$obj.' <a target=_blank href="'.$fpatch.'" class=green>'.$dir.$fname.'</a> уже существует.</span> Удалите старый '.$obj.' самостоятельно либо выберите другое имя '.$obj.'</br>' ;
   else {  $cnt=file_put_contents($fdir,$cont) ;
           if ($cnt) { echo $obj.'<span class="green bold"> успешно создан</span> - <a target=_blank href="'.$fpatch.'" class=black>'.$dir.$fname.'</a><br>' ;
                       check_file_perms($fdir,0) ;
                       // ДОДЕЛАТЬ: проверка доступности страницы сайта - загружаем, проверяем что размер>0 и ответ=200
                      }
           else  { echo '<div class=red>'.$dir.$fname.' - не удалось создать <strong>'.$obj.'</strong></div><br>' ;
                   //_event_reg('Ошибка создания файла на сервере',$dir.$fname) ;
                 }
        }
   $info_text=ob_get_flush() ;
   _event_reg('Создание скрипта страницы сайта',$info_text) ;
   return($cnt) ;
}

function get_dir_list($dir)
{ $list=array() ;
  $list_files=scandir($dir) ;
    foreach($list_files as $file_name) if ($file_name!='.' and $file_name!='..' and $file_name!='__MACOSX' and is_dir($dir.$file_name)) $list[$file_name]=$dir.$file_name.'/' ;
  return($list) ;
}
//function get_files_list($dir,$mode=0,$pattern=array())
// mode: 0 - выдавать полный пусть к файлу
//       1 - только имена файлов
// $pattern - расширентя
// новый вызов функции:
// !!!! РАЗОБРАТЬСЯ С ОПЦИЯМИ. ОПТИМИЗИРОВАТЬ

function get_files_list($dir,$options=array(),$pattern=array())
{ $ext_pattern=array() ; $name_pattern=array() ; $mode=0 ;
  // обепечиваем совместимость старых и новых параметров
  if (!is_array($options) and $options==1) { $mode=1 ; $options=array() ; }
  else if (is_array($options) and !_sizeof($options)) $mode=0 ;
  else if (is_array($options) and isset($options['mode'])) $mode=$options['mode'] ;
  if (_sizeof($pattern)) $ext_pattern=$pattern ;
  else if (isset($options['ext_pattern'])) $ext_pattern=$options['ext_pattern'] ;
  if (isset($options['name_pattern'])) $name_pattern=$options['name_pattern'] ;

  //damp_array($pattern,1,-1) ;
  //damp_array($options,1,-1) ;
    $list_files=array() ;
  if (!is_dir($dir)) $dir=_DIR_TO_ROOT.$dir ;
  if (!is_dir($dir)) {echo '<div class=alert>Директория '.$dir.' не существует</div>' ; return ;} ;
  try
  {
  $list_files=scandir($dir) ;
  }
  catch (Exception $e)
  {
        echo 'Ошибка: ',  $e->getMessage(), "\n";
  }
  //catch()
  $list=array() ; $reg_pattern="" ;
  if (!is_array($ext_pattern)) { $ext=$ext_pattern ; $ext_pattern=array() ; $ext_pattern[]=$ext  ; }
  if (!is_array($name_pattern)) { $name=$name_pattern ; $name_pattern=array() ; $name_pattern[]=$name  ; }
  $_reg_pattern=array() ;
  if (_sizeof($ext_pattern)) foreach($ext_pattern as $ext) $_reg_pattern[]='(\.'.$ext.'$)' ;
  if (_sizeof($name_pattern)) foreach($name_pattern as $name) $_reg_pattern[]='('.str_replace('*','(.+?)',$name).')' ;

  //damp_array($list_files) ;
  if (_sizeof($_reg_pattern)) $reg_pattern='/'.implode('|',$_reg_pattern).'/is' ;
  if ($options['reg_pattern']) $reg_pattern=$options['reg_pattern'] ;
  //print_r($list_files) ;
  if (_sizeof($list_files)) foreach($list_files as $file_name)
  { if ($file_name!='.' and $file_name!='..' and is_file($dir.$file_name))
    { if (!$reg_pattern)                             $list[]=($mode)? $file_name:$dir.$file_name ;
      else if (preg_match($reg_pattern,$file_name))  $list[]=($mode)? $file_name:$dir.$file_name ;
    }
  }
  return($list) ;
}

// рекурсивное получение списка файлов в указанной директории (включая поддиректории)
// аналог следующей функции, была сделана для импорта информации о файлах движка

function get_all_files($dir,$options=array())
{  $list_files=get_files_list($dir,$options,$options['file_pattern']) ; if (!is_array($list_files)) $list_files=array() ;
   $sub_dir_list=get_dir_list($dir) ;
   if (_sizeof($sub_dir_list)) foreach($sub_dir_list as $sub_dir_name)
   { if (!_sizeof($options['no_include_dirs']) or (_sizeof($options['no_include_dirs']) and !in_array($sub_dir_name,$options['no_include_dirs'])))
     { if ($options['include_dir']) $list_files[]=$sub_dir_name ;
       $sub_dir_file_list=get_all_files($sub_dir_name,$options) ; //damp_array($sub_dir_file_list,1,-1) ;
       if (_sizeof($sub_dir_file_list))  $list_files=array_merge($list_files,$sub_dir_file_list) ;
     }
   }
  return($list_files) ;
}

// рекурсивное получение всех директорий и файлов от указанного места
// $dir - директория, с которой надо начинать обсмотр
// $no_index - абсолютные пути директорий, которые не надо индексировать
// $pattern - массив расширений, файлы которых должны попасть в список. Если параметр не указан - все файлы
// пример:
// $no_index[]=_DIR_TO_ROOT.'/AddOns/' ;
// $no_index[]=_DIR_TO_ROOT.'/webstat/' ;
// $dirs=get_dir_files_list(_DIR_TO_ROOT.'/',$no_index,array('php','html','htm')) ;

function get_dir_files_list($dir,$no_index=array(),$pattern=array(),$to_level=-1,$no_files=0)
{ if (!$to_level) return ;
  //echo 'Получаем содержимое директории <b>'.$dir.'</b><br>' ;
  $dirs=get_dir_list($dir) ;
  if (_sizeof($dirs)) foreach($dirs as $dir_name=>$subdir)
    if (!in_array($subdir,$no_index)) $res[$subdir]=get_dir_files_list($subdir,$no_index,$pattern) ;
  //if (!in_array($subdir,$no_index)) $res[$dir_name]=$subdir ; //get_dir_files_list($subdir,$no_index,$pattern,$to_level-1) ;
  if (!$no_files) $res['files']=get_files_list($dir,1,$pattern) ;
  return $res ;
}

function get_files_list_size($dir)
{ if (!is_dir($dir)) $dir=_DIR_TO_ROOT.$dir ;
  if (!is_dir($dir)) {echo '<div class=alert>Директория '.$dir.' не существует</div>' ; return(array()) ;} ;
  $list_files=scandir($dir) ;
  $size=0 ; $count=0 ;
  foreach($list_files as $file_name)
    if ($file_name!='.' and $file_name!='..' and is_file($dir.$file_name))
        { $size+=filesize($dir.$file_name) ; $count++ ; }
  return(array('size'=>$size,'count'=>$count)) ;
}


// получение инфорации по спику файлов
function get_files_info($list_files)
{$res=array() ;
 if (_sizeof($list_files)) foreach($list_files as $file_name)
 { $res_file_name=hide_server_dir($file_name) ;
   $res[$res_file_name]['size']=filesize($file_name) ;
   $res[$res_file_name]['rdata']=filemtime($file_name) ;
   if (stripos($file_name,'.php')===false and stripos($file_name,'.js')===false and stripos($file_name,'.css')===false) $res[$res_file_name]['md5']=md5_file($file_name) ;
   else { $text=file_get_contents($file_name) ;
          $text=str_replace(' ','',$text) ;
          $text=str_replace("\n",'',$text) ;
          $text=str_replace("\r",'',$text) ;
          $text=str_replace("\t",'',$text) ;
          $res[$res_file_name]['md5']=md5($text) ;
        }
   //$res[$res_file_name]['sha1']=sha1_file($file_name) ;
   //$res[$res_file_name]['crc32']=crc32(file_get_contents($file_name)) ;
 }
 return($res);
}

 // возвращает информацию по размеру файла
 function get_file_info($fname,$not_found_info)
  { //echo 'fname='.$fname.'<br>' ;
    if ($not_found_info and file_exists($fname))
       $text=show_size(filesize($fname)) ;
  	   else $text=$not_found_info.' - файл не существует<br/>' ;
    return($text) ;
  }

function check_file_perms($file_dir,$debug=0)
{  $new_file_info=get_file_perms_info($file_dir) ;
   $status=($new_file_info['perms']==decoct(_CREATE_FILE_PERMS))? '<span class="green bold">ОК</span>':'<span class="red">требуют корректировки</span>' ;
   if ($debug) echo 'Текущие права доступа к файлу: '.$status.' (<span class="black bold">'.$new_file_info['perms'].'</span>) ' ;
   if ($new_file_info['perms']!=decoct(_CREATE_FILE_PERMS))
   { $res=chmod($file_dir,_CREATE_FILE_PERMS);
     if ($debug)
     {	if ($res) 	echo '<span class=green>успешно изменены</span> на <span class="black bold">0'.decoct(_CREATE_FILE_PERMS).'</span>' ;
       else 		echo '<span class="red bold">не удалось изменить</span>' ;
     }
   }
     if ($debug)   echo '<br>' ;
}

function get_file_perms_info($dir)
{  $uid=fileowner($dir) ;
   if (function_exists('posix_getpwuid')) $uid_info=posix_getpwuid($uid) ;
   if (function_exists('posix_getgrgid')) $groupinfo = posix_getgrgid($uid_info['gid']);
   $cur_perms=mb_substr(sprintf('%o', fileperms($dir)),-4) ;
   return(array('perms'=>$cur_perms,'owner'=>$uid_info['name'],'group'=>$groupinfo['name'])) ;
}

function hide_server_dir($dir,$small_patch='/')
{
  return(str_replace(_DIR_TO_ROOT.'/',$small_patch,$dir)) ;
}

// $options['use_dir_to_extract'] - директори, куда распаковывать файлы (от корня сайта, например, /public/123/), иначе будет использованна директория по имени архива в директории архива
// если директории нет, в любом случае она будет создана
function extract_zip_arhive($fdir,$options=array())
{ echo '<span class=green>Распаковываем</span> <strong>'.hide_server_dir($fdir,'~/').'</strong><br>' ;
  include_once(_DIR_TO_ENGINE.'/AddOns/pclzip.lib.php') ;
  if (!$options['use_dir_to_extract'])
  { $fname=basename($fdir) ;
    list($dir_name)=explode('.',$fname) ;
    $dir=dirname($fdir).'/'.$dir_name.'/' ;
    //echo 'dir='.$dir.'<br>' ;
  } else $dir=_DIR_TO_ROOT.$options['use_dir_to_extract'] ;
  echo 'Архив будет распакован в <strong>'.hide_server_dir($dir,'~/').'</strong><br>' ;
  if (!is_dir($dir)) create_dir($dir) ;
  if (is_dir($dir))
  { $obj_pclzip = new PclZip($fdir) ;
	$file_list=$obj_pclzip->extract($dir) ;
    if (!_sizeof($file_list)) echo '<div class=alert>Не удалось извлечь файлы из архива или архив пуст</div>' ;
    else
    { echo 'Архив успешно распакован (<strong>'._sizeof($file_list).' файлов</strong>) в <strong>'.hide_server_dir($dir).'</strong><br>' ;
      //unlink($fdir) ;
      return ($dir) ;
    }
  } else echo '<div class=alert>Не удалось создать директорию для распаковки архива: <strong>'.hide_server_dir($dir).'</strong> </div>' ;
  return('') ;
}

// получение изображений инсталяционного каталога сервера _PATH_TO_SERVER_SETUP_ALT
// $dir_dest - адрес файла : /root/index.php
// $dir_descr - имя файла назначения, с относителбным путем отн.корня сайта : /index.php
function SETUP_get_img($dir_source,$dir_dest)
{ global $install_options ;
  if (_sizeof($install_options) and !$install_options['install_copy_images']) return ;
  // проверяем существование каталога, куда будем копировать файл
  $abs_dir=_DIR_TO_ROOT.dirname($dir_dest) ;
  if ($abs_dir and !is_dir($abs_dir)) {echo '<span class=error>Директория назначения </span><strong>'.$abs_dir.'</strong> не существует<br>' ; return ; }
  // проверяем существование dest файла
  $abs_dir_desct=_DIR_TO_ROOT.$dir_dest ;
  if (file_exists($abs_dir_desct)){echo '<span class=info>Файл <strong>'.$dir_dest.'</strong></span> уже существует<br>' ; return ; }
  // пытаемся получить содержимое source файлы
  $cont=@file_get_contents(_PATH_TO_SERVER_SETUP_ALT.$dir_source) ;
  if (!strlen($cont)){echo '<span class=error>Не удалось получить файл</span> <strong>'.$dir_source.'</strong><br>' ; return ; }
  // пытаемся сохранить содержимое под desct именем
  if (!file_put_contents($abs_dir_desct,$cont)) { echo '<span class=error>Не удалось получить файл </span><strong>'.$dir_source.'</strong> в <strong>'.$abs_dir_desct.'</strong><br>' ; return(0) ;}
  echo 'Изображение <strong>'.basename($dir_dest).'</strong> успешно скопирован в <strong>'.$dir_dest.'</strong><br>' ;
  return(1) ;
}

// $dir_source  - откуда копируем, файл в директории на сервере инсталятора, например '/admin/mime.zip'
// $dir_dest    - куда распаковываем - краткий путь к директории на сервере, например '/admin/img/'
function SETUP_get_img_from_arhive($dir_source,$dir_dest)
{ global $install_options ;
  if (_sizeof($install_options) and !$install_options['install_copy_images']) return ;
  // не проверяем существование каталога, куда будем копировать файл - он будет создан при распаковке
  // получаем путь к файлу, куда скопировать архив
  $arh_file_desct=_DIR_TO_ROOT.'/admin/'.basename($dir_source) ;
  // пытаемся получить содержимое source файлы
  $cont=@file_get_contents(_PATH_TO_SERVER_SETUP_ALT.$dir_source) ;
  if (!strlen($cont)){echo '<span class=error>Не удалось получить файл</span> <strong>'.$dir_source.'</strong><br>' ; return ; }
  // пытаемся сохранить содержимое под desct именем
  if (!file_put_contents($arh_file_desct,$cont)) { echo '<span class=error>Не удалось получить файл </span><strong>'.$dir_source.'</strong> в <strong>'.$arh_file_desct.'</strong><br>' ; return(0) ;}
  echo 'Архив <strong>'.basename($dir_source).'</strong> успешно скопирован в <strong>'.hide_server_dir($arh_file_desct,'~/').'</strong><br>' ;
  extract_zip_arhive($arh_file_desct,array('use_dir_to_extract'=>$dir_dest)) ;
  return(1) ;
}



// получение файла из инсталяционного каталога сервера _PATH_TO_SERVER_SETUP_ALT
// $dir_dest - адрес файла : /root/index.php
// $dir_descr - имя файла назначения, с относителбным путем отн.корня сайта : /index.php
function SETUP_get_file($dir_source,$dir_dest,$copy_css_js=0)
{ global $install_options ;
  if (_sizeof($install_options) and (!$install_options['install_copy_script'] or !$install_options['install_copy_css_js'])) return ;
  $cont=@file_get_contents(_PATH_TO_SERVER_SETUP_ALT.$dir_source) ;
  $abs_dir_desct=_DIR_TO_ROOT.$dir_dest ;
  $abs_dir=_DIR_TO_ROOT.dirname($dir_dest) ;
  if (!strlen($cont)){echo '<span class=error>Не удалось получить файл</span> <strong>'.$dir_source.'</strong><br>' ; return ; }
  if ($abs_dir and !is_dir($abs_dir)) {echo '<span class=error>Директория назначения </span><strong>/'.$abs_dir.'</strong> не существует<br>' ; return ; }
  if (file_exists($abs_dir_desct)){echo '<span class=info>Файл <strong>'.$dir_dest.'</strong></span> уже существует<br>' ; return ; }
  if (!file_put_contents($abs_dir_desct,$cont)) { echo '<span class=error>Не удалось получить файл </span><strong>'.$dir_source.'</strong> в <strong>'.$abs_dir_desct.'</strong><br>' ; return(0) ;}
  echo 'Файл <strong>'.basename($dir_dest).'</strong> успешно скопирован в <strong>'.$dir_dest.'</strong><br>' ;
  if (!$copy_css_js) return(1) ;
  $dir_source=str_replace('.php','.css',$dir_source) ;
  SETUP_append_file($dir_source,'/style.css') ;
  $dir_source=str_replace('.css','.js',$dir_source) ;
  SETUP_append_file($dir_source,'/script.js') ;
  return(1) ;
}

function SETUP_append_file($dir_source,$dir_dest)
{ $cont=@file_get_contents(_PATH_TO_SERVER_SETUP_ALT.$dir_source) ;
  if (!$cont){/*echo 'Файл <strong>'.$dir_source.'</strong> не существует<br>' ;*/ return ; }
  $abs_dir_desct=_DIR_TO_ROOT.$dir_dest ;
  $abs_dir=_DIR_TO_ROOT.dirname($dir_dest) ;
  $cont2=@file_get_contents($abs_dir_desct) ;
  $header="\n/*Добавлено автоматически из файла ".basename($dir_source)."*/\n" ;
  if ($abs_dir and !is_dir($abs_dir)) {echo 'Директория назначения <strong>/'.$abs_dir.'</strong> не существует<br>' ; return ; }
  if (file_put_contents($abs_dir_desct,$cont2.$header.$cont)) { echo 'Файл <strong>'.basename($dir_source).'</strong> успешно добавлен в <strong>'.$dir_dest.'</strong><br>' ; return(1) ;}
  else echo 'Не удалось изменить файл <strong>'.$dir_source.'</strong> в <strong>'.$abs_dir_desct.'</strong><br>' ;
}

// загрузка шаблонов из инсталяционного каталога сервера
function SETUP_get_templates($modul_dir,$arr_func)
{ global $install_options ;
  if (_sizeof($install_options) and !$install_options['install_copy_templates']) return ;

  if (!is_array($arr_func)) $arr_func[]=$arr_func ;
  if (_sizeof($arr_func)) foreach($arr_func as $func_name)
  {  $res=SETUP_get_file($modul_dir.'templates/'.$func_name.'.php','/'._CLASS_.'/templates/'.$func_name.'.php') ;
     if ($res) { SETUP_append_file($modul_dir.'templates/'.$func_name.'.css','/style.css') ;
                 SETUP_append_file($modul_dir.'templates/'.$func_name.'.js','/script.js') ;
               }


  }
}

 // операции с настройками сайта
 function SETUP_add_section_to_site_setting($sect_name)
 { include_once(_DIR_TO_MODULES.'/engine/i_setup.php') ;
   $id=SETUP()->SETUP_add_section_to_site_setting($sect_name) ;
   return($id) ;
 }

 // операции с настройками сайта
 function SETUP_add_rec_to_site_setting($sect_id,$name,$value,$code,$options=array())
 { include_once(_DIR_TO_MODULES.'/engine/i_setup.php') ;
   SETUP()->SETUP_add_rec_to_site_setting($sect_id,$name,$value,$code,$options) ;
 }

 // Добавление нового раздела в списказ
 function SETUP_add_section_to_site_list($sect_name,$options=array())
 { include_once(_DIR_TO_MODULES.'/engine/i_setup.php') ;
   $id=SETUP()->SETUP_add_section_to_site_list($sect_name,$options) ;
   return($id) ;
 }

 // Добавление нового списка в раздел
 function SETUP_add_list_to_site_list($sect_id,$name,$arr_name,$options=array())
 { include_once(_DIR_TO_MODULES.'/engine/i_setup.php') ;
   $id=SETUP()->SETUP_add_list_to_site_list($sect_id,$name,$arr_name,$options);
   return($id) ;
 }

 // Добавление записи в список
 function SETUP_add_rec_to_site_list($list_id,$clss,$rec=[],$options=[])
{ include_once(_DIR_TO_MODULES.'/engine/i_setup.php') ;
  $id=SETUP()->SETUP_add_rec_to_site_list($list_id,$clss,$rec,$options) ;
   return($id) ;
 }

 // добавление поддерживаемого класса в список и автоматическое добавление необходимых полей
 /*function SETUP_add_class_to_table($table_id,$clss)
 { global $install_options ;
   if (_sizeof($install_options) and !$install_options['settings']) return ;
   if (!isset($_SESSION['descr_obj_tables'][$table_id])) $table_id=$_SESSION['pkey_by_table'][$table_id] ;
   $id=execSQL_value('select pkey from '.TM_DOT.' where parent="'.$table_id.'" and clss=104 and indx="'.$clss.'"') ; // проверяем запись в списке по parent и id
   if ($id) return ;
   adding_rec_to_table('obj_descr_obj_tables',array('parent'=>$table_id,'clss'=>104,'enabled'=>1,'indx'=>$clss)) ;
   DESKTOP()->include_extension('table/table_checked') ;
   table_checked($table_id) ;
 } */


//*************************************************************************************************************************************/
//
// фукции работы с изображениями
//
//*************************************************************************************************************************************/

 // возвращает информацию по размеру изображения
  function get_image_info($fname,$not_found_info='')
  { //if ($not_found_info and file_exists($fname))
    if (file_exists($fname))
  	    { // файл существует
  	      $size=@getimagesize($fname) ;
          $fsize=filesize($fname) ;
  	      $text=$size[0].'x'.$size[1].' - <span class=green>'.show_size($fsize).'</span><br/>' ;
  	    }
  	   else $text=$not_found_info.' - файл не существует<br/>' ;
    return($text) ;
  }

  // возвращает информацию типу изображения не в виде числа, как exif_imagetype, а в виде слова
  function get_image_type($fname,$not_found_info='')
  { //echo 'fname='.$fname.'<br>' ;
    if (file_exists($fname))
  	    { // файл существует
  	      $id_type=exif_imagetype($fname) ;
          switch ($id_type)
          {
			case 1:  $type='GIF' ; break ;
			case 2:  $type='JPEG' ; break ;
			case 3:  $type='PNG' ; break ;
			case 4:  $type='SWF' ; break ;
			case 5:  $type='PSD' ; break ;
			case 6:  $type='BMP' ; break ;
			case 7:  $type='TIFF_II' ; break ;
			case 8:  $type='TIFF_MM' ; break ;
			case 9:  $type='JPC' ; break ;
			case 10: $type='JP2' ; break ;
			case 11: $type='JPX' ; break ;
			case 12: $type='JB2' ; break ;
			case 13: $type='SWC' ; break ;
			case 14: $type='IFF' ; break ;
			case 15: $type='WBMP' ; break ;
			case 16: $type='XBM' ; break ;
			//default: $type='Неизвестный формат '.(($id_type)? '# '.$id_type:'') ;
          }

  	    }
    return($type) ;
  }

// возвращает адрес указанного клона для информации по объекту
// rec:	- 	запись по объекту в формате obj_info
//		-	объект - элемент дерева каталога
//		-	запись по фото в формате $rec['obj_clss_3']
//	либо можно указать свои tkey и name

function img_clone(&$rec=array(),$clone_name='source',$options=array())
{
  if (!is_object($rec) and strpos($rec['_image_name'],_MAIN_PROTOCOL)!==false) return($rec['_image_name'])  ;

  $patch='' ; $alg=0 ;
  if ($options['use_name'])	    { $name=$options['use_name'] ; $tkey=_DOT($rec['tkey'])->list_clss[3] ; }   // используемые указанное имя - для случаев, когда необходимо показать неосновое фото объекта
  else if (is_object($rec)) 	{ $name=$rec->image_name ;  $tkey=_DOT($rec->tkey)->list_clss[3] ; $alg=1 ;}   // используем имя фото в объекте - для случаев. когда в первом параметре передается не массив а объект
  else if ($rec['file_name']/* and $rec['clss']==3*/) { $name=$rec['file_name'] ;  $tkey=$rec['tkey'] ; $alg=2 ; } // для записи по фото используем имя файла
  else if ($rec['_image_name']) { $name=$rec['_image_name'] ;   $tkey=_DOT($rec['tkey'])->list_clss[3] ; $alg=3 ; }       // для записи по объекту используем имя фото в _image_name
  else if ($rec['tkey'] and _DOT($rec['tkey'])->list_clss[3])
  { $tkey=_DOT($rec['tkey'])->list_clss[3] ;
      $patch=$_SESSION['img_pattern'][_DOT($tkey)->img_pattern][$clone_name]['no_photo'] ;
      $alg=4 ;
  }   // объект без фото
  if ($options['use_tkey'])		 $tkey=$options['use_tkey'] ;
  if (!$patch and $tkey)
  { $dir_to_img=_DOT($tkey)->dir_to_file.$clone_name.'/'.$name ;
    $path_to_img=_DOT($tkey)->patch_to_file.$clone_name.'/'.$name ;
    //echo '$dir_to_img='.$dir_to_img.'<br>' ;
    if (!$name or !file_exists($dir_to_img))
    {
      $host_dir_to_img=_DOT($tkey)->list_clone_img($clone_name)['default'] ;
      $dir_to_img=_DIR_TO_ROOT.$host_dir_to_img ;
      $path_to_img=_MAIN_PROTOCOL._MAIN_DOMAIN.$host_dir_to_img ;
      //echo '$dir_to_img='.$dir_to_img ;
      //echo '$path_to_img='.$path_to_img.'<br>' ;
    }

    $patch=($options['return_dir'])? $dir_to_img:$path_to_img ;
     //echo '$patch='.$path_to_img.'<br>' ;
  }
  if (!$patch and $tkey)


  if ($options['debug'])
  {
    echo 'Алгоритм: '.$alg.'<br>' ;
  }
  // отклбчено, т.к. использование is_file вызывает тормоза сайта
  //if (!$dir and $tkey)   $dir=_DOT($tkey)->dir_to_file.$clone_name.'/'.$name ;
  //if (!_DOT($tkey)->no_check_exist_file and $dir and !is_file($dir) and is_array(_DOT($tkey)->list_clone_img($clone_name))) { $patch=_DOT($tkey)->list_clone_img($clone_name)['default'] ; }

  if (!$patch) $patch=$_SESSION['img_pattern'][_DOT($tkey)->img_pattern]['no_photo'] ;
  if (!$patch) $patch=$_SESSION['img_pattern']['no_photo'] ;

  //if (!$name) 	$patch=_DOT($tkey)->list_clone_img($clone_name)['default'] ;
  //else 			$patch=_DOT($tkey)->patch_to_file.$clone_name.'/'.$name ;
  //$patch=str_replace('http://xxx.ru','',$patch) ;
  return($patch) ;
}

// возвращает информацию по указанному клону изображения
/* функция отключена 04.06.12 - нигде не используется
// Внимание! если включать, переделать вызов функции img_clone - у неё сменился набор входных параметров
function img_clone_info(&$rec=array(),$clone_name='source',$use_name='',$use_tkey=0)
{ global $update_dir ;
  $res['patch']=img_clone($rec,$clone_name,$use_name) ;

  if (is_object($rec)) { $use_tkey=($use_tkey)? $use_tkey:$rec->image_tkey ; $use_name=($use_name)? $use_name:$rec->image_name ; }
  else if ($rec['clss']!=3) { $use_tkey=($use_tkey)? $use_tkey:$rec['_image_tkey'] ; $use_name=($use_name)? $use_name:$rec['_image_name'] ; }
  else { $use_tkey=($use_tkey)? $use_tkey:$rec['tkey'] ; $use_name=($use_name)? $use_name:$rec['obj_name'] ; }
  				  //echo  'use_name='.$use_name.'<br>' ;

  $res['dir']=_DOT($use_tkey)->dir_to_file.$clone_name.'/'.$use_name ;

  if ($update_dir) $res['dir']=str_replace($update_dir,'',$res['dir']) ;
  if (file_exists($res['dir'])) $res['size']=getimagesize($res['dir']) ;
  //print_r($res['size']) ;
  //echo _DOT($use_tkey)->dir_to_file ;

  if (_sizeof($res['size'])) { $res['a_on_click_to_openPopup']='onclick="open_window(\''.$res['patch'].'\','.($res['size'][0]+50).','.($res['size'][1]+50).');return(false);"' ;
                              $res['a_on_click_to_mainImage']='onclick="document.getElementById(\'main_image\').src=\''.$res['patch'].'\';return(false);"' ;
                              $res['a_on_click_to_popupDiv']='onclick="show_image(\''.$res['patch'].'\','.($res['size'][0]).','.($res['size'][1]).');return false;"' ;
                            }

  return($res) ;
}
*/

// возвращает информацию по размеру исходного изображения
// $rec - запись из массива $rec['obj_clss_3'] или запись по объекту, но тогда там должны присутсвовать поля _image_name, _image_tkey
// возвращается массив информации в виде
//	dir		/home/roman/data/www/gigaprom.clss.ru/public/catalog/source/221_5993_407766.jpg
//	size	0			621
//			1			777
//			2			2
//			3			width="621" height="777"
//			bits		8
//			channels	3
//			mime		image/jpeg
//	id
/* отключенно 4.06.12 - нигде не используется
function img_source_info(&$rec,$clone_name='source')
{
  $tkey=($rec['_image_tkey'])? $rec['_image_tkey']:$rec['tkey'] ;
  $image_name=($rec['_image_name'])? $rec['_image_name']:$rec['obj_name'] ;

  $res['dir']=_DOT($tkey)->dir_to_file.$clone_name.'/'.$image_name ;
  if (file_exists($res['dir'])) $res['size']=getimagesize($res['dir']) ;
  $res['id']=$rec['pkey'].'_'.$res['size'][0].'_'.$res['size'][1] ;
  return($res) ;
}
*/

  // создаем ссылку, аналогочиную текущей странице $_SERVER('REQUEST_URI'), но
  // со значение параметров par=value, переданных через $options

  //
  function generate_href($options=array(),$use_patch='')
  { global $SF_REQUEST_URI ;
    if (_IS_SYSTEM_IP) echo 'Функция "generate_href" более не используется. используйте c_system:generate_url()' ;
    $arr=parse_url($SF_REQUEST_URI) ;
    parse_str($arr['query'],$params);
    if (isset($params['page']) and $options['page']==1) unset($params['page']) ;
    if ($options['page']==1)                            unset($options['page']) ;
    $params=array_merge($params,$options) ;

    $str_par=(_sizeof($params))? '?'.rawurldecode(http_build_query($params)):'' ;
    if ($use_patch)  $href=$use_patch.$str_par ; else $href=$arr['path'].$str_par ;
    return($href) ;
  }

  function delete_param_from_url($url,$param_name)
  { $arr=parse_url($url) ;
    parse_str($arr['query'],$params);
    unset($params[$param_name]) ;
    $res_url='' ;
    if ($arr['scheme']) $res_url.=$arr['scheme'].'://' ;
    if ($arr['scheme']) $res_url.=$arr['host'] ;
    $res_url.=$arr['path'] ;
    if (_sizeof($params)) $res_url.='?'.rawurldecode(http_build_query($params)) ;
    return($res_url) ;
  }

  function change_param_to_url($url,$params)
  { $arr=parse_url($url) ;
    parse_str($arr['query'],$params);
    if (_sizeof($params)) foreach($params as $name=>$value) $params[$name]=$value ;
    $res_url='' ;
    if ($arr['scheme']) $res_url.=$arr['scheme'].'://' ;
    if ($arr['scheme']) $res_url.=$arr['host'] ;
    $res_url.=$arr['path'] ;
    if (_sizeof($params)) $res_url.='?'.rawurldecode(http_build_query($params)) ;
    return($res_url) ;
  }

  function get_param_from_url($url,$name)
  { $arr=parse_url($url) ;
    parse_str($arr['query'],$params);
    return($params[$name]) ;
  }

  // выделяем номер страницы из $path : /catalog/Весы/page_3.html?sort=1
  // возвращаем номер страницы
  function extract_page_number_from_path($path)
  { $page=0 ;
    if (strpos($path,'page_')!==false) // выделяем номер страницы из адреса
     {  $arr_path=explode('/',$path) ;
        $str_page=$arr_path[_sizeof($arr_path)-1] ;
        if (preg_match_all('/page_(.+?)\.html/is',$str_page,$matches,PREG_SET_ORDER))
        { $page=$matches[0][1];  //foreach($matches as $match) $arr[]=$match[1];
          $path=str_replace($matches[0][0],'',$path) ;
        }
     }
    return(array($page,$path)) ;
  }


//*************************************************************************************************************************************/
//
// фукции обработки массивов объектов
//
//*************************************************************************************************************************************/

 // сгруппировать записи по времени, поле времени передается в поле $fname
function group_by_data($arr,$fname)
{ $res_arr=array()  ;
  if (_sizeof($arr)) foreach($arr as $rec)
    { $t=getdate($rec[$fname]) ;
      $t1=mktime(0, 0, 0, $t['mon'],$t['mday'],$t['year']); // дата начала дня события
      //$t2=mktime(23, 59, 59, $t['mon'],$t['mday'],$t['year']); // дата окончания дня события
      $res_arr[$t1][]=$rec ;
    }
  return($res_arr) ;
}

  // сгруппировать записи по типу классов, если задан второй параметр, ключем будет значение указанного поля
  function group_by_clss($arr,$used_keys='')
  {  $new_arr=array() ;
     if (_sizeof($arr)) { if ($used_keys=='') foreach ($arr as $rec) $new_arr[$rec['clss']][]=$rec ;
  						 else  foreach ($arr as $rec) $new_arr[$rec['clss']][$rec[$used_keys]]=$rec ;
  					  }
    return ($new_arr) ;
  }

  // сгруппировать записи по указанному полю, если задан второй параметр, ключем будет значение указанного поля
  // если задано третте поле, значение ключа будет равно значению указанного поля (а не массив)
  //$list_parent=group_by_field('parent',$arr,$fname,'cnt') ;
  function group_by_field($fname,$arr,$used_keys='',$used_value='')
  { $new_arr=array() ;
    if (is_array($arr) and _sizeof($arr))
                      { if (!$used_keys)     foreach ($arr as $rec) $new_arr[$rec[$fname]][]=$rec ;
  						elseif(!$used_value) foreach ($arr as $rec) $new_arr[$rec[$fname]][$rec[$used_keys]]=$rec ;
  						else                 foreach ($arr as $rec) $new_arr[$rec[$fname]][$rec[$used_keys]]=$rec[$used_value] ;
  					  }
    return ($new_arr) ;
  }

  function merge_info(&$arr1,&$arr2)
  { if (_sizeof($arr2)) foreach($arr2 as $key=>$value) if (!$arr1[$key]) $arr1[$key]=$value ; }


  function get_count_obj(&$list_obj)
    { $cnt=0 ;
      if (_sizeof($list_obj)) foreach ($list_obj as $cur_tkey=>$tkey_arr)
	     if (_sizeof($tkey_arr)) foreach ($tkey_arr as $clss=>$clss_arr) $cnt+=_sizeof($clss_arr) ;
       return($cnt) ;
    }

 function arrayToObject($array)
 { if(count($array)>0)
    {   foreach($array as $key => $value) if(is_array($value)) $array[$key] = arrayToObject($value);
        return (object)$array;
    }
  else return FALSE;
}


//*************************************************************************************************************************************/
//
// фукции контроля и проверок
//
//*************************************************************************************************************************************/

function check_htacess_files()
{  global $dir_to_FCKeditor,$dir_to_phpMyAdmin,$FCKeditor_vers,$phpMyAdmin_vers ;
   echo '<br><br>' ;

   // формироруем список проверяем папок
   $arr_check[_SERVER_ENGINE_VERS.'/']=_DIR_TO_ENGINE.'/' ;
   $arr_check[_CLASS_.'/']=_DIR_TO_CLASS.'/' ;
   $arr_check['ini/']=_DIR_TO_ROOT.'/ini/' ;
   $arr_check['fckeditor_v'.$FCKeditor_vers.'/']=$dir_to_FCKeditor ;
   $arr_check['phpMyAdmin_v'.$phpMyAdmin_vers.'/']=$dir_to_phpMyAdmin ;
   $i=0 ;
   if (_sizeof($arr_check)) foreach($arr_check as $title=>$dir)
     if (is_dir($dir)) if (!file_exists($dir.'.htaccess')) { $i++ ; echo "<div class='red bold'>Директория '".$title."' не защишена!</div>"; }

   if ($i) echo '<br><br>' ;
}


function check_input_var(&$var,$type,$options=array())
{
  switch($type)
  { case 'float': $var=(float) $var ; break ;
    case 'int': $var=(int) $var ; break ;
    case 'string': $var=(string) $var ; break ;
    case 'ip':  if (!$var) return ; $arr=explode('.',$var) ; $var=((int) $arr[0]).'.'.((int) $arr[1]).'.'.((int) $arr[2]).'.'.((int) $arr[3]) ; break ;
    case 'reffer':  if (!$var) return ; $arr=explode('.',$var) ;if (isset($_SESSION['descr_obj_tables'][$arr[1]])) { $var='' ; return ;} $var=((int) $arr[0]).'.'.((int) $arr[1]) ; break ;
    case 'plain_text': $var=strip_tags($var) ; break ;
    case 'email': $temp=explode('@',strip_tags($var)) ; if (_sizeof($temp)==2) $var=$temp[0].'@'.$temp[1] ; else $var="" ; break ;
  }
  //echo 'переменная='.$var.'<br>' ;
}

function safe_file_names($file_name,$options=array())
{  $res=$file_name ;
   //if ($options['source_is_utf8'])
   ////if (strpos($file_name,'%')!==false) {  $res=urldecode($file_name);
   ////                                       if (!preg_match("/[А-я]/", $file_name)) $res=iconv('utf-8','windows-1251',$res) ;
   ////                                      }
   // http://saintist.ru/2010/04/20/opredelenie-chto-tekst-v-kodirovke-utf-8/
   ////$res_UTF8 = (preg_match("/^([\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/",$res)) ? true : false;
   ////$res_UTF8=iconv('utf-8','windows-1251',$res) ;  //если получилось преобразовать из UFT8 в 1251 значит текст был в кодироке utf8
   ////if ($res_UTF8) $res=iconv('utf-8','windows-1251',$res) ;
   $res=translit($res) ;
   if (strpos($res,'?')!==false) $res=ENGINE()->generate_UID().'.jpg' ; // для ситуаций, когда передается url типа img.php?image=_Files_4719_.jpg&h=402
   else
   {    if (!isset($options[' - ']))  $options[' - ']='-' ;
        if (!isset($options[' ']))  $options[' ']='_' ;
        if (!isset($options['\''])) $options['\'']='' ;
        if (!isset($options['/'])) $options['/']='_' ;
        if (!isset($options['"']))  $options['"']='' ;
        if (!isset($options['№']))  $options['№']='#' ;
        if (!isset($options['&']))  $options['&']='' ;
        if (!isset($options[',']))  $options[',']='' ;
        if (!isset($options['?']))  $options['?']='' ;
        if (!isset($options['(']))  $options['(']='' ;
        if (!isset($options[')']))  $options[')']='' ;
   }
   if (_sizeof($options)) foreach($options as $search=>$replace) $res=str_replace($search,$replace,$res);
   if (!$options['no_to_lower']) $res=strtolower($res);
   return($res);
}

// перевод переданный путь в безопасный для загрузки файлов путь
// необходимо вызывать перед загрузкой файлов по сслыке.
// если в данной ссылке присутсвуют присутствуют русские буквы или пробелы - они будут заменены на коответствующие коды символов
function safe_patch_files($patch)
{  if(preg_match("/[А-я]/",$patch))
   {	$arr=parse_url($patch) ;
        //$res=$arr['scheme'].'://'.$arr['host'].urlencode(iconv('windows-1251','utf-8',$arr['path'])) ;
        $res=$arr['scheme'].'://'.$arr['host'].urlencode($arr['path']) ;
       $res=str_replace('%2F','/',$res) ;
       $res=str_replace('%2520','%20',$res) ;
   } else $res=str_replace(' ','%20',$patch) ;
   return($res) ;
}

// аналогичная функция ))) - смотреть надо, что уже сделано
function safe_web_patch($patch)
{  $arr=parse_url($patch) ;
   $arr2=explode('/',$arr['path']) ;
   //if (_sizeof($arr2)) foreach($arr2 as $id=>$name) $arr2[$id]=urlencode(iconv('windows-1251','utf-8',$name)) ;
   if (_sizeof($arr2)) foreach($arr2 as $id=>$name) $arr2[$id]=urlencode($name) ;
   $arr['path']=implode('/',$arr2) ;
   $arr['path']=str_replace('+','%20',$arr['path']) ;
   if ($arr['port']) $arr['host'].=':'.$arr['port'] ;
   $patch=$arr['scheme'].'://'.$arr['host'].$arr['path'] ;
   if ($arr['query']) $patch.='?'.$arr['query'] ;
   return($patch) ;
}

// готовим текс для размещения в url
// в tkey передается код таблицы нсли возможено задание отдельного порядка правил формирования URL
function safe_text_to_url($text,$tkey=0)
{  $URL_SPACE=_URL_SPACE ;
   $URL_LANG=_URL_LANG ;
   if ($tkey and _sizeof($_SESSION['url_setting'][$tkey]))
   { if ($_SESSION['url_setting'][$tkey]['url_space'])  $URL_SPACE=$_SESSION['url_setting'][$tkey]['url_space'] ;
     if ($_SESSION['url_setting'][$tkey]['url_lang'])   $URL_LANG=$_SESSION['url_setting'][$tkey]['url_lang'] ;
   }
   $text=trim($text) ;
   $text=stripslashes($text) ;
   $text=strip_tags($text) ;
   // при необходимости переводим в транслит
   if ($URL_LANG=='TRANSLIT')
   {
       $text=strtolower(translit($text)) ;
       $text=iconv('utf-8','ASCII//TRANSLIT',$text) ;
   }
   //else $text=iconv('utf-8','windows-1251',$text) ; надо проверять
   //echo 'text='.$text.'<br>' ;
   //trace() ;
   // заменяем вредные символы на пробелы

   $text=str_replace(array("\\",'/','"',"'",'`',',','.','+','?','&','#','%','<','>','[',']'),' ',$text) ;
   $text=trim($text) ;
   // заменяем подряд следующие пробелы ( в том числе переносы строк и табуляторы) на символ-заменитель пробела
   $text=preg_replace('/\s+/',$URL_SPACE,$text) ;
   $text=preg_replace('/\-+/',$URL_SPACE,$text) ;
   //echo  $text.'<br>' ;

   return($text) ;
}


//*************************************************************************************************************************************/
//
// функции контроля версии движка и настройки параметров
//
//*************************************************************************************************************************************/


function export_params_to_XML()
 { global  $engine_vers ;
   $engine = new obj_XML('engine_info','',array('date'=>date('Y-m-d H:i'),'version'=>$engine_vers)) ;
   $params = $engine->add_child('params') ;
   //$engine->add_value($params,'use_cache') ;
   //$engine->add_value($params,'use_cache_for_system_ip') ;
   $engine->add_value($params,'log_pages_for_system_ip') ;
   $engine->add_value($params,'fast_edit_for_system_ip') ;
   $engine->add_value($params,'use_trash') ;
   $engine->add_value($params,'no_index_robots_php') ;
   $engine->add_value($params,'alt_format_index_tables') ;
   $engine->add_value($params,'enabled_fast_edit_to_system_ip') ;
   //$engine->add_value($params,'reboot_all_for_system_ip') ; // !!! _REBOOT_ALL_FOR_SYSTEM_IP
   $engine->add_value($params,'debug') ;
   $engine->add_value($params,'debug_SQL_query') ;
   $engine->add_value($params,'debug_sql_save_obj') ;
   $engine->add_value($params,'debug_mails') ;
   $engine->add_value($params,'debug_modul') ;
   $engine->add_value($params,'debug_templates') ;
   $engine->add_value($params,'debug_page') ;
   $engine->add_value($params,'debug_metatags') ;
   $engine->add_value($params,'time_line_mode') ;
   $engine->add_value($params,'send_mail_by_error') ;
   $engine->add_value($params,'alert_moduls') ;
   $engine->add_value($params,'alert_moduls') ;
   $engine->add_value($params,'log_events_info') ;
   $engine->add_value($params,'upload_dir_name') ;
   $engine->add_value($params,'info_db_error') ;
   $engine->add_value($params,'show_errors') ;
   $engine->add_value($params,'error_report_level') ;
   $engine->add_value($params,'create_dir_perms') ;
   $engine->add_value($params,'create_file_perms') ;
   $imp = new DOMImplementation; // Creates an instance of the DOMImplementation class
   //$dtd = $imp->createDocumentType('yml_catalog','',''); // Creates a DOMDocumentType instance
   $doc = $imp->createDocument("",""); // Creates a DOMDocument instance
   //$doc->encoding = 'windows-1251';
   $doc->encoding = 'utf-8';
   $doc->formatOutput = true;
   $engine->to_XML($doc,$doc,0) ;
 }

 // создаем XML на основе перечня файлов
 function export_list_files_to_XML($list_files)
 { global $engine_vers ;
   $engine = new obj_XML('engine_info','',array('date'=>date('Y-m-d H:i'),'version'=>$engine_vers,'script_data'=>filemtime($_SERVER['SCRIPT_FILENAME']))) ;
   $files = $engine->add_child('files') ;
   if (_sizeof($list_files)) foreach ($list_files as $file_name=>$file_info) $files->add_child('file','',array('name'=>str_replace(_DIR_TO_ROOT.'/engine_v'.$engine_vers,'',$file_name),'md5'=>$file_info['md5']/*,'sha1'=>$file_info['sha1'],'crc32'=>$file_info['crc32']*/,'size'=>$file_info['size'],'rdata'=>$file_info['rdata'])) ;
   $imp = new DOMImplementation; // Creates an instance of the DOMImplementation class
   //$dtd = $imp->createDocumentType('yml_catalog','',''); // Creates a DOMDocumentType instance
   $doc = $imp->createDocument("",""); // Creates a DOMDocument instance
   //$doc->encoding = 'windows-1251';
   $doc->encoding = 'utf-8';
   $doc->formatOutput = true;
   $engine->to_XML($doc,$doc,0) ;
 }


 function get_project_info()
 {

 }


//*************************************************************************************************************************************/
//
// другие функции
//
//*************************************************************************************************************************************/

 // стандартная функция получения данных по объекту формы, переданная через $_POST,$_GET или options
 function obj_info_to_input($options=array())
 {  global $obj_info ;
    $_reffer_name='' ;
    $_reffer='' ;
    $_reffer_href='' ;
    $_reffer_parent='' ;

    // данные по объекту передаются через _POST
    if (!$_reffer and $_POST['_reffer'])                 $_reffer=$_POST['_reffer'] ;
    if (!$_reffer_name and $_POST['_reffer_name'])       $_reffer_name=$_POST['_reffer_name'] ;
    if (!$_reffer_href and $_POST['_reffer_href'])       $_reffer_href=$_POST['_reffer_href'] ;
    if (!$_reffer_parent and $_POST['_reffer_parent'])   $_reffer_parent=$_POST['_reffer_parent'] ;

    // данные по объекту передаются через $options
    if (!$_reffer        and $options['_reffer'])         $_reffer=$options['_reffer'] ;
    if (!$_reffer_name   and $options['_reffer_name'])    $_reffer_name=$options['_reffer_name'] ;
    if (!$_reffer_href   and $options['_reffer_href'])    $_reffer_href=$options['_reffer_href'] ;
    if (!$_reffer_parent and $options['_reffer_parent'])  $_reffer_parent=$options['_reffer_parent'] ;

    // данные по объекту передаются через $options['cur_obj']
    if (!$_reffer        and $options['cur_obj']['_reffer'])  $_reffer=$options['cur_obj']['_reffer'] ;
    if (!$_reffer_name   and $options['cur_obj']['__name'])   $_reffer_name=$options['cur_obj']['__name'] ;
    if (!$_reffer_href   and $options['cur_obj']['__href'])   $_reffer_href=$options['cur_obj']['__href'] ;
    if (!$_reffer_parent and $options['cur_obj']['parent'])   $_reffer_parent=$options['cur_obj']['parent'] ;

    // данные по объекту передаются через $obj_info
    if (!$_reffer        and $obj_info['_reffer'])          $_reffer=$obj_info['_reffer'] ;
    if (!$_reffer_name   and $obj_info['__name'])           $_reffer_name=$obj_info['__name'] ;
    if (!$_reffer_href   and $obj_info['_reffer_href'])     $_reffer_href=$obj_info['__href'] ;
    if (!$_reffer_parent and $obj_info['_reffer_parent'])   $_reffer_parent=$obj_info['parent'] ;

    if ($_reffer)        {?><input name="_reffer"        type="hidden" value="<?echo $_reffer?>"><?}
	if ($_reffer_name)   {?><input name="_reffer_name"   type="hidden" value="<?echo htmlspecialchars($_reffer_name)?>"><?}
	if ($_reffer_href)   {?><input name="_reffer_href"   type="hidden" value="<?echo htmlspecialchars($_reffer_href)?>"><?}
	if ($_reffer_parent) {?><input name="_reffer_parent" type="hidden" value="<?echo htmlspecialchars($_reffer_parent)?>"><?}

    $_reffer_name=mb_substr($_reffer_name,0,30).'..."' ;
    return($_reffer_name) ;
 }

 function is_demo_mode()
 { if (_ENGINE_DEMO_MODE)
   { ?><div class=alert>Включен режим работы "только чтение", изменения запрещены</div><?
     return(1) ;
   }
   else return(0) ;
 }

function show_select_action($name,$items)
{ ?><select name=<?echo $name?>><?
  if (_sizeof($items)) foreach($items as $value=>$title) {?><option value="<?echo $value?>" <?if ($_SESSION['form_values'][$name]==$value) echo ' selected'?>><?echo $title?></option><?}
  ?></select><?
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// СТАНДАРТИЗАЦИЯ ОТВЕТОВ МОДУЛЕЙ
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// формирует массив ответа на основе обычного текстового кода
function prepare_result($text_code,$res=array())
 { $res['code']=$text_code ;
   $res['type']=(stripos($res['code'],'success')===false)? 'error':'success' ;
   return($res) ;
 }


// преобразуем различные варианты результатов операций в единый вид
// $data - просто код ошибки, create_success
//       - array('message_id',......) код сообщения + объект
//       - array('type','code','text','rec') тип, код сообщения и сообщение по умолчанию
// на выходе
// array('type'=> error, success
//       'code'=> access_denited,space_field
//       'text'=> текст по умолчанию, если в account_show_message не будет переопределн другой текст для code
//       'rec'=>  запись по объекту
//      )
function parse_result($data)
{ // если самый последний вариант сообщения - возвращаем его как есть
  if (is_array($data) and isset($data['type']) and isset($data['code']) and !isset($data['message_id'])) return($data) ;
  $res=array() ;
  // самый старый вариант $data - просто код ошибки, типа create_success
  if (!is_array($data)) { $res['code']=$data ; $data=array() ; }
  // чуть меннее старый вариант - $data - массив, результат операции передается в $data['message_id']
  else if (isset($data['message_id'])) { $res['code']=$data['message_id'] ; unset($data['message_id']) ; }
  // если получилось определить $res['code'] и не задан $data['type'], пытается определить его
  if ($res['code'] and !$data['type']) $res['type']=(strpos($res['code'],'success')===false)? 'error':'success' ;
  // если в data еще есть поля это информация по объекту, помещаем её в результат
  if (_sizeof($data)) $res['rec']=$data ;
  return($res) ;
}

function get_result_code($data)
{ $arr=parse_result($data) ;
  return($arr['code']) ;
}

function get_result_type($data)
{ $arr=parse_result($data) ;
  return($arr['type']) ;
}

function get_result_data($data)
{ if (!is_array($data)) return(array()) ;
  if (isset($data['message_id'])) {unset($data['message_id']) ; return($data) ; }
  else return($data[1]) ;
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function include_template($template_name)
{
  include_once(_DIR_TO_TEMPLATES.'/'.$template_name) ;
}

function get_table_id($table_name) { return($_SESSION['pkey_by_table'][$table_name]) ; }
function get_table_name($table_id) { return($_SESSION['tables'][$table_id]) ; }

function decode_pers_code($code)
{
   $b1=get_name_perms($code[1]) ;
   $b2=get_name_perms($code[2]) ;
   $b3=get_name_perms($code[3]) ;
   return(array('owner'=>$b1,'group'=>$b2,'other'=>$b3)) ;
}


function get_name_perms($value)
{  switch($value)
   { case 0: $text='-' ; break ;
     case 1: $text='x' ; break ;
     case 2: $text='w' ; break ;
     case 3: $text='wx' ; break ;
     case 4: $text='r' ; break ;
     case 5: $text='rx' ; break ;
     case 6: $text='rw' ; break ;
     case 7: $text='rwx' ; break ;
   }
   return($text) ;
}

function generate_clss_style_icon($list_clss)
{ if (_sizeof($list_clss))
  {?><style type="text/css"><?
      foreach($list_clss as $clss) {?>body#tree_objects li[clss="<?echo $clss?>"] div.clss{background-image:url('<?echo _CLSS($clss)->icons?>');}<? echo "\n" ;}
   ?></style><?
  }
}

function get_no_index_dirs()
{  $no_index[]=_DIR_TO_ROOT.'/AddOns/' ;
   $no_index[]=_DIR_TO_ROOT.'/webstat/' ;
   $no_index[]=_DIR_TO_ROOT.'/ini/' ;
   $no_index[]=_DIR_TO_ROOT.'/'._ADMIN_.'/' ;
   $no_index[]=_DIR_TO_ROOT.'/!alt/' ;
   $no_index[]=_DIR_TO_ENGINE.'/' ;
   $no_index[]=_DIR_TO_CLASS.'/' ;
   // исключаем из поиска каталога, где размещаются фото и файлы объектов - там может быть очень много файлов
   $files_dir=execSQL_line('select dir_to_image from obj_descr_obj_tables where clss=101 and dir_to_image!=""') ;
   if (_sizeof($files_dir)) foreach($files_dir as $dir_name) $no_index[]=_DIR_TO_ROOT.'/'.$dir_name.'/' ;
   return($no_index) ;
}


function get_func_out($name,$options=array())
{
    ob_start() ; $name() ; $text=ob_get_clean() ; return($text);
}

function get_template_out($name,$options=array())
{
    ob_start() ; print_template($name,$options) ; $text=ob_get_clean() ; return($text);
}

function get_ext_template_out($ext,$name,$options=array())
{
    ob_start() ; ext_template($ext,$name,$options) ; $text=ob_get_clean() ; return($text);
}

function conver_FILES_to_recs($finfo)
{ $recs=array() ;
  if (_sizeof($finfo['error'])) foreach($finfo['error'] as $indx=>$error) if (!$error) $recs[]=array('name'=>$finfo['name'][$indx],'type'=>$finfo['type'][$indx],'tmp_name'=>$finfo['tmp_name'][$indx],'error'=>$finfo['error'][$indx],'size'=>$finfo['size'][$indx]) ;
  return($recs) ;
}

// возвразщает правильный падеж, в зависимости от количества
// $arr[0] - для 1,21,31,151... товар
// $arr[1] - для 2,3,4,22,32,152... товара
// $arr[2] - для 5,6,7,8,9,10,11...20,25...29... товаров
// get_case_by_count(5,array('товар','товара','товаров'))
// get_case_by_count_1_2_5(5,'товар,товара,товаров') - сокращенный вариант
function get_case_by_count_1_2_5($source_cnt,$arr) {return(get_case_by_count($source_cnt,$arr));}
function get_case_by_count($source_cnt,$arr)
{  $text='' ;
   if (!is_array($arr)) $arr=explode(',',$arr) ;
   $cnt=($source_cnt<=20)? $source_cnt:($source_cnt % 10) ;
   if ($cnt==1) $text=$arr[0] ; //'товар' ;
   elseif ($cnt>=2 and $cnt<=4) $text=$arr[1] ; // 'товара' ;
   elseif ($cnt==0 or $cnt>=5) $text=$arr[2] ; // 'товаров' ;
   return($text) ;
}

function get_format_by_name($file_name)
{
  $arr=explode('.',$file_name) ;
  $ext=$arr[_sizeof($arr)-1] ;
  $format=strtoupper($ext) ;
  return($format) ;
}

// особенность работы с serialize
// перед сохранением массива в serialize необходимо проверить что поля из формы не обработаны слешами при включенной директиве magic_quotes_gpc
// если директива включена - удаляем слеши из значения посредством stripslashes
// также при сохранении серилизованной строки в БД через update_rec_in_table необходимо передать опцию no_stripslashes=1
// чтобы в случае magic_quotes_gpc=1 из сохраняемой строки не были удалены слешы перед применением к строке mysql_real_escape_string
//
// пример сохранения данных в БД:
// $ser_data=add_data_to_serialize_array('',$options['EXT']) ;
// update_rec_in_table($this->tkey,array('autor_info'=>$ser_data),'pkey='.$tiket['pkey'],array('no_stripslashes'=>1)) ;

function add_data_to_serialize_array($ser_text,$new_data=array())
{
  if ($ser_text) $arr=unserialize($ser_text) ; else $arr=array() ;
  if (_sizeof($new_data)) foreach($new_data as $fname=>$value)
  {  if (get_magic_quotes_gpc()) $value=stripslashes($value) ;
     $arr[$fname]=$value ;
  }
  $result=serialize($arr) ;
  return($result) ;
}

// экранирование перед сохранением в базе с учетом get_magic_quotes_gpc
function prepare_slashes($text,$options=array())
{ //  Если magic_quotes_gpc включены, то сначала данные следует обработать функцией stripslashes().
  //  Если функцию mysql_real_escape_string применить к уже проэкранированным данным, то данные будут проэкранированы дважды.
  if (get_magic_quotes_gpc() and !$options['no_stripslashes']) $text=stripslashes($text) ;
  $text=mysqli_real_escape_string($GLOBALS['DB_LINK'],$text) ;
  //echo 'text before save db: <strong>'.$text.'</strong><br>' ;
  return($text) ;
}

function get_serial_data($str,$prev_info=array())
{ if (!$str and !_sizeof($prev_info)) return('') ;
  ob_start() ;
  if (!is_array($str)) { if (strlen($str)) $arr=unserialize($str) ; else $arr=array() ; }
  else $arr=$str ;
  $arr=array_merge($prev_info,$arr) ;
  ?><table class=left><?
  if (_sizeof($arr)) foreach($arr as $fname=>$value)
   { $title=isset($_SESSION['serialize_fieds_names'][$fname])? $_SESSION['serialize_fieds_names'][$fname]:$fname ;
     ?><tr><td><?echo $title?></td><td><?echo $value?></td></tr><?
   }
  ?></table><?
  return(ob_get_clean()) ;
}

function damp_serial_data($recs)
{ ob_start() ;
  ?><table class="left serial_data"><?
  if (_sizeof($recs)) foreach($recs as $fname=>$value)
   { $title=isset($_SESSION['serialize_fieds_names'][$fname])? $_SESSION['serialize_fieds_names'][$fname]:$fname ;
     ?><tr><td><?echo $title?></td><td><?echo $value?></td></tr><?
   }
  ?></table><?
  return(ob_get_clean()) ;
}

function save_form_values_to_session($data)
 { if (_sizeof($data)) foreach($data as $id=>$value)
     if (!is_array($value)) $_SESSION['form_values'][$id]=stripslashes($value) ;
     else foreach($value as $id2=>$value2) $_SESSION['form_values'][$id][$id2]=stripslashes($value2) ;
   //damp_array($_SESSION['form_values']) ;
 }

function echo_form_saved($name1,$name2='')
{ if (!$name2) echo htmlspecialchars($_SESSION['form_values'][$name1]);
  else         echo htmlspecialchars($_SESSION['form_values'][$name1][$name2]) ;

}

function get_type_by_mime_type($mime)
{ $arr=explode('/',$mime) ;
  $ext=strtoupper($arr[1]) ;
  return($ext) ;
}


// подготовка условия для выборки данных
// возвращает условие для подстановки его в запрос SQL
// перектрытие данной функиии не требуется
function prepare_search_usl($fname,$operand,$worlds)
{ if (!is_array($worlds))
 { $temp=str_replace(',',' ',$worlds) ;
   $worlds=explode(' ',$temp) ;
 }
 $usl="" ;  $res_usl=array() ;
   if (_sizeof($worlds)) foreach($worlds as $word) if(trim($word))
    switch ($operand)
    { case '=':        $res_usl[] = $fname.'="'.$word.'"' ; break;
      case 'like%%':   $res_usl[] = $fname.' like "%'.$word.'%"' ; break;
      case 'like%':    $res_usl[] = $fname.' like "%'.$word.'"' ; break;
    }

   if (_sizeof($res_usl)) $usl='('.implode(' and ',$res_usl).')' ;
   return($usl) ;
}


// получение имени поля для дополнительного языка
 function get_cur_lang_field($rec,$fname)
 { if (!_CUR_LANG) return($rec[$fname]) ; // если не используем язык, или язык по умолчанию, возвращаем значение поля
   if ($rec[$fname._CUR_LANG_SUFF]) return($rec[$fname._CUR_LANG_SUFF]) ; else return($rec[$fname]) ;
 }


 // преобразует редиректорные ссылки яндекса в нормальные
  function check_yandex_link($referer)
  { $result=$referer ;
    if (strpos($referer, "yand")!==false)
    { $arr=parse_url($referer) ;
      if ($arr['path']=='/clck/jsredir')
      {  parse_str($arr['query'],$params) ;
         $result='http://yandex.ru/yandsearch?text='.$params['text'] ;
      }
    }
    return($result) ;
  }



function convert_list_to_tree(&$recs,&$arr,$parent=0,$arr_allow_ids=array())
{ if (_sizeof($recs))  foreach($recs as $id=>$rec) if ($rec['parent']==$parent) { $arr[$rec['pkey']]=array() ; unset($recs[$id]) ; }
  if (_sizeof($arr)) foreach ($arr as $child_pkey=>$arr_child_ids) convert_list_to_tree($recs,$arr[$child_pkey],$child_pkey,$arr_allow_ids) ;
}

function convert_list_to_tree2(&$recs,&$arr,$parent=0,$arr_allow_ids=array())
{ if (_sizeof($recs))  foreach($recs as $id=>$rec) if ($rec['parent']==$parent) { $arr[$rec['pkey']]=array('name'=>$rec['obj_name']) ; unset($recs[$id]) ; }
  if (_sizeof($arr)) foreach ($arr as $child_pkey=>$arr_child_ids) if ($child_pkey!='name') convert_list_to_tree2($recs,$arr[$child_pkey],$child_pkey,$arr_allow_ids) ;
}

function convert_tree_to_select_options_arr($arr_tree,&$recs,&$options_list,$parent_name='')
{  if (_sizeof($arr_tree)) foreach ($arr_tree as $id=>$arr_childs)
   {   $options_list[$id]=($parent_name)? $parent_name.' / '.$recs[$id]['obj_name']:$recs[$id]['obj_name']  ;
       if (_sizeof($arr_childs)) convert_tree_to_select_options_arr($arr_childs,$recs,$options_list,$options_list[$id]) ;
   }
}


function removeBOM($str="")
{
        if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
                $str=substr($str, 3);
        }
        return $str;
 }


function get_whois_info($domain)
  {     ob_start() ;
        system("whois ".$domain) ;
        $text=ob_get_clean() ;
        $arr=explode("\n",$text) ;
        //damp_array($arr,1,-1) ;
        $result=array() ;
        if (_sizeof($arr)) foreach($arr as $line) if ($line and substr($line,0,1)!='%')
        { $arr2=explode(':',$line) ;
          $param=trim($arr2[0]) ;
          $value=trim($arr2[1]) ;
          //echo $param.'='.$value.'<br>' ;
          if ($param and $value) switch($param)
          { //case 'domain': $result['domain']=$value ; break ;
            case 'nameserver':
            case 'nserver': $result['nserver'][]=$value ; break ;
            case 'state': $result['domain_status']=$value ; break ;
            case 'Registrar':
            case 'registrar': $result['registrator']=$value ; break ;
            //case 'created': $result['created']=$value ; break ;
            case 'expires':
            case 'expiration-date':
            case 'paid-till': $result['expire_domain']=StrToData($value) ; break ;

          }
        }
        ob_start() ;
        system("host ".$domain) ;
        $text=ob_get_clean() ;
        $arr=explode("\n",$text) ;
        //damp_array($arr,1,-1) ;
        if (_sizeof($arr)) foreach($arr as $line) if ($line)
        {  preg_match_all('/(.+?) has address (\d+\.\d+\.\d+\.\d+)/is', $line, $matches); //
           if ($matches[2][0]) $result['server_ip']=$matches[2][0] ;
           preg_match_all('/(.+?) mail is handled by (\d+) (.+?\.)/Uis', $line, $matches); //
           if ($matches[3][0]) $result['mail_server']=$matches[3][0] ;
        }
        return($result) ;
  }


  function include_ext($ext_name)
  {
     list($dir,$fname)=explode('/',$ext_name) ;
     if (!$fname) return(file_exists(_DIR_EXT.'/'.$dir)) ;
     elseif (file_exists(_DIR_EXT.'/'.$dir.'/'.$fname)) {include_once(_DIR_EXT.'/'.$dir.'/'.$fname) ; return(1) ; }
     else return(0) ;
  }

// https://snipp.ru/php/array-unique-multi
function array_unique_key($array, $key)
{
$tmp = $key_array = array();
$i = 0;

foreach($array as $val) {
	if (!in_array($val[$key], $key_array)) {
		$key_array[$i] = $val[$key];
		$tmp[$i] = $val;
	}
	$i++;
}
return $tmp;
}

//https://zalinux.ru/?p=2573
if (! function_exists("array_key_last")) {
    function array_key_last($array) {
        if (!is_array($array) || empty($array)) {
            return NULL;
        }

        return array_keys($array)[count($array)-1];
    }
}



?>
