<?php
#-------------------------------------------------------------------------
# Module: Newsletter Made Simple
#        (c) to 2008 by Paul Lempkepf
#        (c) 2008 and on by Robert Campbell (calguy1000@cmsmadesimple.org)
#
#  An addon module for CMS Made Simple to provide a flexible
#  mailing list solution.
#
#-------------------------------------------------------------------------
# CMSMS - CMS Made Simple is (c) 2005 by Ted Kulp (wishy@cmsmadesimple.org)
# Visit the CMSMS Homepage at: http://www.cmsmadesimple.org
#
#-------------------------------------------------------------------------
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# However, as a special exception to the GPL, this software is distributed
# as an addon module to CMS Made Simple.  You may not use this software
# in any Non GPL version of CMS Made simple, or in any version of CMS
# Made simple that does not indicate clearly and obviously in its admin
# section that the site was built with CMS Made simple.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Or read it online: http://www.gnu.org/licenses/licenses.html#GPL
#
#-------------------------------------------------------------------------
#END_LICENSE
if( !isset($gCms) ) exit;
if (!$this->CheckPermission('Manage NMS Users')) return;
$this->SetCurrentTab('users');
if( isset($params['cancel']) ) $this->RedirectToTab();

function __map_fields($mod,$raw_fields,$columns)
{
  $out = array();
  if( count($raw_fields) > count($columns) ) throw new CmsException($mod->Lang('error_importformat4'));

  for( $i = 0; $i < count($columns); $i++ ) {
    $out[$columns[$i]] = isset($raw_fields[$i])?$raw_fields[$i]:'';
  }
  return $out;
}

function __insert_user($mod,$line_fields,$fielddefs,$lists,$ignored_columns,$delete_from_lists)
{
  $db = cmsms()->GetDb();
  // gather lists to insert
  $lists_to_add = array();
  $lists_to_remove = array();
  foreach( $line_fields as $key => $val ) {
      if( !startswith($key,'l::') || in_array($key,$ignored_columns) ) continue;
      $key = substr($key,3);
      $listid = $lists[$key];
      if( $val ) {
          $lists_to_add[] = $listid;
      }
      else {
          $lists_to_remove[] = $listid;
      }
  }

  // gather fields to insert
  $fields_to_add = array();
  foreach( $line_fields as $key => $val ) {
    if( !startswith($key,'f::') || $val === '' || in_array($key,$ignored_columns) ) continue;
    $key = substr($key,3);
    $fldid = $fielddefs[$key]['id'];
    $fields_to_add[$fldid] = nms_utils::expand_fielddata($val);
  }

  if( !count($lists_to_add) && !count($lists_to_remove) ) {
      throw new CmsException($mod->Lang('error_importformat4'));
  }

  $exists = FALSE;
  $query = 'SELECT userid FROM '.NMS_USERS_TABLE.' WHERE email = ?';
  $userid = $db->GetOne($query,array($line_fields['email']));
  if( $userid ) {
    $exists = TRUE;
    $query = 'UPDATE '.NMS_USERS_TABLE.' SET username = ? WHERE userid = ? AND email = ?';
    $tmp = array();
    $tmp[] = ( isset($line_fields['username']) ) ? $line_fields['username'] : '';
    $tmp[] = $userid;
    $tmp[] = $line_fields['email'];
    $dbr = $db->Execute($query, $tmp);
  }
  else {
    $query = 'INSERT INTO '.NMS_USERS_TABLE.'
              (uniqueid,email,username,disabled,confirmed,htmlemail,dateadded,dateconfirmed,error_count,bounce_count)
              VALUES (?,?,?,0,1,1,NOW(),NOW(),0,0)';
    $row = array(md5(uniqid(rand(),1)));
    $row[] = $line_fields['email'];
    $row[] = ( isset($line_fields['username']) ) ? $line_fields['username'] : '';
    $dbr = $db->Execute($query,$row);
    $userid = $db->Insert_ID();
  }

  if( count($fields_to_add) ) {
    // add field values
    if( $exists ) {
      $query = 'DELETE FROM '.NMS_USER_DATA_TABLE.' WHERE userid = ?';
      $db->Execute($query,array($userid));
    }

    $query = 'INSERT INTO '.NMS_USER_DATA_TABLE.' (userid,fieldid,value) VALUES (?,?,?)';
    foreach( $fields_to_add as $fieldid => $val ) {
      $db->Execute($query,array($userid,$fieldid,$val));
    }
  }

  // add list memberships
  if( $exists ) {
      if( $delete_from_lists ) {
          $query = 'DELETE FROM '.NMS_LISTUSER_TABLE.' WHERE userid = ?';
          $db->Execute($query,array($userid));
      }
      else if( count($lists_to_remove) ) {
          $query = 'DELETE FROM '.NMS_LISTUSER_TABLE.' WHERE userid = ? AND listid = ('.implode(',',$lists_to_remove).')';
          $db->Execute($query,array($userid));
      }
  }

  if( count($lists_to_add) ) {
    $query = 'INSERT INTO '.NMS_LISTUSER_TABLE.' (userid,listid,active,entered) VALUES (?,?,1,NOW())';
    foreach( $lists_to_add as $listid ) {
      $dbr = $db->Execute($query,array($userid,$listid));
    }
  }
}

if( isset($params['submit']) ) {
  $createfields = (int)get_parameter_value($params,'createfields',0);
  $createlists = (int)get_parameter_value($params,'createlists',0);
  $delete_from_lists = (int)get_parameter_value($params,'delete_from_lists',1);
  cms_userprefs::set('nms_import_createfields',$createfields);
  cms_userprefs::set('nms_import_createlists',$createlists);
  cms_userprefs::set('nms_import_delete_from_lists',$delete_from_lists);

  try {
    // validate the uploaded file.
    $key = $id.'input_filename';
    if( !isset($_FILES[$key]) || !is_array($_FILES[$key]) ) throw new Exception($this->Lang('error_nofilesuploaded'));
    $file = $_FILES[$key];
    if (!isset($file['type'])) $file['type'] = '';
    if (!isset($file['size'])) $file['size'] = '';
    if (!isset($file['tmp_name'])) $file['tmp_name'] = '';
    if( $file['size'] == 0 || $file['error'] > 0 ) throw new CmsException($this->Lang('error_uploadproblem'));

    $ext = substr($file['name'],strrpos($file['name'],'.')+1);
    $ext = strtolower($ext);
    if( $ext != 'txt' && $ext != 'csv' ) throw new CmsException($this->Lang('error_uploadcsvtype'));

    // open the file, get the first line.
    $fh = fopen($file['tmp_name'],'r');
    if( !$fh ) throw new CmsException($this->Lang('error_uploadproblem'));
    $headerline = cge_utils::fgets($fh);
    if( !startswith( $headerline, '#') ) throw new CmsException($this->Lang('error_importformat1'));

    // get columns from the headerline, check for minimum columns
    $headerline = ltrim($headerline,'#');
    $ignorecolumns = array();
    $columns = cge_array::smart_explode($headerline);
    foreach( $columns as &$col ) {
      $col = trim($col);
    }
    unset($col);

    // check for required columns
    if( !in_array('email',$columns) ) throw new CmsException($this->Lang('error_importformat2'));
    $fnd = FALSE;
    foreach( $columns as $col2 ) {
      if( startswith($col2,'l::') ) {
	$fnd = TRUE; break;
      }
    }
    unset($col2);
    if( !$fnd ) throw new CmsException($this->Lang('error_importformat3'));

    // now get the lists, and the fields
    $fielddefs = array();
    $tmp = nms_fielddef::load_all();
    if( is_array($tmp) && count($tmp) ) {
      foreach( $tmp as $obj ) {
	$fielddefs[$obj['name']] = $obj;
      }
    }
    unset($tmp);

    $query = 'SELECT listid,name FROM '.NMS_LIST_TABLE.' WHERE COALESCE(dynamic,0) = 0 ORDER BY name';
    $tmp = $db->GetArray($query);
    $lists = array();
    if( is_array($tmp) && count($tmp) ) {
      foreach( $tmp as $row ) {
	$lists[$row['name']] = $row['listid'];
      }
    }

    // make sure the field(s) specified in columns are valid.
    foreach( $columns as $col ) {
      if( !startswith($col,'f::') ) continue;
      $fieldname = substr($col,3);
      if( !isset($fielddefs[$fieldname]) ) {
	// ruh-roh.
	if( $createfields ) {
	  $obj = new nms_fielddef;
	  $obj['type'] = $obj::TYPE_TEXTBOX;
	  $obj['name'] = $fieldname;
	  $obj['prompt'] = ucwords($fieldname);
	  $obj['required'] = 0;
	  $obj->save();
	  $fielddefs[$fieldname] = $obj;
	}
	else {
	  $ignorecolumns[] = $col;
	}
      }
    }
    unset($col);

    // make sure the list(s) specified in columns are valid.
    foreach( $columns as $col ) {
      if( !startswith($col,'l::') ) continue;
      $listname = substr($col,3);
      if( !isset($lists[$listname]) ) {
	if( $createlists ) {
	  // gotta create the list
	  $query = 'INSERT INTO '.NMS_LIST_TABLE.' (name,active,public,dynamic,dateadded) VALUES (?,1,1,0,NOW())';
	  $db->Execute($query,array($listname));
	  $lists[$listname] = $db->Insert_ID();
	}
	else {
	  $ignorecolumns[] = $col;
	}
      }
    }
    unset($col);

    $errors = array();
    $linenum = 1;
    $num_added = 0;
    while( !feof($fh) ) {
      try {
	$line = cge_utils::fgets($fh);
	$linenum++;
	$p = strpos($line,'#');
	if( $p !== FALSE ) $line = substr($line,0,$p);
	$line = trim($line);
	if( !$line ) continue;

	// map fields into columns
	$raw_fields = cge_array::smart_explode($line);
	$line_fields = __map_fields($this,$raw_fields,$columns);
	__insert_user($this,$line_fields,$fielddefs,$lists,$ignorecolumns,$delete_from_lists);
	$num_added++;
      }
      catch( Exception $e ) {
	$errors[$linenum] = $e->GetMessage();
      }
    }

    if( count($errors) ) {
      $smarty->assign('errors',$errors);
    }
    else {
      $this->SetMessage($this->Lang('msg_imported',$num_added));
      $this->RedirectToTab();
    }
  }
  catch( Exception $e ) {
    echo $this->ShowErrors($e->GetMessage());
  }
}

// display a page that will allow users to upload a csv file, process it
// and then display results, and allow importing more users
$smarty->assign('startform', $this->CreateFormStart($id, 'import_users', $returnid, 'post', 'multipart/form-data'));
$smarty->assign('endform', $this->CreateFormEnd());
$smarty->assign('create_fields',cms_userprefs::get('nms_import_createfields',0));
$smarty->assign('create_lists',cms_userprefs::get('nms_import_createlists',0));
$smarty->assign('delete_from_lists',cms_userprefs::get('nms_import_delete_from_lists',1));

echo $this->ProcessTemplate('import.tpl');

?>