PageRenderTime 50ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/html/AppCode/expressionengine/libraries/Cp_search.php

https://github.com/w3bg/www.hsifin.com
PHP | 549 lines | 342 code | 80 blank | 127 comment | 39 complexity | 3966a76585ee5742fc43f83013859b23 MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author ExpressionEngine Dev Team
  7. * @copyright Copyright (c) 2003 - 2010, EllisLab, Inc.
  8. * @license http://expressionengine.com/user_guide/license.html
  9. * @link http://expressionengine.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine CP Search Class
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Core
  19. * @category Core
  20. * @author ExpressionEngine Dev Team
  21. * @link http://expressionengine.com
  22. */
  23. class Cp_search {
  24. var $map;
  25. var $_c_cache = array();
  26. /**
  27. * Constructor
  28. *
  29. * @access public
  30. */
  31. function Cp_search()
  32. {
  33. $this->EE =& get_instance();
  34. $this->_search_map();
  35. $this->EE->lang->loadfile('cp_search');
  36. }
  37. // --------------------------------------------------------------------
  38. /**
  39. * Generate Search Results
  40. *
  41. * Grabs the results for the cp search function and loads the
  42. * proper cp variables
  43. *
  44. * @access public
  45. * @param type
  46. * @return void
  47. */
  48. function generate_results($search)
  49. {
  50. $result = array();
  51. $sql = "SELECT *, MATCH(keywords) AGAINST (?) AS relevance
  52. FROM ".$this->EE->db->dbprefix('cp_search_index')."
  53. WHERE MATCH(keywords) AGAINST (?)
  54. ORDER BY relevance DESC";
  55. $query = $this->EE->db->query($sql, array($search, $search));
  56. foreach($query->result() as $row)
  57. {
  58. // Don't show things they cannot use
  59. if ($row->access != 'all' && $this->EE->session->userdata['group_id'] != 1 && $this->EE->session->userdata[$row->access] != 'y')
  60. {
  61. continue;
  62. }
  63. $url = BASE.AMP.'C='.$row->controller.AMP.'M='.$row->method;
  64. $name = $this->_get_description($row->controller, $row->method);
  65. $result[] = array('url' => $url, 'name' => $name);
  66. }
  67. return $result;
  68. }
  69. // --------------------------------------------------------------------
  70. /**
  71. * Get Result Name
  72. *
  73. * Creates a proper language key for a given controller+method
  74. *
  75. * @access private
  76. * @param string
  77. * @return string
  78. */
  79. function _get_description($controller, $method)
  80. {
  81. $options = $this->map[$controller][$method];
  82. if ( ! is_array($options) && substr($options, -4) == '_cfg')
  83. {
  84. return $this->EE->lang->line($options);
  85. }
  86. if (is_array($options))
  87. {
  88. unset($options['access'], $options['keywords']);
  89. $options = array_pop($options);
  90. }
  91. if (substr($options, -4) == '_cfg')
  92. {
  93. return $this->EE->lang->line($options);
  94. }
  95. else
  96. {
  97. $prefix = $controller.'_';
  98. if ($start = strpos($controller, '_'))
  99. {
  100. $prefix = substr($controller, $start + 1, 4).'_';
  101. }
  102. if (strpos($method, $prefix) === 0)
  103. {
  104. return $this->EE->lang->line($method);
  105. }
  106. return $this->EE->lang->line($prefix.$method);
  107. }
  108. }
  109. // --------------------------------------------------------------------
  110. /**
  111. * Checks for an existing index
  112. *
  113. * If no index exists it will return false, redirect to rebuild
  114. *
  115. * @access private
  116. * @return void
  117. */
  118. function _check_index($language = 'english')
  119. {
  120. $this->EE->db->where('language', $language);
  121. $count = $this->EE->db->count_all_results('cp_search_index');
  122. return ($count > 0);
  123. }
  124. // --------------------------------------------------------------------
  125. /**
  126. * Build Index
  127. *
  128. * Builds a controller and method lookup based on relevant
  129. * language keys used by these methods
  130. *
  131. * @access public
  132. * @param type
  133. * @return void
  134. */
  135. function _build_index($language)
  136. {
  137. // PHP 4 redundancy dept. of redundancy
  138. $this->EE =& get_instance();
  139. $this->EE->load->model('admin_model');
  140. $this->EE->lang->loadfile('admin');
  141. $data = array();
  142. $subtext = $this->EE->admin_model->get_config_field_subtext();
  143. foreach($this->map as $controller => $method_map)
  144. {
  145. foreach($method_map as $method => $val)
  146. {
  147. $values = array();
  148. $options = $val;
  149. $access = 'all';
  150. if (is_array($options))
  151. {
  152. if (isset($options['access']))
  153. {
  154. $access = $options['access'];
  155. unset($options['access']);
  156. }
  157. if (isset($options['keywords']))
  158. {
  159. $values[] = $options['keywords'];
  160. unset($options['keywords']);
  161. }
  162. // Flatten! Flatten!
  163. $options = array_pop($options);
  164. }
  165. if (is_array($options))
  166. {
  167. foreach($options as $keyword)
  168. {
  169. $values[] = $keyword;
  170. }
  171. }
  172. elseif (is_string($options) && substr($options, -4) == '_cfg')
  173. {
  174. $config = $this->EE->admin_model->get_config_fields($options);
  175. foreach($config as $lang_key => $whatever)
  176. {
  177. $values[] = $this->EE->lang->line($lang_key);
  178. }
  179. if (isset($subtext[$options]))
  180. {
  181. foreach($subtext[$options] as $lang_keys)
  182. {
  183. foreach($lang_keys as $key)
  184. {
  185. $values[] = $key;
  186. }
  187. }
  188. }
  189. }
  190. else
  191. {
  192. if ($options)
  193. {
  194. $values = array_merge($values, $this->_parse_controller($controller, $method, TRUE));
  195. }
  196. else
  197. {
  198. $values = array_merge($values, $this->_parse_controller($controller, $method));
  199. }
  200. $values[] = $this->_get_description($controller, $method);
  201. }
  202. if ( ! count($values) > 0)
  203. {
  204. continue;
  205. }
  206. $data = array('controller' => $controller,
  207. 'method' => $method,
  208. 'keywords' => implode(' ', $values),
  209. 'access' => $access,
  210. 'language' => $language
  211. );
  212. $this->EE->db->insert('cp_search_index', $data);
  213. }
  214. }
  215. return TRUE;
  216. }
  217. // --------------------------------------------------------------------
  218. /**
  219. * Parse Controller
  220. *
  221. * Walks through a given controller function looking
  222. * for language keys
  223. *
  224. * @access public
  225. * @param type
  226. * @return void
  227. */
  228. function _parse_controller($controller, $method, $process_views = FALSE)
  229. {
  230. $nonsense = array('unauthorized_access', 'none', 'all', 'open', 'closed', 'and_more', 'install', 'uninstall', 'add', 'edit', 'delete');
  231. $map = array();
  232. $lang_files = array();
  233. if ( ! file_exists(APPPATH.'controllers/cp/'.$controller.EXT))
  234. {
  235. return array();
  236. }
  237. // Cache controller info so we don't parse the same file a bajilion times
  238. if ( ! isset($this->_c_cache['name']) OR $this->_c_cache['name'] != $controller)
  239. {
  240. // Grab the file contents
  241. $this->_c_cache['source'] = file_get_contents(APPPATH.'controllers/cp/'.$controller.EXT);
  242. // Initialize arrays
  243. $this->_c_cache['methods'] = array();
  244. $this->_c_cache['lang_files'] = array();
  245. $lang_files[] = current(explode('_', $controller, 2));
  246. // Language files used by this class
  247. if (preg_match_all('#'.preg_quote('$this->lang->loadfile(').'(\042|\047)([^\\1]*?)\\1#', $this->_c_cache['source'], $matches))
  248. {
  249. foreach($matches[2] as $match)
  250. {
  251. $lang_files[] = $match;
  252. }
  253. }
  254. // Methods used by this class
  255. if (preg_match_all('#function\s+(\w+)\(#i', $this->_c_cache['source'], $functions))
  256. {
  257. foreach($functions[0] as $key => $func)
  258. {
  259. $name = $functions[1][$key];
  260. $start = strpos($this->_c_cache['source'], $functions[0][$key]);
  261. $end = isset($functions[0][$key+1]) ? strpos($this->_c_cache['source'], $functions[0][$key+1]) : strlen($this->_c_cache['source']);
  262. $this->_c_cache['methods'][$name] = array($start, $end);
  263. }
  264. }
  265. }
  266. // We're only here for one thing
  267. if ( ! isset($this->_c_cache['methods'][$method]))
  268. {
  269. return array();
  270. }
  271. // Grab the function source
  272. $start = $this->_c_cache['methods'][$method][0];
  273. $end = $this->_c_cache['methods'][$method][1];
  274. $chunk = substr($this->_c_cache['source'], $start, $end - $start);
  275. $views = array();
  276. $langs = array();
  277. // Views loaded by this function
  278. if (preg_match_all('#'.preg_quote('$this->load->view(').'(\042|\047)([^\\1]*?)\\1#', $chunk, $matches))
  279. {
  280. foreach($matches[2] as $match)
  281. {
  282. $views[] = $match;
  283. if ($process_views)
  284. {
  285. $langs = $this->_process_view($match);
  286. }
  287. }
  288. }
  289. else
  290. {
  291. // No views - no output - no point in giving them a link!
  292. return array();
  293. }
  294. // Language keys used by the function
  295. if (preg_match_all('#'.preg_quote('$this->lang->line(').'(\042|\047)([^\\1]*?)\\1#', $chunk, $matches))
  296. {
  297. foreach($matches[2] as $match)
  298. {
  299. // Skip the ridiculously common ones
  300. if (in_array($match, $nonsense))
  301. {
  302. continue;
  303. }
  304. $langs[] = $match;
  305. }
  306. }
  307. $language = 'english';
  308. $lang_files = array_unique($lang_files);
  309. $langs = array_unique($langs);
  310. $values = array();
  311. foreach($lang_files as $langfile)
  312. {
  313. include(APPPATH.'language/'.$language.'/'.$langfile.'_lang'.EXT);
  314. if (isset($lang))
  315. {
  316. foreach($langs as $lang_key)
  317. {
  318. if (isset($lang[$lang_key]))
  319. {
  320. $values[] = $lang[$lang_key];
  321. }
  322. }
  323. }
  324. }
  325. return $values;
  326. }
  327. // --------------------------------------------------------------------
  328. /**
  329. * Process View
  330. *
  331. * Finds language keys in a view
  332. *
  333. * @access public
  334. * @param type
  335. * @return void
  336. */
  337. function _process_view($view)
  338. {
  339. $nonsense = array('unauthorized_access', 'none', 'all', 'open', 'closed', 'and_more', 'install', 'uninstall', 'add', 'edit', 'delete');
  340. $langs = array();
  341. $path = PATH_CP_THEME.$this->EE->config->item('cp_theme').'/'.$view.EXT;
  342. if ( ! file_exists($path))
  343. {
  344. return $langs;
  345. }
  346. $view = str_replace(EXT, '', $view);
  347. $view = file_get_contents($path);
  348. if (preg_match_all('#'.preg_quote('lang(').'(\042|\047)([^\\1]*?)\\1#', $view, $matches))
  349. {
  350. foreach($matches[2] as $match)
  351. {
  352. // Skip the ridiculously common ones
  353. if (in_array($match, $nonsense))
  354. {
  355. continue;
  356. }
  357. $langs[] = $match;
  358. }
  359. }
  360. return $langs;
  361. }
  362. // --------------------------------------------------------------------
  363. function _search_map()
  364. {
  365. // How it works:
  366. // The array contains controllers and method names that are indexed
  367. // by the search function. The value for every method element can
  368. // take on three values:
  369. // 1. something_cfg - uses the language arrays in the admin_model
  370. // 2. custom keywords - a custom array of keywords (not multilingual - use with care)
  371. // 3. TRUE/FALSE - parse called view files for language keys?
  372. // if false, only the function will be searched for lang keys
  373. // Set to false to improve indexing performance, but only do it
  374. // on methods that use lots of language keys or you'll neuter the index
  375. //
  376. // By using a multidimensional array we can add access control:
  377. // array('access' => 'can_access_accessories', <regular options>)
  378. //
  379. // As well as keywords to increase result relevance
  380. // array('keywords' => 'cookies', <regular options>)
  381. //
  382. $this->map = array(
  383. 'admin_system' => array(
  384. 'general_configuration' => array('access' => 'can_access_sys_prefs', 'general_cfg'),
  385. 'output_debugging_preferences' => array('access' => 'can_access_sys_prefs', 'output_cfg'),
  386. 'database_settings' => array('access' => 'can_access_sys_prefs', 'db_cfg'),
  387. 'security_session_preferences' => array('access' => 'can_access_sys_prefs', 'keywords' => 'cookie cookies', 'security_cfg'),
  388. 'throttling_configuration' => array('access' => 'can_access_sys_prefs', 'throttling_cfg'),
  389. 'localization_settings' => array('access' => 'can_access_sys_prefs', 'localization_cfg'),
  390. 'email_configuration' => array('access' => 'can_access_sys_prefs', 'email_cfg'),
  391. 'cookie_settings' => array('access' => 'can_access_sys_prefs', 'keywords' => 'cookies', 'cookie_cfg'),
  392. 'image_resizing_preferences' => array('access' => 'can_access_sys_prefs', 'image_cfg'),
  393. 'captcha_preferences' => array('access' => 'can_access_sys_prefs', 'captcha_cfg'),
  394. 'word_censoring' => array('access' => 'can_access_sys_prefs', 'censoring_cfg'),
  395. 'mailing_list_preferences' => array('access' => 'can_access_sys_prefs', 'mailinglist_cfg'),
  396. 'emoticon_preferences' => array('access' => 'can_access_sys_prefs', 'emoticon_cfg'),
  397. 'tracking_preferences' => array('access' => 'can_access_sys_prefs', 'tracking_cfg'),
  398. 'mailing_list_preferences' => array('access' => 'can_access_sys_prefs', 'mailinglist_cfg'),
  399. 'search_log_configuration' => array('access' => 'can_access_sys_prefs', 'search_log_cfg')
  400. ),
  401. 'admin_content' => array(
  402. 'global_channel_preferences' => array('access' => 'can_admin_channels', 'channel_cfg'),
  403. 'field_group_management' => array('access' => 'can_admin_channels', TRUE),
  404. 'category_management' => array('access' => 'can_admin_categories', TRUE)
  405. ),
  406. 'addons_accessories'=> array(
  407. 'index' => array('access' => 'can_access_accessories', TRUE)
  408. ),
  409. 'addons_extensions' => array(
  410. 'index' => array('access' => 'can_access_extensions', TRUE)
  411. ),
  412. // 'addons_fieldtypes' => array(
  413. // 'index' => array('access' => 'can_access_modules', TRUE)
  414. // ),
  415. 'addons_modules' => array(
  416. 'index' => array('access' => 'can_access_modules', TRUE)
  417. ),
  418. 'addons_plugins' => array(
  419. 'index' => array('access' => 'can_access_plugins', TRUE)
  420. ),
  421. 'content_publish' => array(
  422. 'index' => array('keywords' => 'publish new entry', TRUE)
  423. ),
  424. 'content_files' => array(
  425. 'index' => array('access' => 'can_access_files', TRUE)
  426. ),
  427. 'design' => array(
  428. 'user_message' => array('access' => 'can_admin_design', TRUE),
  429. 'global_template_preferences' => array('access' => 'can_admin_design', 'template_cfg'),
  430. 'system_offline' => array('access' => 'can_admin_design', TRUE),
  431. 'email_notification' => array('access' => 'can_admin_templates', TRUE),
  432. 'member_profile_templates' => array('access' => 'can_admin_mbr_templates', TRUE)
  433. ),
  434. 'members' => array(
  435. 'register_member' => array('access' => 'can_admin_members', TRUE),
  436. 'member_validation' => array('access' => 'can_admin_members', TRUE),
  437. 'view_members' => array('access' => 'can_access_members', TRUE),
  438. 'ip_search' => array('access' => 'can_admin_members', 'keywords' => 'ip IP', TRUE),
  439. 'custom_profile_fields' => array('access' => 'can_admin_members', TRUE),
  440. 'member_group_manager' => array('access' => 'can_admin_mbr_groups', TRUE),
  441. 'member_config' => array('access' => 'can_admin_members', TRUE),
  442. 'member_banning' => array('access' => 'can_ban_users', TRUE),
  443. 'member_search' => TRUE
  444. ),
  445. 'tools_data' => array(
  446. 'sql_manager' => array('access' => 'can_access_data', TRUE),
  447. 'search_and_replace' => array('access' => 'can_access_data', TRUE),
  448. 'recount_stats' => array('access' => 'can_access_data', TRUE),
  449. 'php_info' => array('access' => 'can_access_data', TRUE),
  450. 'clear_caching' => array('access' => 'can_access_data', TRUE)
  451. ),
  452. 'tools_logs' => array(
  453. 'view_cp_log' => array('access' => 'can_access_logs', TRUE),
  454. 'view_throttle_log' => array('access' => 'can_access_logs', TRUE),
  455. 'view_search_log' => array('access' => 'can_access_logs', TRUE),
  456. 'view_email_log' => array('access' => 'can_access_logs', TRUE)
  457. ),
  458. 'tools_utilities' => array(
  459. 'member_import' => array('access' => 'can_access_utilities', TRUE),
  460. 'import_from_mt' => array('access' => 'can_access_utilities', TRUE),
  461. 'import_from_xml' => array('access' => 'can_access_utilities', TRUE),
  462. 'translation_tool' => array('access' => 'can_access_utilities', TRUE)
  463. ),
  464. );
  465. }
  466. }
  467. // END Cp_search class
  468. /* End of file Cp_search.php */
  469. /* Location: ./system/expressionengine/libraries/Cp_search.php */