user->isGuest ) { $this->goHome (); } else { if (Yii::$app->session ['userSessionTimeout'] < time ()) { Yii::$app->user->logout (); $this->goHome (); Yii::$app->session->setFlash ( 'success', 'You have been logged out!' ); } else { Yii::$app->session->set ( 'userSessionTimeout', time () + Yii::$app->params ['sessionTimeoutSeconds'] ); return true; } } return true; // or false to not run the action } /** * Function that adds the checked samples to the shopping cart. */ public function actionAdd() { if (Yii::$app->request->isAjax) { $user = Yii::$app->user->id; $array = Yii::$app->getRequest ()->getBodyParams ()['CartForm']; $final = $array ['checked']; // "/" were replaced by "SLASH" in the var names it needs to be re-replaced during //entry in shopping cart. foreach ($final as $key =>$value){ if(preg_match('*SLASH*', $key)){ unset($final[$key]); $final[str_replace('SLASH', '/',$key)] = $value; } } DBInterface::addToShoppingCart ( $final, $user ); } } /** * function updating the pjax widget, which shows the shopping cart content. * @return string */ public function actionAddedlist(){ $shoppingCart = sizeof(DBInterface::getShoppingCart(Yii::$app->user->identity->id)); return $this->renderPartial('addedlist', ['shoppingCart'=>$shoppingCart]); } /** * function which adds one sample to the shopping cart, given a unit id. It also updates the pjax * widget. This function is called on the single record sites. * @param unknown $unitID */ public function actionAddone($unitID, $collectionCode, $institutionCode){ var_dump($unitID); var_dump($collectionCode); var_dump($institutionCode); DBInterface::addToShoppingCart([($unitID."---".$collectionCode."---".$institutionCode)=>'1'], Yii::$app->user->id); $this->renderAjax('added'); } /** * renders the shopping cart primary site. * @return Ambigous */ public function actionCart() { $user = Yii::$app->user->identity->id; $cartContent = DBInterface::getShoppingCart ( $user ); $ids = array_column ( $cartContent, 'unit_id' ); $colcodes = array_column ( $cartContent, 'collection_code' ); $instcodes = array_column ( $cartContent, 'institution_code' ); $cartInfo = [ ]; $documents = [ ]; $i=0; foreach ( $ids as $id ) { $doc = $this->getInfo ( $id, $colcodes[$i], $instcodes[$i] ); array_push ( $documents, $doc ); //var_dump ( $doc ); $ar = $this->getLowest ( $doc ); $cites = false; if($doc[$ar[1]]['citesStatus']!="N/A"){ $cites = true; } //Write the necessary information into an array. $cartInfo [$ar [0]] = [ 'ScientificName' => $doc [$ar [1]] ['fullScientificName'], 'Country' => $doc [$ar [1]] ['country'], 'RecordNo' => $ar [0], 'Institution' => $doc [$ar [1]] ['institution'], 'Type' => $doc [$ar [1]] ['sampletype'], 'cites' =>$cites, 'collectioncode' =>$doc [$ar [1]] ['collectioncode'], 'institutioncode' =>$doc [$ar [1]] ['institutioncode'] ]; $i++; } Yii::$app->session ['theDocumentsArray'] = $documents; return $this->render ( 'cart', [ 'cartContent' => $cartInfo ] ); } /** * Returns the unitID of the "lowest" sampletype and its index in $doc * * @param unknown $doc * @return * */ private function getLowest($doc) { $order = [ 'DNA', 'tissue', 'enviro', 'specimen', 'culture', 'eVoucher', 'unknown' ]; foreach ( $order as $key ) { $count = 0; foreach ( $doc as $d ) { if ($d['sampletype'] == $key) { return array ( $d ['unitID'], $count ); } $count ++; } } } /** * Get the information stored in SOLR for a unit id * @param unknown $unit_id The record to be searched * @return unknown the record. */ private function getInfo($unitID, $collectioncode, $institutioncode) { $config = SOLRQueryManager::getConfigDetails (); $query = SOLRQueryManager::createSearchQuery ( $config ); $unitID = str_replace ( " ", "\ ", $unitID ); $unitID = str_replace ( "(", "(", $unitID ); $unitID = str_replace ( ")", ")", $unitID ); $unitID = str_replace ( ":", ":", $unitID ); $collectioncode = str_replace ( " ", "\ ", $collectioncode ); $collectioncode = str_replace ( "(", "(", $collectioncode ); $collectioncode = str_replace ( ")", ")", $collectioncode ); $collectioncode = str_replace ( ":", ":", $collectioncode ); $institutioncode = str_replace ( " ", "\ ", $institutioncode ); $institutioncode = str_replace ( "(", "(", $institutioncode ); $institutioncode = str_replace ( ")", ")", $institutioncode ); $institutioncode = str_replace ( ":", ":", $institutioncode ); $fq = "{!join from=tripleidstoreid to=tripleidstoreid fromIndex=" . Yii::$app->params ['solrsearchname'] . "}"; $fq.= "unitID:" . $unitID." AND collectioncode:".$collectioncode. " AND institutioncode:".$institutioncode; $raw_response = SOLRQueryManager::fillAndExecuteQuery ( $query, '*:*', $fq, [ ], False ); // while programming: check if null or [] for the parameter after fq $doc = $raw_response->getDocuments (); return $doc; } /** * this function generates the csv file containing information about the Dna or tissue samples * which are stored in $documents, which is an array of Solr-reponses * The generated file is named automatically, because it is deleted after the mail was sent, * because the minimum of personal information shoud be stored. * * @param unknown $documents * @param unknown $lowestIndex * @return The genreated filename and an array containing the information * which will be written in the confirmation mails. */ private function generateCSV($documents, $filename, $forInst) { try { $hasCites=false; $mailArray = []; $mailInfo = array('fullScientificName','familia','country','DNA_ID', 'tissue_ID', 'specimen_ID', 'tripleidstoreid', 'citesStatus'); // $mailInfo = array('fullScientificName','familia','country','DNA_ID', 'tissue_ID', 'specimen_ID', 'citesStatus'); $filename = str_replace(",", "", $filename); $filename = str_replace(" ", "", $filename); $filename = join(DIRECTORY_SEPARATOR,[Yii::$aliases['@mailtmp'],$filename]).rand(0,200).".csv"; $handle = fopen ( $filename, 'w' ); $firstLine = array ( 'DNA_ID', 'DNA_GUID', 'tissue_ID', 'tissue_GUID', 'specimen_ID', 'specimen_GUID', 'fullScientificName', 'familia', 'ordo', 'classis', 'phylum', 'regnum', 'continent', 'country', 'ocean', 'locality', 'longitude', 'latitude', 'collectors', 'collectionDate', 'collectorNo' ); fwrite ( $handle, implode ( ',', $firstLine ) . "\r\n" ); foreach ( $documents as $doc ) { $lowestIndex = $this->getLowest ( $doc )[1]; $helperAr = [ ]; // Gather the hierarchy information for DNA, tissue and specimen foreach ( $doc as $d ) { if($d['citesStatus']!="N/A") $hasCites=true; if ($d ['sampletype'] == 'DNA' && ! isset ( $helperAr ['DNA_ID'] )) { $helperAr ['DNA_ID'] = $d ['unitID'] . ";" . $d ['collectioncode'] . ";" . $d ['institutioncode']; try { $helperAr ['DNA_GUID'] = $d ['guid']; } catch ( Exception $e ) { $helperAr ['DNA_GUID'] = ''; } } if ($d ['sampletype'] == 'tissue') { $helperAr ['tissue_ID'] = $d ['unitID'] . ";" . $d ['collectioncode'] . ";" . $d ['institutioncode']; try { $helperAr ['tissue_GUID'] = $d ['guid']; } catch ( Exception $e ) { $helperAr ['tissue_GUID'] = ''; } } if ($d ['sampletype'] == 'specimen'||$d ['sampletype'] == 'culture') { $helperAr ['specimen_ID'] = $d ['unitID'] . ";" . $d ['collectioncode'] . ";" . $d ['institutioncode']; try { $helperAr ['specimen_GUID'] = $d ['guid']; } catch ( Exception $e ) { $helperAr ['specimen_GUID'] = ''; } } } // fill the missing fields with an empty string foreach ( array ( 'DNA_ID', 'tissue_ID', 'specimen_ID', 'DNA_GUID', 'tissue_GUID', 'specimen_GUID' ) as $key ) { if (! isset ( $helperAr [$key] )) { $helperAr [$key] = ''; } } // Gather all the missing information from the lowest sample =>DNA (lowest), tissue, specimen $array = $doc [$lowestIndex]; foreach ( array ( 'fullScientificName', 'familia', 'ordo', 'classis', 'phylum', 'regnum', 'country', 'locality', 'collectors' ) as $key ) { try { $helperAr [$key] = $array [$key]; } catch ( Exception $e ) { $helperAr [$key] = ''; } } try { $coord = $array ['coordinates'] [0]; if (isset ( $coord )) { $coord = explode ( ",", $coord ); $helperAr ['longitude'] = $coord [0]; $helperAr ['latitude'] = $coord [1]; } else { $helperAr ['longitude'] = ''; $helperAr ['latitude'] = ''; } } catch ( Exception $e ) { $helperAr ['longitude'] = ''; $helperAr ['latitude'] = ''; } // $helperAr['collectionDate']= $array['gatheringyear'];//TODO $helperAr ['collectionDate'] = ""; $helperAr ['collectorNo'] = $array ['collectornumber']; $helperAr ['continent'] = $array ['continent'] [0]; $helperAr ['ocean'] = $array ['ocean'] [0]; $helperAr ['tripleidstoreid'] =$array ['tripleidstoreid']; $helperAr['citesStatus'] =$array['citesStatus']; // write the line to the file. Replace all existing commas by semicolons $line = ''; foreach ( $firstLine as $value ) { $rep = str_replace ( ",", ";", $helperAr [$value] ); $line .= $rep . ','; } fwrite ( $handle, $line . "\r\n" ); foreach($mailInfo as $item){ if(!$helperAr['DNA_ID']==''){ $mailArray[$helperAr['DNA_ID']][$item] = $helperAr[$item]; } elseif(!$helperAr['tissue_ID']==''){ $mailArray[$helperAr['tissue_ID']][$item] = $helperAr[$item]; } elseif(!$helperAr['specimen_ID']==''){ $mailArray[$helperAr['specimen_ID']][$item] = $helperAr[$item]; } } } if($hasCites && $forInst) fwrite ( $handle, "This pre-order contains request for CITES material. Please check carefully whether the customer is allowed to receive this material.\n" ); fclose ( $handle ); } catch ( Exception $e ) { // TODO } return [$filename,$mailArray,'cites'=>$hasCites]; } /** * This function renders a page containing an ActiveForm where you can enter your cites code. * This page is rendered in a Modal window. * @return \yii\web\Response|Ambigous */ public function actionCheckout() { $this->layout = 'form'; $model = new CheckoutForm (); if ($model->load ( Yii::$app->request->post () ) && $model->validate ()) { Yii::$app->user->identity->saveNewUserData ( $_POST ['CheckoutForm'] ); $this->layout = 'main'; return $this->redirect ( 'overview' ); } return $this->render ( 'checkout', [ 'model' => $model ] ); } /** * Deletes all non-ordered samples (for the current user) from the shopping cart. * @return \yii\web\Response */ public function actionDelete() { DBInterface::emtpyShoppingCart ( Yii::$app->user->identity->id ); return $this->goHome (); } /** * This is the action which actually performs the checkout! */ public function actionThankyou() { $files = [ ]; if(empty(Yii::$app->session ['theDocumentsArray'])){ return $this->goHome(); } DBInterface::emtpyShoppingCart ( Yii::$app->user->identity->id ); $support = \Yii::$app->params ['supportEmail']; $documents = Yii::$app->session ['theDocumentsArray']; $user = Yii::$app->user->identity; // send the checkout mails to the institutions $institution = $this->getAllDocsForAllInstitutions ( $documents ); $contactPeople = []; $instMail = 'institutionConfirmation'; foreach ($institution as $key =>$inst){ $tripleidstoreid = $inst[0][0]['tripleidstoreid']; $contactPerson = DBInterface::getMail($tripleidstoreid)[0]; array_push($contactPeople , $contactPerson); $ar2 = $this->generateCSV($inst, 'order'.$key, true); $files = array($ar2[0]); $cites=$ar2['cites']; //Get the comment a user made for this institution $comment = Yii::$app->session['CommentArray']['comments'][$key]; $numSent = $this->sendMailWithFiles($contactPerson['email'], $support, $instMail, '[GGBN] Sample request', $files, $comment, $user, $contactPerson, $ar2[1], $cites ); if(!$numSent){ Yii::$app->mailer->compose () ->setFrom (Yii::$app->params ['noreplyMail'] ) ->setTo ( Yii::$app->params ['adminMail'] ) ->setSubject ( 'Order Mail not sent' ) ->setTextBody ( "The mail for the order to ".$contactPerson['email']." was not sent." ) ->send (); } //write the information into the user_shopping_statistics database table. $this->writeStats($contactPerson['parentInstitutionID'], $ar2[1]); } // send the confirmation mail to the users //TODO: add MTA path. $ar1 = $this->generateCSV ( $documents, 'yourorder', false ); // $MTA = path $files = [$ar1[0]]; $mail = 'customerConfirmation'; $numSent = $this->sendMailWithFiles ( $user->email, $support, $mail, '[GGBN] Your sample order', $files, null, $user, $contactPeople, $ar1[1], false); if(!$numSent){ Yii::$app->mailer->compose () ->setFrom (Yii::$app->params ['noreplyMail'] ) ->setTo ( Yii::$app->params ['adminMail'] ) ->setSubject ( 'Order Mail not sent to customer ' ) ->setTextBody ( "The mail for the order to ".$user->email." was not sent." ) ->send (); } //cleanup actions Yii::$app->session->remove('theDocumentsArray'); Yii::$app->session->remove('CommentArray'); $this->cleanUpDir(Yii::$aliases['@mailtmp'],$files); return $this->render('thankyou'); } /** * Sends the confirmation emails. * @param unknown $to destination email * @param unknown $from sender email * @param unknown $mail the mail template * @param unknown $subject the subject of the mail * @param unknown $files the files to join * @param unknown $comment the comment the user made for this institution * @param unknown $user the identity object * @param unknown $contactPerson an array containing all the necessary information on the contact person (name, email, Institution) * @param unknown $infoInMailArray The information on the ordered samples */ private function sendMailWithFiles($to, $from, $mail, $subject, $files, $comment, $user, $contactPerson, $infoInMailArray, $cites) { $mail = \Yii::$app->mailer->compose ( [ 'html' => $mail . '-html', //'text' => $mail . '-text' ], [ 'user' => Yii::$app->user->identity, 'comment' =>$comment, 'contactPerson'=>$contactPerson, 'information' =>$infoInMailArray, 'citesStatus'=>$cites ] )->setFrom (Yii::$app->params ['noreplyMail']) ->setTo ( $to )->setSubject ( $subject ); foreach ( $files as $file ) { $mail->attach ( $file ); } return $mail->send (); } /** * creates an array, that contains for every insitution all ordered samples, (the information is * stored in the document format) * @param unknown $documents * @return multitype:multitype:unknown */ private function getAllDocsForAllInstitutions($documents) { $resultsArray = [ ]; //var_dump($documents); foreach ( $documents as $d ) { if (array_key_exists ( strtoupper($d[0] ['institution']), $resultsArray )) { array_push ( $resultsArray [strtoupper($d[0] ['institution'])],$d); } else { $resultsArray [strtoupper($d[0] ['institution'])] = array($d); } } //var_dump($resultsArray); return $resultsArray; } /** * Return the last overview before actual ordering the samples. * @return Ambigous |\yii\web\Response */ public function actionOverview() { $model = new CheckoutForm(); if(empty(Yii::$app->session ['theDocumentsArray'])){ return $this->render('cart'); } if($model->load ( Yii::$app->request->post () ) && $model->validate ()){ Yii::$app->session['CommentArray']=$_POST['CheckoutForm']; return $this->redirect('thankyou'); } $docs = $this->getAllDocsForAllInstitutions ( Yii::$app->session ['theDocumentsArray'] ); //var_dump($docs); $arr = [ ]; foreach ( $docs as $key => $value ) { $arr [$key] = [ ]; foreach($value as $val){ $ind = $this->getLowest($val)[1]; $logo = $this->getLogo ( $val [$ind] ['tripleidstoreid'] ); array_push ( $arr [$key], array ( 'unitID' => $val [$ind] ['unitID'], 'fullScientificName' => $val [$ind] ['fullScientificName'], 'sampletype' => $val [$ind] ['sampletype'], 'logo' => $logo ) ); } } return $this->render ( 'overview', [ 'info' => $arr, 'model' => $model ] ); } /** * Deletes one sample from the shopping cart. * @param unknown $unit_id The unit_id of the sample to be deleted. * @return \yii\web\Response */ public function actionDeleteone($unit_id,$collection_code,$institution_code) { DBInterface::deleteFromShoppingCart ( $unit_id, $collection_code,$institution_code, Yii::$app->user->id ); return $this->redirect ( 'cart' ); } /** * Gets the logo of an institution given a tripleidstoreid * @param unknown $tripleidstoreid * @return unknown */ private function getLogo($tripleidstoreid) { $query = DBInterface::getLogo ( $tripleidstoreid ); return $query ['logoURL']; } /** * Function responsible for filling the shopping_statistics db table. * It counts the different sampletypes. * @param unknown $id The parentInstitutionID * @param unknown $mailArray the information */ private function writeStats($id, $mailArray){ $dna = 0; $tissue = 0; $dna_request = 0; //var_dump($mailArray); foreach ($mailArray as $ma){ if(!empty($ma['DNA_ID'])){ $dna++; } elseif(!empty($ma['tissue_ID'])){ $tissue++; } elseif (!empty($ma['specimen_ID'])){ $dna_request++; } } DBInterface::stats($id, array($dna, $tissue, $dna_request)); } /** * removes all created csv files from the mailTmp dir. (See aliases) * @param unknown $dir */ private function cleanUpDir($dir,$todel){ $todelbases=[]; foreach ($todel as $t) $todelbases[]=basename($t); // Yii::info("look for cleanup ".implode(", ", $todelbases)); $files = glob($dir."\\*"); // get all file names foreach($files as $file){ // iterate files // Yii::info("wants to delete file ".basename($file)); if(is_file($file) && in_array(basename($file), $todelbases)) unlink($file); // delete file } } }