The followings are the available columns in table 'protected_file':
Inheritance: extends BaseActiveRecordVersioned
Esempio n. 1
0
 /**
  * create a new protected file object which has properties that can be used for writing an actual file to
  *
  * @param string $name
  * @return ProtectedFile
  */
 public static function createForWriting($name)
 {
     $file = new ProtectedFile();
     $file->name = $name;
     $file->generateUID();
     $path = $file->getFilePath();
     if (!file_exists($path)) {
         if (!@mkdir($path, 0755, true)) {
             throw new Exception("{$path} could not be created: permission denied");
         }
     }
     return $file;
 }
 public function actionCrop($dims = '1328x560,776x864')
 {
     $dimensions = explode(',', $dims);
     $xy = explode('x', $dimensions[0]);
     $wh = explode('x', $dimensions[1]);
     $src_x = $xy[0];
     $src_y = $xy[1];
     $dest_w = $wh[0];
     $dest_h = $wh[1];
     // find all cropped images in ophinvisualfields_field_measurement->cropped_image_id:
     $fields = OphInVisualfields_Field_Measurement::model()->findAll();
     foreach ($fields as $field) {
         $full = ProtectedFile::model()->findByPk($field->image_id);
         $cropped = ProtectedFile::model()->findByPk($field->cropped_image_id);
         // if the value isnt set, move on
         if (!$full || !$cropped) {
             continue;
         }
         // next step, take image_id and open image:
         if (file_exists($full->getPath())) {
             $src = imagecreatefromgif($full->getPath());
             $dest = imagecreatetruecolor($dest_w, $dest_h);
             imagecopy($dest, $src, 0, 0, $src_x, $src_y, $dest_w, $dest_h);
             imagegif($dest, $cropped->getPath());
             echo 'patient: ' . $field->getPatientMeasurement()->patient->hos_num . ', path: ' . $cropped->getPath() . PHP_EOL;
             // Reset sizes
             $full->size = filesize($full->getPath());
             $full->save();
             $cropped->size = filesize($cropped->getPath());
             $cropped->save();
         }
     }
 }
 public static function fromFhir($fhirObject)
 {
     $report = parent::fromFhir($fhirObject);
     $patient = \Patient::model()->find('id=?', array($report->patient_id));
     $report->patient_id = $patient->id;
     $eye = 'Right';
     if ($report->eye == 'L') {
         $eye = 'Left';
     } elseif ($report->eye == 'B') {
         $eye = 'Both';
     }
     $report->eye_id = \Eye::model()->find('name=:name', array(':name' => $eye))->id;
     if (isset($fhirObject->xml_file_data)) {
         $report->xml_file_data = base64_decode($fhirObject->xml_file_data);
     }
     $title = $report->file_reference;
     if (\ProtectedFile::model()->find('name = ?', array($title))) {
         throw new EverythingsFine("Duplicate filename: {$title} (patient ID {$report->patient_id})");
     }
     $protected_file = \ProtectedFile::createForWriting($title);
     $protected_file->name = $title;
     file_put_contents($protected_file->getPath(), base64_decode($report->image_scan_data));
     $protected_file->mimetype = 'image/gif';
     $protected_file->save();
     $cropped_file = \ProtectedFile::createForWriting($title);
     // all content is base64 encoded, so decode it:
     file_put_contents($cropped_file->getPath(), base64_decode($report->image_scan_crop_data));
     $cropped_file->mimetype = 'image/gif';
     $cropped_file->name = $title;
     $cropped_file->save();
     $report->scanned_field_id = $protected_file->id;
     $report->scanned_field_crop_id = $cropped_file->id;
     return $report;
 }
 public function actionImport()
 {
     echo "<h1>Importing files:</h1>";
     foreach (glob(Yii::app()->basePath . '/data/test/*') as $src_file) {
         $file = ProtectedFile::createFromFile($src_file);
         if (!$file->save()) {
             throw new CException('Cannot save file' . print_r($file->getErrors(), true));
         }
         unlink($src_file);
         echo "<p>Imported " . $file->uid . ' - ' . $file->name . "</p>";
     }
     echo "<p>Done!</p>";
 }
Esempio n. 5
0
 /**
  * abstraction to process FileCollection form.
  *
  * @param OphCoTherapyapplication_FileCollection $model
  * @param string                                 $audit_type
  */
 protected function processFileCollectionForm($model, $audit_type = 'create')
 {
     $model->attributes = $_POST['OphCoTherapyapplication_FileCollection'];
     // validate the model
     $model->validate();
     $transaction = Yii::app()->getDb()->beginTransaction();
     // slightly complex rollback process because of files being copied into the protected file store
     // we want to be able to roll this back as well as the db process.
     try {
         $pf_ids = $this->processFileCollectionFileUpload($model, $_FILES['OphCoTherapyapplication_FileCollection_files']);
         if (!count($model->getErrors())) {
             if ($model->save()) {
                 // because this might be an update, we get the current files on the model so that we don't remove files
                 // from it
                 $curr_pf_ids = array();
                 foreach ($model->files as $file) {
                     $curr_pf_ids[] = $file->id;
                 }
                 $model->updateFiles(array_merge($curr_pf_ids, $pf_ids));
                 Audit::add('admin', $audit_type, $model->id, null, array('module' => 'OphCoTherapyapplication', 'model' => 'OphCoTherapyapplication_FileCollection'));
                 Yii::app()->user->setFlash('success', 'File Collection created');
                 $transaction->commit();
                 $this->redirect(array('viewfilecollections'));
             }
         }
         // clear out any protected files that might have been created.
         $criteria = new CDbCriteria();
         $criteria->addInCondition('id', $pf_ids);
         foreach (ProtectedFile::model()->findAll($criteria) as $pf) {
             $pf->delete();
         }
         // if we've got this far, something is amiss
         $transaction->rollback();
     } catch (Exception $e) {
         Yii::log('OphCoTherapyapplication_FileCollection creation error: ' . $e->getMessage(), 'error');
         Yii::app()->user->setFlash('error', 'An unexpected error has occurred');
         // clear out any protected files that might have been created.
         $criteria = new CDbCriteria();
         $criteria->addInCondition('id', $pf_ids);
         foreach (ProtectedFile::model()->findAll($criteria) as $pf) {
             $pf->delete();
         }
         $transaction->rollback();
     }
 }
 /**
  * main method to run the command for file collection creation.
  *
  * @TODO: look for a summary text file to include.
  * @TODO: search for existing file collections and update instead of adding.
  *
  * @param array $args
  *
  * @return int|void
  */
 public function run($args)
 {
     if (!count($args) == 1) {
         $this->usageError('missing source path argument');
     }
     if (!is_readable($args[0])) {
         $this->usageError('cannot read specified source path ' . $args[0]);
     }
     $base_path = $args[0];
     // read directory structure into data
     $file_list = $this->buildFileList($base_path, './');
     $file_ext_regexp = implode('|', $this->file_extensions);
     $sets = array();
     // determine the file collections to be created
     foreach ($file_list as $fname => $details) {
         if (preg_match('/' . $file_ext_regexp . '$/', $fname)) {
             $path = str_replace(DIRECTORY_SEPARATOR, ' - ', dirname($fname));
             if (!@$sets[$path]) {
                 $summary_text = $this->summary_text_default;
                 $summary_filepath = $base_path . dirname($fname) . DIRECTORY_SEPARATOR . $this->summary_filename;
                 if ($this->summary_filename && file_exists($summary_filepath)) {
                     // read the summary text in from the file
                     $summary_text = file_get_contents($summary_filepath);
                 }
                 $sets[$path] = array('summary' => $summary_text, 'files' => array($details));
             } else {
                 $sets[$path]['files'][] = $details;
             }
         }
     }
     $created = 0;
     $modified = 0;
     // iterate through and create the file collections.
     foreach ($sets as $set_name => $set_details) {
         $created_flag = false;
         $transaction = Yii::app()->getDb()->beginTransaction();
         $pf_list = array();
         $pf_ids = array();
         try {
             foreach ($set_details['files'] as $details) {
                 $pf = ProtectedFile::createFromFile($details['source']);
                 if ($pf->save()) {
                     $pf_ids[] = $pf->id;
                     $pf_list[] = $pf;
                 } else {
                     foreach ($pf_list as $pf) {
                         $pf->delete();
                     }
                     break;
                 }
             }
             // update the existing file collection if there is one
             $criteria = new CDbCriteria();
             $criteria->addCondition('name = :nm');
             $criteria->params = array(':nm' => $set_name);
             if (!($fc = OphCoTherapyapplication_FileCollection::model()->find($criteria))) {
                 $fc = new OphCoTherapyapplication_FileCollection();
                 $fc->name = $set_name;
                 $created_flag = true;
             }
             $fc->summary = $set_details['summary'];
             if (!$fc->validate()) {
                 echo "unexpected validation error with file collection\n";
                 var_dump($fc->getErrors());
                 $transaction->rollback();
             } else {
                 if ($fc->save()) {
                     $fc->updateFiles($pf_ids);
                     Audit::add('admin', 'create', $fc->id, null, array('module' => 'OphCoTherapyapplication', 'model' => 'OphCoTherapyapplication_FileCollection'));
                     $transaction->commit();
                     $created_flag ? $created++ : $modified++;
                 } else {
                     foreach ($pf_list as $pf) {
                         $pf->delete();
                     }
                     $transaction->rollback();
                 }
             }
         } catch (Exception $e) {
             echo $e->getMessage();
             foreach ($pf_list as $pf) {
                 $pf->delete();
             }
             $transaction->rollback();
         }
     }
     echo 'Processing complete, ' . $created . ' collections created, ' . $modified . " collections updated\n";
 }
Esempio n. 7
0
 public function getDecryptedSignature($signature_pin)
 {
     if ($signature_pin) {
         if ($this->signature_file_id) {
             $signature_file = ProtectedFile::model()->findByPk($this->signature_file_id);
             $image_data = base64_decode($this->decryptSignature(file_get_contents($signature_file->getPath()), md5(md5($this->id) . $this->generateUniqueCodeWithChecksum($this->getUniqueCode()) . $signature_pin)));
             if (strlen($image_data) > 100) {
                 return $image_data;
             }
         }
     }
     return false;
 }
Esempio n. 8
0
 /**
  * Store the PDF as a ProtectedFile in the system
  *
  * @return ProtectedFile
  * @throws Exception
  */
 public function storePDF()
 {
     $pf = ProtectedFile::createFromFile($this->outDir . '/' . $this->outFile);
     $pf->save();
     $this->cleanUp();
     return $pf;
 }
Esempio n. 9
0
 /**
  * Trawl an existing OE database and find all files that match the given
  * pattern. A pattern MUST be specified.
  *
  * If no pattern is specified, all images that match the standard humphrey
  * image size are processed.
  */
 public function actionRedact($pattern = null)
 {
     $criteria = new CDbCriteria();
     if ($pattern != null) {
         $criteria->condition = 'name like :name';
         $criteria->params = array(':name' => $pattern);
     } else {
         echo 'You MUST specify a file pattern to match.';
     }
     $files = ProtectedFile::model()->findAll($criteria);
     // we can't really filter images, except on size - for now just
     // assume the count is half the amount when taking thumbnails into
     // consideration
     echo count($files) / 2 . ' files found for modification.';
     if ($files) {
         foreach ($files as $file) {
             if (file_exists($file->getPath())) {
                 $this->anonymiseTif($file->getPath());
             } else {
                 echo 'Could not transform file; ' . $file->getPathName() . ' does not exist.' . PHP_EOL;
             }
         }
     }
 }
Esempio n. 10
0
 public function actionImport($importDir, $archiveDir, $errorDir, $dupDir, $interval = 'PT45M', $pasImport = false)
 {
     $this->importDir = $this->checkSeparator($importDir);
     $this->archiveDir = $this->checkSeparator($archiveDir);
     $this->errorDir = $this->checkSeparator($errorDir);
     $this->dupDir = $this->checkSeparator($dupDir);
     $this->interval = $interval;
     $fhirMarshal = Yii::app()->fhirMarshal;
     $eventType = EventType::model()->find('class_name=:class_name', array(':class_name' => 'OphInVisualfields'));
     if (!$eventType) {
         echo 'Cannot find OphInVisualfields event type, cannot continue' . PHP_EOL;
         die;
     }
     echo 'Processing FMES files...' . PHP_EOL;
     $filenames = glob($this->importDir . '/*.fmes');
     echo count($filenames) . " files to process\n";
     foreach ($filenames as $file) {
         try {
             $basename = basename($file);
             echo $basename . PHP_EOL;
             // First check the file has not already been imported:
             $field = file_get_contents($file);
             $fieldObject = $fhirMarshal->parseXml($field);
             if ($protected_file = ProtectedFile::model()->find('name=:name', array(':name' => $fieldObject->file_reference))) {
                 echo '- ProtectedFile exists (' . $protected_file->id . ')' . PHP_EOL;
                 $this->move($this->dupDir, $file);
                 continue;
             }
             // Extract the patient number
             $matches = array();
             preg_match('/__OE_PATIENT_ID_([0-9]*)__/', $field, $matches);
             if (count($matches) < 2) {
                 echo '- Failed to extract patient ID' . PHP_EOL;
                 $this->move($this->errorDir, $file);
                 continue;
             }
             $match = str_pad($matches[1], 7, '0', STR_PAD_LEFT);
             // Fetch the patient
             if ($pasImport) {
                 $model = new Patient(null);
                 $model->hos_num = $match;
                 $results = $model->search()->getData();
                 $patient = reset($results);
             } else {
                 $patient = Patient::model()->find('hos_num=:hos_num', array(':hos_num' => $match));
             }
             if (!$patient) {
                 echo "- Failed to find patient ({$match})" . PHP_EOL;
                 $this->move($this->errorDir, $file);
                 continue;
             }
             $pid = $patient->id;
             $field = preg_replace('/__OE_PATIENT_ID_([0-9]*)__/', $pid, $field);
             // Convert to measurement
             $resource_type = 'MeasurementVisualFieldHumphrey';
             $service = Yii::app()->service->getService($resource_type);
             $fieldObject = $fhirMarshal->parseXml($field);
             $tx = Yii::app()->db->beginTransaction();
             $ref = $service->fhirCreate($fieldObject);
             $tx->commit();
             $refId = $ref->getId();
             $measurement = OphInVisualfields_Field_Measurement::model()->findByPk($refId);
             $study_datetime = $measurement->study_datetime;
             // Check for existing legacy events
             if (!($episode = Episode::model()->find('legacy = 1 AND patient_id = :patient_id', array(':patient_id' => $pid)))) {
                 echo '- No legacy episode found, creating...';
                 $episode = new Episode();
                 $episode->legacy = 1;
                 $episode->patient_id = $pid;
                 $episode->save();
                 echo 'done' . PHP_EOL;
                 // As there are no previous legacy events, we can create a new event
                 $this->newEvent($episode, $eventType, $measurement);
                 $this->move($this->archiveDir, $file);
             } else {
                 // There is a legacy episode, so there may be unmatched legacy field events
                 $criteria = new CdbCriteria();
                 $criteria->condition = 'event_type_id = :event_type_id and t.deleted = 0 and ep.deleted = 0 and ep.legacy = 1 and ep.patient_id = :patient_id';
                 $criteria->join = 'join episode ep on ep.id = t.episode_id';
                 $criteria->order = 't.event_date desc';
                 $criteria->params = array(':patient_id' => $pid, ':event_type_id' => $eventType->id);
                 if ($this->interval) {
                     // we're looking for all events that are bound to a legacy episode,
                     // for the given patient, looking for the last created test -
                     // this accounts for multiple tests per eye - the implication
                     // being that the newest test overrides the last test for the same eye
                     // (e.g. when a mistake is made and the test is re-ran):
                     // Base time on interval defined by user, a narrow time slot that the test falls within
                     $startCreatedTime = new DateTime($study_datetime);
                     $endCreatedTime = new DateTime($study_datetime);
                     $startCreatedTime->sub(new DateInterval($this->interval));
                     $endCreatedTime->add(new DateInterval($this->interval));
                     $criteria->condition .= ' AND t.event_date >= STR_TO_DATE("' . $startCreatedTime->format('Y-m-d H:i:s') . '", "%Y-%m-%d %H:%i:%s") AND t.event_date <= STR_TO_DATE("' . $endCreatedTime->format('Y-m-d H:i:s') . '", "%Y-%m-%d %H:%i:%s")';
                 }
                 // Of events, there can only be one or none:
                 // FIXME: This can return multiple events, so how do we choose?
                 $events = Event::model()->findAll($criteria);
                 if (count($events) == 1) {
                     echo '- Found existing event (' . $events[0]->id . ')' . PHP_EOL;
                     $element = Element_OphInVisualfields_Image::model()->find('event_id = :event_id', array(':event_id' => $events[0]->id));
                     $side = strtolower($measurement->eye->name);
                     if ($existing = $element->{"{$side}_field"}) {
                         if ($measurement->study_datetime > $existing->study_datetime) {
                             echo "Newer than existing measurement on {$side}, overwriting\n";
                             $element->{"{$side}_field_id"} = $measurement->id;
                             $unattached = $existing;
                         } else {
                             echo "Older than existing measurement on {$side}, ignoring\n";
                             $unattached = $measurement;
                         }
                         // Add dummy reference for the unattached measurement
                         $ref = new MeasurementReference();
                         $ref->patient_measurement_id = $unattached->getPatientMeasurement()->id;
                         $ref->save();
                     } else {
                         echo "No existing measurement on {$side}, adding\n";
                         $element->{"{$side}_field_id"} = $measurement->id;
                     }
                     $element->save();
                     $this->move($this->archiveDir, $file);
                 } elseif (count($events) > 1) {
                     echo '- Found more than one matching event, cannot attach' . PHP_EOL;
                     $this->move($this->errorDir, $file);
                 } else {
                     // No events in match window, so we create a new one
                     $this->newEvent($episode, $eventType, $measurement);
                     $this->move($this->archiveDir, $file);
                 }
             }
         } catch (Exception $ex) {
             echo $ex . PHP_EOL;
             if (@$tx && $tx->active) {
                 echo '- rolling back tx' . PHP_EOL;
                 $tx->rollback();
             }
             $this->move($this->errorDir, $file);
         }
     }
 }
 /**
  * create the PDF file as a ProtectedFile for the given side.
  *
  * @param CController $controller
  * @param array       $template_data
  * @param string      $side
  *
  * @throws Exception
  *
  * @return ProtectedFile|null
  */
 protected function createAndSavePdfForSide(CController $controller, array $template_data, $side)
 {
     if ($html = $this->getPDFContentForSide($controller, $template_data, $side)) {
         $html = '<link rel="stylesheet" type="text/css" href="' . $controller->assetPath . '/css/print.css" />' . "\n" . $html;
         $this->event->lock();
         if (!$this->event->hasPDF('therapy_application')) {
             $wk = new WKHtmlToPDF();
             $wk->setDocuments(1);
             $wk->setDocRef($this->event->docref);
             $wk->setPatient($this->event->episode->patient);
             $wk->setBarcode($this->event->barcodeHTML);
             $wk->generatePDF($this->event->imageDirectory, 'event', 'therapy_application', $html, false, false);
         }
         $this->event->unlock();
         if (@$_GET['html']) {
             return Yii::app()->end();
         }
         $pfile = ProtectedFile::createForWriting('ECForm - ' . $side . ' - ' . $template_data['patient']->hos_num . '.pdf');
         if (!@copy($this->event->getPDF('therapy_application'), $pfile->getPath())) {
             throw new Exception('Unable to write to file: ' . $pfile->getPath());
         }
         if (!$pfile->save()) {
             throw new Exception('Unable to save file: ' . print_r($pfile->errors, true));
         }
         return $pfile;
     }
     return;
 }
 /**
  * removes the compressed file association for this collection. Should be called when the files for it are
  * changed so that a new compressed file is created when needed.
  *
  * will also call the delete function on the protected file itself to remove orphaned files
  */
 protected function cleanCompressedFile()
 {
     // note we have to work on the file id not the relation
     if ($id = $this->zipfile_id) {
         $this->zipfile_id = null;
         if ($this->save()) {
             $pf = ProtectedFile::model()->findByPk($id);
             try {
                 $pf->delete();
             } catch (Exception $e) {
                 // ignore this exception as it's because the compressed file is referenced elsewhere
             }
         }
     }
 }