PageRenderTime 107ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/system/cp/cp.utilities.php

https://github.com/danboy/Croissierd
PHP | 5636 lines | 3811 code | 1272 blank | 553 comment | 490 complexity | 26e0bc0fa448a1550a0a0c14d0e6633d MD5 | raw file
  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010 EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/docs/license.html
  13. =====================================================
  14. File: cp.utilities.php
  15. -----------------------------------------------------
  16. Purpose: Utilities
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class Utilities {
  24. /** -------------------------------------------
  25. /** Extensions Manager
  26. /** -------------------------------------------*/
  27. function extensions_manager($message = '')
  28. {
  29. global $DSP, $IN, $PREFS, $LANG, $DB, $FNS, $EXT;
  30. $debug = TRUE;
  31. $extension_files = array();
  32. $extensions_installed = array();
  33. /** ---------------------------------------
  34. /** Extensions Available
  35. /** ---------------------------------------*/
  36. $i = 0;
  37. if ($fp = @opendir(PATH_EXT))
  38. {
  39. while (false !== ($file = readdir($fp)))
  40. {
  41. if (substr($file, -strlen(EXT)) == EXT && substr($file, 0, 4) == 'ext.')
  42. {
  43. $extension_files[$i] = substr($file, 4, -strlen(EXT));
  44. $i++;
  45. }
  46. }
  47. closedir($fp);
  48. }
  49. /** ---------------------------------------
  50. /** Extensions Enabled
  51. /** ---------------------------------------*/
  52. $query = $DB->query("SELECT class, version FROM exp_extensions WHERE enabled = 'y'");
  53. if ($query->num_rows > 0)
  54. {
  55. foreach($query->result as $row) $extensions_installed[strtolower($row['class'])] = $row['version'];
  56. }
  57. /** ---------------------------------------
  58. /** Create Output
  59. /** ---------------------------------------*/
  60. $DSP->crumbline = FALSE;
  61. if ($PREFS->ini('allow_extensions') == 'y')
  62. {
  63. $DSP->right_crumb($LANG->line('disable_extensions'), BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=toggle_extension_confirm'.AMP.'which=disable');
  64. }
  65. else
  66. {
  67. $DSP->right_crumb($LANG->line('enable_extensions'), BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=toggle_extension_confirm'.AMP.'which=enable');
  68. }
  69. $r = $DSP->qdiv('tableHeading', $LANG->line('extensions_manager'));
  70. if ($message != '')
  71. {
  72. $r .= $DSP->qdiv('success', $message);
  73. }
  74. // List of Extensions Table
  75. $r .= $DSP->table('tableBorder', '0', '0', '100%');
  76. if (count($extension_files) == 0)
  77. {
  78. $r .= $DSP->tr().
  79. $DSP->td('tableCellTwo', '', '2').
  80. '<b>'.$LANG->line('no_extensions_exist').'</b>'.
  81. $DSP->td_c().
  82. $DSP->tr_c();
  83. }
  84. else
  85. {
  86. $r .= $DSP->tr().
  87. $DSP->td('tableHeadingAlt', '55%').
  88. $LANG->line('extension_name').
  89. $DSP->td_c().
  90. $DSP->td('tableHeadingAlt', '15%').
  91. $LANG->line('documentation').
  92. $DSP->td_c().
  93. $DSP->td('tableHeadingAlt', '15%').
  94. $LANG->line('settings').
  95. $DSP->td_c().
  96. $DSP->td('tableHeadingAlt', '15%').
  97. $LANG->line('status').
  98. $DSP->td_c().
  99. $DSP->tr_c();
  100. }
  101. $i = 0;
  102. if (count($extension_files) > 0)
  103. {
  104. $extension_meta = array('description', 'settings_exist', 'docs_url', 'name', 'version');
  105. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  106. foreach ($extension_files as $extension_name)
  107. {
  108. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  109. /** ------------------------------------
  110. /** Load Extension and Fetch Metadata
  111. /** ------------------------------------*/
  112. $meta = array();
  113. $class_name = ucfirst($extension_name);
  114. if ( ! class_exists($class_name))
  115. {
  116. if ($debug === TRUE)
  117. {
  118. include(PATH_EXT.'ext.'.$extension_name.EXT);
  119. }
  120. else
  121. {
  122. @include(PATH_EXT.'ext.'.$extension_name.EXT);
  123. }
  124. if ( ! class_exists($class_name)) continue;
  125. }
  126. $OBJ = new $class_name();
  127. foreach($extension_meta as $meta_item)
  128. {
  129. ${$meta_item} = ( ! isset($OBJ->{$meta_item})) ? '' : $OBJ->{$meta_item};
  130. }
  131. if ($name == '')
  132. {
  133. $name = ucwords(str_replace('_',' ',$extension_name));
  134. }
  135. /** ------------------------------------
  136. /** Different Output depending on current status
  137. /** ------------------------------------*/
  138. if ($PREFS->ini('allow_extensions') == 'y' && isset($extensions_installed[$extension_name]))
  139. {
  140. // Double check that the extension is up to date
  141. // If not, then quickly run the update script to make
  142. // sure that we are up to date before changing any settings
  143. if ($OBJ->version > $EXT->version_numbers[$class_name] && method_exists($OBJ, 'update_extension') === TRUE)
  144. {
  145. $update = $OBJ->update_extension($EXT->version_numbers[$class_name]);
  146. $EXT->version_numbers[$class_name] = $OBJ->version;
  147. }
  148. $installed = $LANG->line('extension_enabled') . ' ('.$DSP->anchor(BASE.AMP.'C=admin'.
  149. AMP.'M=utilities'.
  150. AMP.'P=toggle_extension'.
  151. AMP.'which=disable'.
  152. AMP.'name='.$extension_name,
  153. $LANG->line('disable_extension'),
  154. "onclick='if(!confirm(\"".
  155. $LANG->line('toggle_extension_confirmation').
  156. "\")) return false;'").')';
  157. $link = $DSP->qspan('defaultBold', $name).' (v.'.$version.')';
  158. if ($description != '' && $description != '')
  159. {
  160. $link .= NL.$DSP->br().NL.$description;
  161. }
  162. $settings_link = $DSP->anchor(BASE.AMP.'C=admin'.
  163. AMP.'M=utilities'.
  164. AMP.'P=extension_settings'.
  165. AMP.'name='.$extension_name,
  166. $LANG->line('settings'));
  167. }
  168. else
  169. {
  170. $link = $DSP->qspan('defaultLight', $name.' (v.'.$version.')');
  171. if ($PREFS->ini('allow_extensions') == 'y')
  172. {
  173. $installed = $LANG->line('extension_disabled') . ' ('.$DSP->anchor(BASE.AMP.'C=admin'.
  174. AMP.'M=utilities'.
  175. AMP.'P=toggle_extension'.
  176. AMP.'which=enable'.
  177. AMP.'name='.$extension_name,
  178. $LANG->line('enable_extension'),
  179. "onclick='if(!confirm(\"".
  180. $LANG->line('toggle_extension_confirmation').
  181. "\")) return false;'").')';
  182. }
  183. else
  184. {
  185. $installed = $LANG->line('extension_disabled');
  186. }
  187. $settings_link = $DSP->qspan('defaultLight', $LANG->line('settings'));
  188. }
  189. if ($docs_url != '')
  190. {
  191. $docs_url = $DSP->anchor($FNS->fetch_site_index().$qm.'URL='.urlencode($docs_url), $LANG->line('documentation'), '', TRUE);
  192. }
  193. $r .= $DSP->tr()
  194. . $DSP->table_qcell($style, $link, '55%')
  195. . $DSP->table_qcell($style, ($docs_url == '') ? '--' : $docs_url, '15%')
  196. . $DSP->table_qcell($style, ($settings_exist != 'y') ? '--' : $settings_link, '15%')
  197. . $DSP->table_qcell($style, $installed, '15%')
  198. .$DSP->tr_c();
  199. unset($OBJ);
  200. }
  201. }
  202. $r .= $DSP->table_c();
  203. $DSP->title = $LANG->line('extensions_manager');
  204. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  205. $DSP->crumb_item($LANG->line('extensions_manager'));
  206. $DSP->body = $r;
  207. }
  208. /* END */
  209. /** -------------------------------------------
  210. /** Extension Settings Form
  211. /** -------------------------------------------*/
  212. function extension_settings($message = '')
  213. {
  214. global $DSP, $IN, $PREFS, $LANG, $DB, $FNS, $REGX;
  215. if ($PREFS->ini('allow_extensions') != 'y')
  216. {
  217. return $DSP->no_access_message();
  218. }
  219. if ($IN->GBL('name') === FALSE OR ! preg_match("/^[a-z0-9][\w.-]*$/i",$IN->GBL('name'))) return false;
  220. $class_name = ucfirst($IN->GBL('name'));
  221. $current = array();
  222. /** ---------------------------------------
  223. /** Extensions Enabled
  224. /** ---------------------------------------*/
  225. $query = $DB->query("SELECT settings FROM exp_extensions
  226. WHERE enabled = 'y' AND class = '".$DB->escape_str($class_name)."'
  227. LIMIT 1");
  228. if ($query->num_rows > 0 && $query->row['settings'] != '')
  229. {
  230. $current = $REGX->array_stripslashes(unserialize($query->row['settings']));
  231. }
  232. /** -----------------------------
  233. /** Call Extension File
  234. /** -----------------------------*/
  235. if ( ! class_exists($class_name))
  236. {
  237. @include(PATH_EXT.'ext.'.$IN->GBL('name').EXT);
  238. if ( ! class_exists($class_name)) return false;
  239. }
  240. $OBJ = new $class_name();
  241. foreach(array('description', 'settings_exist', 'docs_url', 'name', 'version') as $meta_item)
  242. {
  243. ${$meta_item} = ( ! isset($OBJ->{$meta_item})) ? '' : $OBJ->{$meta_item};
  244. }
  245. if ($name == '')
  246. {
  247. $name = ucwords(str_replace('_',' ',$extension_name));
  248. }
  249. // -----------------------------------
  250. // Fetch Extension Language file
  251. //
  252. // If there are settings, then there is a language file
  253. // because we need to know all the various variable names in the settings
  254. // form. I was tempted to give these language files a prefix but I
  255. // decided against it for the sake of simplicity and the fact that
  256. // a module might have extension's bundled with them and it would make
  257. // sense to have the same language file for both.
  258. // -----------------------------------
  259. $LANG->fetch_language_file($IN->GBL('name'));
  260. /** ---------------------------------------
  261. /** Creating Their Own Settings Form?
  262. /** ---------------------------------------*/
  263. if (method_exists($OBJ, 'settings_form') === TRUE)
  264. {
  265. return $OBJ->settings_form($current);
  266. }
  267. /** ---------------------------------------
  268. /** Right Crumb Tab
  269. /** ---------------------------------------*/
  270. $DSP->crumbline = TRUE;
  271. $DSP->right_crumb($LANG->line('disable_extension'), BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=toggle_extension_confirm'.AMP.'which=disable'.AMP.'name='.$IN->GBL('name'));
  272. /** -----------------------------
  273. /** Create Page's Content
  274. /** -----------------------------*/
  275. $r = $DSP->table('', '', '', '100%')
  276. .$DSP->tr()
  277. .$DSP->td('default', '', '', '', 'top')
  278. .$DSP->heading($LANG->line('extension_settings'));
  279. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  280. $docs = ($docs_url == '') ? '' : ' ['.$DSP->anchor($FNS->fetch_site_index().$qm.'URL='.urlencode($docs_url), $LANG->line('documentation'), '', TRUE).']';
  281. $r .= $DSP->td_c()
  282. .$DSP->td('default', '', '', '', 'middle')
  283. .$DSP->qdiv('defaultRight', '<strong>'.$docs.'</strong>'.NBS.NBS)
  284. .$DSP->td_c()
  285. .$DSP->tr_c()
  286. .$DSP->tr()
  287. .$DSP->td('default', '100%', '2', '', 'top');
  288. $r .= Utilities::extension_settings_form($name, $IN->GBL('name'), $OBJ->settings(), $current);
  289. $r .= $DSP->td_c()
  290. .$DSP->tr_c()
  291. .$DSP->table_c()
  292. .$DSP->td_c()
  293. .$DSP->tr_c()
  294. .$DSP->table_c();
  295. $DSP->title = $LANG->line('extension_settings');
  296. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  297. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=extensions_manager', $LANG->line('extensions_manager')));
  298. $DSP->crumb .= $DSP->crumb_item($name);
  299. $DSP->body = $r;
  300. }
  301. /* END */
  302. /** -----------------------------
  303. /** Store Extension Settings
  304. /** -----------------------------*/
  305. function save_extension_settings()
  306. {
  307. global $IN, $DB, $FNS;
  308. // Basic security check
  309. if ( ! preg_match("/^[a-z0-9][\w.-]*$/i",$IN->GBL('name'))) return false;
  310. if ( ! class_exists(ucfirst($IN->GBL('name'))))
  311. {
  312. include(PATH_EXT.'ext.'.strtolower($IN->GBL('name')).EXT);
  313. }
  314. // Ok, I admit that we should be able to simply unset the 'name' value
  315. // from the $_POST array and simply insert that into the database.
  316. // I, Paul Burdick of the Sinister House geeks, am slowly becoming
  317. // anal retentive in my young age and decided to make sure only those
  318. // settings specified by the extension are inserted AND that there is
  319. // always an empty string in the really rare chance that one is not
  320. // specified.
  321. if (class_exists(ucfirst($IN->GBL('name'))))
  322. {
  323. $class_name = ucfirst($IN->GBL('name'));
  324. $OBJ = new $class_name();
  325. /** ---------------------------------------
  326. /** Processing Their Own Settings Form?
  327. /** ---------------------------------------*/
  328. if (method_exists($OBJ, 'settings_form') === TRUE)
  329. {
  330. $OBJ->save_settings();
  331. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=extensions_manager');
  332. exit;
  333. }
  334. if (method_exists($OBJ, 'settings') === TRUE)
  335. {
  336. $settings = $OBJ->settings();
  337. }
  338. $insert = array();
  339. foreach($settings as $key => $value)
  340. {
  341. if ( ! is_array($value))
  342. {
  343. $insert[$key] = ($IN->GBL($key, 'POST') !== FALSE) ? $IN->GBL($key, 'POST') : $value;
  344. }
  345. elseif (is_array($value) && isset($value['1']) && is_array($value['1']))
  346. {
  347. if(is_array($IN->GBL($key, 'POST')) OR $value[0] == 'ms')
  348. {
  349. $data = (is_array($IN->GBL($key, 'POST'))) ? $IN->GBL($key, 'POST') : array();
  350. $data = array_intersect($data, array_keys($value['1']));
  351. }
  352. else
  353. {
  354. if ($IN->GBL($key, 'POST') === FALSE)
  355. {
  356. $data = ( ! isset($value['2'])) ? '' : $value['2'];
  357. }
  358. else
  359. {
  360. $data = $IN->GBL($key, 'POST');
  361. }
  362. }
  363. $insert[$key] = $data;
  364. }
  365. else
  366. {
  367. $insert[$key] = ($IN->GBL($key, 'POST') !== FALSE) ? $IN->GBL($key, 'POST') : '';
  368. }
  369. }
  370. $DB->query("UPDATE exp_extensions SET settings = '".addslashes(serialize($insert))."' WHERE class = '".$DB->escape_str($IN->GBL('name'))."'");
  371. }
  372. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=extensions_manager');
  373. exit;
  374. }
  375. /* END */
  376. /** -----------------------------
  377. /** Create Form Automagically
  378. /** -----------------------------*/
  379. function extension_settings_form($extension_name, $name, $fdata, $data)
  380. {
  381. global $DSP, $LANG;
  382. $r = $DSP->form_open(
  383. array(
  384. 'action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=save_extension_settings',
  385. 'name' => 'settings_'.$name,
  386. 'id' => 'settings_'.$name
  387. ),
  388. array('name' => $name)
  389. );
  390. $r .= $DSP->table('tableBorder', '0', '', '100%');
  391. $r .= $DSP->tr();
  392. $r .= $DSP->td('tableHeadingAlt', '', '2');
  393. $r .= $extension_name;
  394. $r .= $DSP->td_c();
  395. $r .= $DSP->tr_c();
  396. $i = 0;
  397. /** -----------------------------
  398. /** Blast through the array
  399. /** -----------------------------*/
  400. foreach ($fdata as $key => $val)
  401. {
  402. $style = ($i % 2) ? 'tableCellOne' : 'tableCellTwo'; $i++;
  403. $default_data = (is_array($val)) ? '' : $val;
  404. $data[$key] = ( ! isset($data[$key])) ? $default_data : $data[$key];
  405. if (!is_array($val) || $val['0'] != 'sf')
  406. {
  407. $r .= $DSP->tr();
  408. // If the form type is a textarea, we'll align the text at the top, otherwise, we'll center it
  409. if (is_array($val) && ($val['0'] == 't' OR $val['0'] == 'ms' OR ($val['0'] == 'c' && sizeof($val['1']) > 1)))
  410. {
  411. $r .= $DSP->td($style, '50%', '', '', 'top');
  412. }
  413. else
  414. {
  415. $r .= $DSP->td($style, '50%', '');
  416. }
  417. /** -----------------------------
  418. /** Preference heading
  419. /** -----------------------------*/
  420. $r .= $DSP->div('defaultBold');
  421. $label = ( ! is_array($val)) ? $key : '';
  422. // Fix for array form variables like cat_id[]
  423. // Such names to do no work well with the
  424. // translation utility sadly.
  425. if (($LANG->line($key) === false || $LANG->line($key) == '') && strpos($key, '[]') !== false)
  426. {
  427. if ($LANG->line(str_replace('[]','',$key)) === FALSE)
  428. {
  429. $r .= '<label for="'.$key.'">'.ucwords(str_replace('_', ' ', $key))."</label>";
  430. }
  431. else
  432. {
  433. $r .= $LANG->line(str_replace('[]','',$key), $label);
  434. }
  435. }
  436. else
  437. {
  438. $r .= $LANG->line($key, $label);
  439. }
  440. $r .= $DSP->div_c();
  441. /** -----------------------------
  442. /** Preference sub-heading
  443. /** -----------------------------*/
  444. $r .= $DSP->td_c();
  445. /** -----------------------------
  446. /** Preference value
  447. /** -----------------------------*/
  448. $r .= $DSP->td($style, '50%', '');
  449. }
  450. if (is_array($val))
  451. {
  452. /** -----------------------------
  453. /** Drop-down menus
  454. /** -----------------------------*/
  455. if ($val['0'] == 's' || $val['0'] == 'ms')
  456. {
  457. $multi = ($val['0'] == 'ms') ? "class='multiselect' size='8' multiple='multiple'" : "class='select'";
  458. $nkey = ($val['0'] == 'ms') ? $key.'[]' : $key;
  459. if (isset($val['2']))
  460. {
  461. $r .= "<select name='{$nkey}' $multi ".$val['2'].">\n";
  462. }
  463. else
  464. {
  465. $r .= "<select name='{$nkey}' $multi >\n";
  466. }
  467. $data[$key] = ($data[$key] == '') ? $val['2'] : $data[$key];
  468. foreach ($val['1'] as $k => $v)
  469. {
  470. if ($val['0'] == 's' || ! is_array($data[$key]))
  471. {
  472. $selected = ($k == $data[$key]) ? 1 : '';
  473. }
  474. elseif(is_array($data[$key]))
  475. {
  476. $selected = (in_array($k,$data[$key])) ? 1 : '';
  477. }
  478. $name = ($LANG->line($v) == false OR $key == 'weblog_id') ? $v : $LANG->line($v);
  479. $r .= $DSP->input_select_option($k, $name, $selected);
  480. }
  481. $r .= $DSP->input_select_footer();
  482. }
  483. elseif ($val['0'] == 'r')
  484. {
  485. /** -----------------------------
  486. /** Radio buttons
  487. /** -----------------------------*/
  488. if ( ! isset($val['2']))
  489. {
  490. $val['2'] = '';
  491. }
  492. $data[$key] = ($data[$key] == '') ? $val['2'] : $data[$key];
  493. foreach ($val['1'] as $k => $v)
  494. {
  495. $selected = ($k == $data[$key]) ? 1 : '';
  496. $r .= $LANG->line($v).$DSP->nbs();
  497. $r .= $DSP->input_radio($key, $k, $selected, ( ! isset($val['3'])) ? '' : $val['3']).$DSP->nbs(3);
  498. }
  499. }
  500. elseif ($val['0'] == 'c')
  501. {
  502. /** -----------------------------
  503. /** Checkboxes
  504. /** -----------------------------*/
  505. if ( ! isset($val['2']))
  506. {
  507. $val['2'] = '';
  508. }
  509. $data[$key] = ($data[$key] == '') ? $val['2'] : $data[$key];
  510. foreach ($val['1'] as $k => $v)
  511. {
  512. $selected = ($k == $data[$key]) ? 1 : '';
  513. if (sizeof($val['1']) == 1)
  514. {
  515. $r .= $DSP->input_checkbox($key, $k, $selected);
  516. }
  517. else
  518. {
  519. $r .= $DSP->qdiv('publishPad', $DSP->input_checkbox($key, $k, $selected).' '.$LANG->line($v));
  520. }
  521. }
  522. }
  523. elseif ($val['0'] == 't')
  524. {
  525. /** -----------------------------
  526. /** Textarea fields
  527. /** -----------------------------*/
  528. // The "kill_pipes" index instructs us to
  529. // turn pipes into newlines
  530. $data[$key] = ($data[$key] == '') ? $val['1'] : $data[$key];
  531. if (isset($val['2']['kill_pipes']) AND $val['2']['kill_pipes'] === TRUE)
  532. {
  533. $text = '';
  534. foreach (explode('|', $data[$key]) as $exp)
  535. {
  536. $text .= $exp.NL;
  537. }
  538. }
  539. else
  540. {
  541. $text = $data[$key];
  542. }
  543. $rows = (isset($val['2']['rows'])) ? $val['2']['rows'] : '15';
  544. $r .= $DSP->input_textarea($key, $text, $rows);
  545. }
  546. elseif ($val['0'] == 'f' || $val['0'] == 'sf')
  547. {
  548. switch($val['1'])
  549. {
  550. case 'new_table' :
  551. $i = 0;
  552. // Close current tables
  553. $r .= $DSP->table_c();
  554. $r .= $DSP->div_c();
  555. // Open new table
  556. $r .= $DSP->div('', '', $key);
  557. $r .= $DSP->table('tableBorder', '0', '', '100%');
  558. $r .= $DSP->tr();
  559. $r .= $DSP->td('tableHeadingAlt', '', '2');
  560. $r .= $LANG->line($val['2']);
  561. $r .= $DSP->td_c();
  562. $r .= $DSP->tr_c();
  563. break;
  564. }
  565. }
  566. }
  567. else
  568. {
  569. /** -----------------------------
  570. /** Text input fields
  571. /** -----------------------------*/
  572. $r .= $DSP->input_text($key, $data[$key], '20', '120', 'input', '100%');
  573. }
  574. $r .= $DSP->td_c();
  575. $r .= $DSP->tr_c();
  576. }
  577. $r .= $DSP->table_c();
  578. $r .= $DSP->div_c();
  579. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit($LANG->line('submit'), 'submit'));
  580. return $r;
  581. }
  582. /* END */
  583. /** -------------------------------------------
  584. /** Plugin Manager
  585. /** -------------------------------------------*/
  586. // Helper function used to sort plugins
  587. function _plugin_title_sorter($a, $b)
  588. {
  589. return strnatcasecmp($a['title'], $b['title']);
  590. }
  591. function plugin_manager($message = '')
  592. {
  593. global $DSP, $IN, $PREFS, $LANG, $FNS;
  594. if ( ! @include_once(PATH_LIB.'pclzip.lib.php'))
  595. {
  596. return $DSP->no_access_message('PclZip Library does not appear to be installed. It is required.');
  597. }
  598. $is_writable = (is_writable(PATH_PI) && $PREFS->ini('demo_date') == FALSE) ? TRUE : FALSE;
  599. $plugins = array();
  600. $info = array();
  601. if ($fp = @opendir(PATH_PI))
  602. {
  603. while (false !== ($file = readdir($fp)))
  604. {
  605. if ( preg_match("/^pi\.[a-z\_0-9]+?".preg_quote(EXT, '/')."$/", $file))
  606. {
  607. if ( ! @include_once(PATH_PI.$file))
  608. {
  609. continue;
  610. }
  611. $name = str_replace('pi.', '', $file);
  612. $name = str_replace(EXT, '', $name);
  613. $plugins[] = $name;
  614. $info[$name] = $plugin_info;
  615. }
  616. }
  617. closedir($fp);
  618. }
  619. if ( in_array('magpie', $plugins) && $PREFS->ini('demo_date') == FALSE)
  620. $r = '<div style="float: left; width: 69%; margin-right: 2%;">';
  621. else
  622. $r = '<div style="float: left; width: 100%;">';
  623. if ($is_writable)
  624. {
  625. $r .= $DSP->form_open(
  626. array(
  627. 'action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_remove_conf',
  628. 'name' => 'target',
  629. 'id' => 'target'
  630. )
  631. );
  632. $r .= $DSP->toggle();
  633. }
  634. if ($message != '')
  635. {
  636. $r .= $DSP->qdiv('itemWrapper', $DSP->qdiv('highlight', $message));
  637. }
  638. $r .= $DSP->table('tableBorder', '0', '10', '100%').
  639. $DSP->tr().
  640. $DSP->td('tableHeading', ($is_writable) ? '97%' : '100%', '').
  641. count($plugins).' '.$LANG->line('plugin_installed').
  642. $DSP->td_c();
  643. if ($is_writable)
  644. {
  645. $r .= $DSP->td('tableHeading', '3%', '').
  646. $DSP->input_checkbox('toggleflag', '', '', "onclick=\"toggle(this);\"").
  647. $DSP->td_c();
  648. }
  649. $r .= $DSP->tr_c();
  650. if (count($plugins) == 0)
  651. {
  652. $r .= $DSP->tr().
  653. $DSP->td('tableCellTwo', '', '2').
  654. '<b>'.$LANG->line('no_plugins_exist').'</b>'.
  655. $DSP->td_c().
  656. $DSP->tr_c();
  657. }
  658. $i = 0;
  659. if (count($plugins) > 0)
  660. {
  661. foreach ($plugins as $plugin)
  662. {
  663. $version = '(v.'.trim($info[$plugin]['pi_version']).')';
  664. $update = '';
  665. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  666. $name = $DSP->qspan('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_info'.AMP.'name='.$plugin, $info[$plugin]['pi_name']));
  667. $description = $info[$plugin]['pi_description'];
  668. $r .= $DSP->tr();
  669. $r .= $DSP->table_qcell($style, $name.' '.$version.' '.$update.$DSP->br().$description, ($is_writable) ? '85%' : '100%');
  670. if ($is_writable)
  671. {
  672. $r .= $DSP->table_qcell($style, $DSP->input_checkbox('toggle[]', $plugin), '15%');
  673. }
  674. $r .= $DSP->tr_c();
  675. }
  676. }
  677. $r .= $DSP->table_c();
  678. if ($is_writable)
  679. {
  680. $r .= $DSP->div('itemWrapper', 'right')
  681. .$DSP->input_submit($LANG->line('plugin_remove'))
  682. .$DSP->div_c()
  683. .$DSP->form_close();
  684. }
  685. $r .= $DSP->div_c();
  686. /** -------------------------------------------
  687. /** Latest Plugin Table
  688. /** -------------------------------------------*/
  689. // Do we have the Magpie plugin so we can parse the EE plugin RSS feed?
  690. if (in_array('magpie', $plugins) && $PREFS->ini('demo_date') == FALSE)
  691. {
  692. $request = 'http://expressionengine.com/feeds/pluginlist/';
  693. $target = parse_url($request);
  694. $fp = @fsockopen($target['host'], 80, $errno, $errstr, 15);
  695. $code = '';
  696. if (is_resource($fp))
  697. {
  698. fputs ($fp,"GET " . $request . " HTTP/1.0\r\n" );
  699. fputs ($fp,"Host: " . $target['host'] . "\r\n" );
  700. fputs ($fp,"User-Agent: EE/EllisLab PHP/" . phpversion() . "\r\n\r\n");
  701. $getting_headers = true;
  702. while ( ! feof($fp))
  703. {
  704. $line = fgets($fp, 4096);
  705. if ($getting_headers == false)
  706. {
  707. $code .= $line;
  708. }
  709. elseif (trim($line) == '')
  710. {
  711. $getting_headers = false;
  712. }
  713. }
  714. @fclose($fp);
  715. }
  716. $plugins = new MagpieRSS($code);
  717. $i = 0;
  718. if (count($plugins->items) > 0)
  719. {
  720. // Example pagination: &perpage=10&page=10&sortby=alpha
  721. $paginate = '';
  722. $extra = ''; // Will hold sort method
  723. $total_rows = count($plugins->items);
  724. $perpage = ( ! $IN->GBL('perpage')) ? 10 : $IN->GBL('perpage');
  725. $page = ( ! $IN->GBL('page')) ? 0 : $IN->GBL('page');
  726. $sortby = ( ! $IN->GBL('sortby')) ? '' : $IN->GBL('sortby');
  727. $base = BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_manager';
  728. if ($sortby == 'alpha')
  729. {
  730. usort($plugins->items, array('Utilities', '_plugin_title_sorter'));
  731. $extra = AMP.'sortby=alpha';
  732. $link = $DSP->anchor($base, $LANG->line('plugin_by_date'));
  733. $title = $LANG->line('plugins').$DSP->qspan('defaultSmall', $LANG->line('plugin_by_letter').' : '.$link);
  734. }
  735. else
  736. {
  737. $link = $DSP->anchor($base.AMP.'sortby=alpha', $LANG->line('plugin_by_letter'));
  738. $title = $LANG->line('plugins').$DSP->qspan('defaultSmall', $LANG->line('plugin_by_date').' : '.$link);
  739. }
  740. $ten_plugins = array_slice($plugins->items, $page, $perpage-1);
  741. // Latest Plugins Table
  742. $r .= '<div style="float: left; width: 29%; clear: right;">';
  743. $r .= $DSP->table('tableBorder', '0', '10', '100%').
  744. $DSP->tr().
  745. $DSP->td('tableHeadingAlt', '', '').
  746. $title.
  747. $DSP->td_c().
  748. $DSP->tr_c();
  749. $curl_installed = ( ! extension_loaded('curl') || ! function_exists('curl_init')) ? FALSE : TRUE;
  750. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  751. foreach ($ten_plugins as $item)
  752. {
  753. $attr = explode('|', $item['dc']['subject']);
  754. $dl = $attr[0];
  755. $version = '(v.'.$attr[1].')';
  756. $require = ( ! $attr[2] ) ? '' : $DSP->br().$DSP->qspan('highlight', $LANG->line('plugin_requires').': '.$attr[2]);
  757. $name = $DSP->qspan('defaultBold', $DSP->anchor($FNS->fetch_site_index().$qm.'URL='.$item['link'], $item['title']));
  758. $description = $FNS->word_limiter($item['description'], '20');
  759. $install = ( ! class_exists('PclZip') || ! $is_writable || ! $curl_installed) ? '' : $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_install'.AMP.'file='.$dl, '<span style=\'color:#009933;\'>'.$LANG->line('plugin_install').'</span>');
  760. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  761. $r .= $DSP->tr();
  762. $r .= $DSP->table_qcell($style, $name.' '.$version.$DSP->nbs().$require.$DSP->qdiv('itemWrapper', $description).$install, '60%');
  763. $r .= $DSP->tr_c();
  764. }
  765. $r .= $DSP->table_c();
  766. if ($total_rows > $perpage)
  767. {
  768. $paginate = $DSP->pager( BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_manager'.$extra.AMP.'perpage='.$perpage,
  769. $total_rows,
  770. $perpage,
  771. $page,
  772. 'page'
  773. );
  774. }
  775. $r .= $DSP->qdiv('itemWrapper', $paginate.BR.BR);
  776. $r .= $DSP->div_c();
  777. }
  778. }
  779. $DSP->title = $LANG->line('plugin_manager');
  780. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  781. $DSP->crumb_item($LANG->line('plugin_manager'));
  782. $DSP->body = $r;
  783. }
  784. /* END */
  785. /** -------------------------------------------
  786. /** Plugin Info
  787. /** -------------------------------------------*/
  788. function plugin_info()
  789. {
  790. global $IN, $DSP, $LANG, $FNS, $PREFS;
  791. // Basic security check
  792. if ( ! preg_match("/^[a-z0-9][\w.-]*$/i",$IN->GBL('name'))) return false;
  793. $name = $IN->GBL('name');
  794. if ( ! @include(PATH_PI.'pi.'.$name.EXT))
  795. {
  796. return $DSP->error_message('Unable to load the following plugin: '.$name.EXT);
  797. }
  798. $qm = ($PREFS->ini('force_query_string') == 'y') ? '' : '?';
  799. $DSP->title = ucwords(str_replace("_", " ", $name));
  800. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  801. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_manager', $LANG->line('plugin_manager'))).
  802. $DSP->crumb_item(ucwords(str_replace("_", " ", $name)));
  803. $i = 0;
  804. $r = $DSP->table('tableBorder', '0', '10', '100%').
  805. $DSP->tr().
  806. $DSP->td('tableHeading', '', '2').
  807. $LANG->line('plugin_information').
  808. $DSP->td_c().
  809. $DSP->tr_c();
  810. if ( ! isset($plugin_info) OR ! is_array($plugin_info))
  811. {
  812. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  813. $name = ucwords(str_replace("_", " ", $name));
  814. $r .= $DSP->tr();
  815. $r .= $DSP->table_qcell($style, $DSP->qspan('defaultBold', $LANG->line('pi_name')), '30%');
  816. $r .= $DSP->table_qcell($style, $DSP->qspan('defaultBold', $name), '70%');
  817. $r .= $DSP->tr_c();
  818. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  819. $r .= $DSP->tr();
  820. $r .= $DSP->td($style, '', '2').$DSP->qspan('default', $LANG->line('no_additional_info'));
  821. $r .= $DSP->td_c();
  822. $r .= $DSP->tr_c();
  823. }
  824. else
  825. {
  826. foreach ($plugin_info as $key => $val)
  827. {
  828. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  829. $item = ($LANG->line($key) != FALSE) ? $LANG->line($key) : ucwords(str_replace("_", " ", $key));
  830. if ($key == 'pi_author_url')
  831. {
  832. if (substr($val, 0, 4) != "http")
  833. $val = "http://".$val;
  834. $val = $DSP->anchor($FNS->fetch_site_index().$qm.'URL='.$val, $val, '', 1);
  835. }
  836. if ($key == 'pi_usage')
  837. $val = nl2br(htmlspecialchars($val));
  838. $r .= $DSP->tr();
  839. $r .= $DSP->table_qcell($style, $DSP->qspan('defaultBold', $item), '30%', 'top');
  840. $r .= $DSP->table_qcell($style, $DSP->qspan('default', $val), '70%');
  841. $r .= $DSP->tr_c();
  842. }
  843. }
  844. $r .= $DSP->table_c();
  845. $DSP->body = $r;
  846. }
  847. /* END */
  848. /** -------------------------------------------
  849. /** Plugin Extraction from ZIP file
  850. /** -------------------------------------------*/
  851. function plugin_install()
  852. {
  853. global $IN, $DSP, $LANG, $PREFS;
  854. if ($PREFS->ini('demo_date') != FALSE)
  855. {
  856. return $DSP->no_access_message();
  857. }
  858. if ( ! @include_once(PATH_LIB.'pclzip.lib.php'))
  859. {
  860. return $DSP->error_message($LANG->line('plugin_zlib_missing'));
  861. }
  862. if ( ! is_writable(PATH_PI))
  863. {
  864. return $DSP->error_message($LANG->line('plugin_folder_not_writable'));
  865. }
  866. if ( ! extension_loaded('curl') || ! function_exists('curl_init'))
  867. {
  868. return $DSP->error_message($LANG->line('plugin_no_curl_support'));
  869. }
  870. $file = $IN->GBL('file');
  871. $local_name = basename($file);
  872. $local_file = PATH_PI.$local_name;
  873. // Get the remote file
  874. $c = curl_init($file);
  875. curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
  876. // prevent a PHP warning on certain servers
  877. if (! ini_get('safe_mode') && ! ini_get('open_basedir'))
  878. {
  879. curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
  880. }
  881. $code = curl_exec($c);
  882. curl_close($c);
  883. $file_info = pathinfo($local_file);
  884. if ($file_info['extension'] == 'txt' ) // Get rid of any notes/headers in the TXT file
  885. {
  886. $code = strstr($code, '<?php');
  887. }
  888. if ( ! $fp = fopen($local_file, 'wb'))
  889. {
  890. return $DSP->error_message($LANG->line('plugin_problem_creating_file'));
  891. }
  892. flock($fp, LOCK_EX);
  893. fwrite($fp, $code);
  894. flock($fp, LOCK_UN);
  895. fclose($fp);
  896. @chmod($local_file, 0777);
  897. // Check file information so we know what to do with it
  898. if ($file_info['extension'] == 'txt' ) // We've got a TXT file!
  899. {
  900. $new_file = basename($local_file, '.txt');
  901. if ( ! rename($local_file, PATH_PI.$new_file))
  902. {
  903. $message = $LANG->line('plugin_install_other');
  904. }
  905. else
  906. {
  907. @chmod($new_file, 0777);
  908. $message = $LANG->line('plugin_install_success');
  909. }
  910. }
  911. else if ($file_info['extension'] == 'zip' ) // We've got a ZIP file!
  912. {
  913. // Unzip and install plugin
  914. if (class_exists('PclZip'))
  915. {
  916. $zip = new PclZip($local_file);
  917. chdir(PATH_PI);
  918. $ok = @$zip->extract('');
  919. if ($ok)
  920. {
  921. $message = $LANG->line('plugin_install_success');
  922. unlink($local_file);
  923. }
  924. else
  925. {
  926. $message = $LANG->line('plugin_error_uncompress');
  927. }
  928. chdir(PATH);
  929. }
  930. else
  931. {
  932. $message = $LANG->line('plugin_error_no_zlib');
  933. }
  934. }
  935. else
  936. {
  937. $message = $LANG->line('plugin_install_other');
  938. }
  939. return Utilities::plugin_manager($message);
  940. }
  941. /* END */
  942. /** -------------------------------------------
  943. /** Plugin Removal Confirmation
  944. /** -------------------------------------------*/
  945. function plugin_remove_confirm()
  946. {
  947. global $IN, $DSP, $LANG, $PREFS;
  948. if ($PREFS->ini('demo_date') != FALSE)
  949. {
  950. return $DSP->no_access_message();
  951. }
  952. $r = $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_remove'));
  953. $i = 0;
  954. foreach ($_POST as $key => $val)
  955. {
  956. if (strstr($key, 'toggle') AND ! is_array($val))
  957. {
  958. $r .= $DSP->input_hidden('deleted[]', $val);
  959. $i++;
  960. }
  961. }
  962. $message = ($i == 1) ? 'plugin_single_confirm' : 'plugin_multiple_confirm';
  963. $r .= $DSP->qdiv('alertHeading', $LANG->line('plugin_delete_confirm'))
  964. .$DSP->div('box')
  965. .$DSP->qdiv('itemWrapper', '<b>'.$LANG->line($message).'</b>');
  966. $r .= $DSP->qdiv('itemWrapper', $DSP->qdiv('alert', $LANG->line('action_can_not_be_undone')))
  967. .$DSP->qdiv('itemWrapper', BR.$DSP->input_submit($LANG->line('deinstall')).BR)
  968. .$DSP->div_c()
  969. .$DSP->form_close();
  970. $DSP->title = $LANG->line('plugin_delete_confirm');
  971. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  972. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_manager', $LANG->line('plugin_manager'))).
  973. $DSP->crumb_item($LANG->line('plugin_delete_confirm'));
  974. $DSP->body = $r;
  975. }
  976. /** -------------------------------------------
  977. /** Plugin Removal
  978. /** -------------------------------------------*/
  979. function plugin_remove()
  980. {
  981. global $IN, $DSP, $LANG, $PREFS;
  982. if ($PREFS->ini('demo_date') != FALSE)
  983. {
  984. return $DSP->no_access_message();
  985. }
  986. $deleted = $IN->GBL('deleted');
  987. $message = '';
  988. $style = '';
  989. $i = 0;
  990. $DSP->title = $LANG->line('plugin_removal');
  991. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  992. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=plugin_manager', $LANG->line('plugin_manager'))).
  993. $DSP->crumb_item($LANG->line('plugin_removal'));
  994. $r = $DSP->table('tableBorder', '0', '10', '100%').
  995. $DSP->tr().
  996. $DSP->td('tableHeading', '', '').
  997. $LANG->line('plugin_removal_status').
  998. $DSP->td_c().
  999. $DSP->tr_c();
  1000. foreach ( $deleted as $name )
  1001. {
  1002. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  1003. if (unlink(PATH_PI.'pi.'.$name.'.php'))
  1004. $message = $LANG->line('plugin_removal_success').' '.ucwords(str_replace("_", " ", $name));
  1005. else
  1006. $message = $LANG->line('plugin_removal_error').' '.ucwords(str_replace("_", " ", $name)).'.';
  1007. $r .= $DSP->tr();
  1008. $r .= $DSP->table_qcell($style, $DSP->qdiv('itemWrapper', $DSP->qdiv('highlight', $message)), '100%');
  1009. $r .= $DSP->tr_c();
  1010. }
  1011. $r .= $DSP->table_c();
  1012. $DSP->body = $r;
  1013. }
  1014. /* END */
  1015. /** -------------------------------------------
  1016. /** Disable Extensions Confirmation
  1017. /** -------------------------------------------*/
  1018. function toggle_extension_confirm()
  1019. {
  1020. global $IN, $DSP, $LANG;
  1021. // Basic security check
  1022. if ($IN->GBL('name') !== FALSE && ! preg_match("/^[a-z0-9][\w.-]*$/i",$IN->GBL('name'))) return false;
  1023. $r = $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=toggle_extension'));
  1024. if ($IN->GBL('which') == 'enable')
  1025. {
  1026. $message = ($IN->GBL('name') !== FALSE) ? 'enable_extension_conf' : 'enable_extensions_conf';
  1027. $r .= $DSP->input_hidden('which', 'enable');
  1028. }
  1029. else
  1030. {
  1031. $message = ($IN->GBL('name') !== FALSE) ? 'disable_extension_conf' : 'disable_extensions_conf';
  1032. $r .= $DSP->input_hidden('which', 'disable');
  1033. }
  1034. $r .= $DSP->input_hidden('name', ($IN->GBL('name') !== FALSE) ? $IN->GBL('name') : '');
  1035. $r .= $DSP->qdiv('alertHeading', $LANG->line($message))
  1036. .$DSP->div('box')
  1037. .$DSP->qdiv('itemWrapper', '<b>'.$LANG->line('toggle_extension_confirmation').'</b>');
  1038. $r .= $DSP->qdiv('itemWrapper', BR.$DSP->input_submit($LANG->line('submit')).BR)
  1039. .$DSP->div_c()
  1040. .$DSP->form_close();
  1041. $DSP->title = $LANG->line('extensions_manager');
  1042. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  1043. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=extensions_manager', $LANG->line('extensions_manager'))).
  1044. $DSP->crumb_item($LANG->line($message));
  1045. $DSP->body = $r;
  1046. }
  1047. /** -------------------------------------------
  1048. /** Toggle Extension/s
  1049. /** -------------------------------------------*/
  1050. function toggle_extension()
  1051. {
  1052. global $IN, $FNS, $DB, $PREFS;
  1053. $message = '';
  1054. if ($IN->GBL('name') !== FALSE && $IN->GBL('name') != '')
  1055. {
  1056. // Basic security check
  1057. if ( ! preg_match("/^[a-z0-9][\w.-]*$/i",$IN->GBL('name'))) return false;
  1058. // Disable/Enable Single Extension
  1059. if ($IN->GBL('which') == 'enable')
  1060. {
  1061. // Check if the Extension is already installed and just disabled
  1062. // If so we just turn it back on. If not, we have to activate
  1063. // the extension. We have the enabled field so that if someone
  1064. // disables a parameter we can still have the extension's settings
  1065. // in the database and not lost to the ether.
  1066. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_extensions WHERE class = '".$DB->escape_str(ucfirst($IN->GBL('name')))."'");
  1067. if ($query->row['count'] == 0)
  1068. {
  1069. if ( ! class_exists(ucfirst($IN->GBL('name'))))
  1070. {
  1071. include(PATH_EXT.'ext.'.$IN->GBL('name').EXT);
  1072. }
  1073. if (class_exists(ucfirst($IN->GBL('name'))))
  1074. {
  1075. $class_name = ucfirst($IN->GBL('name'));
  1076. $OBJ = new $class_name();
  1077. if (method_exists($OBJ, 'activate_extension') === TRUE)
  1078. {
  1079. $activate = $OBJ->activate_extension();
  1080. }
  1081. }
  1082. }
  1083. else
  1084. {
  1085. $DB->query("UPDATE exp_extensions SET enabled = 'y' WHERE class = '".$DB->escape_str(ucfirst($IN->GBL('name')))."'");
  1086. }
  1087. }
  1088. else
  1089. {
  1090. $DB->query("UPDATE exp_extensions SET enabled = 'n' WHERE class = '".$DB->escape_str(ucfirst($IN->GBL('name')))."'");
  1091. if ( ! class_exists(ucfirst($IN->GBL('name'))))
  1092. {
  1093. include(PATH_EXT.'ext.'.$IN->GBL('name').EXT);
  1094. }
  1095. if (class_exists(ucfirst($IN->GBL('name'))))
  1096. {
  1097. $class_name = ucfirst($IN->GBL('name'));
  1098. $OBJ = new $class_name();
  1099. if (method_exists($OBJ, 'disable_extension') === TRUE)
  1100. {
  1101. $disable = $OBJ->disable_extension();
  1102. }
  1103. }
  1104. }
  1105. }
  1106. else
  1107. {
  1108. // Disable/Enable All Extensions
  1109. if ($IN->GBL('which') == 'enable')
  1110. {
  1111. Admin::update_config_file(array('allow_extensions' => "y"));
  1112. }
  1113. else
  1114. {
  1115. Admin::update_config_file(array('allow_extensions' => "n"));
  1116. }
  1117. }
  1118. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=extensions_manager');
  1119. exit;
  1120. }
  1121. /* END */
  1122. /** -------------------------------------------
  1123. /** SQL Manager
  1124. /** -------------------------------------------*/
  1125. function sql_info()
  1126. {
  1127. global $DB, $DSP, $PREFS, $LOC, $LANG;
  1128. $i = 0;
  1129. $style_one = 'tableCellOne';
  1130. $style_two = 'tableCellTwo';
  1131. $query = $DB->query("SELECT version() AS ver");
  1132. $DSP->title = $LANG->line('utilities');
  1133. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  1134. $DSP->crumb_item($LANG->line('sql_manager'));
  1135. $DSP->body = $DSP->qdiv('tableHeading', $LANG->line('sql_manager'));
  1136. /** -----------------------------
  1137. /** Table Header
  1138. /** -----------------------------*/
  1139. $DSP->body .= $DSP->table('tableBorder', '0', '0', '100%').
  1140. $DSP->tr().
  1141. $DSP->table_qcell('tableHeadingAlt',
  1142. array(
  1143. $LANG->line('sql_info'),
  1144. $LANG->line('value')
  1145. )
  1146. ).
  1147. $DSP->tr_c();
  1148. /** -------------------------------------------
  1149. /** Database Type
  1150. /** -------------------------------------------*/
  1151. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1152. array(
  1153. $DSP->qspan('defaultBold', $LANG->line('database_type')),
  1154. $PREFS->ini('db_type')
  1155. )
  1156. );
  1157. /** -------------------------------------------
  1158. /** SQL Version
  1159. /** -------------------------------------------*/
  1160. $query = $DB->query("SELECT version() AS ver");
  1161. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1162. array(
  1163. $DSP->qspan('defaultBold', $LANG->line('sql_version')),
  1164. $query->row['ver']
  1165. )
  1166. );
  1167. $DB->fetch_fields = TRUE;
  1168. $query = $DB->query("SHOW TABLE STATUS FROM `".$PREFS->ini('db_name')."`");
  1169. $totsize = 0;
  1170. $records = 0;
  1171. $prelen = strlen($DB->prefix);
  1172. foreach ($query->result as $val)
  1173. {
  1174. if (strncmp($val['Name'], $DB->prefix, $prelen) != 0)
  1175. {
  1176. continue;
  1177. }
  1178. $totsize += ($val['Data_length'] + $val['Index_length']);
  1179. $records += $val['Rows'];
  1180. }
  1181. /** -------------------------------------------
  1182. /** Database Records
  1183. /** -------------------------------------------*/
  1184. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1185. array(
  1186. $DSP->qspan('defaultBold', $LANG->line('records')),
  1187. $records
  1188. )
  1189. );
  1190. /** -------------------------------------------
  1191. /** Database Size
  1192. /** -------------------------------------------*/
  1193. $size = Utilities::byte_format($totsize);
  1194. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1195. array(
  1196. $DSP->qspan('defaultBold', $LANG->line('database_size')),
  1197. $size['0'].' '.$size['1']
  1198. )
  1199. );
  1200. /** -------------------------------------------
  1201. /** Database Uptime
  1202. /** -------------------------------------------*/
  1203. $query = $DB->query("SHOW STATUS");
  1204. $uptime = '';
  1205. $queries = '';
  1206. foreach ($query->result as $key => $val)
  1207. {
  1208. foreach ($val as $v)
  1209. {
  1210. if (preg_match("#^uptime#i", $v))
  1211. {
  1212. $uptime = $key;
  1213. }
  1214. if (preg_match("#^questions#i", $v))
  1215. {
  1216. $queries = $key;
  1217. }
  1218. }
  1219. }
  1220. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1221. array(
  1222. $DSP->qspan('defaultBold', $LANG->line('database_uptime')),
  1223. $LOC->format_timespan($query->result[$uptime]['Value'])
  1224. )
  1225. );
  1226. /** -------------------------------------------
  1227. /** Total Server Queries
  1228. /** -------------------------------------------*/
  1229. /*
  1230. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1231. array(
  1232. $DSP->qspan('defaultBold', $LANG->line('total_queries')),
  1233. number_format($query->result[$queries]['Value'])
  1234. )
  1235. );
  1236. */
  1237. $DSP->body .= $DSP->table_c();
  1238. /** -------------------------------------------
  1239. /** SQL Utilities
  1240. /** -------------------------------------------*/
  1241. $DSP->body .= $DSP->table('tableBorder', '0', '0', '100%').
  1242. $DSP->tr().
  1243. $DSP->table_qcell('tableHeading',
  1244. array(
  1245. $LANG->line('sql_utilities'),
  1246. )
  1247. ).
  1248. $DSP->tr_c();
  1249. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1250. array(
  1251. $DSP->qspan('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=view_database', $LANG->line('view_database')))
  1252. )
  1253. );
  1254. /*
  1255. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1256. array(
  1257. $DSP->qspan('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_backup', $LANG->line('sql_backup')))
  1258. )
  1259. );
  1260. */
  1261. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1262. array(
  1263. $DSP->qspan('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_query', $LANG->line('sql_query')))
  1264. )
  1265. );
  1266. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1267. array(
  1268. $DSP->qspan('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_status', $LANG->line('sql_status')))
  1269. )
  1270. );
  1271. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1272. array(
  1273. $DSP->qspan('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_sysvars', $LANG->line('sql_system_vars')))
  1274. )
  1275. );
  1276. $DSP->body .= $DSP->table_qrow( ($i++ % 2) ? $style_one : $style_two,
  1277. array(
  1278. $DSP->qspan('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_plist', $LANG->line('sql_processlist')))
  1279. )
  1280. );
  1281. $DSP->body .= $DSP->table_c();
  1282. }
  1283. /* END */
  1284. /** -------------------------------------------
  1285. /** SQL Manager
  1286. /** -------------------------------------------*/
  1287. function sql_manager($process = '', $return = FALSE)
  1288. {
  1289. global $DSP, $IN, $DB, $REGX, $SESS, $LANG, $PREFS;
  1290. if ( ! $DSP->allowed_group('can_admin_utilities'))
  1291. {
  1292. return $DSP->no_access_message();
  1293. }
  1294. // We use this conditional only for demo installs.
  1295. // It prevents users from using the SQL manager
  1296. if ($PREFS->ini('demo_date') != FALSE)
  1297. {
  1298. return $DSP->no_access_message();
  1299. }
  1300. $run_query = FALSE;
  1301. $row_limit = 100;
  1302. $paginate = '';
  1303. // Set the "fetch fields" flag to true so that
  1304. // the Query function will return the field names
  1305. $DB->fetch_fields = TRUE;
  1306. $crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities'));
  1307. switch($process)
  1308. {
  1309. case 'plist' :
  1310. $sql = "SHOW PROCESSLIST";
  1311. $query = $DB->query($sql);
  1312. $title = $LANG->line('sql_processlist');
  1313. $crumb .= $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager')));
  1314. $crumb .= $DSP->crumb_item($LANG->line('sql_processlist'));
  1315. break;
  1316. case 'sysvars' :
  1317. $sql = "SHOW VARIABLES";
  1318. $query = $DB->query($sql);
  1319. $title = $LANG->line('sql_system_vars');
  1320. $crumb .= $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager')));
  1321. $crumb .= $DSP->crumb_item($LANG->line('sql_system_vars'));
  1322. break;
  1323. case 'status' :
  1324. $sql = "SHOW STATUS";
  1325. $query = $DB->query($sql);
  1326. $title = $LANG->line('sql_status');
  1327. $crumb .= $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager')));
  1328. $crumb .= $DSP->crumb_item($LANG->line('sql_status'));
  1329. break;
  1330. case 'run_query' :
  1331. $DB->debug = ($IN->GBL('debug', 'POST') !== FALSE) ? TRUE : FALSE;
  1332. $run_query = TRUE;
  1333. $title = $LANG->line('query_result');
  1334. $crumb .= $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager')));
  1335. $crumb .= $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_query', $LANG->line('sql_query')));
  1336. $crumb .= $DSP->crumb_item($LANG->line('query_result'));
  1337. break;
  1338. default : return;
  1339. break;
  1340. }
  1341. // Fetch the query. It can either come from a
  1342. // POST request or a url encoded GET request
  1343. if ($run_query == TRUE)
  1344. {
  1345. if ( ! $sql = stripslashes($IN->GBL('thequery', 'POST')))
  1346. {
  1347. if ( ! $sql = $IN->GBL('thequery', 'GET'))
  1348. {
  1349. return Utilities::sql_query_form();
  1350. }
  1351. else
  1352. {
  1353. $sql = base64_decode($sql);
  1354. }
  1355. }
  1356. $sql = trim(str_replace(";", "", $sql));
  1357. // Determine if the query is one of the non-allowed types
  1358. $qtypes = array('FLUSH', 'REPLACE', 'GRANT', 'REVOKE', 'LOCK', 'UNLOCK');
  1359. foreach ($qtypes as $type)
  1360. {
  1361. if (preg_match("/(^|\s)".$type."\s/si", $sql))
  1362. {
  1363. return $DSP->error_message($LANG->line('sql_not_allowed'));
  1364. }
  1365. }
  1366. // If it's a DELETE query, require that a Super Admin be the one submitting it
  1367. if (preg_match("#^(DELETE|ALTER|DROP)#i", trim($sql)))
  1368. {
  1369. if ($SESS->userdata['group_id'] != '1')
  1370. {
  1371. return $DSP->no_access_message();
  1372. }
  1373. }
  1374. // If it's a SELECT query we'll see if we need to limit
  1375. // the result total and add pagination links
  1376. if (stristr($sql, 'SELECT'))
  1377. {
  1378. if ( ! preg_match("/LIMIT\s+[0-9]/i", $sql))
  1379. {
  1380. // Modify the query so we get the total sans LIMIT
  1381. $row = ( ! $IN->GBL('ROW')) ? 0 : $IN->GBL('ROW');
  1382. $new_sql = $sql." LIMIT ".$row.", ".$row_limit;
  1383. // Have to handle this differently for MySQL < 4
  1384. if (version_compare(mysql_get_server_info(), '4.0-alpha', '<'))
  1385. {
  1386. $temp_sql = preg_replace("/^(\s*SELECT).+?(FROM .+?)/s", "\\1 count(*) AS count \\2", $sql);
  1387. if ( ! $result = $DB->query($temp_sql))
  1388. {
  1389. return $DSP->set_return_data( $title,
  1390. $DSP->heading($title).
  1391. $DSP->qdiv('highlight', $LANG->line('sql_no_result')),
  1392. $crumb
  1393. );
  1394. }
  1395. if (strpos($temp_sql, 'count(*)') === FALSE)
  1396. {
  1397. $total_results = $result->num_rows;
  1398. }
  1399. else
  1400. {
  1401. $total_results = $result->row['count'];
  1402. }
  1403. // run the data query with the limit
  1404. $query = $DB->query($new_sql);
  1405. }
  1406. else
  1407. {
  1408. // magically delicious method for MySQL 4 and above
  1409. $new_sql = preg_replace("/^(\s*SELECT)/", "\\1 SQL_CALC_FOUND_ROWS ", $new_sql);
  1410. if ( ! $query = $DB->query($new_sql))
  1411. {
  1412. return $DSP->set_return_data( $title,
  1413. $DSP->heading($title).
  1414. $DSP->qdiv('highlight', $LANG->line('sql_no_result')),
  1415. $crumb
  1416. );
  1417. }
  1418. $result = $DB->query("SELECT FOUND_ROWS() AS total_rows");
  1419. $total_results = $result->row['total_rows'];
  1420. }
  1421. if ($total_results > $row_limit)
  1422. {
  1423. $url = BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=run_query'.AMP.'thequery='.base64_encode($sql);
  1424. $paginate = $DSP->pager( $url,
  1425. $total_results,
  1426. $row_limit,
  1427. $row,
  1428. 'ROW'
  1429. );
  1430. }
  1431. }
  1432. }
  1433. if ( ! isset($new_sql))
  1434. {
  1435. if ( ! $query = $DB->query($sql))
  1436. {
  1437. return $DSP->set_return_data( $title,
  1438. $DSP->heading($title).
  1439. $DSP->qdiv('highlight', $LANG->line('sql_no_result')),
  1440. $crumb
  1441. );
  1442. }
  1443. }
  1444. $qtypes = array('INSERT', 'UPDATE', 'DELETE', 'ALTER', 'CREATE', 'DROP', 'TRUNCATE');
  1445. $write = FALSE;
  1446. if (preg_match("#^(".implode('|', $qtypes).")#i", $sql))
  1447. {
  1448. $write = TRUE;
  1449. }
  1450. if ($write == TRUE)
  1451. {
  1452. $affected = ($DB->affected_rows > 0) ? $DSP->qdiv('', $LANG->line('total_affected_rows').NBS.$DB->affected_rows) : $DSP->qdiv('box', $DSP->qdiv('success', $LANG->line('sql_good_query')));
  1453. $out = $DSP->div('box').
  1454. $DSP->qdiv('defaultBold', $LANG->line('query')).
  1455. $DSP->qdiv('bigPad', $REGX->xss_clean($sql)).
  1456. $DSP->qdiv('defaultBold bigPad', $affected).
  1457. $DSP->div_c();
  1458. return $DSP->set_return_data( $title,
  1459. $DSP->heading($title).
  1460. $DSP->qdiv('success', $LANG->line('sql_good_result')).
  1461. $out,
  1462. $crumb
  1463. );
  1464. }
  1465. }
  1466. // No result? All that effort for nothing?
  1467. if ($query->num_rows == 0)
  1468. {
  1469. return $DSP->set_return_data( $title,
  1470. $DSP->heading($title).
  1471. $DSP->qdiv('highlight', $LANG->line('sql_no_result')),
  1472. $crumb
  1473. );
  1474. }
  1475. // Build the output
  1476. $r = $DSP->div('box').
  1477. $DSP->qdiv('defaultBold', $LANG->line('query')).
  1478. $DSP->qdiv('bigPad', $REGX->xss_clean($sql)).
  1479. $DSP->qdiv('defaultBold bigPad', str_replace('%x', (isset($total_results)) ? $total_results : $query->num_rows, $LANG->line('total_results'))).
  1480. $DSP->div_c();
  1481. $r .= $DSP->qdiv('tableHeading', $title);
  1482. $r .= $DSP->table('tableBorder', '0', '10', '100%')
  1483. .$DSP->tr();
  1484. foreach ($query->fields as $f)
  1485. {
  1486. $r .= $DSP->td('tableHeadingAlt').$f.$DSP->td_c();
  1487. }
  1488. $r .= $DSP->tr_c();
  1489. // Build our table rows
  1490. $i = 0;
  1491. foreach ($query->result as $key => $val)
  1492. {
  1493. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  1494. $r .= $DSP->tr();
  1495. foreach ($val as $k => $v)
  1496. {
  1497. $r .= $DSP->td($style).htmlspecialchars($v).$DSP->td_c();
  1498. }
  1499. $r .= $DSP->tr_c();
  1500. }
  1501. $r.= $DSP->table_c();
  1502. if ($paginate != '')
  1503. {
  1504. $r .= $DSP->qdiv('', $paginate);
  1505. }
  1506. if ($return == FALSE)
  1507. {
  1508. $DSP->title = $title;
  1509. $DSP->crumb = $crumb;
  1510. $DSP->body = $r;
  1511. }
  1512. else
  1513. {
  1514. return $r;
  1515. }
  1516. }
  1517. /* END */
  1518. /** -------------------------------------------
  1519. /** Delete cache file form
  1520. /** -------------------------------------------*/
  1521. function clear_cache_form($message = FALSE)
  1522. {
  1523. global $DSP, $LANG;
  1524. if ( ! $DSP->allowed_group('can_admin_utilities'))
  1525. {
  1526. return $DSP->no_access_message();
  1527. }
  1528. $DSP->title = $LANG->line('clear_caching');
  1529. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  1530. $DSP->crumb_item($LANG->line('clear_caching'));
  1531. $DSP->body = $DSP->qdiv('tableHeading', $LANG->line('clear_caching'));
  1532. if ($message == TRUE)
  1533. {
  1534. $DSP->body .= $DSP->qdiv('successBox', $DSP->qdiv('success', $LANG->line('cache_deleted')));
  1535. }
  1536. $DSP->body .= $DSP->div('box');
  1537. $DSP->body .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=clear_caching'));
  1538. $DSP->body .= $DSP->div('itemWrapper');
  1539. if ( ! isset($_POST['type']))
  1540. {
  1541. $_POST['type'] = 'all';
  1542. }
  1543. $selected = ($_POST['type'] == 'page') ? 1 : '';
  1544. $DSP->body .= $DSP->input_radio('type', 'page', $selected).$LANG->line('page_caching').BR;
  1545. $selected = ($_POST['type'] == 'tag') ? 1 : '';
  1546. $DSP->body .= $DSP->input_radio('type', 'tag', $selected).$LANG->line('tag_caching').BR;
  1547. $selected = ($_POST['type'] == 'db') ? 1 : '';
  1548. $DSP->body .= $DSP->input_radio('type', 'db', $selected).$LANG->line('db_caching').BR;
  1549. $selected = ($_POST['type'] == 'relationships') ? 1 : '';
  1550. $DSP->body .= $DSP->input_radio('type', 'relationships', $selected).$LANG->line('cached_relationships').BR;
  1551. $selected = ($_POST['type'] == 'all') ? 1 : '';
  1552. $DSP->body .= $DSP->input_radio('type', 'all', $selected).$LANG->line('all_caching');
  1553. $DSP->body .= $DSP->div_c();
  1554. $DSP->body .= $DSP->qdiv('itemWrapper', BR.$DSP->input_submit($LANG->line('submit')));
  1555. $DSP->body .= $DSP->form_close();
  1556. $DSP->body .= $DSP->div_c();
  1557. }
  1558. /* END */
  1559. /** -------------------------------------------
  1560. /** Delete cache files
  1561. /** -------------------------------------------*/
  1562. function clear_caching()
  1563. {
  1564. global $FNS;
  1565. if ( ! isset($_POST['type']))
  1566. {
  1567. return Utilities::clear_cache_form();
  1568. }
  1569. $FNS->clear_caching($_POST['type'], '', TRUE);
  1570. return Utilities::clear_cache_form(TRUE);
  1571. }
  1572. /* END */
  1573. /** -------------------------------------------
  1574. /** SQL backup form
  1575. /** -------------------------------------------*/
  1576. function sql_backup()
  1577. {
  1578. global $DSP, $LANG;
  1579. return;
  1580. if ( ! $DSP->allowed_group('can_admin_utilities'))
  1581. {
  1582. return $DSP->no_access_message();
  1583. }
  1584. ob_start();
  1585. ?>
  1586. <script type="text/javascript">
  1587. <!--
  1588. function setType()
  1589. {
  1590. document.forms[0].type[0].checked = true;
  1591. }
  1592. //-->
  1593. </script>
  1594. <?php
  1595. $buffer = ob_get_contents();
  1596. ob_end_clean();
  1597. $DSP->title = $LANG->line('sql_backup');
  1598. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  1599. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager')));
  1600. $DSP->crumb .= $DSP->crumb_item($LANG->line('sql_backup'));
  1601. $DSP->body = $buffer;
  1602. $DSP->body .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=do_sql_backup'));
  1603. $DSP->body .= $DSP->qdiv('tableHeading', $LANG->line('sql_backup'));
  1604. $DSP->body .= $DSP->div('box');
  1605. $DSP->body .= $DSP->qdiv('itemWrapper', '<b>'.$LANG->line('backup_info').'</b>');
  1606. $DSP->body .= '<fieldset class="box320">';
  1607. $DSP->body .= '<legend>'.$DSP->qdiv('defaultBold', $LANG->line('archive_destination')).'</legend>';
  1608. $DSP->body .= $DSP->input_radio('file', 'y', 1).$LANG->line('save_as_file').BR;
  1609. $DSP->body .= $DSP->input_radio('file', 'n', '', " onclick=\"setType();\"").$LANG->line('view_in_browser');
  1610. $DSP->body .= '</fieldset>';
  1611. $DSP->body .= '<fieldset class="box320">';
  1612. $DSP->body .= '<legend>'.$DSP->qdiv('defaultBold', $LANG->line('archive_type')).'</legend>';
  1613. $DSP->body .= $DSP->input_radio('type', 'text').$LANG->line('plain_text').BR;
  1614. $DSP->body .= $DSP->input_radio('type', 'zip', 1).$LANG->line('zip').BR;
  1615. $DSP->body .= $DSP->input_radio('type', 'gzip').$LANG->line('gzip').NBS.$LANG->line('mac_no_zip');
  1616. $DSP->body .= '</fieldset>';
  1617. $DSP->body .= $DSP->qdiv('itemWrapper', $DSP->input_checkbox('ignore_noncritical', 'y', 1).$LANG->line('ignore_noncritical'));
  1618. $DSP->body .= $DSP->div_c();
  1619. $DSP->body .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit($LANG->line('submit')));
  1620. $DSP->body .= $DSP->form_close();
  1621. }
  1622. /* END */
  1623. /** -------------------------------------------
  1624. /** Do SQL backup
  1625. /** -------------------------------------------*/
  1626. function do_sql_backup($type = '')
  1627. {
  1628. global $IN, $DSP, $DB, $LANG, $LOC;
  1629. return;
  1630. if ( ! $DSP->allowed_group('can_admin_utilities'))
  1631. {
  1632. return $DSP->no_access_message();
  1633. }
  1634. // Names of tables we do not want the data backed up from
  1635. if ($IN->GBL('ignore_noncritical', 'POST') == 'y')
  1636. {
  1637. $ignore = array(
  1638. 'exp_security_hashes ',
  1639. 'exp_sessions',
  1640. 'exp_cp_log',
  1641. 'exp_revision_tracker',
  1642. 'exp_search',
  1643. 'exp_email_console_cache'
  1644. );
  1645. }
  1646. else
  1647. {
  1648. $ignore = array();
  1649. }
  1650. /** ---------------------------------------------------------
  1651. /** Are we backing up the full database or separate tables?
  1652. /** ---------------------------------------------------------*/
  1653. if ($type == '')
  1654. {
  1655. $type = $_POST['type'];
  1656. $file = ($IN->GBL('file', 'POST') == 'y') ? TRUE : FALSE;
  1657. }
  1658. else
  1659. {
  1660. switch ($_POST['table_action'])
  1661. {
  1662. case 'BACKUP_F' : $type = 'text'; $file = TRUE;
  1663. break;
  1664. case 'BACKUP_Z' : $type = 'zip'; $file = TRUE;
  1665. break;
  1666. case 'BACKUP_G' : $type = 'gzip'; $file = TRUE;
  1667. break;
  1668. default : $type = 'text'; $file = FALSE;
  1669. break;
  1670. }
  1671. }
  1672. /** ------------------------------------------------------------
  1673. /** Build the output headers only if we are downloading a file
  1674. /** ------------------------------------------------------------*/
  1675. ob_start();
  1676. if ($file)
  1677. {
  1678. // Assign the name of the of the backup file
  1679. $now = $LOC->set_localized_time();
  1680. $filename = $DB->database.'_'.date('y', $now).date('m', $now).date('d', $now);
  1681. switch ($type)
  1682. {
  1683. case 'zip' :
  1684. if ( ! @function_exists('gzcompress'))
  1685. {
  1686. return $DSP->error_message($LANG->line('unsupported_compression'));
  1687. }
  1688. $ext = 'zip';
  1689. $mime = 'application/x-zip';
  1690. break;
  1691. case 'gzip' :
  1692. if ( ! @function_exists('gzencode'))
  1693. {
  1694. return $DSP->error_message($LANG->line('unsupported_compression'));
  1695. }
  1696. $ext = 'gz';
  1697. $mime = 'application/x-gzip';
  1698. break;
  1699. default :
  1700. $ext = 'sql';
  1701. if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE") || strstr($_SERVER['HTTP_USER_AGENT'], "OPERA"))
  1702. {
  1703. $mime = 'application/octetstream';
  1704. }
  1705. else
  1706. {
  1707. $mime = 'application/octet-stream';
  1708. }
  1709. break;
  1710. }
  1711. if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
  1712. {
  1713. header('Content-Type: '.$mime);
  1714. header('Content-Disposition: inline; filename="'.$filename.'.'.$ext.'"');
  1715. header('Expires: 0');
  1716. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  1717. header('Pragma: public');
  1718. }
  1719. else
  1720. {
  1721. header('Content-Type: '.$mime);
  1722. header('Content-Disposition: attachment; filename="'.$filename.'.'.$ext.'"');
  1723. header('Expires: 0');
  1724. header('Pragma: no-cache');
  1725. }
  1726. }
  1727. else
  1728. {
  1729. echo $DSP->qdiv('tableHeading', $LANG->line('sql_backup'));
  1730. echo '<pre>';
  1731. }
  1732. /** -------------------------------------------
  1733. /** Fetch the table names
  1734. /** -------------------------------------------*/
  1735. $DB->fetch_fields = TRUE;
  1736. // Individual tables
  1737. if (isset($_POST['table_action']))
  1738. {
  1739. foreach ($_POST['table'] as $key => $val)
  1740. {
  1741. $tables[] = $key;
  1742. }
  1743. }
  1744. // the full database
  1745. else
  1746. {
  1747. $tables = $DB->fetch_tables();
  1748. }
  1749. $i = 0;
  1750. foreach ($tables as $table)
  1751. {
  1752. /** -------------------------------------------
  1753. /** Fetch the table structure
  1754. /** -------------------------------------------*/
  1755. echo NL.NL.'#'.NL.'# TABLE STRUCTURE FOR: '.$table.NL.'#'.NL.NL;
  1756. echo 'DROP TABLE IF EXISTS '.$table.';'.NL.NL;
  1757. $query = $DB->query("SHOW CREATE TABLE `".$DB->database.'`.'.$table);
  1758. foreach ($query->result['0'] as $val)
  1759. {
  1760. if ($i++ % 2)
  1761. {
  1762. //$val = str_replace('`', '', $val).NL.NL;
  1763. //$val = preg_replace('/CREATE(.*\))/s', "CREATE\\1;", $val);
  1764. //$val = str_replace('TYPE=MyISAM', '', $val);
  1765. echo $val.';'.NL.NL;
  1766. }
  1767. }
  1768. if ( ! in_array($table, $ignore))
  1769. {
  1770. /** -------------------------------------------
  1771. /** Fetch the data in the table
  1772. /** -------------------------------------------*/
  1773. $query = $DB->query("SELECT * FROM $table");
  1774. if ($query->num_rows == 0)
  1775. {
  1776. continue;
  1777. }
  1778. /** -------------------------------------------
  1779. /** Assign the field name
  1780. /** -------------------------------------------*/
  1781. $fields = '';
  1782. foreach ($query->fields as $f)
  1783. {
  1784. $fields .= $f . ', ';
  1785. }
  1786. $fields = preg_replace( "/, $/" , "" , $fields);
  1787. /** -------------------------------------------
  1788. /** Assign the value in each field
  1789. /** -------------------------------------------*/
  1790. foreach ($query->result as $val)
  1791. {
  1792. $values = '';
  1793. foreach ($val as $v)
  1794. {
  1795. $v = str_replace(array("\x00", "\x0a", "\x0d", "\x1a"), array('\0', '\n', '\r', '\Z'), $v);
  1796. $v = str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $v);
  1797. $v = str_replace('\\', '\\\\', $v);
  1798. $v = str_replace('\'', '\\\'', $v);
  1799. $v = str_replace('\\\n', '\n', $v);
  1800. $v = str_replace('\\\r', '\r', $v);
  1801. $v = str_replace('\\\t', '\t', $v);
  1802. $values .= "'".$v."'".', ';
  1803. }
  1804. $values = preg_replace( "/, $/" , "" , $values);
  1805. if ($file == FALSE)
  1806. {
  1807. $values = htmlspecialchars($values);
  1808. }
  1809. // Build the INSERT string
  1810. echo 'INSERT INTO '.$table.' ('.$fields.') VALUES ('.$values.');'.NL;
  1811. }
  1812. }
  1813. }
  1814. // END WHILE LOOP
  1815. if ($file == FALSE)
  1816. {
  1817. echo '</pre>';
  1818. }
  1819. $buffer = ob_get_contents();
  1820. ob_end_clean();
  1821. /** -------------------------------------------
  1822. /** Create the selected output file
  1823. /** -------------------------------------------*/
  1824. if ($file)
  1825. {
  1826. switch ($type)
  1827. {
  1828. case 'zip' :
  1829. $zip = new Zipper;
  1830. $zip->add_file($buffer, $filename.'.sql');
  1831. echo $zip->output_zipfile();
  1832. break;
  1833. case 'gzip' : echo gzencode($buffer);
  1834. break;
  1835. default : echo $buffer;
  1836. break;
  1837. }
  1838. exit;
  1839. }
  1840. else
  1841. {
  1842. $DSP->title = $LANG->line('utilities');
  1843. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  1844. $DSP->crumb_item($LANG->line('utilities'));
  1845. $DSP->body = $buffer;
  1846. }
  1847. }
  1848. /* END */
  1849. /** -------------------------------------------
  1850. /** SQL tables
  1851. /** -------------------------------------------*/
  1852. function view_database()
  1853. {
  1854. global $DSP, $DB, $PREFS, $LANG;
  1855. if ( ! $DSP->allowed_group('can_admin_utilities'))
  1856. {
  1857. return $DSP->no_access_message();
  1858. }
  1859. $DB->fetch_fields = TRUE;
  1860. $query = $DB->query("SHOW TABLE STATUS FROM `".$PREFS->ini('db_name')."`");
  1861. // Build the output
  1862. $r = Utilities::toggle_code();
  1863. $r .= $DSP->form_open(
  1864. array(
  1865. 'action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=table_action',
  1866. 'name' => 'tables',
  1867. 'id' => 'tables'
  1868. )
  1869. );
  1870. $r .= $DSP->qdiv('tableHeading', $LANG->line('view_database'));
  1871. $r .= $DSP->table('tableBorder', '0', '10', '100%')
  1872. .$DSP->tr()
  1873. .$DSP->td('tableHeadingAlt', '4%').$DSP->input_checkbox('toggleflag', '', '', "onclick=\"toggle(this);\"").$DSP->td_c()
  1874. .$DSP->td('tableHeadingAlt', '36%').$LANG->line('table_name').$DSP->td_c()
  1875. .$DSP->td('tableHeadingAlt', '15%').$LANG->line('browse').$DSP->td_c()
  1876. .$DSP->td('tableHeadingAlt', '15%').$LANG->line('records').$DSP->td_c()
  1877. .$DSP->td('tableHeadingAlt', '15%').$LANG->line('size').$DSP->td_c()
  1878. .$DSP->tr_c();
  1879. // Build our table rows
  1880. $i = 0;
  1881. $records = 0;
  1882. $tables = 0;
  1883. $totsize = 0;
  1884. $prelen = strlen($DB->prefix);
  1885. foreach ($query->result as $val)
  1886. {
  1887. if (strncmp($val['Name'], $DB->prefix, $prelen) != 0)
  1888. {
  1889. continue;
  1890. }
  1891. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  1892. $len = $val['Data_length'] + $val['Index_length'];
  1893. $size = Utilities::byte_format($len, 3);
  1894. $r .= $DSP->tr()
  1895. .$DSP->td($style, '4%')."<input type='checkbox' name=\"table[".$val['Name']."]\" value='y' />".$DSP->td_c()
  1896. .$DSP->td($style, '36%').'<b>'.$val['Name'].'</b>'.$DSP->td_c()
  1897. .$DSP->td($style, '15%')
  1898. .$DSP->anchor(
  1899. BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=run_query'.AMP.'thequery='.base64_encode("SELECT * FROM ".$val['Name']),
  1900. $LANG->line('browse')
  1901. )
  1902. .$DSP->td_c()
  1903. .$DSP->td($style, '15%').$val['Rows'].$DSP->td_c()
  1904. .$DSP->td($style, '15%').$size['0'].' '.$size['1'].$DSP->td_c()
  1905. .$DSP->tr_c();
  1906. $records += $val['Rows'];
  1907. $totsize += $len;
  1908. $tables++;
  1909. }
  1910. $size = Utilities::byte_format($totsize);
  1911. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  1912. $r .= $DSP->tr()
  1913. .$DSP->td($style).NBS.$DSP->td_c()
  1914. .$DSP->td($style).'<b>'.$tables.NBS.$LANG->line('tables').'</b>'.$DSP->td_c()
  1915. .$DSP->td($style).NBS.$DSP->td_c()
  1916. .$DSP->td($style).'<b>'.$records.'</b>'.$DSP->td_c()
  1917. .$DSP->td($style).'<b>'.$size['0'].' '.$size['1'].'</b>'.$DSP->td_c()
  1918. .$DSP->tr_c();
  1919. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  1920. $r .= $DSP->tr()
  1921. .$DSP->td($style, '', '1')
  1922. .$DSP->input_checkbox('toggleflag', '', '', "onclick=\"toggle(this);\"")
  1923. .$DSP->td_c()
  1924. .$DSP->td($style, '', '1')
  1925. .$LANG->line('select_all')
  1926. .$DSP->td_c();
  1927. $r .= $DSP->td($style, '', '4')
  1928. .$DSP->input_select_header('table_action')
  1929. .$DSP->input_select_option('OPTIMIZE', $LANG->line('optimize_table'))
  1930. .$DSP->input_select_option('REPAIR', $LANG->line('repair_table'))
  1931. //.$DSP->input_select_option('BACKUP_V', $LANG->line('view_table_sql'))
  1932. //.$DSP->input_select_option('BACKUP_F', $LANG->line('backup_tables_file'))
  1933. //.$DSP->input_select_option('BACKUP_Z', $LANG->line('backup_tables_zip'))
  1934. //.$DSP->input_select_option('BACKUP_G', $LANG->line('backup_tables_gzip'))
  1935. .$DSP->input_select_footer()
  1936. .$DSP->input_submit($LANG->line('submit'))
  1937. .$DSP->td_c()
  1938. .$DSP->tr_c()
  1939. .$DSP->table_c();
  1940. $r .= $DSP->form_close();
  1941. $DSP->title = $LANG->line('view_database');
  1942. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  1943. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager'))).
  1944. $DSP->crumb_item($LANG->line('view_database'));
  1945. $DSP->body = $r;
  1946. }
  1947. /* END */
  1948. /** -------------------------------------------
  1949. /** JavaScript toggle code
  1950. /** -------------------------------------------*/
  1951. function toggle_code()
  1952. {
  1953. ob_start();
  1954. ?>
  1955. <script type="text/javascript">
  1956. <!--
  1957. function toggle(thebutton)
  1958. {
  1959. if (thebutton.checked)
  1960. {
  1961. val = true;
  1962. }
  1963. else
  1964. {
  1965. val = false;
  1966. }
  1967. var len = document.tables.elements.length;
  1968. for (var i = 0; i < len; i++)
  1969. {
  1970. var button = document.tables.elements[i];
  1971. var name_array = button.name.split("[");
  1972. if (name_array[0] == "table")
  1973. {
  1974. button.checked = val;
  1975. }
  1976. }
  1977. document.tables.toggleflag.checked = val;
  1978. }
  1979. //-->
  1980. </script>
  1981. <?php
  1982. $buffer = ob_get_contents();
  1983. ob_end_clean();
  1984. return $buffer;
  1985. }
  1986. /* END */
  1987. /** ----------------------------------
  1988. /** Number format
  1989. /** ----------------------------------*/
  1990. function byte_format($num)
  1991. {
  1992. if ($num >= 1000000000)
  1993. {
  1994. $num = round($num/107374182)/10;
  1995. $unit = 'GB';
  1996. }
  1997. elseif ($num >= 1000000)
  1998. {
  1999. $num = round($num/104857)/10;
  2000. $unit = 'MB';
  2001. }
  2002. elseif ($num >= 1000)
  2003. {
  2004. $num = round($num/102)/10;
  2005. $unit = 'KB';
  2006. }
  2007. else
  2008. {
  2009. $unit = 'Bytes';
  2010. }
  2011. return array(number_format($num, 1), $unit);
  2012. }
  2013. /* END */
  2014. /** -------------------------------------------
  2015. /** Run table action (repair/optimize)
  2016. /** -------------------------------------------*/
  2017. function run_table_action()
  2018. {
  2019. global $DSP, $DB, $PREFS, $LANG;
  2020. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2021. {
  2022. return $DSP->no_access_message();
  2023. }
  2024. if ( ! isset($_POST['table']))
  2025. {
  2026. return $DSP->error_message($LANG->line('no_buttons_selected'));
  2027. }
  2028. $action = array('OPTIMIZE', 'REPAIR');
  2029. if ( ! in_array($_POST['table_action'], $action))
  2030. {
  2031. return Utilities::do_sql_backup($_POST['table_action']);
  2032. }
  2033. $title = $LANG->line(strtolower($_POST['table_action']));
  2034. $r = $DSP->qdiv('tableHeading', $title);
  2035. $r .= $DSP->table('tableBorder', '0', '10', '100%');
  2036. $r .= $DSP->tr();
  2037. $DB->fetch_fields = TRUE;
  2038. $query = $DB->query("ANALYZE TABLE exp_members");
  2039. foreach ($query->fields as $f)
  2040. {
  2041. $r .= $DSP->td('tableHeadingAlt').$f.$DSP->td_c();
  2042. }
  2043. $r .= $DSP->tr_c();
  2044. $i = 0;
  2045. foreach ($_POST['table'] as $key => $val)
  2046. {
  2047. $sql = $_POST['table_action']." TABLE ".$key;
  2048. $query = $DB->query($sql);
  2049. foreach ($query->result as $key => $val)
  2050. {
  2051. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  2052. $r .= $DSP->tr();
  2053. foreach ($val as $k => $v)
  2054. {
  2055. $r .= $DSP->td($style).$v.$DSP->td_c();
  2056. }
  2057. $r .= $DSP->tr_c();
  2058. }
  2059. }
  2060. $r.= $DSP->table_c();
  2061. // Set the return data
  2062. $DSP->title = $LANG->line('utilities').$DSP->crumb_item($title);
  2063. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2064. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager'))).
  2065. $DSP->crumb_item($title);
  2066. $DSP->body = $r;
  2067. }
  2068. /* END */
  2069. /** -------------------------------------------
  2070. /** SQL query form
  2071. /** -------------------------------------------*/
  2072. function sql_query_form()
  2073. {
  2074. global $DSP, $LANG, $SESS;
  2075. if ($SESS->userdata['group_id'] != '1')
  2076. {
  2077. return $DSP->no_access_message();
  2078. }
  2079. $DSP->title = $LANG->line('utilities');
  2080. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2081. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=sql_manager', $LANG->line('sql_manager'))).
  2082. $DSP->crumb_item($LANG->line('sql_query'));
  2083. $DSP->body = $DSP->qdiv('tableHeading', $LANG->line('sql_query'))
  2084. .$DSP->div('box')
  2085. .$DSP->qdiv('itemWrapper', $LANG->line('sql_query_instructions'))
  2086. .$DSP->qdiv('itemWrapper', '<b>'.$LANG->line('advanced_users_only').'</b>')
  2087. .$DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=run_query'))
  2088. .$DSP->input_textarea('thequery', '', '10', 'textarea', '100%')
  2089. .$DSP->qdiv('itemWrapper', $DSP->input_checkbox('debug', 'y', 0, "id='debug'").$LANG->line('sql_query_debug', 'debug'))
  2090. .$DSP->input_submit($LANG->line('submit'), 'submit')
  2091. .$DSP->div_c()
  2092. .$DSP->form_close();
  2093. }
  2094. /* END */
  2095. /** -------------------------------------------
  2096. /** Search and Replace form
  2097. /** -------------------------------------------*/
  2098. function search_and_replace_form()
  2099. {
  2100. global $DSP, $DB, $LANG, $PREFS, $SESS;
  2101. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2102. {
  2103. return $DSP->no_access_message();
  2104. }
  2105. // Select menu of available fields where a replacement can occur.
  2106. $r = $DSP->input_select_header('fieldname');
  2107. $r .= $DSP->input_select_option('', '--');
  2108. $r .= $DSP->input_select_option('preferences', $LANG->line('site_preferences'));
  2109. foreach($SESS->userdata('assigned_sites') as $site_id => $site_label)
  2110. {
  2111. $r .= $DSP->input_select_option('site_preferences_'.$site_id, NBS.NBS.NBS.NBS.NBS.NBS.$site_label);
  2112. }
  2113. $r .= $DSP->input_select_option('', '--');
  2114. $r .= $DSP->input_select_option('title', $LANG->line('weblog_entry_title'));
  2115. $r .= $DSP->input_select_option('', '--');
  2116. $r .= $DSP->input_select_option('', $LANG->line('weblog_fields'));
  2117. // Fetch the weblog fields
  2118. $sql = "SELECT exp_field_groups.group_id, exp_field_groups.group_name, exp_field_groups.site_id
  2119. FROM exp_weblogs, exp_field_groups
  2120. WHERE exp_weblogs.field_group = exp_field_groups.group_id
  2121. AND exp_weblogs.is_user_blog = 'n'";
  2122. $query = $DB->query($sql);
  2123. $fg_array = array();
  2124. $sql_b = '';
  2125. if ($query->num_rows > 0)
  2126. {
  2127. foreach ($query->result as $row)
  2128. {
  2129. $sql_b .= "'".$row['group_id']."',";
  2130. $fg_array[$row['group_id']] = $row['group_name'];
  2131. }
  2132. $sql_b = substr($sql_b, 0, -1);
  2133. $sql = "SELECT group_id, field_id, field_label, site_label FROM exp_weblog_fields, exp_sites
  2134. WHERE exp_sites.site_id = exp_weblog_fields.site_id
  2135. AND group_id IN (".$sql_b.")";
  2136. if ($PREFS->ini('multiple_sites_enabled') !== 'y')
  2137. {
  2138. $sql .= "AND exp_weblog_fields.site_id = '1' ";
  2139. }
  2140. $sql .= " ORDER BY site_label, group_id, field_label";
  2141. $query = $DB->query($sql);
  2142. $site = '';
  2143. foreach ($query->result as $row)
  2144. {
  2145. if (($PREFS->ini('multiple_sites_enabled') == 'y'))
  2146. {
  2147. if (($site == '' OR $site != $row['site_label']))
  2148. {
  2149. $r .= $DSP->input_select_option('', NBS.NBS.NBS.NBS.NBS.NBS.$row['site_label']);
  2150. }
  2151. $site = $row['site_label'];
  2152. $r .= $DSP->input_select_option('field_id_'.$row['field_id'], NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.$row['field_label'].' ('.$fg_array[$row['group_id']].')');
  2153. }
  2154. else
  2155. {
  2156. $r .= $DSP->input_select_option('field_id_'.$row['field_id'], NBS.NBS.NBS.NBS.NBS.NBS.$row['field_label'].' ('.$fg_array[$row['group_id']].')');
  2157. }
  2158. }
  2159. }
  2160. $r .= $DSP->input_select_option('', '--');
  2161. $r .= $DSP->input_select_option('template_data', $LANG->line('templates'));
  2162. $r .= $DSP->input_select_option('', '--');
  2163. $LANG->fetch_language_file('templates');
  2164. $r .= $DSP->input_select_option('template_data', $LANG->line('template_groups'));
  2165. $sql = "SELECT group_id, group_name, site_label FROM exp_template_groups, exp_sites WHERE exp_sites.site_id = exp_template_groups.site_id ";
  2166. if ($PREFS->ini('multiple_sites_enabled') !== 'y')
  2167. {
  2168. $sql .= "AND exp_template_groups.site_id = '1' ";
  2169. }
  2170. $sql .= "ORDER BY site_label, group_name";
  2171. $query = $DB->query($sql);
  2172. $site = '';
  2173. foreach($query->result as $row)
  2174. {
  2175. if (($PREFS->ini('multiple_sites_enabled') == 'y'))
  2176. {
  2177. if (($site == '' OR $site != $row['site_label']))
  2178. {
  2179. $r .= $DSP->input_select_option('', NBS.NBS.NBS.NBS.NBS.NBS.$row['site_label']);
  2180. }
  2181. $site = $row['site_label'];
  2182. $r .= $DSP->input_select_option('template_'.$row['group_id'], NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.NBS.$row['group_name']);
  2183. }
  2184. else
  2185. {
  2186. $r .= $DSP->input_select_option('template_'.$row['group_id'], NBS.NBS.NBS.NBS.NBS.NBS.$row['group_name']);
  2187. }
  2188. }
  2189. $r .= $DSP->input_select_footer();
  2190. $DSP->title = $LANG->line('utilities');
  2191. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2192. $DSP->crumb_item($LANG->line('search_and_replace'));
  2193. $DSP->body = $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=run_sandr')).
  2194. $DSP->qdiv('tableHeading', $LANG->line('search_and_replace')).
  2195. $DSP->div('box').
  2196. $DSP->qdiv('itemWrapper',$LANG->line('sandr_instructions')).
  2197. $DSP->div('itemWrapper').
  2198. $DSP->qspan('alert', $LANG->line('advanced_users_only')).
  2199. $DSP->div_c().
  2200. $DSP->qdiv('itemWrapper', $DSP->qspan('defaultBold', BR.$LANG->line('search_term'))).
  2201. $DSP->input_textarea('searchterm', '', '4').
  2202. $DSP->qdiv('itemWrapper', $DSP->qspan('defaultBold', BR.$LANG->line('replace_term'))).
  2203. $DSP->input_textarea('replaceterm', '', '4').
  2204. $DSP->qdiv('itemWrapper', $DSP->qspan('defaultBold', BR.$LANG->line('replace_where'))).
  2205. $r.
  2206. $DSP->qdiv('alert', BR.$LANG->line('be_careful').NBS.NBS.$LANG->line('action_can_not_be_undone')).
  2207. $DSP->qdiv('defaultBold', BR.$LANG->line('search_replace_disclaimer').BR).
  2208. $DSP->div_c().
  2209. $DSP->qdiv('itemWrapperTop', $DSP->input_submit($LANG->line('submit'), 'submit')).
  2210. $DSP->form_close();
  2211. }
  2212. /* END */
  2213. /** -------------------------------------------
  2214. /** Search and replace
  2215. /** -------------------------------------------*/
  2216. function search_and_replace()
  2217. {
  2218. global $DSP, $IN, $DB, $LANG, $LOC, $REGX, $PREFS;
  2219. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2220. {
  2221. return $DSP->no_access_message();
  2222. }
  2223. $search = $DB->escape_str($IN->GBL('searchterm'));
  2224. $replace = $DB->escape_str($IN->GBL('replaceterm'));
  2225. $field = $IN->GBL('fieldname');
  2226. if ( ! $search || ! $replace || ! $field)
  2227. {
  2228. return Utilities::search_and_replace_form();
  2229. }
  2230. if ($field == 'title')
  2231. {
  2232. $sql = "UPDATE `exp_weblog_titles` SET `$field` = REPLACE(`$field`, '$search', '$replace')";
  2233. }
  2234. elseif ($field == 'preferences' OR substr($field, 0, strlen('site_preferences_')) == 'site_preferences_')
  2235. {
  2236. $rows = 0;
  2237. if ($field == 'preferences')
  2238. {
  2239. $site_id = $PREFS->ini('site_id');
  2240. }
  2241. else
  2242. {
  2243. $site_id = substr($field, strlen('site_preferences_'));
  2244. }
  2245. /** -------------------------------------------
  2246. /** Site Preferences in Certain Tables/Fields
  2247. /** -------------------------------------------*/
  2248. $preferences = array('exp_weblogs' => array('blog_title',
  2249. 'blog_url',
  2250. 'comment_url',
  2251. 'blog_description',
  2252. 'comment_notify_emails',
  2253. 'weblog_notify_emails',
  2254. 'search_results_url',
  2255. 'tb_return_url',
  2256. 'ping_return_url',
  2257. 'rss_url'),
  2258. 'exp_upload_prefs' => array('server_path',
  2259. 'properties',
  2260. 'file_properties',
  2261. 'url'),
  2262. 'exp_member_groups' => array('group_title',
  2263. 'group_description',
  2264. 'mbr_delete_notify_emails'),
  2265. 'exp_global_variables' => array('variable_data'),
  2266. 'exp_categories' => array('cat_image'),
  2267. 'exp_galleries' => array('gallery_full_name',
  2268. 'gallery_url',
  2269. 'gallery_upload_path',
  2270. 'gallery_image_url',
  2271. 'gallery_batch_path',
  2272. 'gallery_batch_url',
  2273. 'gallery_wm_image_path',
  2274. 'gallery_wm_test_image_path',
  2275. 'gallery_comment_url',
  2276. 'gallery_comment_notify_emails'),
  2277. 'exp_forums' => array('forum_name',
  2278. 'forum_notify_emails',
  2279. 'forum_notify_emails_topics'),
  2280. 'exp_forum_boards' => array('board_label',
  2281. 'board_forum_url',
  2282. 'board_upload_path',
  2283. 'board_notify_emails',
  2284. 'board_notify_emails_topics')
  2285. );
  2286. unset($preferences['exp_galleries']); // Not Site Specific?
  2287. foreach($preferences as $table => $fields)
  2288. {
  2289. if ( ! $DB->table_exists($table) OR $table == 'exp_forums')
  2290. {
  2291. continue;
  2292. }
  2293. $site_field = ($table == 'exp_forum_boards') ? 'board_site_id' : 'site_id';
  2294. foreach($fields as $field)
  2295. {
  2296. $DB->query("UPDATE `{$table}`
  2297. SET `{$field}` = REPLACE(`{$field}`, '$search', '$replace')
  2298. WHERE `$site_field` = '".$DB->escape_str($site_id)."'");
  2299. $rows += $DB->affected_rows;
  2300. }
  2301. }
  2302. if ($DB->table_exists('exp_forums'))
  2303. {
  2304. $query = $DB->query("SELECT board_id FROM exp_forum_boards WHERE board_site_id = '".$DB->escape_str($site_id)."'");
  2305. if ($query->num_rows > 0)
  2306. {
  2307. foreach($query->result as $row)
  2308. {
  2309. foreach($preferences['exp_forums'] as $field)
  2310. {
  2311. $DB->query("UPDATE `exp_forums`
  2312. SET `{$field}` = REPLACE(`{$field}`, '$search', '$replace')
  2313. WHERE `board_id` = '".$DB->escape_str($row['board_id'])."'");
  2314. $rows += $DB->affected_rows;
  2315. }
  2316. }
  2317. }
  2318. }
  2319. /** -------------------------------------------
  2320. /** Site Preferences in Database
  2321. /** -------------------------------------------*/
  2322. $query = $DB->query("SELECT * FROM exp_sites WHERE site_id = '".$DB->escape_str($site_id)."'");
  2323. foreach(array('system', 'weblog', 'template', 'mailinglist', 'member') as $type)
  2324. {
  2325. $prefs = $REGX->array_stripslashes(
  2326. unserialize(
  2327. $query->row['site_'.$type.'_preferences']));
  2328. foreach($PREFS->divination($type) as $value)
  2329. {
  2330. $prefs[$value] = str_replace($search, $replace, $PREFS->ini($value));
  2331. }
  2332. $DB->query($DB->update_string('exp_sites',
  2333. array('site_'.$type.'_preferences' => addslashes(serialize($prefs))),
  2334. "site_id = '".$DB->escape_str($site_id)."'"));
  2335. $rows += $DB->affected_rows;
  2336. }
  2337. }
  2338. elseif ($field == 'template_data')
  2339. {
  2340. $sql = "UPDATE `exp_templates` SET `$field` = REPLACE(`$field`, '$search', '$replace'), `edit_date` = '".$LOC->now."' WHERE group_id IN (";
  2341. $query = $DB->query("SELECT group_id FROM exp_template_groups WHERE is_user_blog = 'n'");
  2342. foreach ($query->result as $row)
  2343. {
  2344. $sql .= "'".$row['group_id']."',";
  2345. }
  2346. $sql = substr($sql, 0, -1).')';
  2347. }
  2348. elseif(preg_match('#^template_#i', $field))
  2349. {
  2350. $sql = "UPDATE `exp_templates` SET `template_data` = REPLACE(`template_data`, '$search', '$replace'), edit_date = '".$LOC->now."'
  2351. WHERE group_id = '".$DB->escape_str(substr($field,9))."'";
  2352. }
  2353. else
  2354. {
  2355. $sql = "UPDATE `exp_weblog_data` SET `".$DB->escape_str($field)."` = REPLACE(`".$DB->escape_str($field)."`, '$search', '$replace') WHERE weblog_id IN (";
  2356. $query = $DB->query("SELECT weblog_id FROM exp_weblogs WHERE is_user_blog = 'n'");
  2357. foreach ($query->result as $row)
  2358. {
  2359. $sql .= "'".$row['weblog_id']."',";
  2360. }
  2361. $sql = substr($sql, 0, -1).')';
  2362. }
  2363. if ( isset($sql))
  2364. {
  2365. $DB->query($sql);
  2366. $rows = $DB->affected_rows;
  2367. }
  2368. $DSP->set_return_data(
  2369. $LANG->line('utilities'),
  2370. $DSP->qdiv('tableHeading', $LANG->line('search_and_replace')).
  2371. $DSP->qdiv('box', $LANG->line('rows_replaced').NBS.NBS.$rows),
  2372. $LANG->line('search_and_replace')
  2373. );
  2374. }
  2375. /* END */
  2376. /** -------------------------------------------
  2377. /** Data pruning
  2378. /** -------------------------------------------*/
  2379. function data_pruning()
  2380. {
  2381. global $DSP, $LANG, $PREFS;
  2382. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2383. {
  2384. return $DSP->no_access_message();
  2385. }
  2386. $r = $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  2387. $r .= $DSP->table_row(array(
  2388. array(
  2389. 'text' => $LANG->line('data_pruning'),
  2390. 'class' => 'tableHeading',
  2391. )
  2392. )
  2393. );
  2394. $r .= $DSP->table_row(array(
  2395. array(
  2396. 'text' => $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=member_pruning', $LANG->line('member_pruning'))),
  2397. 'class' => 'tableCellTwo'
  2398. )
  2399. )
  2400. );
  2401. $r .= $DSP->table_row(array(
  2402. array(
  2403. 'text' => $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=entry_pruning', $LANG->line('weblog_entry_pruning'))),
  2404. 'class' => 'tableCellTwo'
  2405. )
  2406. )
  2407. );
  2408. $r .= $DSP->table_row(array(
  2409. array(
  2410. 'text' => $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=comment_pruning', $LANG->line('comment_pruning'))),
  2411. 'class' => 'tableCellTwo'
  2412. )
  2413. )
  2414. );
  2415. $r .= $DSP->table_row(array(
  2416. array(
  2417. 'text' => $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=trackback_pruning', $LANG->line('trackback_pruning'))),
  2418. 'class' => 'tableCellTwo'
  2419. )
  2420. )
  2421. );
  2422. /* Someday, oh someday...
  2423. $r .= $DSP->table_row(array(
  2424. array(
  2425. 'text' => $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=pm_pruning', $LANG->line('pm_pruning'))),
  2426. 'class' => 'tableCellTwo'
  2427. )
  2428. )
  2429. );
  2430. */
  2431. if ($PREFS->ini('forum_is_installed') == "y")
  2432. {
  2433. $r .= $DSP->table_row(array(
  2434. array(
  2435. 'text' => $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=topic_pruning', $LANG->line('topic_pruning'))),
  2436. 'class' => 'tableCellTwo'
  2437. )
  2438. )
  2439. );
  2440. }
  2441. $r .= $DSP->table_close();
  2442. $DSP->set_return_data($LANG->line('utilities'), $r, $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2443. $DSP->crumb_item($LANG->line('data_pruning')));
  2444. }
  2445. /* END */
  2446. /** -------------------------------------------
  2447. /** Membership pruning
  2448. /** -------------------------------------------*/
  2449. function member_pruning()
  2450. {
  2451. global $IN, $DSP, $LANG, $PREFS, $DB;
  2452. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2453. {
  2454. return $DSP->no_access_message();
  2455. }
  2456. $r = '';
  2457. if ($IN->GBL('update') !== FALSE)
  2458. {
  2459. $r .= $DSP->qdiv('box', $DSP->qdiv('success', str_replace('%x', $IN->GBL('update'), $LANG->line('good_member_pruning'))));
  2460. }
  2461. $r .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_member_conf'));
  2462. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  2463. $r .= $DSP->table_row(array(
  2464. array(
  2465. 'text' => $LANG->line('member_pruning'),
  2466. 'class' => 'tableHeading',
  2467. 'colspan' => '2'
  2468. )
  2469. )
  2470. );
  2471. $data = $DSP->qdiv('itemWrapper', $DSP->qdiv('defaultBold', $LANG->line('mbr_prune_x_days')));
  2472. $data .= $DSP->qdiv('itemWrapper', $DSP->qdiv('highlight', $LANG->line('mbr_prune_zero_note')));
  2473. $r .= $DSP->table_row(array(
  2474. array(
  2475. 'text' => $data,
  2476. 'class' => 'tableCellTwo',
  2477. 'width' => '65%'
  2478. ),
  2479. array(
  2480. 'text' => $DSP->input_text('days_ago', '365', '10', '4', 'input', '40px'),
  2481. 'class' => 'tableCellTwo',
  2482. 'width' => '35%'
  2483. )
  2484. )
  2485. );
  2486. $r .= $DSP->table_row(array(
  2487. array(
  2488. 'text' => $DSP->qdiv('itemWrapper', $DSP->input_checkbox('post_filter', 'y', 1).NBS.$LANG->line('mbr_prune_never_posted')),
  2489. 'class' => 'tableCellTwo',
  2490. 'colspan' => '2'
  2491. )
  2492. )
  2493. );
  2494. $r .= $DSP->table_close();
  2495. $query = $DB->query("SELECT group_id, group_title FROM exp_member_groups WHERE site_id = '".$DB->escape_str($PREFS->ini('site_id'))."' AND group_id != 1 ORDER BY group_title");
  2496. $r .= $DSP->qdiv('tableHeading', $LANG->line('mbr_prune_groups'));
  2497. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  2498. $r .= $DSP->table_row(array(
  2499. array(
  2500. 'text' => $LANG->line('must_select_one'),
  2501. 'class' => 'tableHeadingAlt'
  2502. )
  2503. )
  2504. );
  2505. $i = 0;
  2506. foreach ($query->result as $row)
  2507. {
  2508. // Translate groups if needed
  2509. $group_name = $row['group_title'];
  2510. if (in_array($group_name, array('Guests', 'Banned', 'Members', 'Pending', 'Super Admins')))
  2511. {
  2512. $group_name = $LANG->line(strtolower(str_replace(" ", "_", $group_name)));
  2513. }
  2514. $group_name = str_replace(' ', NBS, $group_name);
  2515. /** ----------------------------------------
  2516. /** Write group rows
  2517. /** ----------------------------------------*/
  2518. $class = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  2519. $r .= $DSP->table_row(array(
  2520. array(
  2521. 'text' => $DSP->qdiv('defaultBold', $DSP->input_checkbox('group_'.$row['group_id'], 'y').NBS.$group_name),
  2522. 'class' => $class,
  2523. 'width' => '50%'
  2524. )
  2525. )
  2526. );
  2527. }
  2528. $r .= $DSP->table_close();
  2529. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit());
  2530. $r .= $DSP->form_close();
  2531. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2532. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  2533. $DSP->crumb_item($LANG->line('member_pruning'));
  2534. $DSP->set_return_data($LANG->line('member_pruning'), $r, $c);
  2535. }
  2536. /* END */
  2537. /** -------------------------------------------
  2538. /** Prune Member Confirmation
  2539. /** -------------------------------------------*/
  2540. function prune_member_confirm()
  2541. {
  2542. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  2543. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2544. {
  2545. return $DSP->no_access_message();
  2546. }
  2547. /** ---------------------------------------
  2548. /** Did they submit the number of day?
  2549. /** ---------------------------------------*/
  2550. if ( ! is_numeric($_POST['days_ago']))
  2551. {
  2552. return $DSP->error_message($LANG->line('must_submit_number'));
  2553. }
  2554. /** ---------------------------------------
  2555. /** Did they submit member groups?
  2556. /** ---------------------------------------*/
  2557. $groups = FALSE;
  2558. foreach ($_POST as $key => $val)
  2559. {
  2560. if (substr($key, 0, 6) == 'group_')
  2561. {
  2562. $groups = TRUE;
  2563. break;
  2564. }
  2565. }
  2566. if ($groups == FALSE)
  2567. {
  2568. return $DSP->error_message($LANG->line('must_submit_group'));
  2569. }
  2570. $r = $DSP->delete_confirmation(
  2571. array(
  2572. 'url' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_members',
  2573. 'heading' => 'member_pruning',
  2574. 'message' => 'prune_member_confirm_msg',
  2575. 'hidden' => $_POST
  2576. )
  2577. );
  2578. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2579. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  2580. $DSP->crumb_item($LANG->line('member_pruning'));
  2581. $DSP->set_return_data($LANG->line('member_pruning'), $r, $c);
  2582. }
  2583. /* END */
  2584. /** -------------------------------------------
  2585. /** Prune Member Data
  2586. /** -------------------------------------------*/
  2587. function prune_members()
  2588. {
  2589. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  2590. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2591. {
  2592. return $DSP->no_access_message();
  2593. }
  2594. /** ---------------------------------------
  2595. /** Did they submit the number of day?
  2596. /** ---------------------------------------*/
  2597. if ( ! is_numeric($_POST['days_ago']))
  2598. {
  2599. return $DSP->error_message($LANG->line('must_submit_number'), 2);
  2600. }
  2601. /** ---------------------------------------
  2602. /** Assign the member groups
  2603. /** ---------------------------------------*/
  2604. $group_filter = '';
  2605. foreach ($_POST as $key => $val)
  2606. {
  2607. if (substr($key, 0, 6) == 'group_')
  2608. {
  2609. if (substr($key, 6) != 1)
  2610. {
  2611. $group_filter .= "'".substr($key, 6)."',";
  2612. }
  2613. }
  2614. }
  2615. /** ---------------------------------------
  2616. /** Did they submit member groups?
  2617. /** ---------------------------------------*/
  2618. if ($group_filter == '')
  2619. {
  2620. return $DSP->error_message($LANG->line('must_submit_group'), 2);
  2621. }
  2622. $group_filter = " group_id != '1' AND group_id IN (".substr($group_filter, 0, -1).')';
  2623. $days_ago = ($_POST['days_ago'] > 0) ? ($LOC->now - (60*60*24*$_POST['days_ago'])) : '';
  2624. /** ---------------------------------------
  2625. /** Fetch the member IDs
  2626. /** ---------------------------------------*/
  2627. if ( ! isset($_POST['post_filter']))
  2628. {
  2629. $sql = "SELECT member_id FROM exp_members WHERE ".$group_filter;
  2630. if ($days_ago != '')
  2631. {
  2632. $sql .= " AND join_date < {$days_ago}";
  2633. }
  2634. }
  2635. else
  2636. {
  2637. $sql = "SELECT m.member_id FROM exp_members m
  2638. LEFT JOIN exp_weblog_titles ON (exp_weblog_titles.author_id = m.member_id)
  2639. LEFT JOIN exp_comments ON (exp_comments.author_id = m.member_id) ";
  2640. if ($PREFS->ini('forum_is_installed') == "y")
  2641. {
  2642. $sql .= "LEFT JOIN exp_forum_topics ON (exp_forum_topics.author_id = m.member_id)
  2643. LEFT JOIN exp_forum_posts ON (exp_forum_posts.author_id = m.member_id) ";
  2644. }
  2645. $sql .= "WHERE ".$group_filter."
  2646. AND exp_weblog_titles.author_id IS NULL
  2647. AND exp_comments.author_id IS NULL ";
  2648. if ($PREFS->ini('forum_is_installed') == "y")
  2649. {
  2650. $sql .= "AND exp_forum_topics.author_id IS NULL
  2651. AND exp_forum_posts.author_id IS NULL ";
  2652. }
  2653. if ($days_ago != '')
  2654. {
  2655. $sql .= " AND m.join_date < {$days_ago}";
  2656. }
  2657. }
  2658. $query = $DB->query($sql);
  2659. if ($query->num_rows == 0)
  2660. {
  2661. return $DSP->error_message($LANG->line('no_members_matched'), 2);
  2662. }
  2663. $total = 0;
  2664. foreach ($query->result as $row)
  2665. {
  2666. $id = $row['member_id'];
  2667. if ($PREFS->ini('forum_is_installed') == "y")
  2668. {
  2669. $DB->query("DELETE FROM exp_forum_administrators WHERE admin_member_id = '{$id}'");
  2670. $DB->query("DELETE FROM exp_forum_moderators WHERE mod_member_id = '{$id}'");
  2671. }
  2672. $DB->query("DELETE FROM exp_members WHERE member_id = '{$id}'");
  2673. $DB->query("DELETE FROM exp_member_data WHERE member_id = '{$id}'");
  2674. $DB->query("DELETE FROM exp_member_homepage WHERE member_id = '{$id}'");
  2675. $message_query = $DB->query("SELECT DISTINCT recipient_id FROM exp_message_copies WHERE sender_id = '$id' AND message_read = 'n'");
  2676. $DB->query("DELETE FROM exp_message_copies WHERE sender_id = '$id'");
  2677. $DB->query("DELETE FROM exp_message_data WHERE sender_id = '$id'");
  2678. $DB->query("DELETE FROM exp_message_folders WHERE member_id = '$id'");
  2679. $DB->query("DELETE FROM exp_message_listed WHERE member_id = '$id'");
  2680. if ($message_query->num_rows > 0)
  2681. {
  2682. foreach($message_query->result as $row)
  2683. {
  2684. $count_query = $DB->query("SELECT COUNT(*) AS count FROM exp_message_copies WHERE recipient_id = '".$row['recipient_id']."' AND message_read = 'n'");
  2685. $DB->query($DB->update_string('exp_members', array('private_messages' => $count_query->row['count']), "member_id = '".$row['recipient_id']."'"));
  2686. }
  2687. }
  2688. $total++;
  2689. }
  2690. // Update global stats
  2691. $STAT->update_member_stats();
  2692. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=member_pruning'.AMP.'update='.$total);
  2693. exit;
  2694. }
  2695. /* END */
  2696. /** -------------------------------------------
  2697. /** Weblog Entry pruning
  2698. /** -------------------------------------------*/
  2699. function entry_pruning()
  2700. {
  2701. global $IN, $DSP, $LANG, $PREFS, $DB;
  2702. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2703. {
  2704. return $DSP->no_access_message();
  2705. }
  2706. $r = '';
  2707. if ($IN->GBL('update') !== FALSE)
  2708. {
  2709. $r .= $DSP->qdiv('box', $DSP->qdiv('success', str_replace('%x', $IN->GBL('update'), $LANG->line('good_entry_pruning'))));
  2710. }
  2711. $r .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_entry_conf'));
  2712. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  2713. $r .= $DSP->table_row(array(
  2714. array(
  2715. 'text' => $LANG->line('weblog_entry_pruning'),
  2716. 'class' => 'tableHeading',
  2717. 'colspan' => '2'
  2718. )
  2719. )
  2720. );
  2721. $data = $DSP->qdiv('itemWrapper', $DSP->qdiv('defaultBold', $LANG->line('weblog_prune_x_days')));
  2722. $data .= $DSP->qdiv('itemWrapper', NBS.NBS.$DSP->input_checkbox('comment_filter', 'y', 1).NBS.$LANG->line('weblog_prune_never_posted'));
  2723. $r .= $DSP->table_row(array(
  2724. array(
  2725. 'text' => $data,
  2726. 'class' => 'tableCellTwo',
  2727. 'width' => '50%'
  2728. ),
  2729. array(
  2730. 'text' => $DSP->input_text('days_ago', '365', '10', '4', 'input', '40px'),
  2731. 'class' => 'tableCellTwo',
  2732. 'width' => '50%'
  2733. )
  2734. )
  2735. );
  2736. $r .= $DSP->table_close();
  2737. $query = $DB->query("SELECT weblog_id, blog_title FROM exp_weblogs ORDER BY blog_title");
  2738. $r .= $DSP->qdiv('tableHeading', $LANG->line('select_prune_blogs'));
  2739. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  2740. $r .= $DSP->table_row(array(
  2741. array(
  2742. 'text' => $LANG->line('must_select_one'),
  2743. 'class' => 'tableHeadingAlt'
  2744. )
  2745. )
  2746. );
  2747. $i = 0;
  2748. foreach ($query->result as $row)
  2749. {
  2750. $class = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  2751. $r .= $DSP->table_row(array(
  2752. array(
  2753. 'text' => $DSP->qdiv('defaultBold', $DSP->input_checkbox('blog_'.$row['weblog_id'], 'y').NBS.$row['blog_title']),
  2754. 'class' => $class,
  2755. 'width' => '50%'
  2756. )
  2757. )
  2758. );
  2759. }
  2760. $r .= $DSP->table_close();
  2761. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit());
  2762. $r .= $DSP->form_close();
  2763. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2764. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  2765. $DSP->crumb_item($LANG->line('weblog_entry_pruning'));
  2766. $DSP->set_return_data($LANG->line('weblog_entry_pruning'), $r, $c);
  2767. }
  2768. /* END */
  2769. /** ---------------------------------------
  2770. /** Weblog Entry Pruning Confirmation
  2771. /** ---------------------------------------*/
  2772. function prune_entry_confirm()
  2773. {
  2774. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  2775. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2776. {
  2777. return $DSP->no_access_message();
  2778. }
  2779. /** ---------------------------------------
  2780. /** Did they submit the number of day?
  2781. /** ---------------------------------------*/
  2782. if ( ! is_numeric($_POST['days_ago']))
  2783. {
  2784. return $DSP->error_message($LANG->line('must_submit_number'));
  2785. }
  2786. /** ---------------------------------------
  2787. /** Did they submit blog IDs?
  2788. /** ---------------------------------------*/
  2789. $blogs = FALSE;
  2790. foreach ($_POST as $key => $val)
  2791. {
  2792. if (substr($key, 0, 5) == 'blog_')
  2793. {
  2794. $blogs = TRUE;
  2795. break;
  2796. }
  2797. }
  2798. if ($blogs == FALSE)
  2799. {
  2800. return $DSP->error_message($LANG->line('must_submit_blog'));
  2801. }
  2802. $r = $DSP->delete_confirmation(
  2803. array(
  2804. 'url' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_entries',
  2805. 'heading' => 'weblog_entry_pruning',
  2806. 'message' => 'prune_entry_confirm_msg',
  2807. 'hidden' => $_POST
  2808. )
  2809. );
  2810. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2811. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  2812. $DSP->crumb_item($LANG->line('weblog_entry_pruning'));
  2813. $DSP->set_return_data($LANG->line('weblog_entry_pruning'), $r, $c);
  2814. }
  2815. /* END */
  2816. /** ---------------------------------------
  2817. /** Prune Entries
  2818. /** ---------------------------------------*/
  2819. function prune_entries()
  2820. {
  2821. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  2822. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2823. {
  2824. return $DSP->no_access_message();
  2825. }
  2826. /** ---------------------------------------
  2827. /** Did they submit the number of day?
  2828. /** ---------------------------------------*/
  2829. if ( ! is_numeric($_POST['days_ago']))
  2830. {
  2831. return $DSP->error_message($LANG->line('must_submit_number'));
  2832. }
  2833. /** ---------------------------------------
  2834. /** Did they submit blog IDs?
  2835. /** ---------------------------------------*/
  2836. $blogs = FALSE;
  2837. $blog_ids = array();
  2838. foreach ($_POST as $key => $val)
  2839. {
  2840. if (substr($key, 0, 5) == 'blog_')
  2841. {
  2842. $blogs .= "'".substr($key, 5)."',";
  2843. $blog_ids[] = substr($key, 5);
  2844. }
  2845. }
  2846. if ($blogs == '')
  2847. {
  2848. return $DSP->error_message($LANG->line('must_submit_blog'), 2);
  2849. }
  2850. $blogs = " w.weblog_id IN (".substr($blogs, 0, -1).')';
  2851. $days_ago = ($_POST['days_ago'] > 0) ? ($LOC->now - (60*60*24*$_POST['days_ago'])) : '';
  2852. /** ---------------------------------------
  2853. /** Fetch the entry IDs
  2854. /** ---------------------------------------*/
  2855. if ( ! isset($_POST['comment_filter']))
  2856. {
  2857. $sql = "SELECT w.entry_id FROM exp_weblog_titles w WHERE ".$blogs;
  2858. if ($days_ago != '')
  2859. {
  2860. $sql .= " AND w.entry_date < {$days_ago}";
  2861. }
  2862. }
  2863. else
  2864. {
  2865. $sql = "SELECT w.entry_id FROM exp_weblog_titles w
  2866. LEFT JOIN exp_comments ON (exp_comments.entry_id = w.entry_id)
  2867. WHERE ".$blogs."
  2868. AND exp_comments.entry_id IS NULL ";
  2869. if ($days_ago != '')
  2870. {
  2871. $sql .= " AND w.entry_date < {$days_ago}";
  2872. }
  2873. }
  2874. $query = $DB->query($sql);
  2875. if ($query->num_rows == 0)
  2876. {
  2877. return $DSP->error_message($LANG->line('no_entries_matched'), 2);
  2878. }
  2879. $total = 0;
  2880. foreach ($query->result as $row)
  2881. {
  2882. $id = $row['entry_id'];
  2883. $DB->query("DELETE FROM exp_weblog_titles WHERE entry_id = '$id'");
  2884. $DB->query("DELETE FROM exp_weblog_data WHERE entry_id = '$id'");
  2885. $DB->query("DELETE FROM exp_category_posts WHERE entry_id = '$id'");
  2886. $DB->query("DELETE FROM exp_trackbacks WHERE entry_id = '$id'");
  2887. $DB->query("DELETE FROM exp_comments WHERE entry_id = '$id'");
  2888. $total++;
  2889. }
  2890. // Update global stats
  2891. $STAT->update_member_stats();
  2892. foreach ($blog_ids as $id)
  2893. {
  2894. $STAT->update_weblog_stats($id);
  2895. $STAT->update_comment_stats($id, '' , FALSE); // Weblog, Not Global
  2896. $STAT->update_trackback_stats($id);
  2897. }
  2898. $STAT->update_comment_stats(); // Global Comment Stats
  2899. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=entry_pruning'.AMP.'update='.$total);
  2900. exit;
  2901. }
  2902. /* END */
  2903. /** -------------------------------------------
  2904. /** Comment pruning
  2905. /** -------------------------------------------*/
  2906. function comment_pruning()
  2907. {
  2908. global $IN, $DSP, $LANG, $PREFS, $DB;
  2909. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2910. {
  2911. return $DSP->no_access_message();
  2912. }
  2913. $r = '';
  2914. if ($IN->GBL('update') !== FALSE)
  2915. {
  2916. $r .= $DSP->qdiv('box', $DSP->qdiv('success', str_replace('%x', $IN->GBL('update'), $LANG->line('good_commennt_pruning'))));
  2917. }
  2918. $r .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_comment_conf'));
  2919. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  2920. $r .= $DSP->table_row(array(
  2921. array(
  2922. 'text' => $LANG->line('comment_pruning'),
  2923. 'class' => 'tableHeading',
  2924. 'colspan' => '2'
  2925. )
  2926. )
  2927. );
  2928. $r .= $DSP->table_row(array(
  2929. array(
  2930. 'text' => $DSP->qdiv('itemWrapper', $DSP->qdiv('defaultBold', $LANG->line('comment_prune_x_days'))),
  2931. 'class' => 'tableCellTwo',
  2932. 'width' => '50%'
  2933. ),
  2934. array(
  2935. 'text' => $DSP->input_text('days_ago', '365', '10', '4', 'input', '40px'),
  2936. 'class' => 'tableCellTwo',
  2937. 'width' => '50%'
  2938. )
  2939. )
  2940. );
  2941. $r .= $DSP->table_close();
  2942. $query = $DB->query("SELECT weblog_id, blog_title FROM exp_weblogs ORDER BY blog_title");
  2943. $r .= $DSP->qdiv('tableHeading', $LANG->line('select_prune_blogs'));
  2944. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  2945. $r .= $DSP->table_row(array(
  2946. array(
  2947. 'text' => $LANG->line('must_select_one'),
  2948. 'class' => 'tableHeadingAlt'
  2949. )
  2950. )
  2951. );
  2952. $i = 0;
  2953. foreach ($query->result as $row)
  2954. {
  2955. $class = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  2956. $r .= $DSP->table_row(array(
  2957. array(
  2958. 'text' => $DSP->qdiv('defaultBold', $DSP->input_checkbox('blog_'.$row['weblog_id'], 'y').NBS.$row['blog_title']),
  2959. 'class' => $class,
  2960. 'width' => '50%'
  2961. )
  2962. )
  2963. );
  2964. }
  2965. $r .= $DSP->table_close();
  2966. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit());
  2967. $r .= $DSP->form_close();
  2968. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  2969. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  2970. $DSP->crumb_item($LANG->line('comment_pruning'));
  2971. $DSP->set_return_data($LANG->line('comment_pruning'), $r, $c);
  2972. }
  2973. /* END */
  2974. /** ---------------------------------------
  2975. /** Comment Pruning Confirmation
  2976. /** ---------------------------------------*/
  2977. function prune_comment_confirmation()
  2978. {
  2979. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  2980. if ( ! $DSP->allowed_group('can_admin_utilities'))
  2981. {
  2982. return $DSP->no_access_message();
  2983. }
  2984. /** ---------------------------------------
  2985. /** Did they submit the number of day?
  2986. /** ---------------------------------------*/
  2987. if ( ! is_numeric($_POST['days_ago']))
  2988. {
  2989. return $DSP->error_message($LANG->line('must_submit_number'));
  2990. }
  2991. /** ---------------------------------------
  2992. /** Did they submit blog IDs?
  2993. /** ---------------------------------------*/
  2994. $blogs = FALSE;
  2995. foreach ($_POST as $key => $val)
  2996. {
  2997. if (substr($key, 0, 5) == 'blog_')
  2998. {
  2999. $blogs = TRUE;
  3000. break;
  3001. }
  3002. }
  3003. if ($blogs == FALSE)
  3004. {
  3005. return $DSP->error_message($LANG->line('must_submit_blog'));
  3006. }
  3007. $r = $DSP->delete_confirmation(
  3008. array(
  3009. 'url' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_comments',
  3010. 'heading' => 'comment_pruning',
  3011. 'message' => 'prune_comment_confirm_msg',
  3012. 'hidden' => $_POST
  3013. )
  3014. );
  3015. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3016. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  3017. $DSP->crumb_item($LANG->line('weblog_entry_pruning'));
  3018. $DSP->set_return_data($LANG->line('weblog_entry_pruning'), $r, $c);
  3019. }
  3020. /* END */
  3021. /** ---------------------------------------
  3022. /** Prune Comments
  3023. /** ---------------------------------------*/
  3024. function prune_comments()
  3025. {
  3026. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  3027. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3028. {
  3029. return $DSP->no_access_message();
  3030. }
  3031. /** ---------------------------------------
  3032. /** Did they submit the number of day?
  3033. /** ---------------------------------------*/
  3034. if ( ! is_numeric($_POST['days_ago']))
  3035. {
  3036. return $DSP->error_message($LANG->line('must_submit_number'));
  3037. }
  3038. /** ---------------------------------------
  3039. /** Did they submit blog IDs?
  3040. /** ---------------------------------------*/
  3041. $blogs = FALSE;
  3042. $blog_ids = array();
  3043. foreach ($_POST as $key => $val)
  3044. {
  3045. if (substr($key, 0, 5) == 'blog_')
  3046. {
  3047. $blogs .= "'".substr($key, 5)."',";
  3048. $blog_ids[] = substr($key, 5);
  3049. }
  3050. }
  3051. if ($blogs == '')
  3052. {
  3053. return $DSP->error_message($LANG->line('must_submit_blog'), 2);
  3054. }
  3055. $blogs = " weblog_id IN (".substr($blogs, 0, -1).')';
  3056. $days_ago = ($_POST['days_ago'] > 0) ? ($LOC->now - (60*60*24*$_POST['days_ago'])) : '';
  3057. /** ---------------------------------------
  3058. /** Fetch the comment IDs
  3059. /** ---------------------------------------*/
  3060. $sql = "SELECT comment_id, entry_id FROM exp_comments WHERE ".$blogs;
  3061. if ($days_ago != '')
  3062. {
  3063. $sql .= " AND comment_date < {$days_ago}";
  3064. }
  3065. $query = $DB->query($sql);
  3066. if ($query->num_rows == 0)
  3067. {
  3068. return $DSP->error_message($LANG->line('no_comments_matched'), 2);
  3069. }
  3070. $total = 0;
  3071. foreach ($query->result as $row)
  3072. {
  3073. $id = $row['comment_id'];
  3074. $entry_id = $row['entry_id'];
  3075. $DB->query("DELETE FROM exp_comments WHERE comment_id = '$id'");
  3076. $total++;
  3077. $res = $DB->query("SELECT MAX(comment_date) AS max_date FROM exp_comments WHERE status = 'o' AND entry_id = '{$entry_id}'");
  3078. $comment_date = ($res->num_rows == 0 OR ! is_numeric($res->row['max_date'])) ? 0 : $res->row['max_date'];
  3079. $res = $DB->query("SELECT COUNT(*) AS count FROM exp_comments WHERE entry_id = '{$entry_id}' AND status = 'o'");
  3080. $DB->query("UPDATE exp_weblog_titles SET comment_total = '".($res->row['count'])."', recent_comment_date = '$comment_date' WHERE entry_id = '{$entry_id}'");
  3081. }
  3082. // Update global stats
  3083. foreach ($blog_ids as $id)
  3084. {
  3085. $STAT->update_comment_stats($id, '' , FALSE);
  3086. }
  3087. $STAT->update_comment_stats(); // Global comment stats only
  3088. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=comment_pruning'.AMP.'update='.$total);
  3089. exit;
  3090. }
  3091. /* END */
  3092. /** -------------------------------------------
  3093. /** Trackback pruning
  3094. /** -------------------------------------------*/
  3095. function trackback_pruning()
  3096. {
  3097. global $IN, $DSP, $LANG, $PREFS, $DB;
  3098. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3099. {
  3100. return $DSP->no_access_message();
  3101. }
  3102. $r = '';
  3103. if ($IN->GBL('update') !== FALSE)
  3104. {
  3105. $r .= $DSP->qdiv('box', $DSP->qdiv('success', str_replace('%x', $IN->GBL('update'), $LANG->line('good_trackback_pruning'))));
  3106. }
  3107. $r .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_trackback_conf'));
  3108. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  3109. $r .= $DSP->table_row(array(
  3110. array(
  3111. 'text' => $LANG->line('trackback_pruning'),
  3112. 'class' => 'tableHeading',
  3113. 'colspan' => '2'
  3114. )
  3115. )
  3116. );
  3117. $r .= $DSP->table_row(array(
  3118. array(
  3119. 'text' => $DSP->qdiv('itemWrapper', $DSP->qdiv('defaultBold', $LANG->line('trackback_prune_x_days'))),
  3120. 'class' => 'tableCellTwo',
  3121. 'width' => '50%'
  3122. ),
  3123. array(
  3124. 'text' => $DSP->input_text('days_ago', '365', '10', '4', 'input', '40px'),
  3125. 'class' => 'tableCellTwo',
  3126. 'width' => '50%'
  3127. )
  3128. )
  3129. );
  3130. $r .= $DSP->table_close();
  3131. $query = $DB->query("SELECT weblog_id, blog_title FROM exp_weblogs ORDER BY blog_title");
  3132. $r .= $DSP->qdiv('tableHeading', $LANG->line('select_prune_blogs'));
  3133. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  3134. $r .= $DSP->table_row(array(
  3135. array(
  3136. 'text' => $LANG->line('must_select_one'),
  3137. 'class' => 'tableHeadingAlt'
  3138. )
  3139. )
  3140. );
  3141. $i = 0;
  3142. foreach ($query->result as $row)
  3143. {
  3144. $class = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  3145. $r .= $DSP->table_row(array(
  3146. array(
  3147. 'text' => $DSP->qdiv('defaultBold', $DSP->input_checkbox('blog_'.$row['weblog_id'], 'y').NBS.$row['blog_title']),
  3148. 'class' => $class,
  3149. 'width' => '50%'
  3150. )
  3151. )
  3152. );
  3153. }
  3154. $r .= $DSP->table_close();
  3155. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit());
  3156. $r .= $DSP->form_close();
  3157. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3158. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  3159. $DSP->crumb_item($LANG->line('trackback_pruning'));
  3160. $DSP->set_return_data($LANG->line('trackback_pruning'), $r, $c);
  3161. }
  3162. /* END */
  3163. /** ---------------------------------------
  3164. /** trackback Pruning Confirmation
  3165. /** ---------------------------------------*/
  3166. function prune_trackback_confirmation()
  3167. {
  3168. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  3169. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3170. {
  3171. return $DSP->no_access_message();
  3172. }
  3173. /** ---------------------------------------
  3174. /** Did they submit the number of day?
  3175. /** ---------------------------------------*/
  3176. if ( ! is_numeric($_POST['days_ago']))
  3177. {
  3178. return $DSP->error_message($LANG->line('must_submit_number'));
  3179. }
  3180. /** ---------------------------------------
  3181. /** Did they submit blog IDs?
  3182. /** ---------------------------------------*/
  3183. $blogs = FALSE;
  3184. foreach ($_POST as $key => $val)
  3185. {
  3186. if (substr($key, 0, 5) == 'blog_')
  3187. {
  3188. $blogs = TRUE;
  3189. break;
  3190. }
  3191. }
  3192. if ($blogs == FALSE)
  3193. {
  3194. return $DSP->error_message($LANG->line('must_submit_blog'));
  3195. }
  3196. $r = $DSP->delete_confirmation(
  3197. array(
  3198. 'url' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_trackbacks',
  3199. 'heading' => 'trackback_pruning',
  3200. 'message' => 'prune_trackback_confirm_msg',
  3201. 'hidden' => $_POST
  3202. )
  3203. );
  3204. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3205. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  3206. $DSP->crumb_item($LANG->line('weblog_entry_pruning'));
  3207. $DSP->set_return_data($LANG->line('weblog_entry_pruning'), $r, $c);
  3208. }
  3209. /* END */
  3210. /** ---------------------------------------
  3211. /** Prune trackbacks
  3212. /** ---------------------------------------*/
  3213. function prune_trackbacks()
  3214. {
  3215. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  3216. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3217. {
  3218. return $DSP->no_access_message();
  3219. }
  3220. /** ---------------------------------------
  3221. /** Did they submit the number of day?
  3222. /** ---------------------------------------*/
  3223. if ( ! is_numeric($_POST['days_ago']))
  3224. {
  3225. return $DSP->error_message($LANG->line('must_submit_number'));
  3226. }
  3227. /** ---------------------------------------
  3228. /** Did they submit blog IDs?
  3229. /** ---------------------------------------*/
  3230. $blogs = FALSE;
  3231. $blog_ids = array();
  3232. foreach ($_POST as $key => $val)
  3233. {
  3234. if (substr($key, 0, 5) == 'blog_')
  3235. {
  3236. $blogs .= "'".substr($key, 5)."',";
  3237. $blog_ids[] = substr($key, 5);
  3238. }
  3239. }
  3240. if ($blogs == '')
  3241. {
  3242. return $DSP->error_message($LANG->line('must_submit_blog'), 2);
  3243. }
  3244. $blogs = " weblog_id IN (".substr($blogs, 0, -1).')';
  3245. $days_ago = ($_POST['days_ago'] > 0) ? ($LOC->now - (60*60*24*$_POST['days_ago'])) : '';
  3246. /** ---------------------------------------
  3247. /** Fetch the trackback IDs
  3248. /** ---------------------------------------*/
  3249. $sql = "SELECT trackback_id FROM exp_trackbacks WHERE ".$blogs;
  3250. if ($days_ago != '')
  3251. {
  3252. $sql .= " AND trackback_date < {$days_ago}";
  3253. }
  3254. $query = $DB->query($sql);
  3255. if ($query->num_rows == 0)
  3256. {
  3257. return $DSP->error_message($LANG->line('no_trackbacks_matched'), 2);
  3258. }
  3259. $total = 0;
  3260. foreach ($query->result as $row)
  3261. {
  3262. $id = $row['trackback_id'];
  3263. $DB->query("DELETE FROM exp_trackbacks WHERE trackback_id = '$id'");
  3264. $total++;
  3265. $res = $DB->query("SELECT MAX(trackback_date) AS max_date FROM exp_trackbacks WHERE entry_id = '{$id}'");
  3266. $trackback_date = ($res->num_rows == 0 OR ! is_numeric($res->row['max_date'])) ? 0 : $res->row['max_date'];
  3267. $res = $DB->query("SELECT COUNT(*) AS count FROM exp_trackbacks WHERE entry_id = '{$id}'");
  3268. $DB->query("UPDATE exp_weblog_titles SET trackback_total = '".($res->row['count'])."', recent_trackback_date = '$trackback_date' WHERE entry_id = '{$id}'");
  3269. }
  3270. // Update global stats
  3271. foreach ($blog_ids as $id)
  3272. {
  3273. $STAT->update_trackback_stats($id);
  3274. }
  3275. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=trackback_pruning'.AMP.'update='.$total);
  3276. exit;
  3277. }
  3278. /* END */
  3279. /** -------------------------------------
  3280. /** Private Message Pruning
  3281. /** -------------------------------------*/
  3282. function pm_pruning()
  3283. {
  3284. global $IN, $DSP, $LANG;
  3285. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3286. {
  3287. return $DSP->no_access_message();
  3288. }
  3289. $r = '';
  3290. if ($IN->GBL('update') !== FALSE)
  3291. {
  3292. $r .= $DSP->qdiv('box', $DSP->qdiv('success', str_replace('%x', $IN->GBL('update'), $LANG->line('good_pm_pruning'))));
  3293. }
  3294. $r .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_pm_conf'));
  3295. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  3296. $r .= $DSP->table_row(array(
  3297. array(
  3298. 'text' => $LANG->line('pm_pruning'),
  3299. 'class' => 'tableHeading',
  3300. 'colspan' => '2'
  3301. )
  3302. )
  3303. );
  3304. $data = $DSP->qdiv('itemWrapper', $DSP->qdiv('defaultBold', $LANG->line('pm_prune_x_days')));
  3305. $r .= $DSP->table_row(array(
  3306. array(
  3307. 'text' => $data,
  3308. 'class' => 'tableCellTwo',
  3309. 'width' => '50%'
  3310. ),
  3311. array(
  3312. 'text' => $DSP->input_text('days_ago', '30', '10', '4', 'input', '40px'),
  3313. 'class' => 'tableCellTwo',
  3314. 'width' => '50%'
  3315. )
  3316. )
  3317. );
  3318. $r .= $DSP->table_close();
  3319. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit());
  3320. $r .= $DSP->form_close();
  3321. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3322. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  3323. $DSP->crumb_item($LANG->line('pm_pruning'));
  3324. $DSP->set_return_data($LANG->line('pm_pruning'), $r, $c);
  3325. }
  3326. /* END */
  3327. /** -------------------------------------
  3328. /** Private Message Pruning Confirmation
  3329. /** -------------------------------------*/
  3330. function prune_pm_confirmation()
  3331. {
  3332. global $DSP, $LANG;
  3333. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3334. {
  3335. return $DSP->no_access_message();
  3336. }
  3337. /** -------------------------------------
  3338. /** Did they submit the number of days?
  3339. /** -------------------------------------*/
  3340. if ( ! is_numeric($_POST['days_ago']))
  3341. {
  3342. return $DSP->error_message($LANG->line('must_submit_number'));
  3343. }
  3344. $r = $DSP->delete_confirmation(
  3345. array(
  3346. 'url' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_pms',
  3347. 'heading' => 'pm_pruning',
  3348. 'message' => 'prune_pm_confirm_msg',
  3349. 'hidden' => $_POST
  3350. )
  3351. );
  3352. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3353. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  3354. $DSP->crumb_item($LANG->line('pm_pruning'));
  3355. $DSP->set_return_data($LANG->line('pm_pruning'), $r, $c);
  3356. }
  3357. /* END */
  3358. /** -------------------------------------
  3359. /** Prune Private Messages
  3360. /** -------------------------------------*/
  3361. function prune_pms()
  3362. {
  3363. global $DB, $DSP, $FNS, $LANG, $LOC;
  3364. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3365. {
  3366. return $DSP->no_access_message();
  3367. }
  3368. /** -------------------------------------
  3369. /** Did they submit the number of days?
  3370. /** -------------------------------------*/
  3371. if ( ! is_numeric($_POST['days_ago']))
  3372. {
  3373. return $DSP->error_message($LANG->line('must_submit_number'));
  3374. }
  3375. if ( ! class_exists('Messages'))
  3376. {
  3377. require PATH_CORE.'core.messages'.EXT;
  3378. }
  3379. $MESS = new Messages;
  3380. $MESS->delete_expiration = $_POST['days_ago'];
  3381. $deletion_time = $LOC->now - ($MESS->delete_expiration*24*60*60);
  3382. $member_ids = array();
  3383. /** -------------------------------------
  3384. /** Members who have old deleted messages
  3385. /** -------------------------------------*/
  3386. $query = $DB->query("SELECT DISTINCT recipient_id FROM exp_message_copies
  3387. WHERE message_deleted = 'y'
  3388. AND message_time_read < $deletion_time");
  3389. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=pm_pruning'.AMP.'update='.$total);
  3390. exit;
  3391. }
  3392. /* END */
  3393. /** -------------------------------------------
  3394. /** Forum Topic pruning
  3395. /** -------------------------------------------*/
  3396. function topic_pruning()
  3397. {
  3398. global $IN, $DSP, $LANG, $PREFS, $DB;
  3399. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3400. {
  3401. return $DSP->no_access_message();
  3402. }
  3403. $r = '';
  3404. if ($IN->GBL('update') !== FALSE)
  3405. {
  3406. $r .= $DSP->qdiv('box', $DSP->qdiv('success', str_replace('%x', $IN->GBL('update'), $LANG->line('good_topic_pruning'))));
  3407. }
  3408. $r .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_topic_conf'));
  3409. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  3410. $r .= $DSP->table_row(array(
  3411. array(
  3412. 'text' => $LANG->line('topic_pruning'),
  3413. 'class' => 'tableHeading',
  3414. 'colspan' => '2'
  3415. )
  3416. )
  3417. );
  3418. $data = $DSP->qdiv('itemWrapper', $DSP->qdiv('defaultBold', $LANG->line('topic_prune_x_days')));
  3419. $data .= $DSP->qdiv('itemWrapper', NBS.NBS.$DSP->input_checkbox('post_filter', 'y', 1).NBS.$LANG->line('prune_if_no_posts'));
  3420. $r .= $DSP->table_row(array(
  3421. array(
  3422. 'text' => $data,
  3423. 'class' => 'tableCellTwo',
  3424. 'width' => '50%'
  3425. ),
  3426. array(
  3427. 'text' => $DSP->input_text('days_ago', '365', '10', '4', 'input', '40px'),
  3428. 'class' => 'tableCellTwo',
  3429. 'width' => '50%'
  3430. )
  3431. )
  3432. );
  3433. $r .= $DSP->table_close();
  3434. $query = $DB->query("SELECT forum_id, forum_name FROM exp_forums WHERE forum_is_cat = 'n' ORDER BY forum_order");
  3435. $r .= $DSP->qdiv('tableHeading', $LANG->line('select_prune_topics'));
  3436. $r .= $DSP->table_open(array('class' => 'tableBorder', 'width' => '100%'));
  3437. $r .= $DSP->table_row(array(
  3438. array(
  3439. 'text' => $LANG->line('must_select_one'),
  3440. 'class' => 'tableHeadingAlt'
  3441. )
  3442. )
  3443. );
  3444. $i = 0;
  3445. foreach ($query->result as $row)
  3446. {
  3447. $class = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  3448. $r .= $DSP->table_row(array(
  3449. array(
  3450. 'text' => $DSP->qdiv('defaultBold', $DSP->input_checkbox('forum_id_'.$row['forum_id'], 'y').NBS.$row['forum_name']),
  3451. 'class' => $class,
  3452. 'width' => '50%'
  3453. )
  3454. )
  3455. );
  3456. }
  3457. $r .= $DSP->table_close();
  3458. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit());
  3459. $r .= $DSP->form_close();
  3460. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3461. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  3462. $DSP->crumb_item($LANG->line('topic_pruning'));
  3463. $DSP->set_return_data($LANG->line('topic_pruning'), $r, $c);
  3464. }
  3465. /* END */
  3466. /** ---------------------------------------
  3467. /** Forum Topic Pruning Confirmation
  3468. /** ---------------------------------------*/
  3469. function prune_topic_confirmation()
  3470. {
  3471. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  3472. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3473. {
  3474. return $DSP->no_access_message();
  3475. }
  3476. /** ---------------------------------------
  3477. /** Did they submit the number of day?
  3478. /** ---------------------------------------*/
  3479. if ( ! is_numeric($_POST['days_ago']))
  3480. {
  3481. return $DSP->error_message($LANG->line('must_submit_number'));
  3482. }
  3483. /** ---------------------------------------
  3484. /** Did they submit forum IDs?
  3485. /** ---------------------------------------*/
  3486. $forums = FALSE;
  3487. foreach ($_POST as $key => $val)
  3488. {
  3489. if (substr($key, 0, 9) == 'forum_id_')
  3490. {
  3491. $forums = TRUE;
  3492. break;
  3493. }
  3494. }
  3495. if ($forums == FALSE)
  3496. {
  3497. return $DSP->error_message($LANG->line('must_submit_forums'));
  3498. }
  3499. $r = $DSP->delete_confirmation(
  3500. array(
  3501. 'url' => 'C=admin'.AMP.'M=utilities'.AMP.'P=prune_topics',
  3502. 'heading' => 'topic_pruning',
  3503. 'message' => 'prune_topic_confirm_msg',
  3504. 'hidden' => $_POST
  3505. )
  3506. );
  3507. $c = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3508. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=prune', $LANG->line('data_pruning'))).
  3509. $DSP->crumb_item($LANG->line('topic_pruning'));
  3510. $DSP->set_return_data($LANG->line('topic_pruning'), $r, $c);
  3511. }
  3512. /* END */
  3513. /** ---------------------------------------
  3514. /** Prune Forum Topics
  3515. /** ---------------------------------------*/
  3516. function prune_topics()
  3517. {
  3518. global $DSP, $FNS, $LANG, $DB, $PREFS, $LOC, $STAT;
  3519. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3520. {
  3521. return $DSP->no_access_message();
  3522. }
  3523. /** ---------------------------------------
  3524. /** Did they submit the number of day?
  3525. /** ---------------------------------------*/
  3526. if ( ! is_numeric($_POST['days_ago']))
  3527. {
  3528. return $DSP->error_message($LANG->line('must_submit_number'));
  3529. }
  3530. /** ---------------------------------------
  3531. /** Did they submit topic IDs?
  3532. /** ---------------------------------------*/
  3533. $forums = FALSE;
  3534. $topic_ids = array();
  3535. foreach ($_POST as $key => $val)
  3536. {
  3537. if (substr($key, 0, 9) == 'forum_id_')
  3538. {
  3539. $forums .= "'".substr($key, 9)."',";
  3540. $topic_ids[] = substr($key, 9);
  3541. }
  3542. }
  3543. if ($forums == '')
  3544. {
  3545. return $DSP->error_message($LANG->line('must_submit_forums'), 2);
  3546. }
  3547. $forums = " t.forum_id IN (".substr($forums, 0, -1).')';
  3548. $days_ago = (is_numeric($_POST['days_ago']) AND $_POST['days_ago'] > 0) ? ($LOC->now - (60*60*24*$_POST['days_ago'])) : '';
  3549. /** ---------------------------------------
  3550. /** Fetch the topic IDs
  3551. /** ---------------------------------------*/
  3552. if ( ! isset($_POST['post_filter']))
  3553. {
  3554. $sql = "SELECT t.topic_id FROM exp_forum_topics t WHERE ".$forums;
  3555. if ($days_ago != '')
  3556. {
  3557. $sql .= " AND t.topic_date < {$days_ago}";
  3558. }
  3559. }
  3560. else
  3561. {
  3562. $sql = "SELECT t.topic_id FROM exp_forum_topics t
  3563. LEFT JOIN exp_forum_posts p ON (p.topic_id = t.topic_id)
  3564. WHERE p.topic_id IS NULL
  3565. AND ".$forums;
  3566. if ($days_ago != '')
  3567. {
  3568. $sql .= " AND t.topic_date < {$days_ago}";
  3569. }
  3570. }
  3571. $query = $DB->query($sql);
  3572. if ($query->num_rows == 0)
  3573. {
  3574. return $DSP->error_message($LANG->line('no_topics_matched'), 2);
  3575. }
  3576. $total = 0;
  3577. foreach ($query->result as $row)
  3578. {
  3579. $id = $row['topic_id'];
  3580. $DB->query("DELETE FROM exp_forum_topics WHERE topic_id = '{$id}'");
  3581. $DB->query("DELETE FROM exp_forum_posts WHERE topic_id = '{$id}'");
  3582. $DB->query("DELETE FROM exp_forum_subscriptions WHERE topic_id = '{$id}'");
  3583. $total++;
  3584. }
  3585. /** -------------------------------------
  3586. /** Update stats
  3587. /** -------------------------------------*/
  3588. include_once PATH_MOD.'forum/mod.forum'.EXT;
  3589. include_once PATH_MOD.'forum/mod.forum_core'.EXT;
  3590. foreach ($topic_ids as $id)
  3591. {
  3592. Forum_Core::_update_post_stats($id);
  3593. }
  3594. $FNS->redirect(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=topic_pruning'.AMP.'update='.$total);
  3595. exit;
  3596. }
  3597. /* END */
  3598. /** -------------------------------------------
  3599. /** Recalculate Statistics - Main Page
  3600. /** -------------------------------------------*/
  3601. function recount_statistics()
  3602. {
  3603. global $DSP, $LANG, $DB, $PREFS;
  3604. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3605. {
  3606. return $DSP->no_access_message();
  3607. }
  3608. // Does the forum exist?
  3609. $forum_exists = FALSE;
  3610. if ($PREFS->ini('forum_is_installed') == "y")
  3611. {
  3612. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_modules WHERE module_name = 'Forum'");
  3613. if ($query->row['count'] > 0)
  3614. {
  3615. $forum_exists = TRUE;
  3616. }
  3617. }
  3618. if ($forum_exists == FALSE)
  3619. {
  3620. $sources = array('exp_members', 'exp_weblog_titles');
  3621. }
  3622. else
  3623. {
  3624. $sources = array('exp_members', 'exp_weblog_titles', 'exp_forums', 'exp_forum_topics');
  3625. }
  3626. $DSP->title = $LANG->line('utilities');
  3627. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3628. $DSP->crumb_item($LANG->line('recount_stats'));
  3629. $DSP->right_crumb($LANG->line('set_recount_prefs'), BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=recount_prefs');
  3630. $r = $DSP->qdiv('tableHeading', $LANG->line('recalculate'));
  3631. $r .= $DSP->qdiv('box', $LANG->line('recount_info'));
  3632. $r .= $DSP->table('tableBorder', '0', '', '100%').
  3633. $DSP->tr().
  3634. $DSP->table_qcell('tableHeadingAlt',
  3635. array(
  3636. $LANG->line('source'),
  3637. $LANG->line('records'),
  3638. $LANG->line('action')
  3639. )
  3640. ).
  3641. $DSP->tr_c();
  3642. $i = 0;
  3643. foreach ($sources as $val)
  3644. {
  3645. $query = $DB->query("SELECT COUNT(*) AS count FROM $val");
  3646. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  3647. $r .= $DSP->tr();
  3648. // Table name
  3649. $r .= $DSP->table_qcell($style, $DSP->qdiv('defaultBold', $LANG->line($val)), '20%');
  3650. // Table rows
  3651. $r .= $DSP->table_qcell($style, $query->row['count'], '20%');
  3652. // Action
  3653. $r .= $DSP->table_qcell($style, $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=do_recount'.AMP.'TBL='.$val, $LANG->line('do_recount')), '20%');
  3654. }
  3655. $style = ($i++ % 2) ? 'tableCellOne' : 'tableCellTwo';
  3656. $r .= $DSP->tr();
  3657. // Table name
  3658. $r .= $DSP->table_qcell($style, $DSP->qdiv('defaultBold', $LANG->line('site_statistics')), '20%');
  3659. // Table rows
  3660. $r .= $DSP->table_qcell($style, '4', '20%');
  3661. // Action
  3662. $r .= $DSP->table_qcell($style, $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=do_stats_recount', $LANG->line('do_recount')), '20%');
  3663. $r .= $DSP->table_c();
  3664. $DSP->body = $r;
  3665. }
  3666. /* END */
  3667. /** -------------------------------------------
  3668. /** Recount preferences form
  3669. /** -------------------------------------------*/
  3670. function recount_preferences_form()
  3671. {
  3672. global $IN, $DSP, $LANG, $PREFS;
  3673. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3674. {
  3675. return $DSP->no_access_message();
  3676. }
  3677. $recount_batch_total = $PREFS->ini('recount_batch_total');
  3678. $DSP->title = $LANG->line('utilities');
  3679. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3680. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=recount_stats', $LANG->line('recount_stats'))).
  3681. $DSP->crumb_item($LANG->line('set_recount_prefs'));
  3682. $r = $DSP->qdiv('tableHeading', $LANG->line('set_recount_prefs'));
  3683. if ($IN->GBL('U'))
  3684. {
  3685. $r .= $DSP->qdiv('box', $DSP->qdiv('success', $LANG->line('preference_updated')));
  3686. }
  3687. $r .= $DSP->form_open(
  3688. array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=set_recount_prefs'),
  3689. array('return_location' => BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=recount_prefs'.AMP.'U=1')
  3690. );
  3691. $r .= $DSP->div('box');
  3692. $r .= $DSP->qdiv('itemWrapper', $DSP->qdiv('defaultBold', $LANG->line('recount_instructions')));
  3693. $r .= $DSP->qdiv('itemWrapper', $LANG->line('recount_instructions_cont'));
  3694. $r .= $DSP->input_text('recount_batch_total', $recount_batch_total, '7', '5', 'input', '60px');
  3695. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit($LANG->line('update')));
  3696. $r .= $DSP->div_c();
  3697. $r .= $DSP->form_close();
  3698. $DSP->body = $r;
  3699. }
  3700. /* END */
  3701. /** -------------------------------------------
  3702. /** Update recount preferences
  3703. /** -------------------------------------------*/
  3704. function set_recount_prefs()
  3705. {
  3706. global $IN, $LANG, $DSP, $PREFS;
  3707. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3708. {
  3709. return $DSP->no_access_message();
  3710. }
  3711. $total = $IN->GBL('recount_batch_total');
  3712. if ($total == '' || ! is_numeric($total))
  3713. {
  3714. return Utilities::recount_preferences_form();
  3715. }
  3716. $this->update_config_prefs(array('recount_batch_total' => $total));
  3717. }
  3718. /* END */
  3719. /** -------------------------------------------
  3720. /** Do General Statistics Recount
  3721. /** -------------------------------------------*/
  3722. function do_stats_recount()
  3723. {
  3724. global $DSP, $LANG, $STAT, $DB, $PREFS;
  3725. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3726. {
  3727. return $DSP->no_access_message();
  3728. }
  3729. $original_site_id = $PREFS->ini('site_id');
  3730. $query = $DB->query("SELECT site_id FROM exp_sites");
  3731. foreach($query->result as $row)
  3732. {
  3733. $PREFS->core_ini['site_id'] = $row['site_id'];
  3734. $STAT->update_comment_stats();
  3735. $STAT->update_member_stats();
  3736. $STAT->update_weblog_stats();
  3737. $STAT->update_trackback_stats();
  3738. }
  3739. $PREFS->core_ini['site_id'] = $original_site_id;
  3740. $DSP->title = $LANG->line('utilities');
  3741. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3742. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=recount_stats', $LANG->line('recalculate'))).
  3743. $DSP->crumb_item($LANG->line('recounting'));
  3744. $DSP->body = $DSP->qdiv('tableHeading', $LANG->line('site_statistics'));
  3745. $DSP->body .= $DSP->div('box');
  3746. $DSP->body .= $DSP->qdiv('success', $LANG->line('recount_completed'));
  3747. $DSP->body .= $DSP->qdiv('itemWrapper', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=recount_stats', $LANG->line('return_to_recount_overview')));
  3748. $DSP->body .= $DSP->div_c();
  3749. }
  3750. /* END */
  3751. /** -------------------------------------------
  3752. /** Do member/weblog recount
  3753. /** -------------------------------------------*/
  3754. function do_recount()
  3755. {
  3756. global $IN, $DSP, $LANG, $DB, $PREFS, $LOC;
  3757. if ( ! $DSP->allowed_group('can_admin_utilities'))
  3758. {
  3759. return $DSP->no_access_message();
  3760. }
  3761. if ( ! $table = $IN->GBL('TBL', 'GET'))
  3762. {
  3763. return false;
  3764. }
  3765. $sources = array('exp_members', 'exp_weblog_titles', 'exp_forums', 'exp_forum_topics');
  3766. if ( ! in_array($table, $sources))
  3767. {
  3768. return false;
  3769. }
  3770. if ( ! isset($_GET['T']))
  3771. {
  3772. $num_rows = FALSE;
  3773. }
  3774. else
  3775. {
  3776. $num_rows = $_GET['T'];
  3777. settype($num_rows, 'integer');
  3778. }
  3779. $batch = $PREFS->ini('recount_batch_total');
  3780. if ($table == 'exp_members')
  3781. {
  3782. // Check to see if the forum module is installed
  3783. $forum_exists = FALSE;
  3784. if ($PREFS->ini('forum_is_installed') == "y")
  3785. {
  3786. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_modules WHERE module_name = 'Forum'");
  3787. if ($query->row['count'] > 0)
  3788. {
  3789. $forum_exists = TRUE;
  3790. }
  3791. }
  3792. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_members");
  3793. $total_rows = $query->row['count'];
  3794. if ($num_rows !== FALSE)
  3795. {
  3796. $query = $DB->query("SELECT member_id FROM exp_members ORDER BY member_id LIMIT $num_rows, $batch");
  3797. foreach ($query->result as $row)
  3798. {
  3799. $res = $DB->query("SELECT count(entry_id) AS count FROM exp_weblog_titles WHERE author_id = '".$row['member_id']."'");
  3800. $total_entries = $res->row['count'];
  3801. $res = $DB->query("SELECT count(comment_id) AS count FROM exp_comments WHERE author_id = '".$row['member_id']."'");
  3802. $total_comments = $res->row['count'];
  3803. $res = $DB->query("SELECT COUNT(*) AS count FROM exp_message_copies WHERE recipient_id = '".$row['member_id']."' AND message_read = 'n'");
  3804. $total_pms = $res->row['count'];
  3805. if ($forum_exists == FALSE)
  3806. {
  3807. $DB->query($DB->update_string('exp_members', array( 'total_entries' => $total_entries,'total_comments' => $total_comments, 'private_messages' => $total_pms), "member_id = '".$row['member_id']."'"));
  3808. }
  3809. else
  3810. {
  3811. $res = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_topics WHERE author_id = '".$row['member_id']."'");
  3812. $total_forum_topics = $res->row['count'];
  3813. $res = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_posts WHERE author_id = '".$row['member_id']."'");
  3814. $total_forum_posts = $res->row['count'];
  3815. $DB->query($DB->update_string('exp_members', array( 'total_entries' => $total_entries,'total_comments' => $total_comments, 'private_messages' => $total_pms, 'total_forum_topics' => $total_forum_topics, 'total_forum_posts' => $total_forum_posts), "member_id = '".$row['member_id']."'"));
  3816. }
  3817. }
  3818. }
  3819. }
  3820. elseif ($table == 'exp_weblog_titles')
  3821. {
  3822. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_weblog_titles");
  3823. $total_rows = $query->row['count'];
  3824. if ($num_rows !== FALSE)
  3825. {
  3826. $query = $DB->query("SELECT entry_id FROM exp_weblog_titles ORDER BY entry_id LIMIT $num_rows, $batch");
  3827. foreach ($query->result as $row)
  3828. {
  3829. $res = $DB->query("SELECT count(comment_id) AS count FROM exp_comments WHERE entry_id = '".$row['entry_id']."' AND status = 'o'");
  3830. $comment_total = $res->row['count'];
  3831. $res = $DB->query("SELECT MAX(comment_date) as recent FROM exp_comments WHERE entry_id = '".$row['entry_id']."' AND status = 'o'");
  3832. $comment_date = $res->row['recent'];
  3833. $res = $DB->query("SELECT count(trackback_id) AS count FROM exp_trackbacks WHERE entry_id = '".$row['entry_id']."'");
  3834. $trackback_total = $res->row['count'];
  3835. $res = $DB->query("SELECT MAX(trackback_date) as recent FROM exp_trackbacks WHERE entry_id = '".$row['entry_id']."'");
  3836. $trackback_date = $res->row['recent'];
  3837. $DB->query($DB->update_string('exp_weblog_titles', array( 'comment_total' => $comment_total, 'recent_comment_date' => $comment_date, 'trackback_total' => $trackback_total, 'recent_trackback_date' => $trackback_date), "entry_id = '".$row['entry_id']."'"));
  3838. }
  3839. }
  3840. }
  3841. elseif ($table == 'exp_forums')
  3842. {
  3843. $query = $DB->query("SELECT forum_id FROM exp_forums WHERE forum_is_cat = 'n'");
  3844. if ($query->num_rows > 0)
  3845. {
  3846. foreach ($query->result as $row)
  3847. {
  3848. $forum_id = $row['forum_id'];
  3849. $res1 = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_topics WHERE forum_id = '{$forum_id}'");
  3850. $total1 = $res1->row['count'];
  3851. $res2 = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_posts WHERE forum_id = '{$forum_id}'");
  3852. $total2 = $res2->row['count'];
  3853. $DB->query("UPDATE exp_forums SET forum_total_topics = '{$total1}', forum_total_posts = '{$total2}' WHERE forum_id = '{$forum_id}'");
  3854. }
  3855. $total_done = 1;
  3856. $total_rows = 0;
  3857. }
  3858. }
  3859. elseif ($table == 'exp_forum_topics')
  3860. {
  3861. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_topics");
  3862. $total_rows = $query->row['count'];
  3863. $query = $DB->query("SELECT forum_id FROM exp_forums WHERE forum_is_cat = 'n' ORDER BY forum_id");
  3864. foreach ($query->result as $row)
  3865. {
  3866. $forum_id = $row['forum_id'];
  3867. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_topics WHERE forum_id = '{$forum_id}'");
  3868. $data['forum_total_topics'] = $query->row['count'];
  3869. $query = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_posts WHERE forum_id = '{$forum_id}'");
  3870. $data['forum_total_posts'] = $query->row['count'];
  3871. $query = $DB->query("SELECT topic_id, title, topic_date, last_post_date, last_post_author_id, screen_name
  3872. FROM exp_forum_topics, exp_members
  3873. WHERE member_id = last_post_author_id
  3874. AND forum_id = '{$forum_id}'
  3875. ORDER BY last_post_date DESC LIMIT 1");
  3876. $data['forum_last_post_id'] = ($query->num_rows == 0) ? 0 : $query->row['topic_id'];
  3877. $data['forum_last_post_title'] = ($query->num_rows == 0) ? '' : $query->row['title'];
  3878. $data['forum_last_post_date'] = ($query->num_rows == 0) ? 0 : $query->row['topic_date'];
  3879. $data['forum_last_post_author_id'] = ($query->num_rows == 0) ? 0 : $query->row['last_post_author_id'];
  3880. $data['forum_last_post_author'] = ($query->num_rows == 0) ? '' : $query->row['screen_name'];
  3881. $query = $DB->query("SELECT post_date, author_id, screen_name
  3882. FROM exp_forum_posts, exp_members
  3883. WHERE member_id = author_id
  3884. AND forum_id = '{$forum_id}'
  3885. ORDER BY post_date DESC LIMIT 1");
  3886. if ($query->num_rows > 0)
  3887. {
  3888. if ($query->row['post_date'] > $data['forum_last_post_date'])
  3889. {
  3890. $data['forum_last_post_date'] = $query->row['post_date'];
  3891. $data['forum_last_post_author_id'] = $query->row['author_id'];
  3892. $data['forum_last_post_author'] = $query->row['screen_name'];
  3893. }
  3894. }
  3895. $DB->query($DB->update_string('exp_forums', $data, "forum_id='{$forum_id}'"));
  3896. unset($data);
  3897. /** -------------------------------------
  3898. /** Update global forum stats
  3899. /** -------------------------------------*/
  3900. $query = $DB->query("SELECT forum_id FROM exp_forums");
  3901. $total_topics = 0;
  3902. $total_posts = 0;
  3903. foreach ($query->result as $row)
  3904. {
  3905. $q = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_topics WHERE forum_id = '".$row['forum_id']."'");
  3906. $total_topics = ($total_topics == 0) ? $q->row['count'] : $total_topics + $q->row['count'];
  3907. $q = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_posts WHERE forum_id = '".$row['forum_id']."'");
  3908. $total_posts = ($total_posts == 0) ? $q->row['count'] : $total_posts + $q->row['count'];
  3909. }
  3910. $DB->query("UPDATE exp_stats SET total_forum_topics = '{$total_topics}', total_forum_posts = '{$total_posts}' WHERE weblog_id = '0'");
  3911. }
  3912. $total_done = 1;
  3913. $total_rows = 0;
  3914. $query = $DB->query("SELECT topic_id FROM exp_forum_topics WHERE thread_total <= 1");
  3915. if ($query->num_rows > 0)
  3916. {
  3917. foreach ($query->result as $row)
  3918. {
  3919. $res = $DB->query("SELECT COUNT(*) AS count FROM exp_forum_posts WHERE topic_id = '".$row['topic_id']."'");
  3920. $count = ($res->row['count'] == 0) ? 1 : $res->row['count'] + 1;
  3921. $DB->query("UPDATE exp_forum_topics SET thread_total = '{$count}' WHERE topic_id = '".$row['topic_id']."'");
  3922. }
  3923. }
  3924. }
  3925. $DSP->title = $LANG->line('utilities');
  3926. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  3927. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=recount_stats', $LANG->line('recalculate'))).
  3928. $DSP->crumb_item($LANG->line('recounting'));
  3929. $r = <<<EOT
  3930. <script type="text/javascript">
  3931. <!--
  3932. function standby()
  3933. {
  3934. if (document.getElementById('batchlink').style.display == "block")
  3935. {
  3936. document.getElementById('batchlink').style.display = "none";
  3937. document.getElementById('wait').style.display = "block";
  3938. }
  3939. }
  3940. -->
  3941. </script>
  3942. EOT;
  3943. $r .= NL.NL;
  3944. $r .= $DSP->qdiv('tableHeading', $LANG->line('recalculate'));
  3945. $r .= $DSP->div('box');
  3946. if ($num_rows === FALSE)
  3947. $total_done = 0;
  3948. else
  3949. $total_done = $num_rows + $batch;
  3950. if ($total_done >= $total_rows)
  3951. {
  3952. $r .= $DSP->qdiv('success', $LANG->line('recount_completed'));
  3953. $r .= $DSP->qdiv('itemWrapper', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=recount_stats', $LANG->line('return_to_recount_overview')));
  3954. }
  3955. else
  3956. {
  3957. $r .= $DSP->qdiv('itemWrapper', $LANG->line('total_records').NBS.$total_rows);
  3958. $r .= $DSP->qdiv('itemWRapper', $LANG->line('items_remaining').NBS.($total_rows - $total_done));
  3959. $line = $LANG->line('click_to_recount');
  3960. $to = (($total_done + $batch) >= $total_rows) ? $total_rows : ($total_done + $batch);
  3961. $line = str_replace("%x", $total_done, $line);
  3962. $line = str_replace("%y", $to, $line);
  3963. $link = "<a href='".BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=do_recount'.AMP.'TBL='.$table.AMP.'T='.$total_done."' onclick='standby();'><b>".$line."</b></a>";
  3964. $r .= '<div id="batchlink" style="display: block; padding:0; margin:0;">';
  3965. $r .= $DSP->qdiv('itemWrapper', BR.$link);
  3966. $r .= $DSP->div_c();
  3967. $r .= '<div id="wait" style="display: none; padding:0; margin:0;">';
  3968. $r .= $DSP->qdiv('success', BR.$LANG->line('standby_recount'));
  3969. $r .= $DSP->div_c();
  3970. }
  3971. $r .= $DSP->div_c();
  3972. $DSP->body = $r;
  3973. }
  3974. /* END */
  3975. /** -------------------------------------------
  3976. /** Import Utilities Select Page
  3977. /** -------------------------------------------*/
  3978. function import_utilities($message = '')
  3979. {
  3980. global $LANG, $DSP;
  3981. $DSP->body .= $DSP->table('tableBorder', '0', '0', '100%').
  3982. $DSP->tr();
  3983. $DSP->body .= $DSP->td('tableHeading', '');
  3984. $DSP->body .= $LANG->line('import_utilities');
  3985. $DSP->body .= $DSP->td_c();
  3986. $DSP->body .= $DSP->tr_c();
  3987. $DSP->body .= $DSP->tr();
  3988. $DSP->body .= $DSP->td('tableCellTwo');
  3989. $DSP->body .= $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=pm_import', $LANG->line('import_from_pm')));
  3990. $DSP->body .= $DSP->td_c();
  3991. $DSP->body .= $DSP->tr_c();
  3992. $DSP->body .= $DSP->tr();
  3993. $DSP->body .= $DSP->td('tableCellTwo');
  3994. $DSP->body .= $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=mt_import', $LANG->line('import_from_mt')));
  3995. $DSP->body .= $DSP->td_c();
  3996. $DSP->body .= $DSP->tr_c();
  3997. $DSP->body .= $DSP->tr();
  3998. $DSP->body .= $DSP->td('tableCellTwo');
  3999. $DSP->body .= $DSP->qdiv('defaultBold', $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=member_import', $LANG->line('member_import')));
  4000. $DSP->body .= $DSP->td_c();
  4001. $DSP->body .= $DSP->tr_c();
  4002. $DSP->body .= $DSP->table_c();
  4003. $DSP->title = $LANG->line('import_utilities');
  4004. $DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  4005. $DSP->crumb_item($LANG->line('import_utilities'));
  4006. }
  4007. /* END */
  4008. /** -------------------------------------------
  4009. /** Translation select page
  4010. /** -------------------------------------------*/
  4011. function translate_select($message = '')
  4012. {
  4013. global $DSP, $LANG;
  4014. if ( ! $DSP->allowed_group('can_admin_utilities'))
  4015. {
  4016. return $DSP->no_access_message();
  4017. }
  4018. $r = $DSP->qdiv('tableHeading', $LANG->line('translation_tool'));
  4019. if ($message != '')
  4020. {
  4021. $r .= $DSP->qdiv('successBox', $DSP->qdiv('success', $message));
  4022. }
  4023. if ( ! is_writeable(PATH.'translations/'))
  4024. {
  4025. $r .= $DSP->div('box');
  4026. $r .= $DSP->qdiv('alert', $LANG->line('translation_dir_unwritable'));
  4027. $r .= BR;
  4028. $r .= $LANG->line('please_set_permissions');
  4029. $r .= $DSP->br(2);
  4030. $r .= '<b><i>translations</i></b>';
  4031. $r .= BR;
  4032. $r .= $DSP->div_c();
  4033. }
  4034. else
  4035. {
  4036. $r .= $DSP->div('box');
  4037. $r .= $DSP->heading($LANG->line('choose_translation_file'), 5);
  4038. $source_dir = PATH_LANG.'english/';
  4039. if ($fp = @opendir($source_dir))
  4040. {
  4041. while (false !== ($file = readdir($fp)))
  4042. {
  4043. if ( preg_match("/lang\.[a-z\_0-9]+?".preg_quote(EXT, '/')."$/", $file))
  4044. {
  4045. $r .= $DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=translate'.AMP.'F='.$file, $file);
  4046. $r .= BR;
  4047. }
  4048. }
  4049. }
  4050. }
  4051. $DSP->set_return_data(
  4052. $LANG->line('utilities'),
  4053. $r,
  4054. $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).$DSP->crumb_item($LANG->line('translation_tool'))
  4055. );
  4056. }
  4057. /* END */
  4058. /** -------------------------------------------
  4059. /** Translate tool
  4060. /** -------------------------------------------*/
  4061. function translate()
  4062. {
  4063. global $DSP, $IN, $LANG, $FNS;
  4064. if ( ! $DSP->allowed_group('can_admin_utilities'))
  4065. {
  4066. return $DSP->no_access_message();
  4067. }
  4068. $source_dir = PATH_LANG.'english/';
  4069. $dest_dir = PATH.'translations/';
  4070. $which = $FNS->filename_security($_GET['F']);
  4071. require $source_dir.$which;
  4072. $M = $L;
  4073. unset($L);
  4074. if (file_exists($dest_dir.$which))
  4075. {
  4076. $writable = ( ! is_writeable($dest_dir.$which)) ? FALSE : TRUE;
  4077. require $dest_dir.$which;
  4078. }
  4079. else
  4080. {
  4081. $writable = TRUE;
  4082. $L = $M;
  4083. }
  4084. $r = $DSP->qdiv('tableHeading', $LANG->line('translation_tool'));
  4085. $r .= $DSP->form_open(array('action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=save_translation'));
  4086. $r .= $DSP->input_hidden('filename', $which);
  4087. $r .= $DSP->div('box');
  4088. foreach ($M as $key => $val)
  4089. {
  4090. if ($key != '')
  4091. {
  4092. $trans = ( ! isset($L[$key])) ? '' : $L[$key];
  4093. $r .= $DSP->qdiv('itemWrapper', BR.'<b>'.stripslashes($val).'</b>');
  4094. $trans = str_replace(array("&", "'"), array( "&amp;", "&#39;"), $trans);
  4095. if (strlen($trans) < 125)
  4096. {
  4097. $r .= "<input type='text' name='".$key."' value='".stripslashes($trans)."' size='90' class='input' style='width:95%'><br />\n";
  4098. }
  4099. else
  4100. {
  4101. $r .= "<textarea style='width:95%' name='".$key."' cols='90' rows='5' class='textarea' >".stripslashes($trans)."</textarea>";
  4102. }
  4103. }
  4104. }
  4105. $r .= $DSP->div_c();
  4106. $r .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit($LANG->line('save_changes')));
  4107. $DSP->set_return_data(
  4108. $LANG->line('utilities'),
  4109. $r,
  4110. $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
  4111. $DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=trans_menu', $LANG->line('translation_tool'))).
  4112. $DSP->crumb_item($which)
  4113. );
  4114. }
  4115. /* END */
  4116. /** -------------------------------------------
  4117. /** Save translation
  4118. /** -------------------------------------------*/
  4119. function save_translation()
  4120. {
  4121. global $DSP, $LANG, $FNS;
  4122. if ( ! $DSP->allowed_group('can_admin_utilities'))
  4123. {
  4124. return $DSP->no_access_message();
  4125. }
  4126. $dest_dir = PATH.'translations/';
  4127. $filename = $FNS->filename_security($_POST['filename']);
  4128. unset($_POST['filename']);
  4129. $str = '<?php'."\n".'$L = array('."\n\n\n";
  4130. foreach ($_POST as $key => $val)
  4131. {
  4132. $val = str_replace("<", "&lt;", $val);
  4133. $val = str_replace(">", "&gt;", $val);
  4134. $val = str_replace("'", "&#39;", $val);
  4135. $val = str_replace("\"", "&quot;", $val);
  4136. $val = stripslashes($val);
  4137. $str .= "\"$key\" =>\n\"$val\",\n\n";
  4138. }
  4139. $str .= "''=>''\n);\n?".">";
  4140. // Make sure any existing file is writeable
  4141. if (file_exists($dest_dir.$filename))
  4142. {
  4143. @chmod($dest_dir.$filename, 0777);
  4144. }
  4145. $fp = @fopen($dest_dir.$filename, 'wb');
  4146. @flock($fp, LOCK_EX);
  4147. fwrite($fp, $str);
  4148. @flock($fp, LOCK_UN);
  4149. fclose($fp);
  4150. return Utilities::translate_select($LANG->line('file_saved'));
  4151. }
  4152. /* END */
  4153. /** -------------------------------------------
  4154. /** PHP INFO
  4155. /** -------------------------------------------*/
  4156. // The default PHP info page has a lot of HTML we don't want,
  4157. // plus it's gawd-awful looking, so we'll clean it up.
  4158. // Hopefully this won't break if different versions/platforms render
  4159. // the default HTML differently
  4160. function php_info()
  4161. {
  4162. global $DSP, $PREFS, $LANG;
  4163. // We use this conditional only for demo installs.
  4164. // It prevents users from viewing this function
  4165. if ($PREFS->ini('demo_date') != FALSE)
  4166. {
  4167. return $DSP->no_access_message();
  4168. }
  4169. ob_start();
  4170. phpinfo();
  4171. $buffer = ob_get_contents();
  4172. ob_end_clean();
  4173. $output = (preg_match("/<body.*?".">(.*)<\/body>/is", $buffer, $match)) ? $match['1'] : $buffer;
  4174. $output = preg_replace("/width\=\".*?\"/", "width=\"100%\"", $output);
  4175. $output = preg_replace("/<hr.*?>/", "<br />", $output); // <?
  4176. $output = preg_replace("/<a href=\"http:\/\/www.php.net\/\">.*?<\/a>/", "", $output);
  4177. $output = preg_replace("/<a href=\"http:\/\/www.zend.com\/\">.*?<\/a>/", "", $output);
  4178. $output = preg_replace("/<a.*?<\/a>/", "", $output);// <?
  4179. $output = preg_replace("/<th(.*?)>/", "<th \\1 align=\"left\" class=\"tableHeading\">", $output);
  4180. $output = preg_replace("/<tr(.*?).*?".">/", "<tr \\1>\n", $output);
  4181. $output = preg_replace("/<td.*?".">/", "<td valign=\"top\" class=\"tableCellOne\">", $output);
  4182. $output = preg_replace("/cellpadding=\".*?\"/", "cellpadding=\"2\"", $output);
  4183. $output = preg_replace("/cellspacing=\".*?\"/", "", $output);
  4184. $output = preg_replace("/<h2 align=\"center\">PHP License<\/h2>.*?<\/table>/si", "", $output);
  4185. $output = preg_replace("/ align=\"center\"/", "", $output);
  4186. $output = preg_replace("/<table(.*?)bgcolor=\".*?\">/", "\n\n<table\\1>", $output);
  4187. $output = preg_replace("/<table(.*?)>/", "\n\n<table\\1 class=\"tableBorderNoBot\" cellspacing=\"0\">", $output);
  4188. $output = preg_replace("/<h2>PHP License.*?<\/table>/is", "", $output);
  4189. $output = preg_replace("/<br \/>\n*<br \/>/is", "", $output);
  4190. $output = str_replace("<h1></h1>", "", $output);
  4191. $output = str_replace("<h2></h2>", "", $output);
  4192. $DSP->set_return_data(
  4193. $LANG->line('php_info'),
  4194. $output,
  4195. $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).$DSP->crumb_item($LANG->line('php_info'))
  4196. );
  4197. }
  4198. /* END */
  4199. }
  4200. // END CLASS
  4201. // ---------------------------------------------
  4202. // Zip compression class
  4203. // ---------------------------------------------
  4204. //
  4205. // This class is based on a library aquired at Zend:
  4206. // http://www.zend.com/codex.php?id=696&single=1
  4207. class Zipper {
  4208. var $zdata = array();
  4209. var $cdir = array();
  4210. var $offset = 0;
  4211. /** -------------------------------------------
  4212. /** Compress directories
  4213. /** -------------------------------------------*/
  4214. function add_dir($name)
  4215. {
  4216. $name =str_replace ("\\", "/", $name);
  4217. $fd = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  4218. .pack("V", 0)
  4219. .pack("V", 0)
  4220. .pack("V", 0)
  4221. .pack("v", strlen($name))
  4222. .pack("v", 0)
  4223. .$name;
  4224. $this->cdata[] = $fd;
  4225. $cd = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"
  4226. .pack("V", 0)
  4227. .pack("V", 0)
  4228. .pack("V", 0)
  4229. .pack("v", strlen ($name))
  4230. .pack("v", 0)
  4231. .pack("v", 0)
  4232. .pack("v", 0)
  4233. .pack("v", 0)
  4234. .pack("V", 16)
  4235. .pack("V", $this->offset)
  4236. .$name;
  4237. $this->offset = strlen(implode('', $this->cdata));
  4238. $this->cdir[] = $cd;
  4239. }
  4240. /* END */
  4241. /** -------------------------------------------
  4242. /** Compress files
  4243. /** -------------------------------------------*/
  4244. function add_file($data, $name)
  4245. {
  4246. $name = str_replace("\\", "/", $name);
  4247. $u_len = strlen($data);
  4248. $crc = crc32($data);
  4249. $data = gzcompress($data);
  4250. $data = substr($data, 2, -4);
  4251. $c_len = strlen($data);
  4252. $fd = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"
  4253. .pack("V", $crc)
  4254. .pack("V", $c_len)
  4255. .pack("V", $u_len)
  4256. .pack("v", strlen($name))
  4257. .pack("v", 0)
  4258. .$name
  4259. .$data;
  4260. $this->zdata[] = $fd;
  4261. $cd = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"
  4262. .pack("V", $crc)
  4263. .pack("V", $c_len)
  4264. .pack("V", $u_len)
  4265. .pack("v", strlen ($name))
  4266. .pack("v", 0)
  4267. .pack("v", 0)
  4268. .pack("v", 0)
  4269. .pack("v", 0)
  4270. .pack("V", 32 )
  4271. .pack("V", $this->offset)
  4272. .$name;
  4273. $this->offset = strlen(implode('', $this->zdata));
  4274. $this->cdir[] = $cd;
  4275. }
  4276. /* END */
  4277. /** -------------------------------------------
  4278. /** Output final zip file
  4279. /** -------------------------------------------*/
  4280. function output_zipfile()
  4281. {
  4282. $data = implode("", $this->zdata);
  4283. $cdir = implode("", $this->cdir);
  4284. return $data
  4285. .$cdir
  4286. ."\x50\x4b\x05\x06\x00\x00\x00\x00"
  4287. .pack("v", sizeof($this->cdir))
  4288. .pack("v", sizeof($this->cdir))
  4289. .pack("V", strlen($cdir))
  4290. .pack("V", strlen($data))
  4291. ."\x00\x00";
  4292. }
  4293. /* END */
  4294. }
  4295. // END CLASS
  4296. ?>