PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/handlers/class.atkexporthandler.inc

https://github.com/ibuildingsnl/ATK
PHP | 583 lines | 406 code | 63 blank | 114 comment | 69 complexity | 277e935baaa16607c67a62373b95832b MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, LGPL-3.0
  1. <?php
  2. /**
  3. * This file is part of the Achievo ATK distribution.
  4. * Detailed copyright and licensing information can be found
  5. * in the doc/COPYRIGHT and doc/LICENSE files which should be
  6. * included in the distribution.
  7. *
  8. * @package atk
  9. * @subpackage handlers
  10. *
  11. * @copyright (c)2004 Ivo Jansch
  12. * @copyright (c)2004 Ibuildings.nl BV
  13. * @license http://www.achievo.org/atk/licensing ATK Open Source License
  14. *
  15. * @version $Revision: 6323 $
  16. * $Id$
  17. */
  18. /**
  19. * Handler for the 'import' action of a node. The import action is a
  20. * generic tool for importing CSV files into a table.
  21. *
  22. * @author Ivo Jansch <ivo@achievo.org>
  23. * @package atk
  24. * @subpackage handlers
  25. *
  26. */
  27. class atkExportHandler extends atkActionHandler
  28. {
  29. /**
  30. * The action handler.
  31. */
  32. function action_export()
  33. {
  34. global $ATK_VARS;
  35. // Intercept partial call
  36. if (!empty($this->m_partial))
  37. {
  38. $this->partial($this->m_partial);
  39. return;
  40. }
  41. // Intercept delete call
  42. if( array_key_exists( 'dodelete', $this->m_postvars ) && ctype_digit( $this->m_postvars['dodelete'] ) )
  43. {
  44. if( array_key_exists( 'confirmed', $this->m_postvars ) && $this->m_postvars['confirmed'] == 'true' )
  45. {
  46. $this->deleteSelection( $this->m_postvars['dodelete'] );
  47. }
  48. }
  49. //need to keep the postdata after a AF_LARGE selection in the allfield
  50. if(!isset($this->m_postvars["phase"]) && isset($ATK_VARS['atkformdata']))
  51. foreach($ATK_VARS['atkformdata'] as $key=>$value)
  52. $this->m_postvars[$key] = $value;
  53. //need to keep the selected item after an exporterror
  54. $phase = atkArrayNvl($this->m_postvars, "phase", "init");
  55. if (!in_array($phase, array("init", "process")))
  56. $phase = "init";
  57. switch ($phase)
  58. {
  59. case "init": $this->doInit(); break;
  60. case "process": $this->doProcess(); break;
  61. }
  62. return true;
  63. }
  64. /**
  65. * This function shows a form to configure the .csv
  66. */
  67. function doInit()
  68. {
  69. $content = $this->_getInitHtml();
  70. $page = &$this->getPage();
  71. $page->register_scriptcode( "
  72. function toggleSelectionName( fieldval )
  73. {
  74. if( fieldval == undefined )
  75. {
  76. fieldval = $( 'export_selection_options' ).value;
  77. }
  78. new Ajax.Updater('export_attributes', '".partial_url( $this->m_postvars['atknodetype'], 'export', 'export' )."exportvalue='+fieldval+'&' );
  79. if( fieldval != 'none' )
  80. {
  81. if( fieldval != 'new' )
  82. {
  83. new Ajax.Updater('selection_interact', '".partial_url( $this->m_postvars['atknodetype'], 'export', 'selection_interact' )."exportvalue='+fieldval+'&' );
  84. new Ajax.Updater('export_name', '".partial_url( $this->m_postvars['atknodetype'], 'export', 'selection_name' )."exportvalue='+fieldval+'&' );
  85. $( 'selection_interact' ).style.display='';
  86. $( 'export_name' ).style.display='';
  87. $( 'export_save_button' ).style.display='';
  88. }
  89. else
  90. {
  91. $( 'selection_interact' ).style.display='none';
  92. $( 'export_name' ).style.display='';
  93. $( 'export_selection_name' ).value='';
  94. $( 'export_selection_options' ).selectedIndex=0;
  95. $( 'export_save_button' ).style.display='none';
  96. }
  97. }
  98. else
  99. {
  100. $( 'export_name' ).style.display='none';
  101. $( 'selection_interact' ).style.display='none';
  102. $( 'export_save_button' ).style.display='none';
  103. $( 'export_selection_name' ).value='';
  104. }
  105. }" );
  106. $page->register_scriptcode( "
  107. function confirm_delete()
  108. {
  109. var where_to = confirm('".atktext('confirm_delete')."');
  110. var dodelete = $( 'export_selection_options' ).value;
  111. if (where_to == true)
  112. {
  113. window.location= \"".dispatch_url( $this->m_postvars['atknodetype'], 'export', array( 'confirmed' => 'true' ) )."&dodelete=\"+dodelete;
  114. }
  115. }" );
  116. $page->addContent($this->m_node->genericPage("export", $content));
  117. return true;
  118. }
  119. /**
  120. * Handle partial request
  121. *
  122. * @return string
  123. */
  124. public function partial_export()
  125. {
  126. $value = array_key_exists( 'exportvalue', $this->m_postvars ) ? $this->m_postvars['exportvalue'] : null;
  127. return $this->getAttributeSelect( $value );
  128. }
  129. /**
  130. * Partial fetches and displays the name of the selected value
  131. *
  132. * @return string
  133. */
  134. public function partial_selection_name()
  135. {
  136. $selected = array_key_exists( 'exportvalue', $this->m_postvars ) ? $this->m_postvars['exportvalue'] : null;
  137. $value = '';
  138. if( $selected )
  139. {
  140. $db = atkGetDb();
  141. $rows = $db->getRows( 'SELECT name FROM atk_exportcriteria WHERE id = '.(int) $selected );
  142. if( count( $rows ) == 1 )
  143. {
  144. $value = htmlentities( $rows[0]['name'] );
  145. }
  146. }
  147. return '<td>'.atktext("export_selections_name", "atk").': </td><td align="left"><input type="text" size="40" name="export_selection_name" id="export_selection_name" value="'.$value.'"></td>
  148. <input type="hidden" name="exportvalue" value="'.$this->m_postvars['exportvalue'].'" />';
  149. }
  150. /**
  151. * Partial displays a interaction possibilities with an export selection
  152. *
  153. * @return string
  154. */
  155. public function partial_selection_interact( )
  156. {
  157. $selected = array_key_exists( 'exportvalue', $this->m_postvars ) ? $this->m_postvars['exportvalue'] : null;
  158. $theme = atkinstance( 'atk.ui.atktheme' );
  159. $img_delete = $theme->iconPath('delete', 'recordlist' );
  160. $url_delete = dispatch_url( $this->m_node->m_module.'.'.$this->m_node->m_type, 'export', array('dodelete' => $selected ) );
  161. if( $selected )
  162. {
  163. $result = '<a href="'.$url_delete.'" title="'.atktext( 'delete_selection' ).'" onclick="confirm_delete();"><img src="'.$img_delete.'" alt="'.atktext( 'delete_selection' ).'" border="0" /></a>';
  164. return $result;
  165. }
  166. }
  167. /**
  168. * Gets the HTML for the initial mode of the exporthandler
  169. * @return String The HTML for the screen
  170. */
  171. function _getInitHtml()
  172. {
  173. $action = dispatch_url($this->m_node->m_module.'.'.$this->m_node->m_type, "export");
  174. $params = array();
  175. $params["formstart"] = '<form name="entryform" enctype="multipart/form-data" action="'.$action.'" method="post">';
  176. $params["formstart"] .= session_form();
  177. $params["formstart"] .= '<input type="hidden" name="phase" value="process"/>';
  178. $params["buttons"][] = '<input class="btn" type="submit" value="'.atkText("export", "atk").'"/>';
  179. $params["buttons"][] = '<input id="export_save_button" style="display:none;" value="'.atktext("save_export_selection","atk").'" name="save_export" class="btn" type="submit" /> ';
  180. $params["buttons"][] = atkButton(atktext("back", "atk"), "", SESSION_BACK, true);
  181. $params["content"] = atkText("export_config_explanation", "atk", $this->m_node->m_type).'<br/><br/>';
  182. $params["content"] .= $this->_getOptions();
  183. $params["formend"] = '</form>';
  184. return atkInstance("atk.ui.atkui")->renderAction("export", $params, $this->m_node->m_module);
  185. }
  186. /**
  187. * This function checks if there is enough information to export the date
  188. * else it wil shows a form to set how the file wil be exported
  189. */
  190. function doProcess()
  191. {
  192. // Update selection
  193. if( array_key_exists( 'exportvalue', $this->m_postvars )
  194. && array_key_exists( 'save_export', $this->m_postvars )
  195. && '' != $this->m_postvars['export_selection_name'] )
  196. {
  197. $this->updateSelection();
  198. $this->getNode()->redirect(dispatch_url($this->getNode(), 'export'));
  199. }
  200. // Save selection
  201. if( array_key_exists( 'export_selection_options', $this->m_postvars )
  202. && array_key_exists( 'export_selection_name', $this->m_postvars )
  203. && 'none' == $this->m_postvars['export_selection_options']
  204. && '' != $this->m_postvars['export_selection_name'] )
  205. {
  206. $this->saveSelection();
  207. }
  208. // Export CVS
  209. if( !array_key_exists( 'save_export', $this->m_postvars ) )
  210. {
  211. return $this->doExport();
  212. }
  213. }
  214. /**
  215. * Get the options for the export
  216. *
  217. * @return unknown
  218. */
  219. function _getOptions()
  220. {
  221. $content = '<table border="0" width="100%">';
  222. // enable extended export options
  223. if( true === atkconfig( 'enable_export_save_selection' ) )
  224. {
  225. $content .= '<tr><td>'.atktext("export_selections", "atk").': </td><td align="left">'.$this->getExportSelectionDropdown().'&nbsp;&nbsp;&nbsp;<a href="javascript:void(0);" onclick="toggleSelectionName(\'new\');return false;">'.atktext('new', 'atk').'</a></td></tr>';
  226. $content .= '<tr><td>&nbsp;</td><td align="left"><div id="selection_interact"></div></td></tr>';
  227. $content .= '<tr id="export_name" style="display:none;"><td>'.atktext("export_selections_name", "atk").': </td><td align="left"><input type="text" size="40" id="export_selection_name" name="export_selection_name" value=""></td></tr>';
  228. }
  229. $content.= '<tr><td>'.atktext("delimiter", "atk").': </td><td><input type="text" size="2" name="delimiter" value=";"></td></tr>';
  230. $content.= '<tr><td>'.atktext("enclosure", "atk").': </td><td><input type="text" size="2" name="enclosure" value="&quot;"></td></tr>';
  231. $content.= '<tr><td valign="top">'.atktext("export_selectcolumns", "atk").': </td><td><div id="export_attributes">'.$this->getAttributeSelect().'</div></td></tr>';
  232. $content.= '<tr><td>';
  233. $content.= atktext("export_generatetitlerow").': </td><td><input type="checkbox" name="generatetitlerow" class="atkcheckbox" value="1" />';
  234. $content.= '</td></tr>';
  235. $content.= '</table><br /><br />';
  236. return $content;
  237. }
  238. /**
  239. * Build the dropdown field to add the exportselections
  240. *
  241. * @return string
  242. */
  243. private function getExportSelectionDropdown( )
  244. {
  245. $html = '
  246. <select name="export_selection_options" id="export_selection_options" onchange="javascript:toggleSelectionName( );return false;" >
  247. <option value="none">'.atktext('none', 'atk');
  248. $options = $this->getExportSelections();
  249. if( count ( $options ) )
  250. {
  251. foreach( $options AS $option )
  252. {
  253. $html .= '
  254. <option value="'.$option['id'].'">'.htmlentities( $option['name'] ).'</option>';
  255. }
  256. }
  257. $html .= '</select>';
  258. return $html;
  259. }
  260. /**
  261. * Store selectiondetails in the database
  262. *
  263. * @return null
  264. */
  265. private function saveSelection( )
  266. {
  267. $db = atkGetDb( );
  268. $id = $db->nextid( 'exportcriteria' );
  269. $user_id = 0;
  270. if( 'none' !== strtolower( atkConfig( 'authentication' ) ) )
  271. {
  272. $user = atkGetUser( );
  273. $user_id = array_key_exists( atkConfig('auth_userpk'), $user ) ? $user[atkConfig('auth_userpk')] : 0;
  274. }
  275. // first check if the combination of node, name and user_id doesn't already exist
  276. $rows = $db->getRows("SELECT id FROM atk_exportcriteria
  277. WHERE nodetype = '".$this->m_postvars['atknodetype']."'
  278. AND name = '".$this->m_postvars['export_selection_name']."'
  279. AND user_id = ".$user_id);
  280. if (count($rows))
  281. {
  282. return;
  283. }
  284. $query = 'INSERT INTO atk_exportcriteria ( id, nodetype, name, criteria, user_id )
  285. VALUES ( '.$id.', "'.$this->m_postvars['atknodetype'].'", "'.$db->escapeSQL( $this->m_postvars['export_selection_name'] ) .'",
  286. "'. addslashes( serialize( $this->m_postvars ) ).'", '.$user_id.' )';
  287. $db->query( $query );
  288. }
  289. /**
  290. * Update selectiondetails in the database
  291. *
  292. * @return null
  293. */
  294. private function updateSelection( )
  295. {
  296. $db = atkGetDb( );
  297. $user_id = 0;
  298. if( 'none' !== strtolower( atkConfig( 'authentication' ) ) )
  299. {
  300. $user = atkGetUser( );
  301. $user_id = array_key_exists( atkConfig('auth_userpk'), $user ) ? $user[atkConfig('auth_userpk')] : 0;
  302. }
  303. // first check if the combination of node, name and user_id doesn't already exist
  304. $rows = $db->getRows("SELECT id FROM atk_exportcriteria
  305. WHERE nodetype = '".$this->m_postvars['atknodetype']."'
  306. AND name = '".$this->m_postvars['export_selection_name']."'
  307. AND user_id = ".$user_id."
  308. AND id <> ".(int) $this->m_postvars['exportvalue']);
  309. if (count($rows))
  310. {
  311. return;
  312. }
  313. $query = 'UPDATE
  314. atk_exportcriteria
  315. SET
  316. name = "'.$db->escapeSQL( $this->m_postvars['export_selection_name'] ) .'",
  317. criteria = "'.addslashes( serialize( $this->m_postvars) ).'"
  318. WHERE
  319. id = '. (int) $this->m_postvars['exportvalue'];
  320. $db->query( $query );
  321. }
  322. /**
  323. * Delete record
  324. *
  325. * @param integer $id
  326. */
  327. private function deleteSelection( $id )
  328. {
  329. $db = atkGetDb( );
  330. $db->query( 'DELETE FROM atk_exportcriteria WHERE id = '.(int) $id );
  331. }
  332. /**
  333. * Determine the export selections that should be displayed
  334. *
  335. * @return array
  336. */
  337. protected function getExportSelections( )
  338. {
  339. $where = ' nodetype = "'. $this->m_postvars['atknodetype'].'"';
  340. if( 'none' !== strtolower( atkConfig( 'authentication' ) ) )
  341. {
  342. $user = atkGetUser( );
  343. if( 'administrator' !== strtolower( $user['name'] ) )
  344. {
  345. $where .= ' AND user_id IN( 0, '. (int) $user[ atkConfig( 'auth_userpk' ) ].' )';
  346. }
  347. }
  348. $db = atkGetDb( );
  349. return $db->getRows( $query = 'SELECT id, name FROM atk_exportcriteria WHERE '.$where.' ORDER BY name' );
  350. }
  351. /**
  352. * Get all attributes to select for the export
  353. *
  354. * @return String HTML code with checkboxes for each attribute to select
  355. */
  356. function getAttributeSelect()
  357. {
  358. $cols = 5;
  359. $atts = $this->getUsableAttributes();
  360. $content = "";
  361. foreach($atts as $tab => $group)
  362. {
  363. $content .= '<TABLE style="border: 1px solid #d8d8d8; width: 90%">';
  364. if($tab != 'default')
  365. {
  366. $content .= '<TR><TD colspan="'.$cols.'"><div style="background-color: #ccc; color: #00366E; font-weight: bold">'.atktext(array("tab_$tab", $tab),$this->m_node->m_module,$this->m_node->m_type).'</div></TD></TR><TR>';
  367. }
  368. $idx = 0;
  369. foreach($group as $item)
  370. {
  371. if($item['checked']) $checked = 'CHECKED';
  372. else $checked = '';
  373. $content.= '<TD align="left" width="'.(90/$cols).'%"><LABEL><INPUT type="checkbox" name="export_'.$item['name'].'" class="atkcheckbox" value="export_'.$item['name'].'" '.$checked.'>'.$item['text'].'</LABEL></TD>';
  374. $idx++;
  375. if($idx%$cols == 0)
  376. {
  377. $content .= '</TR><TR>';
  378. }
  379. }
  380. while($idx%$cols != 0){
  381. $content .= '<TD width="'.(90/$cols).'%">&nbsp;</TD>';
  382. $idx++;
  383. }
  384. $content .= "</TR></TABLE><BR/>";
  385. }
  386. return $content;
  387. }
  388. /**
  389. * Gives all the attributes that can be used for the import
  390. * @return array the attributes
  391. */
  392. function getUsableAttributes()
  393. {
  394. $selected = $value == 'new' ? false : true;
  395. $criteria = array();
  396. if( !in_array( $value, array( 'new', 'none', '' ) ) )
  397. {
  398. $db = atkGetDb( );
  399. $rows = $db->getRows( 'SELECT * FROM atk_exportcriteria WHERE id = '.(int) $value );
  400. $criteria = unserialize($rows[0]['criteria']);
  401. }
  402. $atts = array();
  403. $attriblist = $this->invoke('getExportAttributes');
  404. foreach($attriblist as $key => $value)
  405. {
  406. $flags = $value->m_flags;
  407. $class = strtolower(get_class($value));
  408. if($value->hasFlag(AF_AUTOKEY) ||
  409. $value->hasFlag(AF_HIDE_VIEW) ||
  410. !(strpos($class, "dummy") === FALSE) ||
  411. !(strpos($class, "image") === FALSE) ||
  412. !(strpos($class,'tabbedpane') === FALSE)
  413. )
  414. continue;
  415. if (method_exists($this->m_node, "getExportAttributeGroup"))
  416. {
  417. $group = $this->m_node->getExportAttributeGroup($value->m_name);
  418. }
  419. else
  420. {
  421. $group = $value->m_tabs[0];
  422. }
  423. if(in_array($group, $atts))
  424. {
  425. $atts[$group] = array();
  426. }
  427. // selected options based on a new selection, or no selection
  428. if( empty( $criteria ) )
  429. {
  430. $atts[$group][] = array( 'name' => $key,
  431. 'text' => $value->label(),
  432. 'checked' => $selected == true ? !$value->hasFlag(AF_HIDE_LIST) : false
  433. );
  434. }
  435. // selected options based on a selection from DB
  436. else
  437. {
  438. $atts[$group][] = array( 'name' => $key,
  439. 'text' => $value->label(),
  440. 'checked' => in_array( 'export_'.$key, $criteria) ? true : false
  441. );
  442. }
  443. }
  444. return $atts;
  445. }
  446. /**
  447. * Return all attributes that can be exported
  448. *
  449. * @return array Array with attribs that needs to be exported
  450. */
  451. function getExportAttributes()
  452. {
  453. $attribs = $this->m_node->getAttributes();
  454. if(is_null($attribs)) { return array(); } else { return $attribs; }
  455. }
  456. /**
  457. * the real import function
  458. * import the uploaded csv file for real
  459. */
  460. function doExport()
  461. {
  462. $enclosure = $this->m_postvars["enclosure"];
  463. $delimiter = $this->m_postvars["delimiter"];
  464. $source = $this->m_postvars;
  465. $list_includes = array();
  466. foreach($source as $name => $value)
  467. {
  468. $pos = strpos($name, 'export_');
  469. if (is_integer($pos) and $pos == 0)
  470. $list_includes[] = substr($name, strlen('export_'));
  471. }
  472. global $g_sessionData;
  473. $session_back = $g_sessionData["default"]["stack"][atkStackID()][atkLevel()-1];
  474. $atkorderby = $session_back['atkorderby'];
  475. $node = &$this->m_node;
  476. $node_bk = $node;
  477. $num_atts = count($node_bk->m_attribList);
  478. $atts = &$node_bk->m_attribList;
  479. foreach($atts as $name => $object)
  480. {
  481. $att = &$node_bk->getAttribute($name);
  482. if(in_array($name, $list_includes) && $att->hasFlag(AF_HIDE_LIST))
  483. $att->removeFlag(AF_HIDE_LIST);
  484. elseif (!in_array($name, $list_includes))
  485. $att->addFlag(AF_HIDE_LIST);
  486. }
  487. if (!is_array($actions))
  488. {
  489. $actions = $node->defaultActions("export");
  490. }
  491. $rl = &atknew("atk.recordlist.atkcustomrecordlist");
  492. $flags = ($node_bk->hasFlag(NF_MRA) ? RL_MRA : 0) | ($node_bk->hasFlag(NF_MRPA) ? RL_MRPA : 0) | ($node_bk->hasFlag(NF_LOCK) ? RL_LOCK : 0);
  493. $node_bk->m_postvars = $session_back;
  494. if (isset($session_back['atkdg']['admin']['atksearch']))
  495. $node_bk->m_postvars['atksearch'] = $session_back['atkdg']['admin']['atksearch'];
  496. if (isset($session_back['atkdg']['admin']['atksearchmode']))
  497. $node_bk->m_postvars['atksearchmode'] = $session_back['atkdg']['admin']['atksearchmode'];
  498. $atkfilter = atkArrayNvl($source, 'atkfilter', "");
  499. $recordset = $node_bk->selectDb($session_back['atkselector'].($session_back['atkselector'] != '' && $atkfilter != '' ? ' AND ' : '').$atkfilter, $atkorderby, "", "", $list_includes, "export");
  500. if (method_exists($this->m_node, "assignExportData")) $this->m_node->assignExportData($list_includes, $recordset);
  501. $recordset_new = array();
  502. foreach($recordset as $row)
  503. {
  504. foreach($row as $name => $value)
  505. {
  506. if(in_array($name, $list_includes))
  507. {
  508. $value = str_replace("\r\n", "\\n", $value);
  509. $value = str_replace("\n", "\\n", $value);
  510. $value = str_replace("\t", "\\t", $value);
  511. $row[$name] = $value;
  512. }
  513. }
  514. $recordset_new[] = $row;
  515. }
  516. $rl->render($node_bk, $recordset_new, "", $enclosure, $enclosure.$delimiter, "\r\n", 1, "", "", array('filename' => 'export_'.$node->m_type), "csv", $source['generatetitlerow'], true);
  517. return true;
  518. }
  519. }
  520. ?>