Support holidays in calendar
[openemr.git] / library / ESign / DbRow / Signable.php
blob9023a623fb5a108536ae6d28eceeeebd77ef23c9
1 <?php
3 namespace ESign;
5 /**
6 * Abstract implementation of SignableIF which represents a signable row
7 * in the database.
8 *
9 * Copyright (C) 2013 OEMR 501c3 www.oemr.org
11 * LICENSE: This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 3
14 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
22 * @package OpenEMR
23 * @author Ken Chapple <ken@mi-squared.com>
24 * @author Medical Information Integration, LLC
25 * @link http://www.open-emr.org
26 **/
28 require_once $GLOBALS['srcdir'].'/ESign/SignableIF.php';
29 require_once $GLOBALS['srcdir'].'/ESign/Signature.php';
30 require_once $GLOBALS['srcdir'].'/ESign/Utils/Verification.php';
32 abstract class DbRow_Signable implements SignableIF
34 private $_signatures = array();
35 private $_tableId = null;
36 private $_tableName = null;
37 private $_verification = null;
39 public function __construct( $tableId, $tableName )
41 $this->_tableId = $tableId;
42 $this->_tableName = $tableName;
43 $this->_verification = new Utils_Verification();
46 public function getSignatures()
48 $this->_signatures = array();
50 $statement = "SELECT E.id, E.tid, E.table, E.uid, U.fname, U.lname, E.datetime, E.is_lock, E.amendment, E.hash, E.signature_hash FROM esign_signatures E ";
51 $statement .= "JOIN users U ON E.uid = U.id ";
52 $statement .= "WHERE E.tid = ? AND E.table = ? ";
53 $statement .= "ORDER BY E.datetime ASC";
54 $result = sqlStatement( $statement, array( $this->_tableId, $this->_tableName ) );
56 while ( $row = sqlFetchArray( $result ) ) {
57 $signature = new Signature( $row['id'], $row['tid'], $row['table'], $row['is_lock'],
58 $row['uid'], $row['fname'], $row['lname'], $row['datetime'], $row['hash'], $row['amendment'], $row['signature_hash'] );
59 $this->_signatures[]= $signature;
62 return $this->_signatures;
65 /**
66 * Get the hash of the last signature of type LOCK.
68 * This is used for comparison with a current hash to
69 * verify data integrity.
71 * @return sha1|empty string
73 protected function getLastLockHash()
75 $statement = "SELECT E.tid, E.table, E.hash FROM esign_signatures E ";
76 $statement .= "WHERE E.tid = ? AND E.table = ? AND E.is_lock = ? ";
77 $statement .= "ORDER BY E.datetime DESC LIMIT 1";
78 $row = sqlQuery( $statement, array( $this->_tableId, $this->_tableName, SignatureIF::ESIGN_LOCK ) );
79 $hash = null;
80 if ( $row && isset($row['hash']) ) {
81 $hash = $row['hash'];
83 return $hash;
86 public function getTableId()
88 return $this->_tableId;
91 public function renderForm()
93 include 'views/esign_signature_log.php';
96 public function isLocked()
98 $statement = "SELECT E.is_lock FROM esign_signatures E ";
99 $statement .= "WHERE E.tid = ? AND E.table = ? AND is_lock = ? ";
100 $statement .= "ORDER BY E.datetime DESC LIMIT 1 ";
101 $row = sqlQuery( $statement, array( $this->_tableId, $this->_tableName, SignatureIF::ESIGN_LOCK ) );
102 if ( $row && $row['is_lock'] == SignatureIF::ESIGN_LOCK ) {
103 return true;
106 return false;
109 public function sign( $userId, $lock = false, $amendment = null )
111 $statement = "INSERT INTO `esign_signatures` ( `tid`, `table`, `uid`, `datetime`, `is_lock`, `hash`, `amendment`, `signature_hash` ) ";
112 $statement .= "VALUES ( ?, ?, ?, NOW(), ?, ?, ?, ? ) ";
114 // Make type string
115 $isLock = SignatureIF::ESIGN_NOLOCK;
116 if ( $lock ) {
117 $isLock = SignatureIF::ESIGN_LOCK;
120 // Create a hash of the signable object so we can verify it's integrity
121 $hash = $this->_verification->hash( $this->getData() );
123 // Crate a hash of the signature data itself. This is the same data as Signature::getData() method
124 $signature = array(
125 $this->_tableId,
126 $this->_tableName,
127 $userId,
128 $isLock,
129 $hash,
130 $amendment );
131 $signatureHash = $this->_verification->hash( $signature );
133 // Append the hash of the signature data to the insert array before we insert
134 $signature[]= $signatureHash;
135 $id = sqlInsert( $statement, $signature );
137 if ( $id === false ) {
138 throw new \Exception( "Error occured while attempting to insert a signature into the database." );
141 return $id;
144 public function verify()
146 $valid = true;
147 // Verify the signable data integrity
148 // Check to see if this SignableIF is locked
149 if ( $this->isLocked() ) {
150 $signatures = $this->getSignatures();
152 // SignableIF is locked, so if it has any signatures, make sure it hasn't been edited since lock
153 if ( count( $signatures ) ) {
155 // Verify the data of the SignableIF object
156 $lastLockHash = $this->getLastLockHash();
157 $valid = $this->_verification->verify( $this->getData(), $lastLockHash );
159 if ( $valid === true ) {
161 // If still vlaid, verify each signatures' integrity
162 foreach( $signatures as $signature ) {
163 if ( $signature instanceof SignatureIF ) {
164 $valid = $signature->verify();
165 if ( $valid === false ) {
166 break;
174 return $valid;