id; } public function renderDefault($id) { $luser = $this->luser; $this->template->id = $this->id; $this->template->addresslist = $luser->get_addresslist($id); $this->template->user = $luser; } protected function createComponentDefault($action) { $uid = $this->user->id; $luser = $this->luser; $addresslist = $luser->get_addresslist($this->getAddresslistid()); $form = new \Nette\Application\UI\Form; $form->addText('name', "Name") ->addRule($form::MIN_LENGTH, "Name must not be empty", 1) ->addRule($form::MAX_LENGTH, "Don't let's be silly", 100) ->addRule($form::PATTERN, "Name must be well-formed", '^[A-Za-z0-9]+([-_ ][A-Za-z0-9]+)*$'); $mygroups = []; $usergroups = $luser->groups; $defaultvalue = $luser->primarygroup->primary; #false; foreach($usergroups as $usergroup) { $mygroups[$usergroup->primary] = $usergroup->name; # addresslist->getOwnergroup if ($usergroup->primary == $addresslist->ownergroup) { $defaultvalue = $usergroup->primary; } } $form->addSelect('group', "group", $mygroups); if ($defaultvalue) { $form['group']->setDefaultValue($defaultvalue); } $form->addSubmit('delete', "Delete"); $form->addSubmit('export', "Export"); $form->addSubmit('upload', "Upload"); $form->addSubmit('submit', "Submit"); $form->addProtection("protection token expired"); $form->onSuccess[] = [$this, 'defaultFormOK']; return $form; } public function defaultFormOK(Nette\Application\UI\Form $form) { # $values = $form->values; $id = $this->id; $uid = $this->user->id; $luser = $this->luser; $addresslists = $luser->addresslists; $addresslist = $addresslists[$id]; if($form['submit']->submittedBy) { $values = $form->values; $addresslist->name = $values->name; $addresslist->addresses = $form->getHttpData($form::DATA_TEXT, 'address[]'); $newownergroup = $form->getHttpData($form::DATA_TEXT, 'group'); // Check if user in specified group if ($luser->inGroup($newownergroup)) { $addresslist->ownergroup = $newownergroup; $this->submit_redirect(); } else { $this->flashMessage('You do not belong to this group'); } } if($form['upload']->submittedBy) { $this->redirect('Addresslist:upload', ['id' => $id]); } if ($form['export']->submittedBy) { $this->redirect('Addresslist:export', ['id' => $id]); } if ($form['delete']->submittedBy) { $this->redirect('Addresslist:delete', ['id' => $id]); } } public function submit_redirect() { $this->redirect('Addresslists:default', ['id' => false]); } public function actionDownload($id) { $uid = $this->user->id; $luser = $this->luser; $addresslists = $luser->addresslists; $addresslist = $addresslists[$id]; $suggestedfilename = preg_replace("/[^a-z0-9 ._()-]/", "", strtolower($addresslist->name)); $format = $this->getParam("format"); switch($format) { case "csv": // Only if requested specifically we send the csv $suggestedfilename .= ".csv"; header("Content-type: text/csv"); header("Content-Disposition: attachment; filename=\"$suggestedfilename\";"); print "# CSV Export addresslist \"$addresslist->name\" (id $id)\n"; print "# Export created at ". date("Y-m-d H:i")."\n"; foreach ($addresslist->addresses as $emailaddress) { print "$emailaddress->address\n"; } break; default: $suggestedfilename .= ".xlsx"; header("Content-type: application/excel"); header("Content-Disposition: attachment; filename=\"$suggestedfilename\";"); //print "pseudo EXCEL FORMAT @#K@ #%@HLH% #@\n"; // All other cases we send the excel version require_once("phpexcel/PHPExcel.php"); $xl = new \PHPExcel(); $xl->setActiveSheetIndex(0); $rowcount=1; foreach ($addresslist->addresses as $emailaddress) { $xl->getActiveSheet()->setCellValue('A'.$rowcount, $emailaddress->address); $rowcount++; } $writer = new \PHPExcel_Writer_Excel2007($xl); $writer->save('php://output'); break; } $this->terminate(); } protected function createComponentUpload($action) { $form = new \Nette\Application\UI\Form; $form->addText('listname', "Addresslistname"); $form->addUpload('filename', "Addressfile") ->setRequired("You need to upload an addressfile"); $form->addSelect('merge', "Merge", [ "no" => "Overwrite entire list with uploaded addresses", "yes" => "Merge existing list with uploaded addressess"]); $form->addSubmit('upload', "Upload addresslist"); $form->addProtection("protection token expired"); $form->onSuccess[] = [$this, 'uploadFormOK']; return $form; } function guess_encoding($firstchunk) { $first2bytes = substr($firstchunk, 0, 2); if($first2bytes === "\xFE\xFF") { return 'utf16be'; } else if($first2bytes === "\xFF\xFE") { return 'utf16le'; } else if(substr($firstchunk, 0, 3) === "\xEF\xBB\xBF") { return 'utf8'; } $len = strlen($firstchunk); $oddzeros = 0; $evenzeros = 0; for($i = 0; $i < $len; $i++) { $c = $firstchunk[$i]; if($c == "\0") { if($i & 1) $oddzeros++; else $evenzeros++; } } if($oddzeros) { if($evenzeros < $len / 256) return 'utf16le'; } else if($evenzeros) { if($oddzeros < $len / 256) return 'utf16be'; } if(preg_match('/^[\x09-\x0D\x1A\x1B\x20-\x7E]+\z/', $firstchunk)) return 'ascii'; if(preg_match('/^(?: [\x09-\x0D\x1A\x1B\x20-\x7E] | [\xC2-\xDF][\x80-\xBF] | [\xE0-\xEF][\x80-\xBF][\x80-\xBF] | [\xF0-\xF4][\x80-\xBF][\x80-\xBF][\x80-\xBF] )+ (?: [\xC2-\xDF] | [\xE0-\xEF][\x80-\xBF]? | [\xF0-\xF4](?:[\x80-\xBF][\x80-\xBF]?)? )?\z/x', $firstchunk)) return 'utf8'; if(preg_match('/^[\x09-\x0D\x1A\x1B\x20-\x7E\xA0-\xFF]+\z/', $firstchunk)) return 'iso-8859-15'; if(preg_match('/^[\x09-\x0D\x1A\x1B\x20-\x80\x82-\x8C\x8E\x91-\x9C\x9E-\xFF]+\z/', $firstchunk)) return 'windows-1252'; return null; } public function uploadFormOK(Nette\Application\UI\Form $form) { $values = $form->values; $id = $this->id; $uid = $this->user->id; $luser = $this->luser; $addresslists = $luser->addresslists; if ($form['upload']->submittedBy) { // upload functionaliteit hier $failureMessages = []; #---------------------------------------------------------------------------- /** @var FileUpload $uploadedFile */ $uploadedFile = $values->filename; $xlfile = $uploadedFile->getTemporaryFile(); require_once("phpexcel/PHPExcel.php"); $inputFileType = \PHPExcel_IOFactory::identify($xlfile); $supportedFiletype=false; switch($inputFileType) { case 'CSV': case 'Excel5': case 'Excel2007': case 'OOCalc': $supportedFiletype = true; break; default: break; } if (!$supportedFiletype) { $this->flashMessage("We could not interpret the supplied file. Make sure it's either an Excel or CSV file (You supplied $inputFileType)"); return; } $objReader = \PHPExcel_IOFactory::createReader($inputFileType); $worksheetData = $objReader->listWorksheetInfo($xlfile); $objPHPExcel = \PHPExcel_IOFactory::load($xlfile); $sheet = $objPHPExcel->getSheet(0); $highestRow = $sheet->getHighestRow(); $highestColumn = $worksheetData[0]["lastColumnLetter"]; ## $sheet->getHighestColumn(); if ($values["merge"] == "no") { // Empty out the current list $newaddresses = []; $addresslists[$id]->addresses = $newaddresses; } $this->flashMessage("Addresslist ".$addresslists[$id]->name. " modified"); // In the upload the first column should be the email address // FIXME-V2: additional columns are ignored currently $addressCount = 0; for ($row=1; $row<=$highestRow; $row++) { $rowData = $sheet->rangeToArray("A$row:$highestColumn$row"); foreach($rowData[0] as $key => $value) { // FIXME: $value kan encoded zijn, naar ascii converteren. UTF-16 wordt niet goed gedetect hier //$value = mb_convert_encoding($value, 'ASCII', mb_detect_encoding($value)); $encoding = $this->guess_encoding($value); if ($encoding != "ascii") { $failureMessages[] = "(line $row) '".$value."'is not properly encoded"; } elseif ($value) { // Check if the value is an actual email address (presence of @) if (strpos($value, '@')===false) { // It might be an ANR or username $ldapvalue = $this->database->ldap->find_email($value); if (!$ldapvalue || strpos($ldapvalue, '@')===false) { // Still not a valid mail address $failureMessages[] = "(line $row) '" . $value."' is not an email address, nor is it recognised as ANR or username"; } else { $newaddresses[] = $ldapvalue; $addressCount++; } } else { if (strpos($value, "\x00")===false) { $newaddresses[] = $value; $addressCount++; } else { // Not only ascii chars in email address $failureMessages[] = "(line $row) '".$value."' is not a valid email address"; } } } } } // And push it all to the DB $addresslists[$id]->addAddresses($newaddresses); $this->template->number = $highestRow; $this->template->validnumber = $addressCount; $this->template->failureMessages = $failureMessages; $this->template->failureCount = count($failureMessages); #---------------------------------------------------------------------------- } } public function actionUpload($id) { $this->id = $id; $this->template->number = 0; } public function renderUpload($id) { $uid = $this->user->id; $luser = $this->luser; $addresslists = $luser->addresslists; switch($id) { case "new": case NULL: break; default: $this->template->addresslist = $addresslist = $addresslists[$id]; } $this->template->id = $id; } protected function createComponentCreate($action) { $uid = $this->user->id; $luser = $this->luser; $form = new \Nette\Application\UI\Form; $form->addText('name', "Name") ->addRule($form::MIN_LENGTH, "Name must not be empty", 1) ->addRule($form::MAX_LENGTH, "Don't let's be silly", 100) ->addRule($form::PATTERN, "Name must be well-formed", '^[A-Za-z0-9]+([-_ ][A-Za-z0-9]+)*$'); $form->addSelect('owner', "owner", [$luser->primary => $luser->name]); $mygroups = []; $usergroups = $luser->groups; foreach($usergroups as $usergroup) { $mygroups[$usergroup->primary] = $usergroup->name; } $form->addSelect('group', "group", $mygroups); $form['group']->setDefaultValue($luser->primarygroup->primary); $form->addSubmit('create', "Create"); $form->addSubmit('cancel', "Cancel") ->setValidationScope(FALSE); $form->addProtection("protection token expired"); $form->onSuccess[] = [$this, 'createFormOK']; return $form; } public function getCreateCancelRedirect() { return 'Addresslists:'; } public function createFormOK(Nette\Application\UI\Form $form) { $values = $form->values; $id = $this->id; $uid = $this->user->id; $luser = $this->luser; $addresslists = $luser->addresslists; if ($form['cancel']->submittedBy) $this->redirect($this->createCancelRedirect); if ($form['create']->submittedBy) { // Create list and then redirect to addresslist/default/NEWLYCREATEDID $name = $values['name']; $owner = $values['owner']; $group = $values['group']; if(!$luser->admin) { if($owner != $luser->primary || !array_key_exists($group, $luser->groups)) { // FIXME die("omghax"); } } $mailinglist = Model\Addresslist::create($this->database, $name, false, $owner, $group); $id = $mailinglist->primary; $this->redirect("Addresslist:default", ['id' => $id]); } } public function renderCreate() { $this->template->user = $this->luser; } public function renderExport($id) { $luser = $this->luser; $this->template->id = $this->id; $this->template->addresslist = $luser->get_addresslist($id); $this->template->user = $luser; } public function renderDelete($id) { $luser = $this->luser; $this->template->addresslist = $luser->addresslists[$id]; $this->template->is_admin = $luser->admin; } protected function createComponentDelete($action) { $form = new Nette\Application\UI\Form; $form->addProtection("protection token expired"); $form->addSubmit('delete', "Delete"); $form->onSuccess[] = [$this, 'deleteFormOK']; return $form; } public function deleteFormOK(Nette\Application\UI\Form $form) { $luser = $this->luser; $addresslist = $luser->addresslists[$this->id]; $addresslist->delete(); $this->FlashMessage("Address list deleted."); $this->redirect('Homepage:default', ['id' => false]); } }