PageRenderTime 28ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/core/gw_includes/core_engine_utils.php

http://glossword.googlecode.com/
PHP | 938 lines | 647 code | 109 blank | 182 comment | 65 complexity | 74072910702ceec179c231714ee52732 MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id$
  4. * @package Glossword 1.9
  5. * @copyright Š Dmitry N. Shilnikov, 2002-2010
  6. * @license GNU/GPL, see http://code.google.com/p/glossword/
  7. */
  8. if (!defined('IS_CLASS_GW_UTILS')) { define('IS_CLASS_GW_UTILS', 1);
  9. class site_engine_utils extends site_engine {
  10. public $rm_specials_patterns, $uri_patterns, $az_order_patterns;
  11. /* Returns HTML-code for a search form (web) */
  12. public function get_search_form()
  13. {
  14. $s = '';
  15. /* */
  16. $s .= '<form action="'. $this->V->server_dir.'/'.$this->V->file_index.'" enctype="application/x-www-form-urlencoded" accept-charset="utf-8" method="post">';
  17. $s .= '<div class="gw-search-form">';
  18. $s .= '<input style="width:10em" type="text" name="searchword" value="" />';
  19. /* Trick for Router */
  20. $s .= '<select name="areas[0]">';
  21. $s .= '<option value="term" selected="selected">in terms</option>';
  22. $s .= '<option value="defn">in definitions</option>';
  23. $s .= '</select>';
  24. $s .= '<input style="cursor:pointer" type="submit" value="'. $this->oTkit->_( 1175 ). '" />';
  25. $s .= '<input name="option" value="com_search" type="hidden" />';
  26. $s .= '<input name="task" value="search" type="hidden" />';
  27. $s .= '<input name="areas[]" value="gw_search" type="hidden" />';
  28. $s .= '</form></div>';
  29. return $s;
  30. }
  31. /* Counts the number of words, approximately */
  32. public function count_words( $s )
  33. {
  34. if ( $s == '' ) { return 0; }
  35. return sizeof( explode( ' ', $s ) );
  36. }
  37. /* */
  38. public function items__filter( $s )
  39. {
  40. $s = $this->rm_specials( $s );
  41. $s = $this->str_normalize( $s );
  42. return $s;
  43. }
  44. /* */
  45. public function get_az_order( $id_lang )
  46. {
  47. $this->oDb->select( 'uc, lc');
  48. $this->oDb->from( array( 'az_letters az' ) );
  49. $this->oDb->where( array( 'az.id_lang' => $id_lang ) );
  50. $this->oDb->order_by( 'az.int_sort' );
  51. $ar_sql = $this->oDb->get()->result_array();
  52. $ar = array();
  53. foreach ($ar_sql as $ar_v )
  54. {
  55. $ar[urldecode( $ar_v['lc'] )] = urldecode( $ar_v['uc'] );
  56. }
  57. return $ar;
  58. }
  59. /* Unicode normalization. Used for Search Index and Alphabetic Order */
  60. public function str_normalize( $s )
  61. {
  62. $s = $this->oCase->lc( $s );
  63. /* Use PECL extension */
  64. if ( class_exists( 'Normalizer' ) )
  65. {
  66. return Normalizer::normalize( $s, Normalizer::FORM_C );
  67. }
  68. /* */
  69. preg_match_all( "/./u", $s, $ar );
  70. $ar = $ar[0];
  71. $ar_c_crc = array();
  72. /* For each character */
  73. foreach ($ar AS $k => &$v )
  74. {
  75. /* Use values as key */
  76. /* PHP-bug: sometimes a string keys becomes interger */
  77. $ar_c_crc[$v] = sprintf( "%u", crc32( $v ) );
  78. }
  79. unset( $v );
  80. if ( empty( $ar_c_crc ) ){ return $s; }
  81. /* */
  82. $is_debug_q = $this->oDb->is_debug_q;
  83. $this->oDb->is_debug_q = false;
  84. $this->oDb->select( 'str_from, str_to' );
  85. $this->oDb->from( 'unicode_normalization' );
  86. $this->oDb->where_in( 'crc32u', array_values( $ar_c_crc ) );
  87. $ar_sql = $this->oDb->get()->result_array();
  88. $this->oDb->is_debug_q = $is_debug_q;
  89. /* Normalize text */
  90. foreach ($ar_sql AS $k => &$v )
  91. {
  92. $s = str_replace( urldecode( $v['str_from'] ), urldecode( $v['str_to'] ), $s );
  93. unset( $ar_sql[$k] );
  94. }
  95. unset( $v );
  96. return $s;
  97. }
  98. /* Normalized value, Source value, Language ID */
  99. public function get_az_index( $s, $s_src, $id_lang )
  100. {
  101. if ( !isset( $this->az_order_patterns[$id_lang] ) )
  102. {
  103. $this->az_order_patterns[$id_lang] = $this->get_az_order( $id_lang );
  104. }
  105. $ar_q = array();
  106. $ar_q['_si'] = $s; /* Temporary, used for Search Index */
  107. /** Prepare Sorting Order **/
  108. $s_src = $this->oCase->lc( $s_src );
  109. $s_src = trim( strip_tags( $s_src ) );
  110. $s_src = $this->oFunc->mb_substr( $s_src, 0, 16 );
  111. $str_az_order = str_replace(
  112. array_keys( $this->az_order_patterns[$id_lang] ),
  113. array_values( $this->az_order_patterns[$id_lang] ),
  114. $s_src
  115. );
  116. $str_az_order = $this->oCase->uc( $str_az_order );
  117. preg_match_all( "/./u", $str_az_order, $ar );
  118. for ( $i = 1; $i <= 8; $i++ )
  119. {
  120. $ar_q['contents_'.$i] = isset( $ar[0][$i-1] ) ? sprintf( "%u", crc32( $ar[0][$i-1] ) ) : 0;
  121. }
  122. $ar_q['contents_so'] = $str_az_order;
  123. /** Prepare Alphabetic Order **/
  124. $ar_q['contents_a'] = isset( $ar[0][0] ) ? $ar[0][0] : '';
  125. $ar_q['contents_b'] = isset( $ar[0][1] ) ? $ar[0][1] : '';
  126. #$s = $this->oCase->uc( trim( $s ) );
  127. #$ar_q['contents_a'] = $this->oFunc->mb_substr( $s, 0, 1 );
  128. #$ar_q['contents_b'] = $this->oFunc->mb_substr( $s, 1, 1 );
  129. /* String is empty or consists of special characters only */
  130. if ( $ar_q['contents_a'] == '' ){ $ar_q['contents_a'] = '#'; }
  131. /* */
  132. #$ar_q['contents_1'] = sprintf( "%u", crc32( $ar_q['contents_a'] ) );
  133. #prn_r( $ar_q );
  134. #exit;
  135. return $ar_q;
  136. }
  137. /* Removes a special characters !#$%... 264 symbols */
  138. public function rm_specials( $s, $newchar = ' ' )
  139. {
  140. /* Always remove `.` */
  141. $s = str_replace( '.', ' ', $s );
  142. /* Remove lines feeds */
  143. $s = $this->oCase->rm_crlf( $s );
  144. /* Add space to HTML-tags */
  145. $s = str_replace('><', '> <', $s );
  146. $s = str_replace('<'.'?'.'php', '', $s );
  147. $s = strip_tags( $s );
  148. /* remove {TEMPLATES}, {%TEMPLATES%} */
  149. #$s = preg_replace( "/{(%)?([A-Za-z0-9:\-_]+)(%)?}/", '', $s );
  150. $s = $this->oCase->rm_entity( $s );
  151. $newchar_encd = urlencode( $newchar );
  152. /* Cache patterns using memory */
  153. if ( !isset( $this->rm_specials_patterns[$newchar_encd] ) )
  154. {
  155. /* Construct filename with cached replacement patterns */
  156. $filename = $this->V->path_temp.'/gw_translit_1_'.$newchar_encd.'.tmp';
  157. /* Cache patterns using files */
  158. if ( file_exists( $filename ) )
  159. {
  160. $this->rm_specials_patterns[$newchar_encd] = unserialize( implode( '', file( $filename ) ) );
  161. }
  162. else
  163. {
  164. /* Read patterns from database */
  165. $this->oDb->select( 'str_from, str_to' );
  166. $this->oDb->from( 'translit' );
  167. $this->oDb->where( array( 'id_profile' => '1' ) );
  168. $ar_sql = $this->oDb->get()->result_array();
  169. $ar_lines = array();
  170. foreach ( $ar_sql as $ar_v )
  171. {
  172. $this->rm_specials_patterns[$newchar_encd][urldecode($ar_v['str_from'])] = ( $newchar != '' && $ar_v['str_to'] != '+' )
  173. ? urldecode( $ar_v['str_to'] )
  174. : $newchar;
  175. }
  176. $this->oFunc->file_put_contents( $filename, serialize( $this->rm_specials_patterns[$newchar_encd] ) );
  177. }
  178. }
  179. /* */
  180. $s = str_replace(
  181. array_keys( $this->rm_specials_patterns[$newchar_encd] ),
  182. array_values( $this->rm_specials_patterns[$newchar_encd] ),
  183. $s
  184. );
  185. /* Leave one character only */
  186. if ( $newchar != '' )
  187. {
  188. /*
  189. 0.000395 - preg_replace
  190. 0.000031 - str_replace
  191. */
  192. $cnt_replace = 1;
  193. while ( $cnt_replace )
  194. {
  195. $s = str_replace( $newchar.$newchar, $newchar, $s, $cnt_replace );
  196. }
  197. }
  198. return $s;
  199. }
  200. /* */
  201. public function strord( $s )
  202. {
  203. preg_match_all( "/./u", $s, $ar_letters );
  204. $ar_ord = array();
  205. for ($i = 1; $i <= 8; $i++)
  206. {
  207. $ar_ord[$i] = isset( $ar_letters[0][$i] ) ? implode('', unpack( "C*", $ar_letters[0][$i] ) ) : 0;
  208. }
  209. return $ar_ord;
  210. }
  211. /* Generates URI for an Item */
  212. public function items__uri( $s, $id_item = '' )
  213. {
  214. /* 327 symbols */
  215. /* 0.26, 110 Queries */
  216. /* 0.09, 10 Queries */
  217. /* Construct filename with cached replacement patterns */
  218. $filename = $this->V->path_temp.'/gw_translit_2.tmp';
  219. /* Cache patterns using memory */
  220. if ( !$this->uri_patterns )
  221. {
  222. /* Cache patterns using files */
  223. if ( file_exists( $filename ) )
  224. {
  225. $this->uri_patterns = unserialize( implode( '', file( $filename ) ) );
  226. }
  227. else
  228. {
  229. /* Read patterns from database */
  230. $this->oDb->select( 'str_from, str_to' );
  231. $this->oDb->from( 'translit' );
  232. $this->oDb->where( array( 'id_profile' => '2' ) );
  233. $ar_sql = $this->oDb->get()->result_array();
  234. $ar_lines = array();
  235. foreach ( $ar_sql as $ar_v )
  236. {
  237. $this->uri_patterns[urldecode($ar_v['str_from'])] = urldecode( $ar_v['str_to'] );
  238. }
  239. $this->oFunc->file_put_contents( $filename, serialize( $this->uri_patterns ) );
  240. }
  241. }
  242. /* */
  243. $s = str_replace( array_keys( $this->uri_patterns ), array_values( $this->uri_patterns ), $s );
  244. /* Keep alphanumeric only characters */
  245. $s = preg_replace( '/[^0-9A-Za-z_-]/', '-', $s );
  246. /* Remove repeated `-` */
  247. $cnt_replace = 1;
  248. while ( $cnt_replace )
  249. {
  250. $s = str_replace( '--', '-', $s, $cnt_replace );
  251. }
  252. $s = rtrim( $s, '-' );
  253. /* No alphanumeric characters found, use Item ID */
  254. if ( $s == '' )
  255. {
  256. $s = $id_item;
  257. }
  258. /* Limit length */
  259. $s = substr( $s, 0, 200 );
  260. return $s;
  261. }
  262. /* */
  263. public function notice_onsubmit( $phrase, $is_success = true )
  264. {
  265. $this->oOutput->append_html( '<div><div class="'.GW_COLOR_TRUE.' updated" id="status-onsumbit">' );
  266. $this->oOutput->append_html( '<a onclick="jsF.destroy_el(\'status-onsumbit\');" style="margin:-1em -1em;font-size:80%;" class="btn remove floatright" href="#" title="'. $this->oTkit->_( 1154 ) .'">'. $this->oTkit->_( 1154 ) .'<span class="icon-rm"></span></a>' );
  267. $this->oOutput->append_html( $phrase );
  268. $this->oOutput->append_html( '</div></div>' );
  269. /* Automatically close window */
  270. $this->oOutput->append_js( 'setTimeout( function(){ jsF.FX_fade_out(\'status-onsumbit\'); }, 4000 );' );
  271. }
  272. /* */
  273. public function langs__get_installed()
  274. {
  275. $ar = array();
  276. foreach ( $this->oTkit->ar_lang_list as $ar_v )
  277. {
  278. $ar[$ar_v['id_lang']] = $ar_v['lang_name'].' - '.$ar_v['lang_native'];
  279. }
  280. /* @todo: put in cache */
  281. return $ar;
  282. }
  283. /* */
  284. public function langs__get_locale_codes()
  285. {
  286. $ar = array();
  287. foreach ( $this->oTkit->ar_lang_list as $ar_v )
  288. {
  289. $ar[$ar_v['isocode1'].'_'.$ar_v['region']] = $ar_v['id_lang'];
  290. }
  291. /* @todo: put in cache */
  292. return $ar;
  293. }
  294. /**
  295. * Constructs alphabetic order and returns HTML for navigation.
  296. *
  297. * @uses $oDb, $oHtml, $oCache.
  298. * @return array [ az, aazz ]
  299. */
  300. public function items__get_az()
  301. {
  302. $ar_az = $ar_aazz = array();
  303. /* Reduce cache time for admin area */
  304. $time_cache_az = ( SITE_ADMIN_MODE ) ? 60 * 2 : $this->V->time_cache_az;
  305. /* A-Z */
  306. #$oTimer = new tkit_timer('az-sql');
  307. /**
  308. * Use DB-based cache.
  309. * Cache off: 0.003457 az sql + 0.007476 az html = 0.010933
  310. * Cache on: 0.002011 az html
  311. */
  312. $cache_key = 'az-' . $this->gv['il'] . $this->V->is_sef .
  313. ( isset( $this->gv['area']['a1'] ) ? $this->gv['area']['a1'] : '-' ) .
  314. ( isset( $this->gv['area']['lc'] ) ? $this->gv['area']['lc'] : '-' ) .
  315. $this->V->id_field_root . SITE_ADMIN_MODE . SITE_WEB_MODE;
  316. if ( $this->V->is_cache_az && $this->oCache->in_cache( $cache_key, 'items-az', $time_cache_az ) )
  317. {
  318. $ar_az = $this->oCache->load();
  319. }
  320. else
  321. {
  322. /* Basic Multilingual Plane: */
  323. /* http://www.unicode.org/roadmaps/bmp/ */
  324. /* Break alphabetic toolbar per every set of characters */
  325. $ar_unicode_map = array(
  326. #array( '20', 'Basic Latin Digits' ),
  327. #array( '41', 'Basic Latin' ),
  328. array( '20', 'Basic Latin && Basic Latin Digits' ),
  329. array( 'c280', 'Latin Extended' ),
  330. array( 'c990', 'IPA Extensions' ),
  331. array( 'cab0', 'Spacing Modifiers' ),
  332. array( 'cc80', 'Combining Diacritics' ),
  333. array( 'cdb0', 'Greek' ),
  334. array( 'd080', 'Cyrillic, Cyrillic Supplement' ),
  335. array( 'd4b0', 'Armenian' )
  336. );
  337. $ar_tb_last = end( $ar_unicode_map );
  338. $int_tb_last = hexdec( $ar_tb_last[0] );
  339. /* Select first letters and Language ID */
  340. # $this->oDb->select( 'c.contents_a, az1.id_lang, CONCAT( l.isocode1,"_", l.region ) locale', false );
  341. # $this->oDb->from( array( 'items i', 'contents c', 'languages l' ) );
  342. # $this->oDb->where( array(
  343. # 'i.id_item = c.id_item' => NULL,
  344. # 'l.id_lang = c.id_lang' => NULL,
  345. # 'c.id_field' => (string) $this->V->id_field_root,
  346. # 'i.is_active' => '1'
  347. # ) );
  348. # $this->oDb->group_by( 'az1.id_lang, c.contents_a' );
  349. # $this->oDb->order_by( 'c.id_lang' );
  350. /* 1.9.3: Custom alphabetic order */
  351. # $this->oDb->join( 'az_letters az1', 'az1.uc_crc32u = c.contents_1 AND c.id_lang = az1.id_lang', 'left', false );
  352. # $this->oDb->order_by( 'az1.int_sort' );
  353. # $this->oDb->order_by( 'c.contents_so' );
  354. $this->oDb->select( 'it.contents_a, it.id_lang_1 id_lang, CONCAT( l.isocode1,"_", l.region ) locale', false );
  355. $this->oDb->from( array( 'items_tmp it' ) );
  356. $this->oDb->join( 'languages l', 'it.id_lang_1 = l.id_lang', 'left' );
  357. $this->oDb->where( array( 'it.is_active' => '1' ) );
  358. $this->oDb->group_by( 'it.id_lang_1, it.contents_a' );
  359. $this->oDb->order_by( 'it.int_sort_1, it.contents_so' );
  360. $ar_sql = $this->oDb->get()->result_array();
  361. #print $oTimer->endp('az sql');
  362. #$oTimer = new tkit_timer('az-html');
  363. $oHref = $this->oHtml->oHref();
  364. foreach ( $ar_sql as $ar_v )
  365. {
  366. $ar_v['contents_a'] = str_replace( "\0", '', $ar_v['contents_a'] );
  367. /* For each letter */
  368. $oHref = $this->oHtml->oHref();
  369. $oHref->set( 'a1', urlencode( $ar_v['contents_a'] ) );
  370. /* 1.9.3: Locale code */
  371. $oHref->set( 'lc', $ar_v['locale'] );
  372. $class_name = '';
  373. if ( isset( $this->gv['area']['a1'] ) && isset( $this->gv['area']['lc'] )
  374. && $ar_v['contents_a'] == $this->gv['area']['a1']
  375. && $ar_v['locale'] == $this->gv['area']['lc']
  376. )
  377. {
  378. $class_name = 'highlight';
  379. }
  380. /* 1.9.3: Group Alphabetic Order using Language ID */
  381. if ( SITE_ADMIN_MODE )
  382. {
  383. $oHref->set( 't', 'items' );
  384. $oHref->set( 'a', 'manage' );
  385. $ar_az[$ar_v['id_lang']][] = $this->oHtmlAdm->a_href(
  386. array( $this->V->file_index, '#area' => $oHref->get() ),
  387. array( 'class' => $class_name, 'title' => $ar_v['contents_a'] ), $ar_v['contents_a']
  388. );
  389. }
  390. else
  391. {
  392. $ar_az[$ar_v['id_lang']][] = $this->oHtml->a_href(
  393. array( $this->V->file_index, '#area' => $oHref->get() ),
  394. array( 'class' => $class_name, 'title' => $ar_v['contents_a'] ), $ar_v['contents_a']
  395. );
  396. }
  397. }
  398. /* Re-arrange */
  399. foreach ( $ar_az as $az_k => $az_v )
  400. {
  401. unset( $ar_az[$az_k] );
  402. $ar_az[] = '<div>';
  403. foreach ( $az_v as $k_tb => $v_tb )
  404. {
  405. $ar_az[] = $v_tb;
  406. }
  407. $ar_az[] = '</div>';
  408. }
  409. # prn_r( $ar_az );
  410. /* Show all */
  411. $oHref->set( 'a1' );
  412. $oHref->set( 'a2' );
  413. $oHref->set( 'lc' );
  414. if ( SITE_ADMIN_MODE )
  415. {
  416. $ar_az[-1] = $this->oHtmlAdm->a_href(
  417. array( $this->V->file_index, '#area' => $oHref->get() ),
  418. array( 'class' => ( !isset( $this->gv['area']['a1'] ) || ( isset( $this->gv['area']['a1'] ) && $this->gv['area']['a1'] ) == '' ? 'highlight' : '' ) ),
  419. $this->oTkit->_( 1044 )
  420. );
  421. }
  422. else
  423. {
  424. /* 1.9.3: Added `showall` classname */
  425. $ar_az[-1] = $this->oHtml->a_href(
  426. array( $this->V->file_index, '#area' => $oHref->get() ),
  427. array(
  428. 'title' => $this->oTkit->_( 1044 ),
  429. 'class' => 'showall' . ( !isset( $this->gv['area']['a1'] ) || ( isset( $this->gv['area']['a1'] ) && $this->gv['area']['a1'] != '' ) == '' ? ' highlight' : '' ) ),
  430. $this->oTkit->_( 1044 )
  431. );
  432. }
  433. /* Cached Units: Save */
  434. if ( $this->V->is_cache_az )
  435. {
  436. $ar_az = $this->oCache->save( $ar_az );
  437. }
  438. }
  439. #print $oTimer->endp('az html');
  440. /* AA-ZZ */
  441. /* 1.9.3: disabled */
  442. if ( 0 && isset( $this->gv['area']['a1'] ) && $this->gv['area']['a1'] != '' )
  443. {
  444. #$oTimer = new tkit_timer('aazz-sql');
  445. $cache_key = 'aazz-' . $this->gv['il'] . $this->V->is_sef . ( isset( $this->gv['area']['a1'] ) ? $this->gv['area']['a1'] : '' ) .
  446. ( isset( $this->gv['area']['a2'] ) ? $this->gv['area']['a2'] : '' ) .
  447. $this->V->id_field_root . SITE_ADMIN_MODE . SITE_WEB_MODE;
  448. if ( $this->oCache->in_cache( $cache_key, 'items-az', $time_cache_az ) )
  449. {
  450. $ar_aazz = $this->oCache->load();
  451. }
  452. else
  453. {
  454. $this->oDb->select( 'c.contents_b' );
  455. $this->oDb->from( array( 'items i', 'contents c' ) );
  456. $this->oDb->where( array( 'i.id_item = c.id_item' => NULL, 'i.is_active' => 1, 'c.id_field' => $this->V->id_field_root, 'c.contents_a' => $this->gv['area']['a1'] ) );
  457. $this->oDb->group_by( 'c.contents_b' );
  458. $ar_sql = $this->oDb->get()->result_array();
  459. # print $oTimer->endp('aazz sql');
  460. # $oTimer = new tkit_timer('aazz-html');
  461. foreach ( $ar_sql as $ar_v )
  462. {
  463. $oHref = $this->oHtml->oHref();
  464. $oHref->set( 'a1', urlencode( $this->gv['area']['a1'] ) );
  465. $oHref->set( 'a2', urlencode( $ar_v['contents_b'] ) );
  466. $class_name = '';
  467. if ( isset( $this->gv['area']['a2'] ) && $ar_v['contents_b'] == $this->gv['area']['a2'] )
  468. {
  469. $class_name = 'highlight';
  470. }
  471. if ( SITE_ADMIN_MODE )
  472. {
  473. $oHref->set( 't', $this->gv['area']['t'] );
  474. $oHref->set( 'a', $this->gv['area']['a'] );
  475. $ar_aazz[] = $this->oHtmlAdm->a_href(
  476. array( $this->V->file_index, '#area' => $oHref->get() ),
  477. array( 'class' => $class_name ),
  478. $this->gv['area']['a1'].$ar_v['contents_b']
  479. );
  480. }
  481. else
  482. {
  483. $ar_aazz[] = $this->oHtml->a_href(
  484. array( $this->V->file_index, '#area' => $oHref->get() ),
  485. array( 'class' => $class_name ),
  486. $this->gv['area']['a1'].$ar_v['contents_b']
  487. );
  488. }
  489. }
  490. /* Cached Units: Save */
  491. $ar_aazz = $this->oCache->save( $ar_aazz );
  492. }
  493. #print $oTimer->endp('aazz html');
  494. }
  495. return array( $ar_az, $ar_aazz );
  496. }
  497. /**
  498. * Generates CAPTCHA image.
  499. *
  500. * @uses $oDb, $oFunc, str_random().
  501. */
  502. public function make_captcha()
  503. {
  504. if (file_exists($this->V->path_includes.'/func_make_captcha.php'))
  505. {
  506. include_once($this->V->path_includes.'/func_make_captcha.php');
  507. return array($this->V->server_dir.'/'.$filename);
  508. }
  509. }
  510. /**
  511. * Generates a random string.
  512. */
  513. static function str_random($alphabet, $maxchar = 8)
  514. {
  515. $str = '';
  516. $alphabet = ($alphabet) ? $alphabet : '23456789bdghkmnqsuvxyz';
  517. $alphabet = str_shuffle($alphabet);
  518. $len = strlen($alphabet);
  519. for ($i = 0; $i < $maxchar; $i++)
  520. {
  521. $sed = mt_rand(0, $len-1);
  522. $str .= $alphabet[$sed];
  523. }
  524. return $str;
  525. }
  526. /* */
  527. public function create_navbar()
  528. {
  529. if ( defined('SITE_THIS_SCRIPT') && SITE_THIS_SCRIPT == $this->V->file_index )
  530. {
  531. return;
  532. }
  533. #$ar_menu[$this->oTkit->_( '1000' )][] = '';
  534. $ar_menu[$this->oTkit->_( '1000' )][] = $this->oHtmlAdm->a_href(
  535. array( $this->V->file_index, 'arg[area]' => '' ),
  536. array( 'title' => $this->oTkit->_( '1152' ) ),
  537. $this->oTkit->_( '1152' )
  538. );
  539. /* Add */
  540. $ar_menu[$this->oTkit->_( '1001' )][] = $this->oHtmlAdm->a_href(
  541. array( $this->V->file_index, 'arg[area]' => 'a.add,t.items' ),
  542. array(),
  543. $this->oTkit->_( '1003' )
  544. );
  545. $ar_menu[$this->oTkit->_( '1001' )][] = $this->oHtmlAdm->a_href(
  546. array( $this->V->file_index, 'arg[area]' => 'a.add,t.infoblocks' ),
  547. array( 'title' => $this->oTkit->_( '1054' ) ),
  548. $this->oTkit->_( '1054' )
  549. );
  550. /* Manage */
  551. $ar_menu[$this->oTkit->_( '1006' )][] = $this->oHtmlAdm->a_href(
  552. array( $this->V->file_index, 'arg[area]' => 'a.manage,t.items' ),
  553. array( 'title' => $this->oTkit->_( '1003' ) ),
  554. $this->oTkit->_( '1003' )
  555. );
  556. $ar_menu[$this->oTkit->_( '1006' )][] = $this->oHtmlAdm->a_href(
  557. array( $this->V->file_index, 'arg[area]' => 'a.manage,t.fields' ),
  558. array( 'title' => $this->oTkit->_( '1020' ) ),
  559. $this->oTkit->_( '1020' )
  560. );
  561. $ar_menu[$this->oTkit->_( '1006' )][] = $this->oHtmlAdm->a_href(
  562. array( $this->V->file_index, 'arg[area]' => 'a.manage,t.infoblocks' ),
  563. array( 'title' => $this->oTkit->_( '1054' ) ),
  564. $this->oTkit->_( '1054' )
  565. );
  566. $ar_menu[$this->oTkit->_( '1006' )][] = $this->oHtmlAdm->a_href(
  567. array( $this->V->file_index, 'arg[area]' => 'a.manage,t.az' ),
  568. array( 'title' => $this->oTkit->_( 1209 ) ),
  569. $this->oTkit->_( 1209 )
  570. );
  571. $ar_menu[$this->oTkit->_( '1006' )][] = $this->oHtmlAdm->a_href(
  572. array( $this->V->file_index, 'arg[area]' => 'a.manage,t.translations' ),
  573. array( 'title' => $this->oTkit->_( 1190 ) ),
  574. $this->oTkit->_( 1190 )
  575. );
  576. /* Setup */
  577. $ar_menu[$this->oTkit->_( 1007 )][] = $this->oHtmlAdm->a_href(
  578. array( $this->V->file_index, 'arg[area]' => 'a.setup,t.systemsettings' ),
  579. array( 'title' => $this->oTkit->_( 1040 ) ),
  580. $this->oTkit->_( 1040 )
  581. );
  582. /* Service */
  583. /* Service - Maintenance */
  584. $ar_menu[$this->oTkit->_( 1008 )][] = $this->oHtmlAdm->a_href(
  585. array( $this->V->file_index, 'arg[area]' => 'a.mnt,t.service' ),
  586. array( 'title' => $this->oTkit->_( 1110 ) ),
  587. $this->oTkit->_( 1110 )
  588. );
  589. /* Service - Localization */
  590. $oJsMenu = new site_jsMenu();
  591. $oJsMenu->icon = $this->oTkit->_( 1183 ).$this->V->str_class_dropdown;
  592. $oJsMenu->event = 'onmouseover';
  593. $oJsMenu->classname = '';
  594. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.manage'."\x01\x01".'t.langs' ), $this->oTkit->_( 1181 ) );
  595. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.manage'."\x01\x01".'t.tvs' ), $this->oTkit->_( 1182 ) );
  596. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.manage'."\x01\x01".'t.translations' ), $this->oTkit->_( 1190 ) );
  597. $ar_menu[$this->oTkit->_( 1008 )][] = $oJsMenu->get_html();
  598. /* Exchange - Export */
  599. $oJsMenu = new site_jsMenu();
  600. $oJsMenu->icon = $this->oTkit->_( 1079 ).$this->V->str_class_dropdown;
  601. $oJsMenu->event = 'onmouseover';
  602. $oJsMenu->classname = '';
  603. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.export'."\x01\x01".'t.items' ), $this->oTkit->_( 1003 ) );
  604. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.export'."\x01\x01".'t.infoblocks' ), $this->oTkit->_( 1054 ) );
  605. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.export'."\x01\x01".'t.langs' ), $this->oTkit->_( 1181 ) );
  606. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.export'."\x01\x01".'t.tvs' ), $this->oTkit->_( 1182 ) );
  607. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.export'."\x01\x01".'t.az' ), $this->oTkit->_( 1209 ) );
  608. $ar_menu[$this->oTkit->_( 1009 )][] = $oJsMenu->get_html();
  609. /* Exchange - Import */
  610. $oJsMenu = new site_jsMenu();
  611. $oJsMenu->icon = $this->oTkit->_( 1077 ).$this->V->str_class_dropdown;
  612. $oJsMenu->event = 'onmouseover';
  613. $oJsMenu->classname = '';
  614. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.import'."\x01\x01".'t.items' ), $this->oTkit->_( 1003 ) );
  615. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.import'."\x01\x01".'t.infoblocks' ), $this->oTkit->_( 1054 ) );
  616. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.import'."\x01\x01".'t.langs' ), $this->oTkit->_( 1181 ) );
  617. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.import'."\x01\x01".'t.tvs' ), $this->oTkit->_( 1182 ) );
  618. $oJsMenu->append( $this->oHtmlAdm->url_normalize( $this->V->file_index.'?#area=a.import'."\x01\x01".'t.az' ), $this->oTkit->_( 1209 ) );
  619. $ar_menu[$this->oTkit->_( 1009 )][] = $oJsMenu->get_html();
  620. /* Right-side menu*/
  621. $ar_menu_right[$this->oTkit->_( '1011' )][] = $this->oHtmlAdm->a_href(
  622. array( $this->V->file_index, 'arg[area]' => 't.user,a.edit,s.pass' ),
  623. array( 'title' => $this->oTkit->_( '1012' ) ),
  624. $this->oTkit->_( '1012' )
  625. );
  626. $ar_menu_right[$this->oTkit->_( '1011' )][] = $this->oHtmlAdm->a_href(
  627. array( $this->V->file_index, 'arg[area]' => 't.user,a.edit,s.profile' ),
  628. array( 'title' => $this->oTkit->_( '1013' ) ),
  629. $this->oTkit->_( '1013' )
  630. );
  631. /* */
  632. $ar_str = $ar_js_menublocks = array();
  633. $ar_str[] = '<ul>';
  634. $ar_str[] = '<li><p></p></li>';
  635. $cnt = 1;
  636. $cnt_current = 0;
  637. $ar_str_sub = array();
  638. foreach ($ar_menu as $str_menu => $ar_a)
  639. {
  640. /* @temp Indicators */
  641. foreach ( $ar_a as $sub_k => $sub_v )
  642. {
  643. $cmp_1 = preg_replace( '/href="(.*?)"(.*)/', "\\1", $sub_v );
  644. if ( strlen($this->gv['_area']) > 1 && strpos( $cmp_1, '='.$this->gv['_area'] ) !== false )
  645. {
  646. $ar_a[$sub_k] = str_replace( 'href=', 'class="on" href=', $sub_v );
  647. $cnt_current = $cnt;
  648. }
  649. }
  650. $ar_str[] = '<li>'.$this->oHtmlAdm->a_href(
  651. array( 'javascript:void(0)' ),
  652. array( 'title' => $str_menu, 'onclick' => 'oGwNavbar.sub(this)', 'id' => 'a-'.$cnt ),
  653. $str_menu
  654. ).'</li>';
  655. $ar_str_sub[] = '<div id="ch-'.$cnt.'" class="gw-navbar-sub hidden"><ul><li>'.implode( '</li><li>', $ar_a ).'</li></ul></div>';
  656. $ar_js_menublocks[] = $cnt;
  657. ++$cnt;
  658. }
  659. $ar_str[] = '<li class="navbar-right"><p></p></li>';
  660. foreach ($ar_menu_right as $str_menu => $ar_a)
  661. {
  662. /* Indicators */
  663. /* @temp */
  664. foreach ( $ar_a as $sub_k => $sub_v )
  665. {
  666. if ( strlen($this->gv['_area']) > 1 && strpos($sub_v, '='.$this->gv['_area'] ) !== false )
  667. {
  668. $ar_a[$sub_k] = str_replace( 'href=', 'class="on" href=', $sub_v );
  669. $cnt_current = $cnt;
  670. }
  671. }
  672. $ar_str[] = '<li class="navbar-right">'.$this->oHtmlAdm->a_href(
  673. array( 'javascript:void(0)' ),
  674. array( 'title' => $str_menu, 'onclick' => 'oGwNavbar.sub(this)', 'id' => 'a-'.$cnt ),
  675. $str_menu
  676. ).'</li>';
  677. $ar_str_sub[] = '<div id="ch-'.$cnt.'" class="navbar-right gw-navbar-sub hidden"><ul><li>'.implode( '</li><li>', $ar_a ).'</li></ul></div>';
  678. $ar_js_menublocks[] = $cnt;
  679. ++$cnt;
  680. }
  681. $this->oOutput->append_js( 'jsF.Set( "menublocks", "['.implode( ',', $ar_js_menublocks ).']" );' );
  682. /* Highlight the current section */
  683. if ( $cnt_current )
  684. {
  685. $this->oOutput->append_js( ' oGwNavbar.sub( fn_getElementById(\'a-'.$cnt_current.'\') ); ' );
  686. }
  687. else
  688. {
  689. $this->oOutput->append_js( ' oGwNavbar.sub( fn_getElementById(\'a-1\') ); ' );
  690. }
  691. $ar_str[] = '</ul>';
  692. # prn_r( $ar_str );
  693. #prn_r( $ar_str_sub );
  694. return implode( '', $ar_str ).implode( '', $ar_str_sub );
  695. }
  696. /**
  697. * Generates sidebar for user.
  698. *
  699. * A temporary version.
  700. */
  701. public function create_sidebar_menu()
  702. {
  703. $s = '';
  704. return $s;
  705. }
  706. /**
  707. * Update some user stats.
  708. */
  709. public function stat_user_rebuild($id_user)
  710. {
  711. $q__users['cnt_bytes'] = $this->stat_items_bytes($id_user);
  712. $q__users['cnt_terms'] = $this->stat_items_num($id_user);
  713. $this->oDb->update( $this->V->db_table_users, $q__users, array('id_user' => $id_user) );
  714. }
  715. /**
  716. * Calculate total number of bytes.
  717. */
  718. public function stat_items_bytes($id_user)
  719. {
  720. $this->oDb->select( 'SUM(cnt_bytes) as sum_bytes' );
  721. $this->oDb->from( array('contents') );
  722. $this->oDb->where( array('id_user_created' => $id_user) );
  723. $ar_sql = $this->oDb->get()->result_array();
  724. return isset($ar_sql[0]['sum_bytes']) ? $ar_sql[0]['sum_bytes'] : 0;
  725. }
  726. /**
  727. * Calculate total number of items.
  728. */
  729. public function stat_items_num($id_user)
  730. {
  731. $this->oDb->select( 'COUNT(*) as cnt_items' );
  732. $this->oDb->from( array('items') );
  733. $this->oDb->where( array('item_id_user_created' => $id_user) );
  734. $ar_sql = $this->oDb->get()->result_array();
  735. return isset($ar_sql[0]['cnt_items']) ? $ar_sql[0]['cnt_items'] : 0;
  736. }
  737. /**
  738. * HTML-code for Meta Refresh
  739. */
  740. public static function gethtml_meta_refresh($url, $delay = 1)
  741. {
  742. return '<meta http-equiv="refresh" content="'.$delay.';url='.$url.'" />';
  743. }
  744. /**
  745. * "Soft" redirect to another location.
  746. */
  747. public function soft_redirect($text = '', $url, $classname = '')
  748. {
  749. if ($classname == GW_COLOR_FALSE)
  750. {
  751. $classname = GW_COLOR_FALSE.' error';
  752. }
  753. else
  754. {
  755. $this->oTpl->assign( 'v:meta_refresh', $this->gethtml_meta_refresh($url, $this->V->time_refresh) );
  756. $classname = $classname.' updated';
  757. }
  758. return '<div class="'.$classname.'" id="status">'.$text.
  759. '<p><a href="'.$url.'">'.$this->oTkit->_(1050).'</a></p></div>';
  760. }
  761. /* */
  762. public function get_perm_map()
  763. {
  764. $ar_perms_map = array();
  765. $ar_perms_map[$this->oTkit->_(1211)]['sys-settings'] = $this->oTkit->_( );
  766. $ar_perms_map[$this->oTkit->_(1211)]['sys-mnt'] = $this->oTkit->_( );
  767. $ar_perms_map[$this->oTkit->_(1211)]['users'] = $this->oTkit->_( );
  768. $ar_perms_map[$this->oTkit->_(1312)]['items'] = $this->oTkit->_( );
  769. $ar_perms_map[$this->oTkit->_(1312)]['items-own'] = $this->oTkit->_( );
  770. $ar_perms_map[$this->oTkit->_(1145)]['email'] = $this->oTkit->_( );
  771. $ar_perms_map[$this->oTkit->_(1145)]['login'] = $this->oTkit->_( );
  772. $ar_perms_map[$this->oTkit->_(1145)]['password'] = $this->oTkit->_( );
  773. $ar_perms_map[$this->oTkit->_(1145)]['profile'] = $this->oTkit->_( );
  774. $ar_perms_map[$this->oTkit->_(1145)]['pm'] = $this->oTkit->_( );
  775. $ar_perms_map[$this->oTkit->_(1313)]['comments'] = $this->oTkit->_( );
  776. $ar_perms_map[$this->oTkit->_(1313)]['comments-own'] = $this->oTkit->_( );
  777. return $ar_perms_map;
  778. }
  779. /**
  780. * Draws progressbar in HTML+CSS
  781. *
  782. * @param int $percent
  783. * @param text $color_txt Progress bar text color
  784. * @param text $color_bg Progress bar Background color
  785. * @return text HTML-code
  786. */
  787. public static function text_progressbar($percent = 100, $color_txt = '#000', $color_bg = '#6C3')
  788. {
  789. if ($percent > 100){ $percent = 100; }
  790. return '<div style="text-align:center;background:#F6F6F6;margin:1px 0;width:100%;border:1px solid #CCC"><div style="font:90% sans-serif;color:'.$color_txt.';background:'.$color_bg.';width:'.$percent.'%">'.$percent.'%</div></div>';
  791. }
  792. /**
  793. * ----------------------------------------------
  794. * Cron functions. Called on /cron.php
  795. * ----------------------------------------------
  796. */
  797. public function cron__()
  798. {
  799. if ( (mt_rand() % 100) < $this->V->prbblty_tasks )
  800. {
  801. $this->cron__user_stats();
  802. }
  803. if ( (mt_rand() % 100) < $this->V->prbblty_tasks )
  804. {
  805. $this->cron__user_clean_sessions();
  806. }
  807. }
  808. /* Recounts user stats */
  809. public function cron__user_stats()
  810. {
  811. $this->oDb->select('id_user', false);
  812. $this->oDb->from( array( $this->V->db_table_sessions ) );
  813. $this->oDb->where( array( 'mdate >' => @date($this->sdf, $this->V->time_gmt - $this->V->time_sec_h)) );
  814. $this->oDb->group_by('id_user');
  815. $this->oDb->limit( 100 );
  816. $ar_sql = $this->oDb->get()->result_array();
  817. foreach ($ar_sql as $ar_v)
  818. {
  819. $this->stat_user_rebuild($ar_v['id_user']);
  820. }
  821. }
  822. /* Cleans old user sessions */
  823. public function cron__user_clean_sessions()
  824. {
  825. # $this->oDb->delete( $this->V->db_table_sessions, array( 'mdate <' => @date($this->sdf, $this->V->time_gmt - $this->V->time_sec_w), 'is_remember' => '0' ) );
  826. $this->oDb->delete( $this->V->db_table_sessions, array( 'mdate <' => @date($this->sdf, $this->V->time_gmt - $this->V->time_sec_w) ) );
  827. }
  828. }}
  829. ?>