PageRenderTime 70ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/system/expressionengine/controllers/cp/tools_utilities.php

https://bitbucket.org/tdevonshire/hoolux
PHP | 2120 lines | 1485 code | 311 blank | 324 comment | 124 complexity | 4918c5ce88dc15fdabd269bb00609767 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author EllisLab Dev Team
  7. * @copyright Copyright (c) 2003 - 2012, EllisLab, Inc.
  8. * @license http://ellislab.com/expressionengine/user-guide/license.html
  9. * @link http://ellislab.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine CP Home Page Class
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Control Panel
  19. * @category Control Panel
  20. * @author EllisLab Dev Team
  21. * @link http://ellislab.com
  22. */
  23. class Tools_utilities extends CI_Controller {
  24. private $errors = array();
  25. private $members = array();
  26. private $members_custom = array();
  27. private $default_fields = array();
  28. private $default_custom_fields = array();
  29. private $taken = array();
  30. private $invalid_names = array();
  31. /**
  32. * Constructor
  33. */
  34. public function __construct()
  35. {
  36. parent::__construct();
  37. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  38. {
  39. show_error(lang('unauthorized_access'));
  40. }
  41. $this->lang->loadfile('tools');
  42. }
  43. // --------------------------------------------------------------------
  44. /**
  45. * Index function
  46. *
  47. * @return void
  48. */
  49. public function index()
  50. {
  51. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  52. {
  53. show_error(lang('unauthorized_access'));
  54. }
  55. $this->cp->set_variable('cp_page_title', lang('tools_utilities'));
  56. $this->javascript->compile();
  57. $this->load->vars(array('controller'=>'tools/tools_utilities'));
  58. $this->load->view('_shared/overview');
  59. }
  60. // --------------------------------------------------------------------
  61. /**
  62. * Import Utilities
  63. *
  64. * Creates the main page for the list of Import Utilities
  65. *
  66. * @return mixed
  67. */
  68. public function import_utilities()
  69. {
  70. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  71. {
  72. show_error(lang('unauthorized_access'));
  73. }
  74. $this->cp->set_variable('cp_page_title', lang('import_utilities'));
  75. $this->javascript->compile();
  76. $this->load->view('tools/import_utilities');
  77. }
  78. // --------------------------------------------------------------------
  79. /**
  80. * Member Import
  81. *
  82. * Creates the initial page for the Member Import
  83. *
  84. * @return mixed
  85. */
  86. public function member_import()
  87. {
  88. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  89. {
  90. show_error(lang('unauthorized_access'));
  91. }
  92. $this->load->library('table');
  93. $this->lang->loadfile('member_import');
  94. $this->cp->set_variable('cp_page_title', lang('member_import'));
  95. $this->javascript->compile();
  96. $this->load->view('tools/member_import');
  97. }
  98. // --------------------------------------------------------------------
  99. /**
  100. * Import Member Data from XML
  101. *
  102. * Creates the initial page for the Import Member Data from XML page
  103. *
  104. * @return mixed
  105. */
  106. public function import_from_xml()
  107. {
  108. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  109. {
  110. show_error(lang('unauthorized_access'));
  111. }
  112. $this->load->library('table');
  113. $this->lang->loadfile('member_import');
  114. $this->_import_xml_form();
  115. }
  116. // --------------------------------------------------------------------
  117. /**
  118. * Import Member Data XML Form
  119. *
  120. * Generates the starting form for the member import
  121. *
  122. * @return void
  123. */
  124. private function _import_xml_form()
  125. {
  126. $this->load->helper('date');
  127. $this->lang->loadfile('member_import');
  128. $this->load->model('member_model');
  129. $this->cp->set_variable('cp_page_title', lang('import_from_xml'));
  130. $this->javascript->compile();
  131. $get_groups = $this->member_model->get_member_groups();
  132. foreach ($get_groups->result() as $member_group)
  133. {
  134. $member_groups[$member_group->group_id] = $member_group->group_title;
  135. }
  136. $vars['language_options'] = array('None' => 'None', 'English' => 'English');
  137. $vars['member_groups'] = $member_groups;
  138. $vars['dst_enabled'] = $this->config->item('daylight_savings');
  139. $vars['auto_custom_field_enabled'] = TRUE;
  140. $this->load->view('tools/import_from_xml', $vars);
  141. }
  142. // --------------------------------------------------------------------
  143. /**
  144. * Import Member Data Validation
  145. *
  146. * Validates main import settings
  147. *
  148. * @return void
  149. */
  150. private function _import_xml_validate()
  151. {
  152. $this->load->library('form_validation');
  153. $config = array(
  154. array(
  155. 'field' => 'xml_file',
  156. 'label' => 'lang:xml_file_loc',
  157. 'rules' => 'required|callback__file_exists'
  158. ),
  159. array(
  160. 'field' => 'group_id',
  161. 'label' => 'lang:default_group_id',
  162. 'rules' => ''
  163. ),
  164. array(
  165. 'field' => 'language',
  166. 'label' => 'lang:language',
  167. 'rules' => ''
  168. ),
  169. array(
  170. 'field' => 'timezones',
  171. 'label' => 'lang:timezones',
  172. 'rules' => ''
  173. ),
  174. array(
  175. 'field' => 'time_format',
  176. 'label' => 'lang:time_format',
  177. 'rules' => ''
  178. ),
  179. array(
  180. 'field' => 'daylight_savings',
  181. 'label' => 'lang:daylight_savings',
  182. 'rules' => ''
  183. ),
  184. array(
  185. 'field' => 'auto_custom_field',
  186. 'label' => 'lang:auto_custom_field',
  187. 'rules' => ''
  188. )
  189. );
  190. $this->form_validation->set_rules($config);
  191. $this->form_validation->set_error_delimiters('<span class="notice">', '</span>');
  192. }
  193. // --------------------------------------------------------------------
  194. /**
  195. * Confirm Import Member Data from XML
  196. *
  197. * Confirmation page for Member Data import
  198. *
  199. * @return mixed
  200. */
  201. public function confirm_xml_form()
  202. {
  203. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  204. {
  205. show_error(lang('unauthorized_access'));
  206. }
  207. $this->lang->loadfile('member_import');
  208. $this->load->library('table');
  209. $this->load->helper('date');
  210. $this->lang->loadfile('member_import');
  211. $this->load->model('member_model');
  212. $this->db->select('group_title');
  213. $this->db->where('group_id', $this->input->post('group_id'));
  214. $this->db->distinct();
  215. $query = $this->db->get('member_groups');
  216. $group_title = '';
  217. $group_name = ' -- ';
  218. if ($query->num_rows() > 0)
  219. {
  220. $row = $query->row_array();
  221. $group_name = $row['group_title'];
  222. }
  223. $this->javascript->compile();
  224. $data = array(
  225. 'xml_file' => $this->input->post('xml_file'),
  226. 'group_id' => $this->input->post('group_id'),
  227. 'language' => ($this->input->post('language') == lang('none')) ? '' : $this->input->post('language'),
  228. 'timezones' => $this->input->post('timezones'),
  229. 'time_format' => $this->input->post('time_format'),
  230. 'daylight_savings' => ($this->input->post('daylight_savings') == 'y') ? 'y' : 'n',
  231. 'auto_custom_field' => ($this->input->post('auto_custom_field') == 'y') ? 'y' : 'n'
  232. );
  233. $vars['data_display'] = array(
  234. 'xml_file' => $data['xml_file'],
  235. 'default_group_id' => $group_name,
  236. 'language' => ($data['language'] == '') ? lang('none') : ucfirst($data['language']),
  237. 'timezones' => lang($data['timezones']),
  238. 'time_format' => ($data['time_format'] == 'us') ? lang('united_states') : lang('european'),
  239. 'daylight_savings' => ($data['daylight_savings'] == 'y') ? lang('yes') : lang('no'),
  240. 'auto_custom_field' => ($data['auto_custom_field'] == 'y') ? lang('yes') : lang('no')
  241. );
  242. $vars['form_hidden'] = $data;
  243. $vars['added_fields'] = array();
  244. // Branch off here if we need to create a new custom field
  245. if ($data['auto_custom_field'] == 'y')
  246. {
  247. $new_custom_fields = $this->custom_field_check($data['xml_file']);
  248. if ($new_custom_fields !== FALSE && count($new_custom_fields) > 0)
  249. {
  250. return $this->_new_custom_fields_form($data, $vars, $new_custom_fields);
  251. }
  252. $vars['message'] = lang('unable_to_parse_custom_fields');
  253. }
  254. $this->_confirm_custom_field_form($vars);
  255. }
  256. // --------------------------------------------------------------------
  257. /**
  258. * Custom Field Confirmed Form
  259. *
  260. * Confirmation screen after custom field validation
  261. *
  262. * @return void
  263. */
  264. private function _confirm_custom_field_form($vars)
  265. {
  266. $this->_import_xml_validate();
  267. if ($this->form_validation->run() === FALSE)
  268. {
  269. return $this->_import_xml_form();
  270. }
  271. $this->load->library('table');
  272. $this->load->helper('date');
  273. $this->cp->set_variable('cp_page_title', lang('confirm_details'));
  274. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=member_import', lang('member_import_utility'));
  275. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=import_from_xml', lang('import_from_xml'));
  276. $vars['post_url'] = 'C=tools_utilities'.AMP.'M=process_xml';
  277. $this->load->view('tools/confirm_import_xml', $vars);
  278. }
  279. // --------------------------------------------------------------------
  280. /**
  281. * Final Import Confirmation Form
  282. *
  283. * Final Import Confirmation Form generated after custom field creation
  284. *
  285. * @return void
  286. */
  287. public function final_confirm_xml_form()
  288. {
  289. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  290. {
  291. show_error(lang('unauthorized_access'));
  292. }
  293. $map = FALSE;
  294. if (isset($_POST['field_map']))
  295. {
  296. $map = TRUE;
  297. }
  298. $this->lang->loadfile('member_import');
  299. $this->load->library('table');
  300. $this->load->helper('date');
  301. $this->load->model('member_model');
  302. $this->db->select('group_title');
  303. $this->db->where('group_id', $this->input->post('group_id'));
  304. $this->db->distinct();
  305. $query = $this->db->get('member_groups');
  306. if ($query->num_rows() > 0)
  307. {
  308. $row = $query->row_array();
  309. $group_name = $row['group_title'];
  310. }
  311. else
  312. {
  313. $group_name = ' -- ';
  314. }
  315. $this->javascript->compile();
  316. $data = array(
  317. 'xml_file' => $this->input->post('xml_file'),
  318. 'group_id' => $this->input->post('group_id'),
  319. 'language' => ($this->input->post('language') == lang('none')) ? '' : $this->input->post('language'),
  320. 'timezones' => $this->input->post('timezones'),
  321. 'time_format' => $this->input->post('time_format'),
  322. 'daylight_savings' => ($this->input->post('daylight_savings') == 'y') ? 'y' : 'n',
  323. 'auto_custom_field' => ($this->input->post('auto_custom_field') == 'y') ? 'y' : 'n'
  324. );
  325. $vars['data_display'] = array(
  326. 'xml_file' => $data['xml_file'],
  327. 'default_group_id' => $group_name,
  328. 'language' => ($data['language'] == '') ? lang('none') : ucfirst($data['language']),
  329. 'timezones' => lang($data['timezones']),
  330. 'time_format' => ($data['time_format'] == 'us') ? lang('united_states') : lang('european'),
  331. 'daylight_savings' => ($data['daylight_savings'] == 'y') ? lang('yes') : lang('no'),
  332. 'auto_custom_field' => ($data['auto_custom_field'] == 'y') ? lang('yes') : lang('no')
  333. );
  334. $vars['form_hidden'] = ($map) ? array_merge($data, $_POST['field_map']) : $data;
  335. $vars['xml_fields'] = $this->input->post('xml_custom_fields');
  336. $this->load->library('table');
  337. $this->load->helper('date');
  338. $this->cp->set_variable('cp_page_title', lang('confirm_details'));
  339. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=member_import', lang('member_import_utility'));
  340. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=import_from_xml', lang('import_from_xml'));
  341. $vars['post_url'] = 'C=tools_utilities'.AMP.'M=process_xml';
  342. $vars['added_fields'] = $this->input->post('added_fields');
  343. $this->load->view('tools/confirm_import_xml', $vars);
  344. }
  345. // --------------------------------------------------------------------
  346. /**
  347. * New Custom Fields Form
  348. *
  349. * Generates the form for new custom field settings
  350. *
  351. * @return void
  352. */
  353. private function _new_custom_fields_form($data, $vars, $new_custom_fields)
  354. {
  355. $this->load->library('table');
  356. $this->load->helper('date');
  357. $this->lang->loadfile('member_import');
  358. $this->javascript->output(array(
  359. '$(".toggle_all").toggle(
  360. function(){
  361. $("input.toggle").each(function() {
  362. this.checked = true;
  363. });
  364. }, function (){
  365. var checked_status = this.checked;
  366. $("input.toggle").each(function() {
  367. this.checked = false;
  368. });
  369. }
  370. );')
  371. );
  372. $this->javascript->compile();
  373. $vars['form_hidden']['new'] = $new_custom_fields['new'];
  374. $vars['xml_fields'] = $new_custom_fields['xml_fields'];
  375. $vars['new_fields'] = $new_custom_fields['new'];
  376. $query = $this->member_model->count_records('member_fields');
  377. $vars['order_start'] = $query + 1;
  378. /** Create the pull-down menu **/
  379. $vars['m_field_type_options'] = array(
  380. 'text'=>lang('text_input'),
  381. 'textarea'=>lang('textarea')
  382. );
  383. $vars['m_field_type'] = '';
  384. /** Field formatting **/
  385. $vars['m_field_fmt_options'] = array(
  386. 'none'=>lang('none'),
  387. 'br'=>lang('auto_br'),
  388. 'xhtml'=>lang('xhtml')
  389. );
  390. $vars['m_field_fmt'] = '';
  391. return $this->load->view('tools/custom_field_form', $vars);
  392. }
  393. // --------------------------------------------------------------------
  394. /**
  395. * Process XML
  396. *
  397. * Imports the members from XML and redirects to the index page on successful completion
  398. *
  399. * @return void
  400. */
  401. public function process_xml()
  402. {
  403. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  404. {
  405. show_error(lang('unauthorized_access'));
  406. }
  407. $this->lang->loadfile('member_import');
  408. $xml_file = ( ! $this->input->post('xml_file')) ? '' : $this->input->post('xml_file');
  409. // Read XML file contents
  410. $contents = read_file($xml_file);
  411. if ($contents === FALSE)
  412. {
  413. return $this->view_xml_errors(lang('unable_to_read_file'));
  414. }
  415. $this->load->library('xmlparser');
  416. // parse XML data
  417. $xml = $this->xmlparser->parse_xml($contents);
  418. if ($xml === FALSE)
  419. {
  420. return $this->view_xml_errors(lang('unable_to_parse_xml'));
  421. }
  422. // Any custom fields exist
  423. $this->db->select('m_field_name, m_field_id');
  424. $m_custom_fields = $this->db->get('member_fields');
  425. if ($m_custom_fields->num_rows() > 0)
  426. {
  427. $custom_fields = TRUE;
  428. foreach ($m_custom_fields->result() as $row)
  429. {
  430. if (isset($_POST['map'][$row->m_field_name]))
  431. {
  432. $this->default_custom_fields[$_POST['map'][$row->m_field_name]] = $row->m_field_id;
  433. }
  434. else
  435. {
  436. $this->default_custom_fields[$row->m_field_name] = $row->m_field_id;
  437. }
  438. }
  439. }
  440. $this->validate_xml($xml);
  441. // Show Errors
  442. if (count($this->errors) > 0)
  443. {
  444. $out = array();
  445. foreach($this->errors as $error)
  446. {
  447. foreach($error as $val)
  448. {
  449. $out[] = $val;
  450. }
  451. }
  452. return $this->view_xml_errors($out);
  453. }
  454. /** -------------------------------------
  455. /** Ok! Cross Fingers and do it!
  456. /** -------------------------------------*/
  457. $imports = $this->do_import();
  458. $msg = lang('import_success_blurb').'<br>'.str_replace('%x', $imports, lang('total_members_imported'));
  459. $this->session->set_flashdata('message_success', $msg);
  460. $this->functions->redirect(BASE.AMP.'C=tools_utilities'.AMP.'M=import_from_xml');
  461. }
  462. // --------------------------------------------------------------------
  463. /**
  464. * Custom Field Check
  465. *
  466. * Finds the fields in the first XML record that do not already exist
  467. *
  468. * @return array
  469. */
  470. public function custom_field_check($xml_file)
  471. {
  472. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  473. {
  474. show_error(lang('unauthorized_access'));
  475. }
  476. // Read XML file contents
  477. $contents = read_file($xml_file);
  478. $new_custom_fields = array();
  479. if ($contents === FALSE)
  480. {
  481. return;
  482. }
  483. $this->load->library('xmlparser');
  484. // parse XML data
  485. $xml = $this->xmlparser->parse_xml($contents);
  486. if ($xml == FALSE)
  487. {
  488. return FALSE;
  489. }
  490. // Retreive Valid fields from database
  491. $query = $this->db->query("SHOW COLUMNS FROM exp_members");
  492. $existing_fields['birthday'] = '';
  493. foreach ($query->result_array() as $row)
  494. {
  495. $existing_fields[$row['Field']] = '';
  496. }
  497. $this->db->select('m_field_name');
  498. $m_custom_fields = $this->db->get('member_fields');
  499. if ($m_custom_fields->num_rows() > 0)
  500. {
  501. foreach ($m_custom_fields->result() as $row)
  502. {
  503. $existing_c_fields[$row->m_field_name] = '';
  504. }
  505. }
  506. // We go through a single iteration to find the fields
  507. if (is_array($xml->children[0]->children))
  508. {
  509. $member = $xml->children['0'];
  510. if ($member->tag == "member")
  511. {
  512. foreach($member->children as $tag)
  513. {
  514. $i = 0;
  515. // Is the XML tag an allowed database field
  516. if ( ! isset($existing_fields[$tag->tag]) && ! isset($existing_c_fields[$tag->tag]))
  517. {
  518. $new_custom_fields['new'][] = $tag->tag;
  519. $new_custom_fields['xml_fields'][] = $tag->tag;
  520. }
  521. elseif (isset($existing_c_fields[$tag->tag]))
  522. {
  523. while($i < 100)
  524. {
  525. $i++;
  526. if ( ! isset($existing_c_fields[$tag->tag.'_'.$i]))
  527. {
  528. $new_custom_fields['new'][] = $tag->tag.'_'.$i;
  529. $new_custom_fields['xml_fields'][] = $tag->tag;
  530. break;
  531. }
  532. }
  533. }
  534. }
  535. }
  536. }
  537. return $new_custom_fields; //array_unique($new_custom_fields);
  538. }
  539. // --------------------------------------------------------------------
  540. /**
  541. * Validate XML for Member Import
  542. *
  543. * Validates both the format and content of Member Import XML
  544. *
  545. * @return mixed
  546. */
  547. public function validate_xml($xml)
  548. {
  549. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  550. {
  551. show_error(lang('unauthorized_access'));
  552. }
  553. $this->lang->loadfile('member_import');
  554. $this->load->library('validate');
  555. $this->load->helper('security');
  556. $this->validate->member_id = '';
  557. $this->validate->val_type = 'new';
  558. $this->validate->fetch_lang = TRUE;
  559. $this->validate->require_cpw = FALSE;
  560. $this->validate->enable_log = FALSE;
  561. $this->validate->cur_username = '';
  562. $this->validate->cur_screen_name = '';
  563. $this->validate->cur_password = '';
  564. $this->validate->cur_email = '';
  565. $i = 0;
  566. // Retreive Valid fields from database
  567. $query = $this->db->query("SHOW COLUMNS FROM exp_members");
  568. foreach ($query->result_array() as $row)
  569. {
  570. $this->default_fields[$row['Field']] = '';
  571. }
  572. $this->db->select('m_field_name, m_field_id');
  573. $m_custom_fields = $this->db->get('member_fields');
  574. if ($m_custom_fields->num_rows() > 0)
  575. {
  576. foreach ($m_custom_fields->result() as $row)
  577. {
  578. $this->default_custom_fields[$row->m_field_name] = $row->m_field_id;
  579. }
  580. }
  581. // we don't allow <unique_id>
  582. unset($this->default_fields['unique_id']);
  583. $u = array(); // username garbage array
  584. $s = array(); // screen_name garbage array
  585. $e = array(); // email garbage array
  586. $m = array(); // member_id garbage array
  587. if (is_array($xml->children[0]->children))
  588. {
  589. foreach($xml->children as $member)
  590. {
  591. if ($member->tag == "member")
  592. {
  593. foreach($member->children as $tag)
  594. {
  595. // Is the XML tag an allowed database field
  596. if (isset($this->default_fields[$tag->tag]))
  597. {
  598. $this->members[$i][$tag->tag] = $tag->value;
  599. }
  600. elseif ($tag->tag == 'birthday')
  601. {
  602. // We have a special XML format for birthdays that doesn't match the database fields
  603. foreach($tag->children as $birthday)
  604. {
  605. switch ($birthday->tag)
  606. {
  607. case 'day':
  608. $this->members[$i]['bday_d'] = $birthday->value;
  609. break;
  610. case 'month':
  611. $this->members[$i]['bday_m'] = $birthday->value;
  612. break;
  613. case 'year':
  614. $this->members[$i]['bday_y'] = $birthday->value;
  615. break;
  616. default:
  617. $this->errors[] = array(lang('invalid_tag')." '&lt;".$birthday->tag."&gt;'");
  618. break;
  619. }
  620. }
  621. if ( ! isset($this->members[$i]['bday_d']) || ! isset($this->members[$i]['bday_m']) || ! isset($this->members[$i]['bday_y']))
  622. {
  623. $this->errors[] = array(lang('missing_birthday_child'));
  624. }
  625. $this->members[$i][$tag->tag] = $tag->value;
  626. }
  627. elseif (isset($this->default_custom_fields[$tag->tag]))
  628. {
  629. $this->members_custom[$i][$tag->tag] = $tag->value;
  630. }
  631. else
  632. {
  633. // not a database field and not a <birthday> so club it like a baby seal!
  634. //$this->errors[] = array(lang('invalid_tag')." '&lt;".$tag->tag."&gt;'");
  635. }
  636. /* -------------------------------------
  637. /* username, screen_name, and email
  638. /* must be validated and unique
  639. /* -------------------------------------*/
  640. switch ($tag->tag)
  641. {
  642. case 'username':
  643. $this->validate->username = $tag->value;
  644. if ( ! in_array($tag->value, $u))
  645. {
  646. $u[] = $tag->value;
  647. }
  648. else
  649. {
  650. $this->errors[] = array(lang('duplicate_username').$tag->value);
  651. }
  652. break;
  653. case 'screen_name':
  654. $this->validate->screen_name = $tag->value;
  655. if ( ! in_array($tag->value, $s))
  656. {
  657. $s[] = $tag->value;
  658. }
  659. else
  660. {
  661. $this->errors[] = array(lang('duplicate_screen_name').$tag->value);
  662. }
  663. break;
  664. case 'email':
  665. if ( ! in_array($tag->value, $e))
  666. {
  667. $e[] = $tag->value;
  668. }
  669. else
  670. {
  671. $this->errors[] = array(lang('duplicate_email').$tag->value);
  672. }
  673. $this->validate->email = $tag->value;
  674. break;
  675. case 'member_id':
  676. if ( ! in_array($tag->value, $m))
  677. {
  678. $m[] = $tag->value;
  679. }
  680. else
  681. {
  682. $this->errors[] = array(str_replace("%x", $tag->value, lang('duplicate_member_id')));
  683. }
  684. break;
  685. case 'password':
  686. // We require a type attribute here, as outlined in the docs.
  687. // This is a quick error check to ensure its present.
  688. if ( ! @$tag->attributes['type'])
  689. {
  690. show_error(str_replace('%x', $this->validate->username, lang('missing_password_type')));
  691. }
  692. // encode password if it is type="text"
  693. $this->members[$i][$tag->tag] = ($tag->attributes['type'] == 'text') ? do_hash($tag->value) : $tag->value;
  694. break;
  695. }
  696. }
  697. $username = (isset($this->members[$i]['username'])) ? $this->members[$i]['username'] : '';
  698. $screen_name = (isset($this->members[$i]['screen_name'])) ? $this->members[$i]['screen_name'] : '';
  699. $email = (isset($this->members[$i]['email'])) ? $this->members[$i]['email'] : '';
  700. /* -------------------------------------
  701. /* Validate separately to display
  702. /* exact problem
  703. /* -------------------------------------*/
  704. $this->validate->validate_username();
  705. if ( ! empty($this->validate->errors))
  706. {
  707. foreach($this->validate->errors as $key => $val)
  708. {
  709. $this->validate->errors[$key] = $val." (Username: '".$username."' - ".lang('within_user_record')." '".$username."')";
  710. }
  711. $this->errors[] = $this->validate->errors;
  712. unset($this->validate->errors);
  713. }
  714. $this->validate->validate_screen_name();
  715. if ( ! empty($this->validate->errors))
  716. {
  717. foreach($this->validate->errors as $key => $val)
  718. {
  719. $this->validate->errors[$key] = $val." (Screen Name: '".$screen_name."' - ".lang('within_user_record')." '".$username."')";
  720. }
  721. $this->errors[] = $this->validate->errors;
  722. unset($this->validate->errors);
  723. }
  724. $this->validate->validate_email();
  725. if ( ! empty($this->validate->errors))
  726. {
  727. foreach($this->validate->errors as $key => $val)
  728. {
  729. $this->validate->errors[$key] = $val." (Email: '".$email."' - ".lang('within_user_record')." '".$username."')";
  730. }
  731. $this->errors[] = $this->validate->errors;
  732. unset($this->validate->errors);
  733. }
  734. /** -------------------------------------
  735. /** Add a random hash if no password is defined
  736. /** -------------------------------------*/
  737. if ( ! isset($this->members[$i]['password']))
  738. {
  739. $this->members[$i]['password'] = do_hash(mt_rand());
  740. }
  741. $i++;
  742. }
  743. else
  744. {
  745. /** -------------------------------------
  746. /** Element isn't <member>
  747. /** -------------------------------------*/
  748. $this->errors[] = array(lang('invalid_element'));
  749. }
  750. }
  751. }
  752. else
  753. {
  754. /** -------------------------------------
  755. /** No children of the root element
  756. /** -------------------------------------*/
  757. $this->errors[] = array(lang('invalid_xml'));
  758. }
  759. }
  760. // --------------------------------------------------------------------
  761. /**
  762. * Do Import
  763. *
  764. * Inserts new members into the database
  765. *
  766. * @return number
  767. */
  768. public function do_import()
  769. {
  770. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  771. {
  772. show_error(lang('unauthorized_access'));
  773. }
  774. // Set our optional default values
  775. $this->default_fields['group_id'] = $this->input->post('group_id');
  776. $this->default_fields['language'] = ($this->input->post('language') == lang('none') OR $this->input->post('language') == '') ? 'english' : strtolower($this->input->post('language'));
  777. $this->default_fields['timezone'] = ($this->input->post('timezones') && $this->input->post('timezones') != '') ? $this->input->post('timezones') : $this->config->item('server_timezone');
  778. $this->default_fields['time_format'] = $this->input->post('time_format');
  779. $this->default_fields['daylight_savings'] = ($this->input->post('daylight_savings') == 'y') ? 'y' : 'n';
  780. $this->default_fields['ip_address'] = '0.0.0.0';
  781. $this->default_fields['join_date'] = $this->localize->now;
  782. // Rev it up, no turning back!
  783. $new_ids = array();
  784. $counter = 0;
  785. $custom_fields = (count($this->default_custom_fields) > 0) ? TRUE : FALSE;
  786. foreach ($this->members as $count => $member)
  787. {
  788. $data = array();
  789. $dupe = FALSE;
  790. foreach ($this->default_fields as $key => $val)
  791. {
  792. if (isset($member[$key]))
  793. {
  794. $data[$key] = $member[$key];
  795. }
  796. elseif ($val != '')
  797. {
  798. $data[$key] = $val;
  799. }
  800. }
  801. if ($custom_fields)
  802. {
  803. foreach ($this->default_custom_fields as $name => $id)
  804. {
  805. if (isset($this->members_custom[$count][$name]))
  806. {
  807. $cdata['m_field_id_'.$id] = $this->members_custom[$count][$name];
  808. }
  809. }
  810. }
  811. // Add a unique_id for each member
  812. $data['unique_id'] = random_string('encrypt');
  813. /* -------------------------------------
  814. /* See if we've already imported a member with this member_id -
  815. /* could possibly occur if an auto_increment value is used
  816. /* before a specified member_id.
  817. /* -------------------------------------*/
  818. if (isset($data['member_id']))
  819. {
  820. if (isset($new_ids[$data['member_id']]))
  821. {
  822. /* -------------------------------------
  823. /* Grab the member so we can re-insert it after we
  824. /* take care of this nonsense
  825. /* -------------------------------------*/
  826. $dupe = TRUE;
  827. $tempdata = $this->db->get_where('members', array('member_id' => $data['member_id']));
  828. if ($custom_fields == TRUE)
  829. {
  830. $tempcdata = $this->db->get_where('member_data', array('member_id' => $data['member_id']));
  831. }
  832. }
  833. }
  834. /* -------------------------------------
  835. /* Shove it in!
  836. /* We are using REPLACE as we want to overwrite existing members if a member id is specified
  837. /* -------------------------------------*/
  838. $this->db->replace('members', $data);
  839. $mid = $this->db->insert_id();
  840. // Add the member id to the array of imported member id's
  841. $new_ids[$mid] = $mid;
  842. if ($custom_fields == TRUE)
  843. {
  844. $cdata['member_id'] = $mid;
  845. }
  846. // Insert the old auto_incremented member, if necessary
  847. if ($dupe === TRUE)
  848. {
  849. unset($tempdata->row['member_id']); // dump the member_id so it can auto_increment a new one
  850. $this->db->insert('members', $tempdata->row);
  851. $replace_mid = $this->db->insert_id();
  852. $new_ids[$replace_mid] = '';
  853. if ($custom_fields == TRUE)
  854. {
  855. $tempcdata->row['member_id'] = $replace_mid;
  856. $this->db->insert('member_data', $tempcdata->row);
  857. }
  858. }
  859. if ($custom_fields == TRUE)
  860. {
  861. $this->db->replace('member_data', $cdata);
  862. }
  863. $counter++;
  864. }
  865. /** -------------------------------------
  866. /** Add records to exp_member_data and exp_member_homepage tables for all imported members
  867. /** -------------------------------------*/
  868. $values = '';
  869. foreach ($new_ids as $key => $val)
  870. {
  871. $values .= "('$key'),";
  872. }
  873. $values = substr($values, 0, -1);
  874. if ($custom_fields == FALSE)
  875. {
  876. $this->db->query("INSERT INTO exp_member_data (member_id) VALUES ".$values);
  877. }
  878. $this->db->query("INSERT INTO exp_member_homepage (member_id) VALUES ".$values);
  879. // Update Statistics
  880. $this->stats->update_member_stats();
  881. return $counter;
  882. }
  883. // --------------------------------------------------------------------
  884. /**
  885. * Create Custom Field Validation
  886. *
  887. * Validates new custom field submission
  888. *
  889. * @return mixed
  890. */
  891. private function _create_custom_validation()
  892. {
  893. $this->load->library('form_validation');
  894. $this->invalid_names = $this->cp->invalid_custom_field_names();
  895. // Gather existing field names
  896. $this->db->select('m_field_name');
  897. $m_custom_fields = $this->db->get('member_fields');
  898. if ($m_custom_fields->num_rows() > 0)
  899. {
  900. foreach ($m_custom_fields->result() as $row)
  901. {
  902. $this->taken[] = $row->m_field_name;
  903. }
  904. }
  905. if (isset($_POST['create_ids']))
  906. {
  907. foreach($_POST['create_ids'] as $key => $val)
  908. {
  909. $this->form_validation->set_rules("m_field_name[".$key."]", '', 'required|callback__valid_name');
  910. $this->form_validation->set_rules("m_field_label[".$key."]", '', 'required');
  911. $this->form_validation->set_rules("required[".$key."]", '', '');
  912. $this->form_validation->set_rules("public[".$key."]", '', '');
  913. $this->form_validation->set_rules("reg_form[".$key."]", '', '');
  914. $this->form_validation->set_rules("xml_field_name[".$key."]", '', '');
  915. }
  916. }
  917. $this->form_validation->set_message('required', lang('s_required'));
  918. $this->form_validation->set_error_delimiters('<span class="notice">', '</span>');
  919. }
  920. // --------------------------------------------------------------------
  921. /**
  922. * Valid Name
  923. *
  924. * Validates new custom field names
  925. *
  926. * @return bool
  927. */
  928. public function _valid_name($str)
  929. {
  930. $error = array();
  931. // Does field name have invalid characters?
  932. if (preg_match('/[^a-z0-9\_\-]/i', $str))
  933. {
  934. $error[] = lang('invalid_characters');
  935. }
  936. // Is the field one of the reserved words?
  937. if (in_array($str, $this->invalid_names))
  938. {
  939. $error[] = lang('reserved_word');
  940. }
  941. // Is the field name taken?
  942. if (in_array($str, $this->taken))
  943. {
  944. $error[] = lang('duplicate_field_name');
  945. }
  946. $this->taken[] = $str;
  947. if (count($error) > 0)
  948. {
  949. $out = implode(',', $error);
  950. $this->form_validation->set_message('_valid_name', $out);
  951. return FALSE;
  952. }
  953. return TRUE;
  954. }
  955. // --------------------------------------------------------------------
  956. /**
  957. * Create Custom Fields
  958. *
  959. * Creates the custom field form
  960. *
  961. * @return mixed
  962. */
  963. public function create_custom_fields()
  964. {
  965. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  966. {
  967. show_error(lang('unauthorized_access'));
  968. }
  969. $this->lang->loadfile('admin_content');
  970. $this->lang->loadfile('members');
  971. $this->lang->loadfile('member_import');
  972. $this->_create_custom_validation();
  973. if ($this->form_validation->run() === FALSE)
  974. {
  975. return $this->confirm_xml_form();
  976. }
  977. $error = array();
  978. $taken = array();
  979. $total_fields = count($this->input->post('create_ids'));
  980. foreach ($_POST['create_ids'] as $k => $v)
  981. {
  982. $data['m_field_name'] = $_POST['m_field_name'][$k];
  983. $data['m_field_label'] = $_POST['m_field_label'][$k];
  984. $data['m_field_description']= (isset($_POST['m_field_description'][$k])) ? $_POST['m_field_description'][$k] : '';
  985. $data['m_field_type'] = (isset($_POST['m_field_type'][$k])) ? $_POST['m_field_type'][$k] : 'text';
  986. $data['m_field_list_items'] = (isset($_POST['m_field_list_items'][$k])) ? $_POST['m_field_list_items'][$k] : '';
  987. $data['m_field_ta_rows'] = (isset($_POST['m_field_ta_rows'][$k])) ? $_POST['m_field_ta_rows'][$k] : '100';
  988. $data['m_field_maxl'] = (isset($_POST['m_field_maxl'][$k])) ? $_POST['m_field_maxl'][$k] : '100';
  989. $data['m_field_width'] = (isset($_POST['m_field_width'][$k])) ? $_POST['m_field_width'][$k] : '100%';
  990. $data['m_field_search'] = 'y';
  991. $data['m_field_required'] = (isset($_POST['required'][$k])) ? 'y' : 'n';
  992. $data['m_field_public'] = (isset($_POST['public'][$k])) ? 'y' : 'n';
  993. $data['m_field_reg'] = (isset($_POST['reg_form'][$k])) ? 'y' : 'n';
  994. $data['m_field_fmt'] = (isset($_POST['m_field_fmt'][$k])) ? $_POST['m_field_fmt'][$k] : 'xhtml';
  995. $data['m_field_order'] = (isset($_POST['m_field_order'][$k])) ? $_POST['m_field_order'][$k] : '';
  996. $this->db->insert('member_fields', $data);
  997. $field_id = $this->db->insert_id();
  998. $this->db->query('ALTER table exp_member_data add column m_field_id_'.$field_id.' text NULL DEFAULT NULL');
  999. $_POST['added_fields'][$_POST['m_field_name'][$k]] = $_POST['m_field_label'][$k];
  1000. //$_POST['xml_custom_fields'][$_POST['xml_field_name'][$k]] = $field_id;
  1001. if ($_POST['new'][$k] != $_POST['m_field_name'][$k])
  1002. {
  1003. $_POST['field_map']['map'][$_POST['m_field_name'][$k]] = $_POST['new'][$k];
  1004. }
  1005. //$this->default_custom_fields[$_POST['m_field_name'][$k]] = 'm_field_id_'.$this->db->insert_id();
  1006. }
  1007. $_POST['auto_custom_field'] = 'n';
  1008. unset($_POST['new']);
  1009. unset($_POST['m_field_name']);
  1010. unset($_POST['m_field_label']);
  1011. unset($_POST['create_ids']);
  1012. return $this->final_confirm_xml_form();
  1013. }
  1014. // --------------------------------------------------------------------
  1015. /**
  1016. * Convert Member Data from Delimited File
  1017. *
  1018. * Creates initial page for the Convert from a Delimited File page
  1019. *
  1020. * @return mixed
  1021. */
  1022. public function convert_from_delimited()
  1023. {
  1024. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  1025. {
  1026. show_error(lang('unauthorized_access'));
  1027. }
  1028. $this->lang->loadfile('member_import');
  1029. $this->_convert_from_delimited_form();
  1030. }
  1031. // --------------------------------------------------------------------
  1032. /**
  1033. * Convert From Delimited Validation
  1034. *
  1035. * Validation for delimited XML conversion
  1036. *
  1037. * @return void
  1038. */
  1039. private function _convert_from_delimited_validation()
  1040. {
  1041. $this->load->library('form_validation');
  1042. $this->form_validation->set_rules('member_file', 'File', 'required|callback__file_exists');
  1043. $this->form_validation->set_rules('delimiter', 'lang:delimiter', 'required|enum[tab,other,comma]');
  1044. $this->form_validation->set_rules('delimiter_special', 'lang:other', 'trim|callback__not_alphanu');
  1045. $this->form_validation->set_rules('enclosure', 'lang:enclosure', 'callback__prep_enclosure');
  1046. $this->form_validation->set_error_delimiters('<span class="notice">', '</span>');
  1047. }
  1048. // --------------------------------------------------------------------
  1049. /**
  1050. * Convert from Delimited FORM
  1051. *
  1052. * Main form for converted delimited data to XML
  1053. *
  1054. * @return void
  1055. */
  1056. private function _convert_from_delimited_form()
  1057. {
  1058. $this->cp->set_variable('cp_page_title', lang('convert_from_delimited'));
  1059. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=member_import', lang('member_import_utility'));
  1060. $this->javascript->output('
  1061. $("#delimiter_special").focus(function() {
  1062. $("#other").attr("checked", true);
  1063. });
  1064. $("#comma,#tab").focus(function() {
  1065. $("#delimiter_special").val("");
  1066. });
  1067. ');
  1068. $this->javascript->compile();
  1069. $this->load->view('tools/convert_from_delimited');
  1070. }
  1071. // --------------------------------------------------------------------
  1072. /**
  1073. * Pair Fields Form
  1074. *
  1075. * For mapping to existing custom fields
  1076. *
  1077. * @return void
  1078. */
  1079. private function _pair_fields_form()
  1080. {
  1081. $this->load->library('table');
  1082. // Snag form POST data
  1083. switch ($this->input->post('delimiter'))
  1084. {
  1085. case 'tab' : $this->delimiter = "\t";
  1086. break;
  1087. case 'other': $this->delimiter = $this->input->post('delimiter_special');
  1088. break;
  1089. case 'comma':
  1090. default: $this->delimiter = ",";
  1091. }
  1092. $member_file = $this->input->post('member_file');
  1093. $this->enclosure = ($this->input->post('enclosure') === FALSE) ? '' : $this->input->post('enclosure');
  1094. // Read data file into an array
  1095. $fields = $this->datafile_to_array($member_file);
  1096. if ( ! isset($fields[0]) OR count($fields[0]) < 3)
  1097. {
  1098. // No point going further if there aren't even the minimum required
  1099. //show_error(lang('not_enough_fields'));
  1100. return $this->view_xml_errors(lang('not_enough_fields'));
  1101. }
  1102. // Retreive Valid fields from database
  1103. $query = $this->db->query("SHOW COLUMNS FROM exp_members");
  1104. foreach ($query->result_array() as $row)
  1105. {
  1106. $this->default_fields[$row['Field']] = '';
  1107. }
  1108. // Retreive custom member fields from database
  1109. $this->db->select('m_field_name');
  1110. $this->db->from('member_fields');
  1111. $this->db->order_by('m_field_name');
  1112. $query = $this->db->get();
  1113. $vars['custom_select_options'][''] = lang('select');
  1114. if ($query->num_rows() > 0)
  1115. {
  1116. foreach ($query->result_array() as $row)
  1117. {
  1118. $this->custom_fields[$row['m_field_name']] = '';
  1119. $vars['custom_select_options'][$row['m_field_name']] = $row['m_field_name'];
  1120. }
  1121. }
  1122. // we do not allow <unique_id> in our XML format
  1123. unset($this->default_fields['unique_id']);
  1124. ksort($this->default_fields);
  1125. $vars['select_options'][''] = lang('select');
  1126. foreach ($this->default_fields as $key => $val)
  1127. {
  1128. $vars['select_options'][$key] = $key;
  1129. }
  1130. $vars['fields'] = $fields;
  1131. $vars['form_hidden'] = array(
  1132. 'member_file' => $this->input->post('member_file'),
  1133. 'delimiter' => $this->input->post('delimiter'),
  1134. 'enclosure' => $this->enclosure,
  1135. 'delimiter_special' => $this->delimiter
  1136. );
  1137. $vars['encrypt'] = '';
  1138. $this->cp->set_variable('cp_page_title', lang('assign_fields'));
  1139. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=member_import', lang('member_import_utility'));
  1140. $this->load->view('tools/convert_xml_pairs', $vars);
  1141. }
  1142. // --------------------------------------------------------------------
  1143. /**
  1144. * Pair Fields
  1145. *
  1146. * Pair delimited data with Member fields
  1147. *
  1148. * @return boolean
  1149. */
  1150. public function pair_fields()
  1151. {
  1152. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  1153. {
  1154. show_error(lang('unauthorized_access'));
  1155. }
  1156. $this->lang->loadfile('member_import');
  1157. $this->_convert_from_delimited_validation();
  1158. if ($this->form_validation->run() === FALSE)
  1159. {
  1160. return $this->_convert_from_delimited_form();
  1161. }
  1162. return $this->_pair_fields_form();
  1163. }
  1164. // --------------------------------------------------------------------
  1165. /**
  1166. * Not Alpha or Numeric
  1167. *
  1168. * Validation callback that makes sure that no alphanumeric chars are submitted
  1169. *
  1170. * @param string
  1171. * @return boolean
  1172. */
  1173. public function _not_alphanu($str = '')
  1174. {
  1175. if ($this->input->post('delimiter') == 'other')
  1176. {
  1177. if ($str == '')
  1178. {
  1179. $this->form_validation->set_message('_not_alphanu', str_replace('%x', lang('other'), lang('no_delimiter')));
  1180. return FALSE;
  1181. }
  1182. preg_match("/[\w\d]*/", $str, $matches);
  1183. if ($matches[0] != '')
  1184. {
  1185. $this->form_validation->set_message('_not_alphanu', lang('alphanumeric_not_allowed'));
  1186. return FALSE;
  1187. }
  1188. }
  1189. return TRUE;
  1190. }
  1191. // --------------------------------------------------------------------
  1192. /**
  1193. * File exists
  1194. *
  1195. * Validation callback that checks if a file exits
  1196. *
  1197. * @param string
  1198. * @return boolean
  1199. */
  1200. public function _file_exists($file)
  1201. {
  1202. if ( ! file_exists($file))
  1203. {
  1204. $this->form_validation->set_message('_file_exists', lang('invalid_path').$file);
  1205. return FALSE;
  1206. }
  1207. return TRUE;
  1208. }
  1209. // --------------------------------------------------------------------
  1210. /**
  1211. * Prep Enclosure
  1212. *
  1213. * Undo changes made by form prep
  1214. *
  1215. * @return string
  1216. */
  1217. public function _prep_enclosure($enclosure)
  1218. {
  1219. // undo changes made by form prep as we need the literal characters
  1220. // and htmlspecialchars_decode() doesn't exist until PHP 5, so...
  1221. $enclosure = str_replace('&#39;', "'", $enclosure);
  1222. $enclosure = str_replace('&amp;', "&", $enclosure);
  1223. $enclosure = str_replace('&lt;', "<", $enclosure);
  1224. $enclosure = str_replace('&gt;', ">", $enclosure);
  1225. $enclosure = str_replace('&quot;', '"', $enclosure);
  1226. $enclosure = stripslashes($enclosure);
  1227. return $enclosure;
  1228. }
  1229. // --------------------------------------------------------------------
  1230. /**
  1231. * Pair Fields Validation
  1232. *
  1233. * Validates paired fields
  1234. *
  1235. * @return void
  1236. */
  1237. public function _pair_fields_validation()
  1238. {
  1239. $this->load->library('form_validation');
  1240. $this->form_validation->set_rules('unique_check', 'lang:other', 'callback__unique_required');
  1241. $this->form_validation->set_rules('encrypt', '', '');
  1242. $this->form_validation->set_error_delimiters('<p class="notice">', '</p>');
  1243. }
  1244. // --------------------------------------------------------------------
  1245. /**
  1246. * Unique Required
  1247. *
  1248. * Check for uniqueness and required values
  1249. *
  1250. * @return void
  1251. */
  1252. public function _unique_required ($selected_fields)
  1253. {
  1254. // Get field pairings
  1255. $paired = array();
  1256. $mssg = array();
  1257. if (is_array($selected_fields))
  1258. {
  1259. foreach ($selected_fields as $val)
  1260. {
  1261. if ($val != '' && in_array($val, $paired))
  1262. {
  1263. $mssg[] = str_replace("%x", $val, lang('duplicate_field_assignment'));
  1264. }
  1265. $paired[] = $val;
  1266. }
  1267. }
  1268. if ( ! in_array('username', $paired))
  1269. {
  1270. $mssg[] = lang('missing_username_field');
  1271. }
  1272. if ( ! in_array('screen_name', $paired))
  1273. {
  1274. $mssg[] = lang('missing_screen_name_field');
  1275. }
  1276. if ( ! in_array('email', $paired))
  1277. {
  1278. $mssg[] = lang('missing_email_field');
  1279. }
  1280. if (count($mssg) > 0)
  1281. {
  1282. $out = implode('<br>', $mssg);
  1283. $this->form_validation->set_message('_unique_required', $out);
  1284. return FALSE;
  1285. }
  1286. return TRUE;
  1287. }
  1288. // --------------------------------------------------------------------
  1289. /**
  1290. * Confirm Data Form
  1291. *
  1292. * Generates confirmation page prior to delimited conversion
  1293. *
  1294. * @return void
  1295. */
  1296. public function confirm_data_form()
  1297. {
  1298. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  1299. {
  1300. show_error(lang('unauthorized_access'));
  1301. }
  1302. $this->lang->loadfile('member_import');
  1303. $this->load->library('table');
  1304. // Snag POST data
  1305. $member_file = ( ! $this->input->post('member_file')) ? '' : $this->input->post('member_file');
  1306. switch ($this->input->post('delimiter'))
  1307. {
  1308. case 'tab' : $this->delimiter = "\t"; break;
  1309. case 'comma' : $this->delimiter = ","; break;
  1310. case 'other': $this->delimiter = $this->input->post('delimiter_special');
  1311. }
  1312. $this->enclosure = ($this->input->post('enclosure') === FALSE) ? '' : $this->input->post('enclosure');
  1313. $encrypt = ($this->input->post('encrypt') == 'y') ? TRUE : FALSE;
  1314. // Get field pairings
  1315. $paired = array();
  1316. $cpaired = array();
  1317. foreach ($_POST as $key => $val)
  1318. {
  1319. if (substr($key, 0, 5) == 'field')
  1320. {
  1321. $_POST['unique_check'][$key] = $val;
  1322. $paired[$key] = $val;
  1323. }
  1324. elseif (substr($key, 0, 7) == 'c_field')
  1325. {
  1326. $_POST['unique_check'][$key] = $val;
  1327. $cpaired[$key] = $val;
  1328. }
  1329. }
  1330. $this->_pair_fields_validation();
  1331. if ($this->form_validation->run() === FALSE)
  1332. {
  1333. return $this->_pair_fields_form();
  1334. }
  1335. // Read the data file
  1336. $fields = $this->datafile_to_array($member_file);
  1337. $vars['form_hidden'] = array('member_file' => $this->input->post('member_file'),
  1338. 'delimiter' => $this->input->post('delimiter'),
  1339. 'delimiter_special' => $this->delimiter,
  1340. 'enclosure' => $this->enclosure,
  1341. 'encrypt' => $this->input->post('encrypt')
  1342. );
  1343. foreach ($paired as $key => $val)
  1344. {
  1345. $vars['form_hidden'][$key] = $val;
  1346. if (isset($cpaired['c_'.$key]) && $cpaired['c_'.$key] != '')
  1347. {
  1348. $vars['form_hidden'][$key] = $cpaired['c_'.$key];
  1349. }
  1350. }
  1351. $vars['fields'] = $fields;
  1352. $vars['paired'] = $paired;
  1353. $vars['cpaired'] = $cpaired;
  1354. $vars['custom_fields'] = (count($cpaired) > 0) ? TRUE : FALSE;
  1355. $vars['type_view'] = FALSE;
  1356. $vars['type_download'] = TRUE;
  1357. $this->cp->set_variable('cp_page_title', lang('confirm_field_assignment'));
  1358. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=member_import', lang('member_import_utility'));
  1359. $this->load->view('tools/confirm_convert_xml', $vars);
  1360. }
  1361. // --------------------------------------------------------------------
  1362. /**
  1363. * Create XML File
  1364. *
  1365. * Creates and XML file from delimited data
  1366. *
  1367. * @return mixed
  1368. */
  1369. public function create_xml()
  1370. {
  1371. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  1372. {
  1373. show_error(lang('unauthorized_access'));
  1374. }
  1375. $this->lang->loadfile('member_import');
  1376. $this->load->helper(array('file', 'xml'));
  1377. // Snag POST data
  1378. $member_file = ( ! $this->input->post('member_file')) ? '' : $this->input->post('member_file');
  1379. switch ($this->input->post('delimiter'))
  1380. {
  1381. case 'tab' : $this->delimiter = "\t"; break;
  1382. case 'comma' : $this->delimiter = ","; break;
  1383. case 'other': $this->delimiter = $this->input->post('delimiter_special');
  1384. }
  1385. $this->enclosure = ($this->input->post('enclosure') === FALSE) ? '' : $this->input->post('enclosure');
  1386. $encrypt = ($this->input->post('encrypt') == 'y') ? TRUE : FALSE;
  1387. $type = $this->input->post('type');
  1388. // Read file contents
  1389. $contents = read_file($member_file);
  1390. if ($contents === FALSE)
  1391. {
  1392. return;
  1393. }
  1394. // Get structure
  1395. $structure = array();
  1396. foreach ($_POST as $key => $val)
  1397. {
  1398. if (substr($key, 0, 5) == 'field')
  1399. {
  1400. $structure[] = $val;
  1401. }
  1402. }
  1403. $this->load->library('xmlparser');
  1404. // parse XML data
  1405. $xml = $this->xmlparser->parse_xml($contents);
  1406. $params = array(
  1407. 'data' => $contents,
  1408. 'structure' => $structure,
  1409. 'root' => 'members',
  1410. 'element' => 'member',
  1411. 'delimiter' => $this->delimiter,
  1412. 'enclosure' => $this->enclosure
  1413. );
  1414. $xml = $this->xmlparser->delimited_to_xml($params, 1);
  1415. // Add type="text" parameter for plaintext passwords
  1416. if ($encrypt === TRUE)
  1417. {
  1418. $xml = str_replace('<password>', '<password type="text">', $xml);
  1419. }
  1420. if ( ! empty($this->xmlparser->errors))
  1421. {
  1422. return $this->view_xml_errors($this->xmlparser->errors);
  1423. }
  1424. // Output to browser or download
  1425. switch ($type)
  1426. {
  1427. case 'view' : return $this->view_xml($xml); break;
  1428. case 'download' : $this->download_xml($xml); break;
  1429. }
  1430. }
  1431. // --------------------------------------------------------------------
  1432. /**
  1433. * View XML
  1434. *
  1435. * View XML in browser
  1436. *
  1437. * @return void
  1438. */
  1439. public function view_xml($xml)
  1440. {
  1441. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  1442. {
  1443. show_error(lang('unauthorized_access'));
  1444. }
  1445. $this->load->helper('string');
  1446. $this->cp->set_variable('cp_page_title', lang('view_xml'));
  1447. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=member_import', lang('member_import_utility'));
  1448. $xml = str_replace("\n", BR, htmlentities($xml));
  1449. $xml = str_replace("\t", repeater(NBS, 4), $xml);
  1450. $vars['output'] = $xml;
  1451. $vars['heading'] = lang('view_xml');
  1452. $this->load->view('tools/view_xml', $vars);
  1453. }
  1454. // --------------------------------------------------------------------
  1455. /**
  1456. * View XML Errors
  1457. *
  1458. * Displays XML Errors
  1459. *
  1460. * @return void
  1461. */
  1462. public function view_xml_errors($errors, $message = '')
  1463. {
  1464. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  1465. {
  1466. show_error(lang('unauthorized_access'));
  1467. }
  1468. $this->load->helper('string');
  1469. $this->cp->set_variable('cp_page_title', lang('parse_error'));
  1470. $this->cp->set_breadcrumb(BASE.AMP.'C=tools_utilities'.AMP.'M=member_import', lang('member_import_utility'));
  1471. $out = '<ul>';
  1472. if (is_array($errors))
  1473. {
  1474. foreach ($errors as $error)
  1475. {
  1476. $out .= '<li>'.$error.'</li>';
  1477. }
  1478. }
  1479. else
  1480. {
  1481. $out .= '<li>'.$errors.'</li>';
  1482. }
  1483. $out .= '</ul>';
  1484. $vars['output'] = $out;
  1485. $vars['heading'] = lang('parse_error');
  1486. $vars['message'] = ($message == '') ? NULL : $message;
  1487. $this->load->view('tools/view_xml', $vars);
  1488. }
  1489. // --------------------------------------------------------------------
  1490. /**
  1491. * Download XML
  1492. *
  1493. * Generates XML download
  1494. *
  1495. * @return void
  1496. */
  1497. public function download_xml($xml)
  1498. {
  1499. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utilities'))
  1500. {
  1501. show_error(lang('unauthorized_access'));
  1502. }
  1503. $this->load->helper('download');
  1504. $now = $this->localize->set_localized_time();
  1505. $filename = 'member_'.date('y', $now).date('m', $now).date('d', $now).'.xml';
  1506. force_download($filename, $xml);
  1507. }
  1508. // --------------------------------------------------------------------
  1509. /**
  1510. * Translation Tool
  1511. *
  1512. * Creates the Translation Tool page
  1513. *
  1514. * @return mixed
  1515. */
  1516. public function translation_tool($message = '')
  1517. {
  1518. if ( ! $this->cp->allowed_group('can_access_tools', 'can_access_utiliā€¦

Large files files are truncated, but you can click here to view the full file