139. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 8/16/2019 12:02:04 PM Eastern Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

139.1 Files compared

# Location File Last Modified
1 Direct_DSM.zip\Direct_DSM\webmail\application\libraries\patient_data Patient_id.php Tue Aug 13 17:30:34 2019 UTC
2 Direct_DSM.zip\Direct_DSM\webmail\application\libraries\patient_data Patient_id.php Thu Aug 15 19:38:08 2019 UTC

139.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 940
Changed 1 2
Inserted 0 0
Removed 0 0

139.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

139.4 Active regular expressions

No regular expressions were active.

139.5 Comparison detail

  1   <?php  if  ( ! define d('BASEPAT H')) exit( 'No direct  script ac cess allow ed');
  2  
  3   require_li brary('pat ient_data/ soap_call' );
  4  
  5   /**
  6   * Looks up  patients  in the Mas ter Vetera ns Index a nd returns  a set of  matching p atients.
  7   *
  8   * @package  direct-pr oject-inno vation-ini tiative
  9   * @subpack age librar ies
  10   */
  11   class Pati ent_id ext ends Soap_ call {
  12       # TODO  - NEED A  WSDL URI
  13           va r $wsdl_ur i = MVI_PA TIENT_SEAR CH_WSDL;
  14           va r $endpoin t_uri = MV I_PATIENT_ SEARCH_END POINT;
  15           va r $process ing_code =  MVI_PROCE SSING_CODE ;
  16           va r $mvi_id_ code = MVI _ID_CODE;
  17           va r $vler_di rect_id_co de = VLER_ DIRECT_ID_ CODE;
  18           va r $vler_di rect_site_ key = VLER _DIRECT_SI TE_KEY;
  19           va r $interac tion_id =  INTERACTIO N_ID;
  20  
  21           pr otected $u nique_tran saction_id ; //autoge nerated ev ery time t he request  is genera ted
  22           pr otected $u nique_quer y_id; //au togenerate d every ti me the req uest is ge nerated
  23           pr otected $u ser; //set  in the co nstructor
  24  
  25           pu blic funct ion __cons truct(){
  26                    pare nt::__cons truct();
  27                    $thi s->user =  User::find _from_sess ion();
  28                    $thi s->curl_op tions = ar ray(
  29                             CURLOP T_SSLCERT  => TLS_SER VER_CERT_P ATH,
  30                             CURLOP T_SSLKEY = > TLS_SERV ER_KEY_PAT H,
  31                             CURLOP T_SSL_VERI FYHOST =>  TLS_SERVER _VERIFYHOS T,
  32                             CURLOP T_SSL_VERI FYPEER =>  TLS_SERVER _VERIFYPEE R,
  33                    );
  34           }
  35  
  36           // returns fa lse if it  encountere d an error , or an ar ray of pat ient data  if the cal l was succ essful
  37           fu nction pat ients_matc hing_crite ria($crite ria){
  38                    if(e mpty($crit eria) || ! is_array($ criteria))  return $t his->CI->e rror->shou ld_be_a_no nempty_arr ay($criter ia);
  39  
  40                    //ch eck that t he require d fields h ave been p rovided
  41                    fore ach( array ('given_na me', 'fami ly_name',  'social_se curity_num ber') as $ required_f ield){
  42                             if(!$t his->CI->i s->nonempt y_string(t rim($crite ria[$requi red_field] )))
  43                                      return $ this->CI-> error->sho uld_be_a_n onempty_st ring($crit eria[$requ ired_field ]);
  44                             $this- >$required _field = $ criteria[$ required_f ield];
  45                    }
  46  
  47                    //ma ke sure th at the ssn  really is  an ssn an d format i t for our  query
  48                    #TOD O - Test p atients pr obably wil l not have  valid SSN s, we need  the abili ty to turn  this off  via some s ort of tes ting mode,  etc.
  49                    if(! $this->CI- >is->strin g_like_a_s ocial_secu rity_numbe r($criteri a['social_ security_n umber']))
  50                             return  $this->CI ->error->s hould_be_a _social_se curity_num ber($crite ria['socia l_security _number']) ;
  51                    $thi s->social_ security_n umber = st r_replace( '-', '', $ this->soci al_securit y_number);
  52  
  53                    //ch eck for op tional fie lds fields
  54                    if(! empty($cri teria['gen der']) &&  in_array(s trtoupper( $criteria[ 'gender']) , array('M ', 'F', 'U ')))
  55                             $this- >gender =  $criteria[ 'gender'];
  56                    if(! empty($cri teria['dat e_of_birth '])){
  57                             if(!$t his->CI->i s->mysql_d ate($crite ria['date_ of_birth'] )) return  $this->CI- >error->sh ould_be_an _x($criter ia['date_o f_birth'],  'date for matted YYY Y-MM-DD');
  58                             $this- >date_of_b irth = str _replace(' -', '', $c riteria['d ate_of_bir th']);
  59                    }
  60  
  61                    retu rn $this-> _find_pati ents();
  62           }
  63  
  64           // returns fa lse if it  encountere d an error , or a Pat ient objec t if the c all was su ccessful
  65           fu nction pat ient_match ing_id($pa tient_id){
  66                    if(! $this->CI- >is->nonem pty_string ($patient_ id)) retur n $this->C I->error-> should_be_ a_nonempty _string($p atient_id) ;
  67                    $thi s->patient _id = $pat ient_id;
  68                    $thi s->xml_tem plate = '_ patient_de mographics ';
  69  
  70                    $pat ients = $t his->_find _patients( );
  71                    if(! is_array($ patients))  return fa lse;
  72  
  73                    if(c ount($pati ents) > 1)  {
  74                             log_me ssage('err or', 'MVI  returned m ore than o ne result  for search  by patien t id for ' .$this->CI ->error->d escribe($p atient_id) .', expect ing only o ne');
  75                    }
  76  
  77                    retu rn element ($patient_ id, $patie nts);
  78           }
  79  
  80           /* * Extends  parent to  ensure tha t {@link u nique_quer y_id} is g enerated e very time  that we ge nerate the  request * /
  81           fu nction req uest_as_xm l(){
  82                    $thi s->unique_ transactio n_id = sha 1(sha1($th is->vler_d irect_site _key . mic rotime())) ;
  83                    $thi s->unique_ query_id =  sha1($thi s->vler_di rect_site_ key . micr otime());
  84                    retu rn parent: :request_a s_xml();
  85           }
  86  
  87   ////////// ////////// ////////// ////////// //
  88   //  PROTEC TED METHOD S
  89   ////////// ////////// ////////// ////////// //
  90  
  91           pr otected fu nction _fi nd_patient s(){
  92                    if(i s_on_local ()) return  $this->mo ck_patient s();
  93                    //ma ke the act ual call
  94                    $res ponse_data  = $this-> call();
  95                    if(e mpty($resp onse_data) ) return f alse; //en countered  error whil e trying t o make the  call; cal l() will p rovide err or message
  96  
  97   #TODO - co nfirm enco ding
  98   #TODO - re cognize to o many pat ients
  99   #TODO - re cognize no  patients
  100                    //se t up objec t to parse  the respo nse data a s xml
  101                    $dom  = new DOM Document(' 1.0', 'UTF -8');
  102                    $dom ->encoding  = 'utf-8' ;
  103                    $dom ->formatOu tput = FAL SE;
  104                    $dom ->preserve WhiteSpace  = TRUE;
  105                    $dom ->substitu teEntities  = TRUE;
  106                    $dom ->loadXML( $response_ data);
  107  
  108                    //se arch for t he <subjec t> element s that rep resent pat ients.
  109                    #TOD O - RECOGN IZE A RESP ONSE WITH  NO PATIENS T
  110                    $xpa th = new D OMXPath($d om);
  111                    $xpa th->regist erNamespac e('x', 'ur n:hl7-org: v3'); //ar gsblargle.   Looks li ke PHP won 't let us  add a name space with out an ide ntifier, s o we'll us e the all- purposeful  x.
  112                     $xpath->re gisterName space('idm ', 'http:/ / DNS . URL ');
  113  
  114   #                $xpa th->regist erNamespac e('xsi', ' http://www .w3.org/20 01/XMLSche ma-instanc e');
  115                    $pat ient_nodes  = $xpath- >query('// idm:PRPA_I N201306UV0 2/x:contro lActProces s//x:patie nt');
  116  
  117                    if(! is_a($pati ent_nodes,  'DOMNodeL ist') || ! $this->CI- >is->nonze ro_unsigne d_integer( $patient_n odes->leng th)){
  118                             //chec k to see i f we have  an AA ackn owledgment  - if not,  there was  something  wrong wit h our quer y
  119                             $accep tability_a cknowledge ment = $xp ath->query ('//idm:PR PA_IN20130 6UV02/x:ac knowledgem ent/x:type Code[@code ="AA"]');
  120                             if(!$t his->CI->i s->nonzero _unsigned_ integer($a cceptabili ty_acknowl edgement-> length)){
  121                                      log_mess age('debug ', 'MVI in dicates th at our sea rch query  was malfor med');
  122                                      return f alse;
  123                             }
  124  
  125                             //we m ight not h ave patien t nodes ju st because  there are  no result s
  126                             $not_f ound = $xp ath->query ('//idm:PR PA_IN20130 6UV02/x:co ntrolActPr ocess/x:qu eryAck/x:q ueryRespon seCode[@co de="NF"]') ;
  127                             if($th is->CI->is ->nonzero_ unsigned_i nteger($no t_found->l ength)){
  128                                      return a rray(); // no patient s found, n o need for  an error  message
  129                             }
  130  
  131                             //chec k to see i f we have  a QE query  error - i f we have  AA + QE, t hen there  were too m any patien ts returne d
  132                             $query _error = $ xpath->que ry('//idm: PRPA_IN201 306UV02/x: controlAct Process/x: queryAck/x :queryResp onseCode[@ code="QE"] ');
  133                             if($th is->CI->is ->nonzero_ unsigned_i nteger($qu ery_error- >length)){
  134                                      $this->f eedback_me ssages[] =  'Your sea rch matche d more pat ients than  could be  returned.   Please na rrow your  search ter ms and try  again.';
  135                                      return f alse;
  136                             }
  137  
  138                             if(!is _a($patien t_nodes, ' DOMNodeLis t')) retur n $this->C I->error-> warning('U nknown err or: unable  to parse  MVI respon se');
  139                    }
  140  
  141                    $pat ients = ar ray();
  142                    fore ach($patie nt_nodes a s $patient _node){
  143                             #TODO  - prefix,  suffix
  144                             #TODO  - assignin g facility ?
  145                             #TODO  - Legal na mes vs ali ases/maide n names
  146                             #TODO  - Include  current ad dress in r esults?
  147  
  148                             $patie nt = new P atient($pa tient_node , $xpath);
  149                             if(!em pty($patie nt->icn()) )
  150                                      $patient s[$patient ->icn()] =  $patient;  //patient s aren't r eally pati ents if we  can't fin d their IC N
  151  
  152                    }
  153  
  154                    retu rn $patien ts;
  155           }
  156  
  157       /**
  158        * Moc k patients  data for  testing th e process  of searchi ng/attachi ng patient  data
  159        * @re turn array
  160        */
  161           pr otected fu nction moc k_patients (){
  162                    $moc k_data = a rray(
  163                '1012663 662V729834 ' => array (
  164                    'giv en_names'  => array(' NWHINELVEN '),
  165                    'fam ily_name'  => 'NWHINZ ZZTESTPATI ENT',
  166                    'ssn ' => '1112 23333',
  167                 ),
  168                '1234567 89' => arr ay(
  169                    'giv en_names'  => array(' Cecilia',  'Helena'),
  170                    'fam ily_name'  => 'Payne- Gaposchkin ',
  171                    'pre fix' => 'D r.',
  172                    'gen der' => 'f ',
  173                    'ass igning_fac ility' =>  'Harvard U niversity' ,
  174                    'id_ state' =>  'Deactivat ed',
  175                    'dat e_of_birth ' => '1900 0510', //  5/10/1900
  176                    'dat e_of_death ' => '1979 1207', //  12/7/1979
  177                    'ssn ' => '1111 11111',
  178                ),
  179                '9876543 21' => arr ay(
  180                    'giv en_names'  => array(' Bonnie', ' Jeanne'),
  181                    'fam ily_name'  => 'Dunbar ',
  182                    'pre fix' => 'D r.',
  183                    'gen der' => 'f ',
  184                    'ass igning_fac ility' =>  'NASA',
  185                    'id_ state' =>  'Temporary ',
  186                    'dat e_of_birth ' => '1949 0303', //  3/3/1949
  187                    'ssn ' => '2222 22222',
  188                ),
  189                '6543219 87' => arr ay(
  190                    'giv en_names'  => array(' Eugene', ' Francis'),
  191                    'fam ily_name'  => 'Kranz' ,
  192                    'pre fix' => 'M r.',
  193                    'gen der' => 'm ',
  194                    'ass igning_fac ility' =>  'NASA',
  195                    'id_ state' =>  'Permanent ',
  196                    'dat e_of_birth ' => '1933 0817', //  8/17/1933
  197                    'ssn ' => '3333 3333',
  198                ),
  199                '7543219 87' => arr ay(
  200                    'giv en_names'  => array(' Edward'),
  201                    'fam ily_name'  => 'Sabine ',
  202                    'pre fix' => 'S ir',
  203                    'suf fix' => 'K CB FRS',
  204                    'gen der' => 'm ',
  205                    'ass igning_fac ility' =>  'Royal Mil itary Acad emy',
  206                    'id_ state' =>  'Deactivat ed',
  207                    'dat e_of_birth ' => '1788 1014', //  10/14/1788
  208                    'dat e_of_death ' => '1883 0626', //6 /26/1883
  209                    'ssn ' => '4444 444444'
  210                ),
  211                '7543218 87' => arr ay(
  212                    'giv en_names'  => array(' Eden'),
  213                    'fam ily_name'  => 'Atwood ',
  214                    'gen der' => 'u ',
  215                    'ass igning_fac ility' =>  'Concord R ecords',
  216                    'id_ state' =>  'Permanent ',
  217                    'dat e_of_birth ' => '1969 0111', //  1/11/1969
  218                    'ssn ' => '5555 555555'
  219                ),
  220                '7543218 88' => arr ay(
  221                    'giv en_names'  => array(' Marie', 'C harlotte',  'Amalie',  'Ernestin e', 'Wilhe lmine', 'P hilippine' ),
  222                    'suf fix' => 'H .R.H.',
  223                    'gen der' => 'f ',
  224                    'ass igning_fac ility' =>  'House of  Saxe-Gotha -Altenburg ',
  225                    'id_ state' =>  'Deactivat ed',
  226                    'dat e_of_birth ' => -6889 030019, //  9/11/1751
  227                    'dat e_of_death ' => -4502 748419, //  4/25/1827
  228                ),
  229                '7943218 88' => arr ay(
  230                    'giv en_names'  => array(' Johannes M üller'),
  231                    'fam ily_name'  => 'von KÃ ¶nigsberg' ,
  232                    'gen der' => 'm ',
  233                    'ass igning_fac ility' =>  'Holy Roma n Empire',
  234                    'id_ state' =>  'Deactivat ed',
  235                    'dat e_of_birth ' => -1683 7817219, / / 6/6/1436
  236                    'dat e_of_death ' => -1557 2921219, / / 7/6/1476
  237                 ),
  238            ) ;
  239  
  240                    fore ach($mock_ data as $i cn => $dat a){
  241                             $data[ 'icn'] = $ icn;
  242                             $mock_ data[$icn]  = new Pat ient($data );
  243                    }
  244  
  245                    retu rn $mock_d ata;
  246           }
  247   }
  248  
  249   class Pati ent{
  250  
  251           pr otected $d om_element ;
  252  
  253           //  raw vars  are exactl y the valu e given by  ICN; thes e will be  formatted  elsewhere
  254           pr otected $r aw_icn;
  255           pr otected $r aw_ssn;
  256  
  257           pr otected $r aw_prefix;
  258           pr otected $r aw_given_n ames;
  259           pr otected $r aw_family_ name;
  260           pr otected $r aw_suffix;
  261  
  262           pr otected $r aw_gender;
  263           pr otected $r aw_assigni ng_facilit y;
  264           pr otected $r aw_date_of _birth; //  formatted  YYYYMMDD  or YYYYMMD DHHMMSS
  265           pr otected $r aw_date_of _death; //  formatted  YYYYMMDD  or YYYYMMD DHHMMSS
  266           pr otected $r aw_id_stat e;
  267  
  268       /**
  269        * Pat ient const ructor.
  270        * @pa ram array  $patient_n ode_or_val ues
  271        * @pa ram null $ xpath
  272        */
  273           fu nction __c onstruct($ patient_no de_or_valu es = array (), $xpath =null){
  274  
  275                $this->i s = get_in stance()-> is;
  276                    $thi s->error =  get_insta nce()->err or;
  277  
  278                    if(i s_a($patie nt_node_or _values, ' DOMElement ')){
  279                             $this- >xpath = $ xpath;
  280                             $this- >load_valu es_from_do m_element( $patient_n ode_or_val ues);
  281                    } el se if(is_a rray($pati ent_node_o r_values))  {
  282                $this->l oad_values _from_arra y($patient _node_or_v alues);
  283           }  else {
  284                         return $th is->error- >should_be _an_array_ or_DOMElem ent_object ($patient_ node_or_va lues);
  285           }
  286           }
  287  
  288           pu blic funct ion hidden _field_mar kup($root_ tag_name =  'patient' ){
  289  
  290                if(!$thi s->is->non empty_stri ng_with_no _whitespac e($root_ta g_name)) {
  291                         return $th is->error- >should_be _a_nonempt y_string_w ith_no_whi tespace($r oot_tag_na me);
  292           }
  293  
  294                    $mar kup = '';
  295                    fore ach($this- >raw_value s as $prop erty => $v alue){
  296                             if(!is _null($val ue)) {
  297                                 $m arkup .= f orm_hidden ($root_tag _name.'['. $property. ']', $valu e);
  298                }
  299                    }
  300  
  301                    retu rn $markup ;
  302           }
  303  
  304           pu blic funct ion raw_va lues(){
  305                    $val ues = get_ object_var s($this);
  306                    unse t($values[ 'is'], $va lues['erro r'], $valu es['dom_el ement'], $ values['xp ath']); // these are  not useful  values to  output
  307                    fore ach($value s as $prop erty => $v alue){
  308                             if(str ing_begins _with('raw _', $prope rty)){
  309                                      $values[ strip_from _beginning ('raw_', $ property)]  = $value;
  310                                      unset($v alues[$pro perty]);
  311                             }
  312                    }
  313                    retu rn $values ;
  314           }
  315  
  316           pu blic funct ion values (){
  317                    $val ues = get_ object_var s($this);
  318                    unse t($values[ 'is'], $va lues['erro r'], $valu es['dom_el ement'], $ values['xp ath']); // these are  not useful  values to  output
  319                    fore ach($value s as $prop erty => $v alue){
  320                             if(str ing_begins _with('raw _', $prope rty)){
  321                                      $non_raw _property  = strip_fr om_beginni ng('raw_',  $property );
  322                                      if(!arra y_key_exis ts($non_ra w_property , $values) )
  323                                               $values[$n on_raw_pro perty] = $ this->$non _raw_prope rty;
  324                                      unset($v alues[$pro perty]);
  325                             }
  326                    }
  327                    retu rn $values ;
  328           }
  329  
  330           // ////////// ////////// /
  331           //  DOM-PARSI NG METHODS
  332           // ////////// ////////// /
  333  
  334  
  335           pr otected fu nction loa d_values_f rom_dom_el ement($dom _element){
  336                    if(! is_a($dom_ element, ' DOMElement ')) return  get_insta nce()->err or->should _be_a_DOME lement_obj ect($dom_e lement);
  337                    if($ dom_elemen t->tagName  != 'patie nt') retur n get_inst ance()->er ror->shoul d_be_a_pat ient_DOMEl ement_obje ct($dom_el ement);
  338  
  339                    $thi s->dom_ele ment = $do m_element;
  340  
  341                    $thi s->raw_icn  = $this-> value_for_ attribute( 'extension ', 'x:id[@ root="'.ge t_instance ()->patien t_id->mvi_ id_code.'" ]');
  342                    $thi s->raw_ssn  = $this-> value_for_ attribute( 'extension ', 'x:pati entPerson/ x:asOtherI Ds[@classC ode="SSN"] /x:id[@roo t="2.16.84 0.1.113883 .4.1"]');
  343                    $thi s->raw_id_ state = $t his->value _for_attri bute('code ', 'x:stat usCode[@co de]');
  344                    $thi s->raw_dat e_of_birth  = $this-> value_for_ attribute( 'value', ' x:patientP erson/x:bi rthTime[@v alue]');
  345                    $thi s->raw_dat e_of_death  = $this-> value_for_ attribute( 'value', ' x:patientP erson/x:de ceasedTime [@value]') ;
  346                    $thi s->raw_gen der = $thi s->value_f or_attribu te('code',  'x:patien tPerson/x: administra tiveGender Code[@code ]');
  347                    $thi s->raw_giv en_names =  $this->va lues_for_t ag('x:pati entPerson/ x:name[@us e="L"]/x:g iven');
  348                    $thi s->raw_fam ily_name =  $this->va lue_for_ta g('x:patie ntPerson/x :name[@use ="L"]/x:fa mily');
  349                    $thi s->raw_pre fix = $thi s->value_f or_tag('x: patientPer son/x:name [@use="L"] /x:prefix' );
  350                    $thi s->raw_suf fix = $thi s->value_f or_tag('x: patientPer son/x:name [@use="L"] /x:suffix' );
  351           }
  352  
  353           pr otected fu nction val ue_for_att ribute($at tribute, $ xpath_for_ tag){
  354                    $val ues = $thi s->values_ for_attrib ute($attri bute, $xpa th_for_tag );
  355                    if(! is_array($ values)) r eturn fals e; //we en countered  an error
  356                    if(c ount($valu es) > 1) $ this->erro r->warning ('More tha n one tag  with attri bute '.$at tribute.'  matched '. $xpath_for _tag.'; ig noring all  but the f irst');
  357                    retu rn first_e lement($va lues);
  358           }
  359  
  360           pr otected fu nction val ues_for_at tribute($a ttribute,  $xpath_for _tag){
  361                    if(! $this->is- >nonempty_ string($at tribute))  return $th is->error- >should_be _a_nonempt y_string($ attribute) ;
  362                    if(! $this->is- >nonempty_ string($xp ath_for_ta g)) return  $this->er ror->shoul d_be_a_non empty_stri ng($xpath_ for_tag);
  363  
  364                    $xpa th_results  = $this-> xpath->que ry($xpath_ for_tag, $ this->dom_ element);
  365  
  366                    if(! is_a($xpat h_results,  'DOMNodeL ist') || $ xpath_resu lts->lengt h < 1) ret urn array( );
  367  
  368                    $val ues = arra y();
  369                    fore ach($xpath _results a s $xpath_r esult){
  370                             if($xp ath_result ->hasAttri bute($attr ibute))
  371                                      $values[ ] = $xpath _result->g etAttribut e($attribu te);
  372                    }
  373                    retu rn $values ;
  374           }
  375  
  376           pr otected fu nction val ue_for_tag ($xpath_fo r_tag){
  377                    $val ues = $thi s->values_ for_tag($x path_for_t ag);
  378                    if(! is_array($ values)) r eturn fals e; //we en countered  an error
  379                    if(c ount($valu es) > 1) $ this->erro r->warning ('More tha n one tag  matched '. $xpath_for _tag.'; ig noring all  but the f irst');
  380                    retu rn first_e lement($va lues);
  381  
  382           }
  383  
  384           pr otected fu nction val ues_for_ta g($xpath_f or_tag){
  385                    if(! $this->is- >nonempty_ string($xp ath_for_ta g)) return  $this->er ror->shoul d_be_a_non empty_stri ng($xpath_ for_tag);
  386  
  387                    $xpa th_results  = $this-> xpath->que ry($xpath_ for_tag, $ this->dom_ element);
  388                    if(! is_a($xpat h_results,  'DOMNodeL ist') || $ xpath_resu lts->lengt h < 1) ret urn array( );
  389  
  390                    $val ues = arra y();
  391                    fore ach($xpath _results a s $xpath_r esult){
  392                             $value s[] = $xpa th_result- >textConte nt;
  393                    }
  394  
  395                    retu rn $values ;
  396           }
  397  
  398           fu nction ful l_name(){
  399                    $nam e = implod e_nonempty (' ', arra y($this->p refix, imp lode(' ',  $this->giv en_names),  $this->fa mily_name) );
  400                    if(! empty($thi s->raw_suf fix)) $nam e .= ', '. $this->suf fix;
  401                    retu rn $name;
  402           }
  403  
  404           fu nction dat e_of_birth (){
  405                    if(e mpty($this ->raw_date _of_birth) ) return ' Unknown';
  406                    retu rn $this-> human_read able_date( $this->raw _date_of_b irth);
  407           }
  408  
  409           fu nction dat e_of_death (){
  410                    if(e mpty($this ->raw_date _of_death) ) return ' &mdash;';
  411                    retu rn $this-> human_read able_date( $this->raw _date_of_d eath);
  412           }
  413  
  414           fu nction gen der(){
  415                    retu rn element (strtouppe r($this->r aw_gender) , array('F ' => 'Fema le', 'M' = > 'Male',  'U' => 'Un differenti ated'));
  416           }
  417  
  418           fu nction icn (){
  419                    if(! string_con tains('^',  (string)$ this->raw_ icn)) retu rn $this-> raw_icn; / /just in c ase they e ver start  formatting  this diff erently
  420                    retu rn substr( $this->raw _icn, 0, s trpos($thi s->raw_icn , '^'));
  421           }
  422  
  423           fu nction id_ state(){
  424                    retu rn ucfirst ($this->ra w_id_state );
  425           }
  426  
  427           fu nction ssn (){
  428                    $ssn  = $this-> raw_ssn;
  429                    if(e mpty($ssn)  || !is_st ring($ssn) ) return ' &mdash;';
  430  
  431                    if(s tring_cont ains('^',  $ssn))
  432                             $ssn =  substr($s sn, 0, str pos($ssn,  '^'));
  433                    retu rn substr( $ssn, 0, 3 ).'-'.subs tr($ssn, 3 , 2).'-'.s ubstr($ssn , 5, 4);
  434           }
  435  
  436           pr otected fu nction hum an_readabl e_date($ti mestamp){
  437                    if(e mpty($time stamp) ||  !is_numeri c($timesta mp) || str len($times tamp) < 8)  return fa lse; //we  don't know  what to d o with it  if we don' t have YYY YMMDD
  438  
  439                    //MV I doesn't  use unix t imestamps  - they ret urn dates  as YYYYMMD D or YYYYM MDDHHMMSSS
  440                    $yea r = substr ($timestam p, 0, 4);
  441                    $mon th = subst r($timesta mp, 4, 2);
  442                    $day  = substr( $timestamp , 6, 2);
  443  
  444                    retu rn $month. '/'.$day.' /'.$year;
  445           }
  446  
  447           pr otected fu nction loa d_values_f rom_array( $values){
  448                    fore ach($value s as $prop erty => $v alue){
  449                             $raw_p roperty =  'raw_'.$pr operty;
  450                             if(pro perty_exis ts(get_cla ss($this),  $raw_prop erty))
  451                                      $this->$ raw_proper ty = $valu e;
  452                             else
  453                                      $this->$ property =  $value;
  454                    }
  455           }
  456  
  457           fu nction __g et($proper ty){
  458                    $raw _property  = 'raw_'.$ property;
  459  
  460                    if(m ethod_exis ts(get_cla ss($this),  $property ))
  461                             return  $this->$p roperty();
  462                    else if(propert y_exists(g et_class($ this), $pr operty))
  463                             return  $this->$p roperty; / /we're hit ting this  because we 're out of  scope, bu t we don't  mind givi ng read-on ly access
  464                    else if(propert y_exists(g et_class($ this), $ra w_property ))
  465                             return  $this->$r aw_propert y;
  466  
  467                    get_ instance() ->error->p roperty_do es_not_exi st($proper ty, get_cl ass($this) , 1);
  468                    retu rn null;
  469           }
  470  
  471   }