Exemple #1
0
 /**
  * Calculates the current age of someone born on $birthdate.
  * Source: stackoverflow.com/questions/3776682/php-calculate-age
  * @param sing $birthdate The birthdate.
  * @return integer The calculated age.
  * @access public
  * @static
  */
 public static function ageFromBirthdate($birthdate)
 {
     // convert to format: YYYY-MM-DD
     $clean_birthdate = date('Y-m-d', CakeTime::fromString($birthdate));
     if (CakeTime::isFuture($clean_birthdate)) {
         throw new OutOfRangeException("Birthdate is in the future: {$clean_birthdate}", BedrockTime::EXCEPTION_CODE_FUTURE_BIRTHDATE);
     }
     //explode the date to get month, day and year
     $parts = explode('-', $clean_birthdate);
     //get age from date or birthdate
     $age = intval(date('md', date('U', mktime(0, 0, 0, $parts[1], $parts[2], $parts[0]))) > date('md') ? date('Y') - $parts[0] - 1 : date('Y') - $parts[0]);
     return $age;
 }
 /**
  *    Days in theme
  *    @param int $theme_id
  */
 public function days($theme_id = null, $user_id = null)
 {
     if (!$theme_id) {
         return;
     }
     $options = array('recursive' => -1, 'conditions' => array('Day.theme_id' => $theme_id), 'order' => array('data ASC'));
     $rows = $this->Day->find('all', $options);
     foreach ($rows as $key => $row) {
         $row['Day']['isFuture'] = false;
         $row['Day']['isPast'] = false;
         $row['Day']['isToday'] = false;
         $row['Day']['comments'] = $this->Comment->find('count', array('conditions' => array('Comment.user_id' => !$this->isUser() ? $user_id : $this->getUserId(), 'Comment.day_id' => $row['Day']['id'])));
         if (CakeTime::isFuture($row['Day']['data'])) {
             $row['Day']['isFuture'] = true;
         }
         if (CakeTime::isPast($row['Day']['data'])) {
             $row['Day']['isPast'] = true;
         }
         if (CakeTime::isToday($row['Day']['data'])) {
             $row['Day']['isToday'] = true;
         }
         $data[] = $row['Day'];
     }
     $this->set($data);
     $this->set('_serialize', array_keys($data));
 }
 public function oldCopyRound($projectId = null)
 {
     if ($this->request->is('post') || $this->request->is('put')) {
         //$this -> autoRender = false;
         if (!empty($this->request->data['Round']['Round'])) {
             $oldRoundId = $this->request->data['Round']['Round'];
             $round = $this->Round->find('first', array('recursive' => -1, 'conditions' => array('Round.id' => $oldRoundId)));
             if (trim($this->request->data['Round']['title']) == '' || !isset($this->request->data['Round']['title'])) {
                 $this->Session->setFlash('Please select one Title');
                 $this->redirect(array('controller' => 'rounds', 'action' => 'copyRound', $projectId));
             }
             App::uses('CakeTime', 'Utility');
             if (CakeTime::isFuture($round['Round']['ends_in_date'])) {
                 $this->Round->id = $round['Round']['id'];
                 $date = CakeTime::format('-1 days', '%Y-%m-%d');
                 $this->Round->saveField('ends_in_date', $date);
             }
             if (empty($this->request->data['Round']['User'])) {
                 $this->Session->setFlash('You must choose at least one user');
                 $this->redirect(array('controller' => 'rounds', 'action' => 'copyRound', $projectId));
             } else {
                 $oldRoundId = $this->request->data['Round']['Round'];
                 $this->Round->create();
                 $this->request->data['Round']['ends_in_date'] = NULL;
                 $users = $this->request->data['Round']['User'];
                 $conditions_userRounds = array('UsersRound.round_id' => $oldRoundId, 'UsersRound.user_id' => $users);
                 //guardamos los usuarios en condiciones
                 unset($this->request->data['Round']['User']);
                 $title = $this->request->data['Round']['title'];
                 $this->request->data['Round']['title'] = $title . '-[0%]';
                 $errors = "";
                 //$db = $this->Round->getDataSource();
                 //$db->begin();
                 if ($this->Round->save($this->request->data, false)) {
                     //se deshabilita el save para poder guardar rounds con ends_in_date = NULL
                     //esta bandera marcara que un round esta en estado de copia
                     $this->Session->setFlash('We are creating a new version of the round. Please be patient', 'information');
                     //cortamos la ejecucion parab el usuario pero el script sigue en ejecucion
                     //de esta forma el usuario puedeseguir navegando
                     $this->backGround(array('controller' => 'projects', 'action' => 'view', $round['Round']['project_id']));
                     $round_id = $this->Round->id;
                     $newRoundId = $this->Round->id;
                     $size_userRounds = $this->Round->UsersRound->find('count', array('recursive' => -1, 'conditions' => $conditions_userRounds));
                     /**
                      * tamaño de particiones
                      * Haremos una particion de los rounds para no sobrecargar la memoria
                      * ** */
                     if ($size_userRounds > 0) {
                         //hacemos partioces de user_rounds de 100
                         $particiones_userRounds = 100;
                         $size_userRounds_total = $size_userRounds;
                         //si el tamaño es mayor que la particion calculamos cuantas veces vamos a tener que hacer
                         if ($size_userRounds > $particiones_userRounds) {
                             $fin_userRounds = $size_userRounds / $particiones_userRounds;
                             //calculamos el numero de beces a la baja
                             // por ejemplo 2.5 se haces dos veces
                             $fin_userRounds = floor($fin_userRounds);
                             //si existe resto se hace una vez mas
                             if ($size_userRounds % $particiones_userRounds != 0) {
                                 $fin_userRounds++;
                             }
                         } else {
                             // si no la particion es = al tamaño
                             $particiones_userRounds = $size_userRounds;
                             $fin_userRounds = 1;
                         }
                         $contador_userRounds = 0;
                         $procces_userRounds = 0;
                         $time = date('Y-m-d H:i:s');
                         //variables para monotorizar la copia
                         $worked = 0;
                         $procces = 0;
                         while ($contador_userRounds < $fin_userRounds) {
                             $usersRounds = $this->Round->UsersRound->find('all', array('offset' => $procces_userRounds, 'limit' => $particiones_userRounds, 'recursive' => -1, 'fields' => array('UsersRound.id', 'UsersRound.user_id', 'UsersRound.document_id', 'UsersRound.text_marked'), 'conditions' => $conditions_userRounds));
                             //se eligen bucles for en vez de bucles foreach dado que son mas rapidos si se van a modificar datos
                             //http://www.phpbench.com/
                             $usersRoundTam = sizeof($usersRounds);
                             for ($i = 0; $i < $usersRoundTam; $i++) {
                                 $procces++;
                                 $worked = $procces / $size_userRounds_total * 100;
                                 if (round($worked) % 10 == 0) {
                                     $data = array('Round' => array('title' => $title . '-[' . round($worked) . '%]'));
                                     $this->Round->save($data);
                                 }
                                 $usersRounds[$i]['UsersRound']['created'] = $time;
                                 $conditions = array('Annotation.round_id' => $oldRoundId, 'Annotation.document_id' => $usersRounds[$i]['UsersRound']['document_id'], 'Annotation.user_id' => $usersRounds[$i]['UsersRound']['user_id'], 'Annotation.users_round_id' => $usersRounds[$i]['UsersRound']['id']);
                                 $textoForMatches = $usersRounds[$i]['UsersRound']['text_marked'];
                                 $usersRounds[$i]['UsersRound']['round_id'] = $newRoundId;
                                 unset($usersRounds[$i]['UsersRound']['id']);
                                 unset($usersRounds[$i]['UsersRound']['text_marked']);
                                 $this->Round->UsersRound->create();
                                 if ($this->Round->UsersRound->save($usersRounds[$i])) {
                                     $size_annotations = $this->Round->UsersRound->Annotation->find('count', array('recursive' => -1, 'conditions' => $conditions));
                                     if ($size_annotations > 0) {
                                         $parseKey = Configure::read('parseKey');
                                         $parseIdAttr = Configure::read('parseIdAttr');
                                         /**
                                          * Particiones de anotaciones
                                          */
                                         $particiones_annotations = 400;
                                         if ($size_annotations > $particiones_annotations) {
                                             $fin_annotations = $size_annotations / $particiones_annotations;
                                             $fin_annotations = floor($fin_annotations);
                                             if ($size_annotations % $particiones_annotations != 0) {
                                                 $fin_annotations++;
                                             }
                                         } else {
                                             $particiones_annotations = $size_annotations;
                                             $fin_annotations = 1;
                                         }
                                         $contador_annotations = 0;
                                         $procces_annotations = 0;
                                         $annotations_id = array();
                                         while ($contador_annotations < $fin_annotations) {
                                             $annotations = $this->Round->UsersRound->Annotation->find('all', array('offset' => $procces_annotations, 'limit' => $particiones_annotations, 'recursive' => -1, 'conditions' => $conditions));
                                             $annotationTam = sizeof($annotations);
                                             for ($j = 0; $j < $annotationTam; $j++) {
                                                 $oldId = $annotations[$j]['Annotation']['id'];
                                                 unset($annotations[$j]['Annotation']['id']);
                                                 //insertamos nuevo user round
                                                 $annotations[$j]['Annotation']['users_round_id'] = $this->Round->UsersRound->id;
                                                 //insertamos nuevo round
                                                 $annotations[$j]['Annotation']['round_id'] = $newRoundId;
                                                 if (empty($annotations[$j]['Annotation']['annotated_text'])) {
                                                     $annotations[$j]['Annotation']['annotated_text'] = 'empty?';
                                                 }
                                                 $this->Round->UsersRound->Annotation->create();
                                                 if ($this->Round->UsersRound->Annotation->save($annotations[$j])) {
                                                     $newId = $this->Round->UsersRound->Annotation->id;
                                                     array_push($annotations_id, $newId);
                                                     $this->Round->UsersRound->Annotation->query("insert into annotations_questions ( annotation_id,question_id,answer)\n                                                     SELECT " . $newId . ",question_id,answer FROM annotations_questions where annotation_id = {$oldId}");
                                                 }
                                             }
                                             //$i = 0; $i < $annotationTam; $i++
                                             if ($procces_annotations + $particiones_annotations * 2 > $size_annotations) {
                                                 $procces_annotations += $particiones_annotations;
                                                 $particiones_annotations = $size_annotations - $procces_annotations;
                                             } else {
                                                 $procces_annotations += $particiones_annotations;
                                             }
                                             $contador_annotations++;
                                         }
                                         /*
                                          * A partir de este punto machearemos las anotaciones en el documento actualizando su ID
                                          * */
                                         preg_match_all("/<mark[^>]*" . $parseKey . "[^>]*[^>]*>/", $textoForMatches, $matches);
                                         $numberOfMaches = sizeof($matches[0]);
                                         // el sistema es flexible frente a contratiempos imprevistos como que el umero de anotaciones parseadas sean distintos a la base de datos
                                         $pos = -1;
                                         $k = 0;
                                         $ultimoId = -1;
                                         while ($k < $numberOfMaches) {
                                             preg_match('/[^>]*' . $parseIdAttr . '=.?(\\d+).?[^>]/', $matches[0][$k], $id);
                                             if ($ultimoId != $id) {
                                                 $ultimoId = $id;
                                                 $pos++;
                                             }
                                             //                                                debug($annotations_id[$pos]);
                                             $search = $matches[0][$k];
                                             //                                                if(!isset($annotations_id[$pos])) {
                                             //                                                    debug($id);
                                             //                                                }
                                             $replace = preg_replace('/' . $parseIdAttr . '=.(\\d+)./', $parseIdAttr . '="' . $annotations_id[$pos] . '"', $search);
                                             $textoForMatches = str_replace($search, $replace, $textoForMatches);
                                             $k++;
                                         }
                                         if ($pos + 1 != sizeof($annotations_id)) {
                                             //                                                debug(sizeof($annotations_id));
                                             //                                                debug($numberOfMaches);
                                             //                                                debug($pos);
                                             //                                                debug($usersRounds[$i]['UsersRound']['document_id']);
                                             $errors = "This round is courrupted.  Unexpected error has occurred. Do not worry this is not a fatal error. But please contact the administrator. Error: 'other number annotations database VS parse'";
                                         }
                                     }
                                     //guardamos el documento con el texto anotado actualizado
                                     $usersRounds[$i]['UsersRound']['text_marked'] = $textoForMatches;
                                     unset($usersRounds[$i]['UsersRound']['id']);
                                     $this->Round->UsersRound->save($usersRounds[$i]);
                                 }
                                 //$this->Round->UsersRound->save($usersRounds[$i])
                             }
                             //$i = 0; $i < $usersRoundTam; $i++
                             if ($procces_userRounds + $particiones_userRounds * 2 >= $size_userRounds) {
                                 $procces_userRounds += $particiones_userRounds;
                                 $particiones_userRounds = $size_userRounds - $procces_userRounds;
                             } else {
                                 $procces_userRounds += $particiones_userRounds;
                             }
                             $contador_userRounds++;
                         }
                     }
                     //finalmente actualizamos los datos del round con los datos que metio el usuario e introducimos los tipos de anotacion
                     //del round origen
                     $date = CakeTime::format('+30 days', '%Y-%m-%d');
                     $data = array('Round' => array('description' => $errors, 'ends_in_date' => $date, 'title' => $title), 'User' => array('User' => $users));
                     if ($this->Round->save($data)) {
                         //$this->Round->commit();
                         $round_id = $this->Round->id;
                         $this->Round->query("insert into types_rounds ( round_id,type_id) select {$round_id},type_id\n                                                                                                          from types_rounds \n                                                                                                            where round_id = {$oldRoundId}");
                         //$db->commit();
                         //$db->close();
                     } else {
                         //$db->rollback();
                         //$db->close();
                     }
                 } else {
                     //$db->rollback();
                     //$db->close();
                     $this->Session->setFlash('Unexpected error ocurs, error Id: roundCopySave');
                     $this->redirect(array('controller' => 'rounds', 'action' => 'copyRound', $projectId));
                 }
             }
         } else {
             $this->Session->setFlash('There are no data to be copied!');
             $this->redirect(array('controller' => 'rounds', 'action' => 'copyRound', $projectId));
         }
     } else {
         $this->Round->Project->id = $projectId;
         if (!$this->Round->Project->exists()) {
             throw new NotFoundException(__('Invalid round'));
         }
         //!$this->Round->exists()
         $deleteCascade = Configure::read('deleteCascade');
         $conditions = array('project_id' => $projectId, 'ends_in_date IS NOT NULL');
         if ($deleteCascade) {
             $conditions = array('project_id' => $projectId, 'ends_in_date IS NOT NULL', 'title!=\'Removing...\'');
         }
         $rounds = $this->Round->find('list', array('conditions' => $conditions));
         if (empty($rounds)) {
             $this->Session->setFlash('Insufficient data for this operation');
             $this->redirect(array('controller' => 'projects', 'action' => 'view', $projectId));
         } else {
             $cond = array('project_id' => $projectId);
             $users = $this->Round->Project->ProjectsUser->find('all', array('fields' => 'user_id', 'conditions' => $cond, 'recursive' => -1));
             $users = $this->flatten($users);
             $userConditions = array('id' => $users);
             if ($deleteCascade) {
                 $userConditions = array('username !=' => 'Removing...', 'id' => $users);
             }
             $users = $this->Round->User->find('list', array('conditions' => $userConditions));
         }
         $this->set('rounds', $rounds);
         $this->set('users', $users);
         $this->set('projectId', $projectId);
     }
 }
 function uploadFinalPredictions()
 {
     $this->Cookie = $this->Components->load('Cookie');
     $this->Cookie->type('rijndael');
     //        $this->Cookie->time = '999 hours';
     if ($this->request->is(array('post', 'put'))) {
         //            debug($this->request->data);
         $email = $this->request->data['Participant']['email'];
         $code = $this->request->data['Participant']['code'];
         $task = $this->request->data['Participant']["task"];
         $run = $this->request->data['Participant']["run"];
         $maxUploadTask = Configure::read('max_participant_task_upload');
         $tasks = Configure::read('biocreative_tasks');
         $finalDate = Configure::read('final_date_to_upload_tasks');
         $startDate = Configure::read('initial_date_to_upload_tasks');
         if (!in_array($task, $tasks) && $run < 0 && $run > 5) {
             $this->Session->setFlash("Incorrect data");
             return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
         }
         App::uses('CakeTime', 'Utility');
         $isEnd = CakeTime::isPast($finalDate);
         $isFuture = CakeTime::isFuture($startDate);
         if ($isEnd || $isFuture) {
             $this->Session->setFlash("The final delivery date has expired");
             return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
         }
         $project_id = -1;
         if ($this->data['Participant']['remember_me'] && isset($code) && isset($email)) {
             $cookie = array();
             $cookie['email'] = $email;
             $cookie['code'] = $code;
             $this->Cookie->write('participantData', $cookie, true, '+2 weeks');
         } else {
             if ($this->Cookie->check('participantData')) {
                 $this->Cookie->destroy('participantData');
             }
         }
         App::uses('Folder', 'Utility');
         App::uses('File', 'Utility');
         //            debug($this->request->data);
         if ($this->request->data['Participant']['final_prediction']['size'] > 0) {
             /* ============================================= */
             /* ==============Load analysis=================== */
             /* ============================================= */
             if ($this->request->data['Participant']['final_prediction']['size'] > $this->filesize2bytes(Configure::read('max_file_size'))) {
                 $this->Session->setFlash("The file can not be more than " . Configure::read('max_file_size'));
                 return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
             }
             $file = $this->request->data['Participant']['final_prediction']['name'];
             if (pathinfo($file, PATHINFO_EXTENSION) != 'tsv') {
                 $this->Session->setFlash("The file must be in TSV format");
                 return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
             }
             $file = new File($this->request->data['Participant']['final_prediction']['tmp_name']);
             if ($file->readable()) {
                 $content = $file->read();
                 $file->close();
                 $lines = explode("\n", $content);
                 $incorrectFormat = empty($lines);
                 $count = 0;
                 $size = count($lines);
                 $correctColumns = 5;
                 if ($task == "CPD") {
                     $correctColumns = 4;
                 }
                 for ($index = 0; $index < $size; $index++) {
                     if (strlen(trim($lines[$index])) > 0) {
                         if (!$incorrectFormat) {
                             $columns = explode("\t", $lines[$index]);
                             for ($i = 0; $i < count($columns); $i++) {
                                 if (strlen(trim($columns[$i])) == 0) {
                                     $incorrectFormat = true;
                                 }
                             }
                             $incorrectFormat = $incorrectFormat || sizeof($columns) != $correctColumns;
                             $count++;
                         } else {
                             break;
                         }
                     }
                 }
                 //                    $correctFormat = $this->correctTsvFormat($file, 5);
                 if ($incorrectFormat) {
                     //                        $count=$this->incorrecLineTsvFormat($file);
                     if ($task == "CPD") {
                         $this->Session->setFlash("Incorrect content file. Line {$count} is incorrect. " . "Content file must be contain 4 columns");
                     } else {
                         $this->Session->setFlash("Incorrect content file. Line {$count} is incorrect. " . "Content file must be in this format WO2009026621A1->A:12:24->1->0.99->paliperidone");
                     }
                     return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
                 }
                 $participant = $this->Participant->find('first', array("recursive" => -1, "fields" => array("id", "team_id"), "conditions" => array('Participant.email' => $email, 'Participant.code' => $code)));
                 $participantID = $participant["Participant"]["id"];
                 $team_id = $participant["Participant"]["team_id"];
                 $this->request->data['Participant']['id'] = $participantID;
                 $this->participantSaveConnection($this->request->data['Participant'], "uploadTeamPrediction");
                 $path = Configure::read('participantsPath');
                 $path = $path . DS . $task . DS . $team_id;
                 $dir = new Folder($path, true, 0755);
                 $tempPath = $this->request->data['Participant']['final_prediction']['tmp_name'];
                 $file = new File($tempPath);
                 if ($file->readable()) {
                     $content = $file->read();
                     $newPath = $dir->pwd() . DS . "{$run}.tsv";
                     $file->copy($newPath);
                     $path = $newPath;
                     chmod($newPath, 0200);
                     $data = array('participant_id' => $participantID, 'biocreative_task' => $task, 'run' => $run);
                     $finalfile = $this->Participant->FinalPrediction->find('first', array("conditions" => $data, 'fields' => 'id'));
                     if (!empty($finalfile)) {
                         $this->Participant->FinalPrediction->id = $finalfile['FinalPrediction']['id'];
                         $this->Session->setFlash("The file has been updated successfully", "success");
                         $type = "updated";
                     } else {
                         $this->Participant->FinalPrediction->create();
                         $this->Session->setFlash("The file has been created successfully", "success");
                         $type = "uploaded";
                     }
                     $data = array('participant_id' => $participantID, 'run' => $run, 'email' => $email, 'biocreative_task' => $task, 'file' => $content, 'file_name' => $this->request->data['Participant']['final_prediction']['name']);
                     if (!$this->Participant->FinalPrediction->save($data)) {
                         $this->Session->setFlash("File could not be saved");
                         return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
                     } else {
                         $this->sendMailWithAttachment("finalPredictionSuccess", $email, "[MARKYT - BIOCREATIVE V (CHEMDNER)] Final submision", array("run" => $run, "type" => $type, "task" => $task), array("{$run}.tsv" => $tempPath));
                     }
                     return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
                 }
             } else {
                 throw new Exception("Ops! file could not be readed");
             }
         } else {
             $this->Session->setFlash("One team prediction file is needed");
             return $this->redirect(array('controller' => 'Participants', 'action' => 'analysis'));
         }
     }
 }