1: <?php
2:
3: namespace Neodynamic\SDK\Web;
4: use Exception;
5: use ZipArchive;
6:
7:
8: include 'phpseclib/Math/BigInteger.php';
9: include 'phpseclib/Crypt/Hash.php';
10: include 'phpseclib/Crypt/Random.php';
11: include 'phpseclib/Crypt/Base.php';
12: include 'phpseclib/Crypt/RSA.php';
13: include 'phpseclib/Crypt/Rijndael.php';
14: include 'phpseclib/Crypt/AES.php';
15:
16:
17: WebClientPrint::$licenseOwner = '';
18: WebClientPrint::$licenseKey = '';
19:
20:
21:
22: WebClientPrint::$wcpCacheFolder = 'wcpcache/';
23:
24: 25: 26: 27: 28: 29: 30: 31: 32:
33: class WebClientPrint {
34:
35: const VERSION = '6.0.0.0';
36: const CLIENT_PRINT_JOB = 'clientPrint';
37: const WCP = 'WEB_CLIENT_PRINT';
38: const WCP_SCRIPT_AXD_GET_PRINTERS = 'getPrinters';
39: const WCP_SCRIPT_AXD_GET_PRINTERSINFO = 'getPrintersInfo';
40: const WCPP_SET_PRINTERS = 'printers';
41: const WCPP_SET_PRINTERSINFO = 'printersInfo';
42: const WCP_SCRIPT_AXD_GET_WCPPVERSION = 'getWcppVersion';
43: const WCPP_SET_VERSION = 'wcppVer';
44: const GEN_WCP_SCRIPT_URL = 'u';
45: const GEN_DETECT_WCPP_SCRIPT = 'd';
46: const SID = 'sid';
47: const PING = 'wcppping';
48:
49: const WCP_CACHE_WCPP_INSTALLED = 'WCPP_INSTALLED';
50: const WCP_CACHE_WCPP_VER = 'WCPP_VER';
51: const WCP_CACHE_PRINTERS = 'PRINTERS';
52: const WCP_CACHE_PRINTERSINFO = 'PRINTERSINFO';
53:
54:
55: 56: 57: 58:
59: static $licenseOwner = '';
60: 61: 62: 63:
64: static $licenseKey = '';
65: 66: 67: 68:
69: static $webClientPrintAbsoluteUrl = '';
70: 71: 72: 73: 74:
75: static $wcpCacheFolder = '';
76:
77: 78: 79: 80: 81: 82: 83:
84: public static function cacheAdd($sid, $key, $val){
85: if (Utils::isNullOrEmptyString(self::$wcpCacheFolder)){
86: throw new Exception('WebClientPrint wcpCacheFolder is missing, please specify it.');
87: }
88: if (Utils::isNullOrEmptyString($sid)){
89: throw new Exception('WebClientPrint FileName cache is missing, please specify it.');
90: }
91: $cacheFileName = (Utils::strEndsWith(self::$wcpCacheFolder, '/')?self::$wcpCacheFolder:self::$wcpCacheFolder.'/').$sid.'.wcpcache';
92: $dataWCPP_VER = '';
93: $dataPRINTERS = '';
94: $dataPRINTERSINFO = '';
95:
96: if(file_exists($cacheFileName)){
97: $cache_info = parse_ini_file($cacheFileName);
98:
99: $dataWCPP_VER = $cache_info[self::WCP_CACHE_WCPP_VER];
100: $dataPRINTERS = $cache_info[self::WCP_CACHE_PRINTERS];
101: $dataPRINTERSINFO = $cache_info[self::WCP_CACHE_PRINTERSINFO];
102: }
103:
104: if ($key === self::WCP_CACHE_WCPP_VER){
105: $dataWCPP_VER = self::WCP_CACHE_WCPP_VER.'='.'"'.$val.'"';
106: $dataPRINTERS = self::WCP_CACHE_PRINTERS.'='.'"'.$dataPRINTERS.'"';
107: $dataPRINTERSINFO = self::WCP_CACHE_PRINTERSINFO.'='.'"'.$dataPRINTERSINFO.'"';
108: } else if ($key === self::WCP_CACHE_PRINTERS){
109: $dataWCPP_VER = self::WCP_CACHE_WCPP_VER.'='.'"'.$dataWCPP_VER.'"';
110: $dataPRINTERS = self::WCP_CACHE_PRINTERS.'='.'"'.$val.'"';
111: $dataPRINTERSINFO = self::WCP_CACHE_PRINTERSINFO.'='.'"'.$dataPRINTERSINFO.'"';
112: } else if ($key === self::WCP_CACHE_PRINTERSINFO){
113: $dataWCPP_VER = self::WCP_CACHE_WCPP_VER.'='.'"'.$dataWCPP_VER.'"';
114: $dataPRINTERS = self::WCP_CACHE_PRINTERS.'='.'"'.$dataPRINTERS.'"';
115: $dataPRINTERSINFO = self::WCP_CACHE_PRINTERSINFO.'='.'"'.$val.'"';
116: }
117:
118: $data = $dataWCPP_VER.chr(13).chr(10).$dataPRINTERS.chr(13).chr(10).$dataPRINTERSINFO;
119: $handle = fopen($cacheFileName, 'w') or die('Cannot open file: '.$cacheFileName);
120: fwrite($handle, $data);
121: fclose($handle);
122:
123: }
124:
125: 126: 127: 128: 129: 130: 131:
132: public static function cacheGet($sid, $key){
133: if (Utils::isNullOrEmptyString(self::$wcpCacheFolder)){
134: throw new Exception('WebClientPrint wcpCacheFolder is missing, please specify it.');
135: }
136: if (Utils::isNullOrEmptyString($sid)){
137: throw new Exception('WebClientPrint FileName cache is missing, please specify it.');
138: }
139: $cacheFileName = (Utils::strEndsWith(self::$wcpCacheFolder, '/')?self::$wcpCacheFolder:self::$wcpCacheFolder.'/').$sid.'.wcpcache';
140: if(file_exists($cacheFileName)){
141: $cache_info = parse_ini_file($cacheFileName, FALSE, INI_SCANNER_RAW);
142:
143: if($key===self::WCP_CACHE_WCPP_VER || $key===self::WCP_CACHE_WCPP_INSTALLED){
144: return $cache_info[self::WCP_CACHE_WCPP_VER];
145: }else if($key===self::WCP_CACHE_PRINTERS){
146: return $cache_info[self::WCP_CACHE_PRINTERS];
147: }else if($key===self::WCP_CACHE_PRINTERSINFO){
148: return $cache_info[self::WCP_CACHE_PRINTERSINFO];
149: }else{
150: return '';
151: }
152: }else{
153: return '';
154: }
155: }
156:
157: 158: 159: 160:
161: public static function cacheClean($minutes){
162: if (!Utils::isNullOrEmptyString(self::$wcpCacheFolder)){
163: $cacheDir = (Utils::strEndsWith(self::$wcpCacheFolder, '/')?self::$wcpCacheFolder:self::$wcpCacheFolder.'/');
164: if ($handle = opendir($cacheDir)) {
165: while (false !== ($file = readdir($handle))) {
166: if ($file!='.' && $file!='..' && (time()-filectime($cacheDir.$file)) > (60*$minutes)) {
167: unlink($cacheDir.$file);
168: }
169: }
170: closedir($handle);
171: }
172: }
173: }
174:
175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193:
194: public static function createWcppDetectionScript($webClientPrintControllerAbsoluteUrl, $sessionID){
195:
196: if (Utils::isNullOrEmptyString($webClientPrintControllerAbsoluteUrl) ||
197: !Utils::strStartsWith($webClientPrintControllerAbsoluteUrl, 'http')){
198: throw new Exception('WebClientPrintController absolute URL is missing, please specify it.');
199: }
200: if (Utils::isNullOrEmptyString($sessionID)){
201: throw new Exception('Session ID is missing, please specify it.');
202: }
203:
204: $url = $webClientPrintControllerAbsoluteUrl.'?'.self::GEN_DETECT_WCPP_SCRIPT.'='.$sessionID;
205: return '<script src="'.$url.'" type="text/javascript"></script>';
206:
207: }
208:
209:
210: 211: 212: 213: 214: 215: 216: 217: 218: 219:
220: public static function createScript($webClientPrintControllerAbsoluteUrl, $clientPrintJobAbsoluteUrl, $sessionID){
221: if (Utils::isNullOrEmptyString($webClientPrintControllerAbsoluteUrl) ||
222: !Utils::strStartsWith($webClientPrintControllerAbsoluteUrl, 'http')){
223: throw new Exception('WebClientPrintController absolute URL is missing, please specify it.');
224: }
225: if (Utils::isNullOrEmptyString($clientPrintJobAbsoluteUrl) ||
226: !Utils::strStartsWith($clientPrintJobAbsoluteUrl, 'http')){
227: throw new Exception('ClientPrintJob absolute URL is missing, please specify it.');
228: }
229: if (Utils::isNullOrEmptyString($sessionID)){
230: throw new Exception('Session ID is missing, please specify it.');
231: }
232:
233:
234: $wcpHandler = $webClientPrintControllerAbsoluteUrl.'?';
235: $wcpHandler .= self::VERSION;
236: $wcpHandler .= '&';
237: $wcpHandler .= microtime(true);
238: $wcpHandler .= '&sid=';
239: $wcpHandler .= $sessionID;
240: $wcpHandler .= '&'.self::GEN_WCP_SCRIPT_URL.'=';
241: $wcpHandler .= base64_encode($clientPrintJobAbsoluteUrl);
242: return '<script src="'.$wcpHandler.'" type="text/javascript"></script>';
243: }
244:
245:
246: 247: 248: 249: 250: 251:
252: public static function generateScript($webClientPrintControllerAbsoluteUrl, $queryString)
253: {
254: if (Utils::isNullOrEmptyString($webClientPrintControllerAbsoluteUrl) ||
255: !Utils::strStartsWith($webClientPrintControllerAbsoluteUrl, 'http')){
256: throw new Exception('WebClientPrintController absolute URL is missing, please specify it.');
257: }
258:
259: parse_str($queryString, $qs);
260:
261: if(isset($qs[self::GEN_DETECT_WCPP_SCRIPT])){
262:
263: $curSID = $qs[self::GEN_DETECT_WCPP_SCRIPT];
264: $dynamicIframeId = 'i'.substr(uniqid(), 0, 3);
265: $absoluteWcpAxd = $webClientPrintControllerAbsoluteUrl.'?'.self::SID.'='.$curSID;
266:
267: $s1 = 'dmFyIGpzV0NQUD0oZnVuY3Rpb24oKXt2YXIgc2V0PDw8LU5FTy1IVE1MLUlELT4+Pj1mdW5jdGlvbigpe3ZhciBlbD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnPDw8LU5FTy1IVE1MLUlELT4+PicpO2lmKHdpbmRvdy5jaHJvbWUpe2VsLmhyZWY9J3dlYmNsaWVudHByaW50dmk6Jythcmd1bWVudHNbMF07dmFyIGV2T2JqPWRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50cycpO2V2T2JqLmluaXRFdmVudCgnY2xpY2snLHRydWUsdHJ1ZSk7ZWwuZGlzcGF0Y2hFdmVudChldk9iail9ZWxzZXtlbC5zcmM9J3dlYmNsaWVudHByaW50dmk6Jythcmd1bWVudHNbMF19fTtyZXR1cm57aW5pdDpmdW5jdGlvbigpe2lmKHdpbmRvdy5jaHJvbWUpe3ZhciBhRWw9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO2FFbC5pZD0nPDw8LU5FTy1IVE1MLUlELT4+Pic7ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhRWwpfWVsc2V7dmFyIGlmRWw9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7aWZFbC5pZD0nPDw8LU5FTy1IVE1MLUlELT4+Pic7aWZFbC5uYW1lPSc8PDwtTkVPLUhUTUwtSUQtPj4+JztpZkVsLndpZHRoPTE7aWZFbC5oZWlnaHQ9MTtpZkVsLnN0eWxlLnZpc2liaWxpdHk9J2hpZGRlbic7aWZFbC5zdHlsZS5wb3NpdGlvbj0nYWJzb2x1dGUnO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZFbCl9fSxwaW5nOmZ1bmN0aW9uKCl7c2V0PDw8LU5FTy1IVE1MLUlELT4+PignPDw8LU5FTy1QSU5HLVVSTC0+Pj4nKyhhcmd1bWVudHMubGVuZ3RoPT0xPycmJythcmd1bWVudHNbMF06JycpKTt2YXIgZGVsYXlfbXM9KHR5cGVvZiB3Y3BwUGluZ0RlbGF5X21zPT09J3VuZGVmaW5lZCcpPzA6d2NwcFBpbmdEZWxheV9tcztpZihkZWxheV9tcz4wKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dmFyIHhocj1uZXcgWE1MSHR0cFJlcXVlc3QoKTt4aHIub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCl7aWYoeGhyLnJlYWR5U3RhdGU9PTQmJnhoci5zdGF0dXM9PTIwMCl7dmFyIGRhdGE9eGhyLnJlc3BvbnNlVGV4dDtpZihkYXRhLmxlbmd0aD4wKXt3Y3BwRGV0ZWN0T25TdWNjZXNzKGRhdGEpfWVsc2V7d2NwcERldGVjdE9uRmFpbHVyZSgpfX19O3hoci5vcGVuKCdHRVQnLCc8PDwtTkVPLVVTRVItSEFTLVdDUFAtPj4+Jyk7eGhyLnNlbmQoKX0sZGVsYXlfbXMpfWVsc2V7dmFyIGZuY1dDUFA9c2V0SW50ZXJ2YWwoZ2V0V0NQUFZlcix3Y3BwUGluZ1RpbWVvdXRTdGVwX21zKTt2YXIgd2NwcF9jb3VudD0wO2Z1bmN0aW9uIGdldFdDUFBWZXIoKXtpZih3Y3BwX2NvdW50PD13Y3BwUGluZ1RpbWVvdXRfbXMpe3ZhciB4aHI9bmV3IFhNTEh0dHBSZXF1ZXN0KCk7eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbigpe2lmKHhoci5yZWFkeVN0YXRlPT00JiZ4aHIuc3RhdHVzPT0yMDApe3ZhciBkYXRhPXhoci5yZXNwb25zZVRleHQ7aWYoZGF0YS5sZW5ndGg+MCl7Y2xlYXJJbnRlcnZhbChmbmNXQ1BQKTt3Y3BwRGV0ZWN0T25TdWNjZXNzKGRhdGEpfX19O3hoci5vcGVuKCdHRVQnLCc8PDwtTkVPLVVTRVItSEFTLVdDUFAtPj4+Jyk7eGhyLnNlbmQoeydfJzoobmV3IERhdGUoKS5nZXRUaW1lKCkpfSk7d2NwcF9jb3VudCs9d2NwcFBpbmdUaW1lb3V0U3RlcF9tc31lbHNle2NsZWFySW50ZXJ2YWwoZm5jV0NQUCk7d2NwcERldGVjdE9uRmFpbHVyZSgpfX19fX19KSgpO2RvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLGZ1bmN0aW9uKCl7anNXQ1BQLmluaXQoKTtqc1dDUFAucGluZygpfSk7';
268:
269: $s2 = base64_decode($s1);
270: $s2 = str_replace('<<<-NEO-HTML-ID->>>', $dynamicIframeId, $s2);
271: $s2 = str_replace('<<<-NEO-PING-URL->>>', $absoluteWcpAxd.'&'.self::PING, $s2);
272: $s2 = str_replace('<<<-NEO-USER-HAS-WCPP->>>', $absoluteWcpAxd, $s2);
273:
274: return $s2;
275:
276: }else if(isset($qs[self::GEN_WCP_SCRIPT_URL])){
277:
278: $clientPrintJobUrl = base64_decode($qs[self::GEN_WCP_SCRIPT_URL]);
279: if (strpos($clientPrintJobUrl, '?')>0){
280: $clientPrintJobUrl .= '&';
281: }else{
282: $clientPrintJobUrl .= '?';
283: }
284: $clientPrintJobUrl .= self::CLIENT_PRINT_JOB;
285: $absoluteWcpAxd = $webClientPrintControllerAbsoluteUrl;
286: $wcppGetPrintersParam = '-getPrinters:'.$absoluteWcpAxd.'?'.self::WCP.'&'.self::SID.'=';
287: $wcpHandlerGetPrinters = $absoluteWcpAxd.'?'.self::WCP.'&'.self::WCP_SCRIPT_AXD_GET_PRINTERS.'&'.self::SID.'=';
288: $wcppGetPrintersInfoParam = '-getPrintersInfo:'.$absoluteWcpAxd.'?'.self::WCP.'&'.self::SID.'=';
289: $wcpHandlerGetPrintersInfo = $absoluteWcpAxd.'?'.self::WCP.'&'.self::WCP_SCRIPT_AXD_GET_PRINTERSINFO.'&'.self::SID.'=';
290: $wcppGetWcppVerParam = '-getWcppVersion:'.$absoluteWcpAxd.'?'.self::WCP.'&'.self::SID.'=';
291: $wcpHandlerGetWcppVer = $absoluteWcpAxd.'?'.self::WCP.'&'.self::WCP_SCRIPT_AXD_GET_WCPPVERSION.'&'.self::SID.'=';
292: $sessionIDVal = $qs[self::SID];
293:
294: $s1 = 'dmFyIGpzV2ViQ2xpZW50UHJpbnQ9KGZ1bmN0aW9uKCl7dmFyIGdldFJlcT1mdW5jdGlvbih1cmwsb25TdWNjZXNzLG9uRmFpbHVyZSxvbkNsZWFuKXt2YXIgeGhyPW5ldyBYTUxIdHRwUmVxdWVzdCgpO3hoci5vbnJlYWR5c3RhdGVjaGFuZ2U9ZnVuY3Rpb24oKXtpZih4aHIucmVhZHlTdGF0ZT09NCYmeGhyLnN0YXR1cz09MjAwKXt2YXIgZGF0YT14aHIucmVzcG9uc2VUZXh0O2lmKGRhdGEubGVuZ3RoPjApe2lmKG9uQ2xlYW4pY2xlYXJJbnRlcnZhbChvbkNsZWFuKTtpZihvblN1Y2Nlc3Mpb25TdWNjZXNzKGRhdGEpfWVsc2V7aWYob25GYWlsdXJlKW9uRmFpbHVyZSgpfX19O3hoci5vcGVuKCdHRVQnLHVybCk7eGhyLnNlbmQoeydfJzoobmV3IERhdGUoKS5nZXRUaW1lKCkpfSl9O3ZhciBzZXRBPWZ1bmN0aW9uKCl7dmFyIGVfaWQ9J2lkXycrbmV3IERhdGUoKS5nZXRUaW1lKCk7aWYod2luZG93LmNocm9tZSl7dmFyIGFFbD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7YUVsLmlkPWVfaWQ7YUVsLmhyZWY9J3dlYmNsaWVudHByaW50dmk6Jythcmd1bWVudHNbMF07dmFyIGV2T2JqPWRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50cycpO2V2T2JqLmluaXRFdmVudCgnY2xpY2snLHRydWUsdHJ1ZSk7YUVsLmRpc3BhdGNoRXZlbnQoZXZPYmopO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYUVsKX1lbHNle3ZhciBpZkVsPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO2lmRWwuaWQ9ZV9pZDtpZkVsLm5hbWU9ZV9pZDtpZkVsLndpZHRoPTE7aWZFbC5oZWlnaHQ9MTtpZkVsLnN0eWxlLnZpc2liaWxpdHk9J2hpZGRlbic7aWZFbC5zdHlsZS5wb3NpdGlvbj0nYWJzb2x1dGUnO2lmRWwuc3JjPSd3ZWJjbGllbnRwcmludHZpOicrYXJndW1lbnRzWzBdO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZFbCl9c2V0VGltZW91dChmdW5jdGlvbigpe2RvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZV9pZCkpfSw1MDAwKX07cmV0dXJue3ByaW50OmZ1bmN0aW9uKCl7c2V0QSgnVVJMX1BSSU5UX0pPQicrKGFyZ3VtZW50cy5sZW5ndGg9PTE/JyYnK2FyZ3VtZW50c1swXTonJykpfSxnZXRQcmludGVyczpmdW5jdGlvbigpe3NldEEoJ1VSTF9XQ1BfQVhEX1dJVEhfR0VUX1BSSU5URVJTX0NPTU1BTkQnKyc8PDwtTkVPLVNFU1NJT04tSUQtPj4+Jyk7dmFyIGRlbGF5X21zPSh0eXBlb2Ygd2NwcEdldFByaW50ZXJzRGVsYXlfbXM9PT0ndW5kZWZpbmVkJyk/MDp3Y3BwR2V0UHJpbnRlcnNEZWxheV9tcztpZihkZWxheV9tcz4wKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Z2V0UmVxKCdVUkxfV0NQX0FYRF9HRVRfUFJJTlRFUlMnKyc8PDwtTkVPLVNFU1NJT04tSUQtPj4+Jyx3Y3BHZXRQcmludGVyc09uU3VjY2Vzcyx3Y3BHZXRQcmludGVyc09uRmFpbHVyZSl9LGRlbGF5X21zKX1lbHNle3ZhciBmbmNHZXRQcmludGVycz1zZXRJbnRlcnZhbChnZXRDbGllbnRQcmludGVycyx3Y3BwR2V0UHJpbnRlcnNUaW1lb3V0U3RlcF9tcyk7dmFyIHdjcHBfY291bnQ9MDtmdW5jdGlvbiBnZXRDbGllbnRQcmludGVycygpe2lmKHdjcHBfY291bnQ8PXdjcHBHZXRQcmludGVyc1RpbWVvdXRfbXMpe2dldFJlcSgnVVJMX1dDUF9BWERfR0VUX1BSSU5URVJTJysnPDw8LU5FTy1TRVNTSU9OLUlELT4+Picsd2NwR2V0UHJpbnRlcnNPblN1Y2Nlc3MsbnVsbCxmbmNHZXRQcmludGVycyk7d2NwcF9jb3VudCs9d2NwcEdldFByaW50ZXJzVGltZW91dFN0ZXBfbXN9ZWxzZXtjbGVhckludGVydmFsKGZuY0dldFByaW50ZXJzKTt3Y3BHZXRQcmludGVyc09uRmFpbHVyZSgpfX19fSxnZXRQcmludGVyc0luZm86ZnVuY3Rpb24oKXtzZXRBKCdVUkxfV0NQX0FYRF9XSVRIX0dFVF9QUklOVEVSU0lORk9fQ09NTUFORCcrJzw8PC1ORU8tU0VTU0lPTi1JRC0+Pj4nKTt2YXIgZGVsYXlfbXM9KHR5cGVvZiB3Y3BwR2V0UHJpbnRlcnNEZWxheV9tcz09PSd1bmRlZmluZWQnKT8wOndjcHBHZXRQcmludGVyc0RlbGF5X21zO2lmKGRlbGF5X21zPjApe3NldFRpbWVvdXQoZnVuY3Rpb24oKXtnZXRSZXEoJ1VSTF9XQ1BfQVhEX0dFVF9QUklOVEVSU0lORk8nKyc8PDwtTkVPLVNFU1NJT04tSUQtPj4+Jyx3Y3BHZXRQcmludGVyc09uU3VjY2Vzcyx3Y3BHZXRQcmludGVyc09uRmFpbHVyZSl9LGRlbGF5X21zKX1lbHNle3ZhciBmbmNHZXRQcmludGVyc0luZm89c2V0SW50ZXJ2YWwoZ2V0Q2xpZW50UHJpbnRlcnNJbmZvLHdjcHBHZXRQcmludGVyc1RpbWVvdXRTdGVwX21zKTt2YXIgd2NwcF9jb3VudD0wO2Z1bmN0aW9uIGdldENsaWVudFByaW50ZXJzSW5mbygpe2lmKHdjcHBfY291bnQ8PXdjcHBHZXRQcmludGVyc1RpbWVvdXRfbXMpe2dldFJlcSgnVVJMX1dDUF9BWERfR0VUX1BSSU5URVJTSU5GTycrJzw8PC1ORU8tU0VTU0lPTi1JRC0+Pj4nLHdjcEdldFByaW50ZXJzT25TdWNjZXNzLG51bGwsZm5jR2V0UHJpbnRlcnNJbmZvKTt3Y3BwX2NvdW50Kz13Y3BwR2V0UHJpbnRlcnNUaW1lb3V0U3RlcF9tc31lbHNle2NsZWFySW50ZXJ2YWwoZm5jR2V0UHJpbnRlcnNJbmZvKTt3Y3BHZXRQcmludGVyc09uRmFpbHVyZSgpfX19fSxnZXRXY3BwVmVyOmZ1bmN0aW9uKCl7c2V0QSgnVVJMX1dDUF9BWERfV0lUSF9HRVRfV0NQUFZFUlNJT05fQ09NTUFORCcrJzw8PC1ORU8tU0VTU0lPTi1JRC0+Pj4nKTt2YXIgZGVsYXlfbXM9KHR5cGVvZiB3Y3BwR2V0VmVyRGVsYXlfbXM9PT0ndW5kZWZpbmVkJyk/MDp3Y3BwR2V0VmVyRGVsYXlfbXM7aWYoZGVsYXlfbXM+MCl7c2V0VGltZW91dChmdW5jdGlvbigpe2dldFJlcSgnVVJMX1dDUF9BWERfR0VUX1dDUFBWRVJTSU9OJysnPDw8LU5FTy1TRVNTSU9OLUlELT4+Picsd2NwR2V0V2NwcFZlck9uU3VjY2Vzcyx3Y3BHZXRXY3BwVmVyT25GYWlsdXJlKX0sZGVsYXlfbXMpfWVsc2V7dmFyIGZuY1dDUFA9c2V0SW50ZXJ2YWwoZ2V0Q2xpZW50VmVyLHdjcHBHZXRWZXJUaW1lb3V0U3RlcF9tcyk7dmFyIHdjcHBfY291bnQ9MDtmdW5jdGlvbiBnZXRDbGllbnRWZXIoKXtpZih3Y3BwX2NvdW50PD13Y3BwR2V0VmVyVGltZW91dF9tcyl7Z2V0UmVxKCdVUkxfV0NQX0FYRF9HRVRfV0NQUFZFUlNJT04nKyc8PDwtTkVPLVNFU1NJT04tSUQtPj4+Jyx3Y3BHZXRXY3BwVmVyT25TdWNjZXNzLG51bGwsZm5jV0NQUCk7d2NwcF9jb3VudCs9d2NwcEdldFZlclRpbWVvdXRTdGVwX21zfWVsc2V7Y2xlYXJJbnRlcnZhbChmbmNXQ1BQKTt3Y3BHZXRXY3BwVmVyT25GYWlsdXJlKCl9fX19LHNlbmQ6ZnVuY3Rpb24oKXtzZXRBLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19fSkoKTs=';
295:
296: $s2 = base64_decode($s1);
297: $s2 = str_replace('URL_PRINT_JOB', $clientPrintJobUrl, $s2);
298: $s2 = str_replace('URL_WCP_AXD_WITH_GET_PRINTERSINFO_COMMAND', $wcppGetPrintersInfoParam, $s2);
299: $s2 = str_replace('URL_WCP_AXD_GET_PRINTERSINFO', $wcpHandlerGetPrintersInfo, $s2);
300: $s2 = str_replace('URL_WCP_AXD_WITH_GET_PRINTERS_COMMAND', $wcppGetPrintersParam, $s2);
301: $s2 = str_replace('URL_WCP_AXD_GET_PRINTERS', $wcpHandlerGetPrinters, $s2);
302: $s2 = str_replace('URL_WCP_AXD_WITH_GET_WCPPVERSION_COMMAND', $wcppGetWcppVerParam, $s2);
303: $s2 = str_replace('URL_WCP_AXD_GET_WCPPVERSION', $wcpHandlerGetWcppVer, $s2);
304: $s2 = str_replace('<<<-NEO-SESSION-ID->>>', $sessionIDVal, $s2);
305:
306: return $s2;
307: }
308:
309: }
310:
311:
312: 313: 314:
315: const GenPrintScript = 0;
316: 317: 318:
319: const GenWcppDetectScript = 1;
320: 321: 322:
323: const ClientSetInstalledPrinters = 2;
324: 325: 326:
327: const ClientGetInstalledPrinters = 3;
328: 329: 330:
331: const ClientSetWcppVersion = 4;
332: 333: 334:
335: const ClientGetWcppVersion = 5;
336: 337: 338:
339: const ClientSetInstalledPrintersInfo = 6;
340: 341: 342:
343: const ClientGetInstalledPrintersInfo = 7;
344:
345:
346: 347: 348: 349: 350: 351: 352:
353: public static function GetProcessRequestType($queryString){
354: parse_str($queryString, $qs);
355:
356: if(isset($qs[self::SID])){
357: if(isset($qs[self::PING])){
358: return self::ClientSetWcppVersion;
359: } else if(isset($qs[self::WCPP_SET_VERSION])){
360: return self::ClientSetWcppVersion;
361: } else if(isset($qs[self::WCPP_SET_PRINTERS])){
362: return self::ClientSetInstalledPrinters;
363: } else if(isset($qs[self::WCPP_SET_PRINTERSINFO])){
364: return self::ClientSetInstalledPrintersInfo;
365: } else if(isset($qs[self::WCP_SCRIPT_AXD_GET_WCPPVERSION])){
366: return self::ClientGetWcppVersion;
367: } else if(isset($qs[self::WCP_SCRIPT_AXD_GET_PRINTERS])){
368: return self::ClientGetInstalledPrinters;
369: } else if(isset($qs[self::WCP_SCRIPT_AXD_GET_PRINTERSINFO])){
370: return self::ClientGetInstalledPrintersInfo;
371: } else if(isset($qs[self::GEN_WCP_SCRIPT_URL])){
372: return self::GenPrintScript;
373: } else {
374: return self::ClientGetWcppVersion;
375: }
376: } else if(isset($qs[self::GEN_DETECT_WCPP_SCRIPT])){
377: return self::GenWcppDetectScript;
378: } else {
379: throw new Exception('No valid ProcessRequestType was found in the specified QueryString.');
380: }
381: }
382:
383: }
384:
385: 386: 387:
388: class Duplex
389: {
390: 391: 392:
393: const DEF = 0;
394: 395: 396:
397: const SIMPLEX = 1;
398: 399: 400:
401: const VERTICAL = 2;
402: 403: 404:
405: const HORIZONTAL = 3;
406:
407: public static function parse($val){
408: if($val === 'DEF') return 0;
409: if($val === 'SIMPLEX') return 1;
410: if($val === 'VERTICAL') return 2;
411: if($val === 'HORIZONTAL') return 3;
412: return 0;
413: }
414: }
415:
416:
417: 418: 419:
420: abstract class ClientPrinter{
421:
422: public $printerId;
423: public function serialize(){
424:
425: }
426: }
427:
428: 429: 430:
431: class DefaultPrinter extends ClientPrinter{
432: public function __construct() {
433: $this->printerId = chr(0);
434: }
435:
436: public function serialize() {
437: return $this->printerId;
438: }
439: }
440:
441: 442: 443:
444: class InstalledPrinter extends ClientPrinter{
445:
446: 447: 448: 449:
450: public $printerName = '';
451:
452: 453: 454: 455:
456: public $printToDefaultIfNotFound = false;
457:
458:
459: 460: 461: 462:
463: public $trayName = '';
464:
465: 466: 467: 468:
469: public $paperName = '';
470:
471: 472: 473: 474: 475:
476: public $duplex = Duplex::DEF;
477:
478:
479: 480: 481: 482:
483: public function __construct($printerName) {
484: $this->printerId = chr(1);
485: $this->printerName = $printerName;
486: }
487:
488: public function serialize() {
489:
490: if (Utils::isNullOrEmptyString($this->printerName)){
491: throw new Exception("The specified printer name is null or empty.");
492: }
493:
494: $serData = $this->printerId.$this->printerName;
495:
496: if ($this->printToDefaultIfNotFound){
497: $serData .= Utils::SER_SEP.'1';
498: } else {
499: $serData .= Utils::SER_SEP.'0';
500: }
501:
502: if ($this->trayName){
503: $serData .= Utils::SER_SEP.$this->trayName;
504: } else {
505: $serData .= Utils::SER_SEP.'def';
506: }
507:
508: if ($this->paperName){
509: $serData .= Utils::SER_SEP.$this->paperName;
510: } else {
511: $serData .= Utils::SER_SEP.'def';
512: }
513:
514: $serData .= Utils::SER_SEP.((int)$this->duplex);
515:
516: return $serData;
517: }
518: }
519:
520: 521: 522:
523: class ParallelPortPrinter extends ClientPrinter{
524:
525: 526: 527: 528:
529: public $portName = "LPT1";
530:
531: 532: 533: 534:
535: public function __construct($portName) {
536: $this->printerId = chr(2);
537: $this->portName = $portName;
538: }
539:
540: public function serialize() {
541:
542: if (Utils::isNullOrEmptyString($this->portName)){
543: throw new Exception("The specified parallel port name is null or empty.");
544: }
545:
546: return $this->printerId.$this->portName;
547: }
548: }
549:
550: 551: 552:
553: class SerialPortPrinter extends ClientPrinter{
554:
555: 556: 557: 558:
559: public $portName = "COM1";
560: 561: 562: 563:
564: public $baudRate = 9600;
565: 566: 567: 568: 569:
570: public $parity = SerialPortParity::NONE;
571: 572: 573: 574: 575:
576: public $stopBits = SerialPortStopBits::ONE;
577: 578: 579: 580:
581: public $dataBits = 8;
582: 583: 584: 585: 586:
587: public $flowControl = SerialPortHandshake::XON_XOFF;
588:
589: 590: 591: 592: 593: 594: 595: 596: 597:
598: public function __construct($portName, $baudRate, $parity, $stopBits, $dataBits, $flowControl) {
599: $this->printerId = chr(3);
600: $this->portName = $portName;
601: $this->baudRate = $baudRate;
602: $this->parity = $parity;
603: $this->stopBits = $stopBits;
604: $this->dataBits = $dataBits;
605: $this->flowControl = $flowControl;
606: }
607:
608: public function serialize() {
609:
610: if (Utils::isNullOrEmptyString($this->portName)){
611: throw new Exception("The specified serial port name is null or empty.");
612: }
613:
614: return $this->printerId.$this->portName.Utils::SER_SEP.$this->baudRate.Utils::SER_SEP.$this->dataBits.Utils::SER_SEP.((int)$this->flowControl).Utils::SER_SEP.((int)$this->parity).Utils::SER_SEP.((int)$this->stopBits);
615: }
616: }
617:
618: 619: 620:
621: class NetworkPrinter extends ClientPrinter{
622:
623: 624: 625: 626:
627: public $dnsName = "";
628: 629: 630: 631:
632: public $ipAddress = "";
633: 634: 635: 636:
637: public $port = 0;
638:
639: 640: 641: 642: 643: 644:
645: public function __construct($dnsName, $ipAddress, $port) {
646: $this->printerId = chr(4);
647: $this->dnsName = $dnsName;
648: $this->ipAddress = $ipAddress;
649: $this->port = $port;
650: }
651:
652: public function serialize() {
653:
654: if (Utils::isNullOrEmptyString($this->dnsName) && Utils::isNullOrEmptyString($this->ipAddress)){
655: throw new Exception("The specified network printer settings is not valid. You must specify the DNS Printer Name or its IP address.");
656: }
657:
658: return $this->printerId.$this->dnsName.Utils::SER_SEP.$this->ipAddress.Utils::SER_SEP.$this->port;
659: }
660: }
661:
662: 663: 664:
665: class UserSelectedPrinter extends ClientPrinter{
666: public function __construct() {
667: $this->printerId = chr(5);
668: }
669:
670: public function serialize() {
671: return $this->printerId;
672: }
673: }
674:
675: 676: 677:
678: class SerialPortParity{
679: const NONE = 0;
680: const ODD = 1;
681: const EVEN = 2;
682: const MARK = 3;
683: const SPACE = 4;
684: public static function parse($val){
685: if($val === 'NONE') return 0;
686: if($val === 'ODD') return 1;
687: if($val === 'EVEN') return 2;
688: if($val === 'MARK') return 3;
689: if($val === 'SPACE') return 4;
690: return 0;
691: }
692: }
693:
694: 695: 696:
697: class SerialPortStopBits{
698: const NONE = 0;
699: const ONE = 1;
700: const TWO = 2;
701: const ONE_POINT_FIVE = 3;
702: public static function parse($val){
703: if($val === 'NONE') return 0;
704: if($val === 'ONE') return 1;
705: if($val === 'TWO') return 2;
706: if($val === 'ONE_POINT_FIVE') return 3;
707: return 0;
708: }
709: }
710:
711: 712: 713:
714: class SerialPortHandshake{
715: const NONE = 0;
716: const REQUEST_TO_SEND = 2;
717: const REQUEST_TO_SEND_XON_XOFF = 3;
718: const XON_XOFF = 1;
719: public static function parse($val){
720: if($val === 'NONE') return 0;
721: if($val === 'XON_XOFF') return 1;
722: if($val === 'REQUEST_TO_SEND') return 2;
723: if($val === 'REQUEST_TO_SEND_XON_XOFF') return 3;
724: return 0;
725: }
726: }
727:
728: 729: 730:
731: class EncryptMetadata{
732:
733: 734: 735:
736: public $publicKeyBase64 = '';
737: 738: 739:
740: public $publicKeySignatureBase64 = '';
741: 742: 743:
744: public $password = '';
745: 746: 747:
748: public $salt = '';
749: 750: 751:
752: public $iv = '';
753: 754: 755:
756: public $iterations = 1000;
757:
758:
759: 760: 761: 762: 763:
764: public function __construct($pubKeyBase64, $pubKeySignatureKeyBase64) {
765: $this->publicKeyBase64 = $pubKeyBase64;
766: $this->publicKeySignatureBase64 = $pubKeySignatureKeyBase64;
767: }
768:
769: public function serialize() {
770:
771: $this->validateMetadata();
772:
773: $sep = '|';
774:
775: $buffer = base64_encode(SecUtils::rsaVerifyAndEncrypt($this->publicKeyBase64, $this->publicKeySignatureBase64, $this->password));
776: $buffer .= $sep;
777: $buffer .= base64_encode(SecUtils::rsaVerifyAndEncrypt($this->publicKeyBase64, $this->publicKeySignatureBase64, $this->salt));
778: $buffer .= $sep;
779: $buffer .= base64_encode(SecUtils::rsaVerifyAndEncrypt($this->publicKeyBase64, $this->publicKeySignatureBase64, $this->iv));
780: $buffer .= $sep;
781: $buffer .= base64_encode(SecUtils::rsaVerifyAndEncrypt($this->publicKeyBase64, $this->publicKeySignatureBase64, strval($this->iterations)));
782:
783: return $buffer;
784: }
785:
786: public function validateMetadata(){
787: if(Utils::isNullOrEmptyString($this->password)){
788: $this->password = Utils::genRandomString(33, 126, 32);
789: }else if (strlen($this->password) > 100){
790: throw new Exception("Password cannot be greater than 100 ASCII chars/bytes.");
791: }
792:
793: if(Utils::isNullOrEmptyString($this->salt)){
794: $this->salt = Utils::genRandomString(33, 126, 32);
795: }else if (strlen($this->salt) > 100){
796: throw new Exception("Salt cannot be greater than 100 ASCII chars/bytes.");
797: }
798:
799: if(Utils::isNullOrEmptyString($this->iv)){
800: $this->iv = Utils::genRandomString(33, 126, 16);
801: }else if (strlen($this->iv) > 16){
802: throw new Exception("IV cannot be greater than 16 ASCII chars/bytes.");
803: }
804:
805: if ($this->iterations < 1000){
806: $this->iterations = 1000;
807: }
808: }
809: }
810:
811:
812: 813: 814:
815: class PrintFile{
816:
817: public $fileIsPasswordProtected = false;
818: public $fileExtension = '';
819:
820: 821: 822: 823:
824: public $filePath = '';
825: 826: 827: 828: 829:
830: public $fileName = '';
831: 832: 833: 834:
835: public $fileBinaryContent = '';
836:
837: 838: 839: 840:
841: public $copies = 1;
842: 843: 844: 845:
846: public $encryptMetadata = null;
847:
848: 849: 850: 851:
852: public $deleteAfterPrinting = true;
853:
854: const PREFIX = 'wcpPF:';
855: const SEP = '|';
856:
857: 858: 859: 860: 861: 862:
863: public function __construct($filePath, $fileName, $fileBinaryContent) {
864: $this->filePath = $filePath;
865: $this->fileName = $fileName;
866: $this->fileBinaryContent = $fileBinaryContent;
867:
868: }
869:
870: public function serialize() {
871: $file = str_replace('\\', 'BACKSLASHCHAR',$this->fileName );
872: $pfc = '';
873: if($this->copies > 1){
874: $pfc = 'PFC='.$this->copies;
875: }
876: $df = 'DEL=F';
877: if($this->deleteAfterPrinting){
878: $df = '';
879: }
880:
881: $fn = $file;
882: $ext = '';
883: if (strrpos($fn, '.') > 0){
884: $fn = substr($fn, 0, strrpos($fn, '.'));
885: $ext = substr($file, strrpos($file, '.'));
886: }
887:
888: if(Utils::isNullOrEmptyString($this->fileExtension)){
889: $file = $fn.$pfc.$df.$ext;
890: } else {
891: $file = $fn.$pfc.$df.$this->fileExtension;
892: }
893:
894: $fileContent = $this->getFileContent();
895:
896: if($this->encryptMetadata != null &&
897: Utils::isNullOrEmptyString($this->encryptMetadata->publicKeyBase64) == false &&
898: $this->fileIsPasswordProtected == false){
899:
900:
901: $this->encryptMetadata->validateMetadata();
902:
903: $fileContent = SecUtils::aesEncrypt($fileContent,
904: $this->encryptMetadata->password,
905: $this->encryptMetadata->salt,
906: $this->encryptMetadata->iv,
907: $this->encryptMetadata->iterations);
908:
909: }
910:
911: return self::PREFIX.$file.self::SEP.$fileContent;
912: }
913:
914: public function getFileContent(){
915: if(!Utils::isNullOrEmptyString($this->filePath)){
916: $handle = fopen($this->filePath, 'rb');
917: $content = fread($handle, filesize($this->filePath));
918: fclose($handle);
919: } else {
920: $content = $this->fileBinaryContent;
921: }
922: return $content;
923: }
924:
925: }
926:
927: 928: 929:
930: class PrintRotation
931: {
932: 933: 934:
935: const None = 0;
936: 937: 938:
939: const Rot90 = 1;
940: 941: 942:
943: const Rot180 = 2;
944: 945: 946:
947: const Rot270 = 3;
948:
949: public static function parse($val){
950: if($val === 'None') return 0;
951: if($val === 'Rot90') return 1;
952: if($val === 'Rot180') return 2;
953: if($val === 'Rot270') return 3;
954: return 0;
955: }
956: }
957:
958: 959: 960:
961: class Sizing
962: {
963: 964: 965:
966: const None = 0;
967: 968: 969:
970: const Fit = 1;
971:
972: public static function parse($val){
973: if($val === 'None') return 0;
974: if($val === 'Fit') return 1;
975: return 0;
976: }
977: }
978:
979: 980: 981:
982: class PrintFilePDF extends PrintFile{
983:
984: 985: 986: 987:
988: public $printAsGrayscale = false;
989:
990: 991: 992: 993:
994: public $printAnnotations = false;
995:
996: 997: 998: 999:
1000: public $pagesRange = '';
1001:
1002: 1003: 1004: 1005:
1006: public $printInReverseOrder = false;
1007:
1008: 1009: 1010: 1011:
1012: public $printRotation = PrintRotation::None;
1013:
1014: 1015: 1016: 1017:
1018: public $password = '';
1019:
1020: 1021: 1022: 1023:
1024: public $duplexPrinting = false;
1025:
1026: 1027: 1028: 1029:
1030: public $duplexPrintingDialogMessage = '';
1031:
1032: 1033: 1034: 1035:
1036: public $autoRotate = false;
1037:
1038: 1039: 1040: 1041:
1042: public $autoCenter = false;
1043:
1044: 1045: 1046: 1047:
1048: public $sizing = Sizing::Fit;
1049:
1050:
1051: public function serialize() {
1052:
1053: $this->fileExtension = '.wpdf';
1054:
1055: return parent::serialize();
1056: }
1057:
1058: public function getFileContent(){
1059:
1060: $pr = urldecode($this->pagesRange);
1061: if (!Utils::isNullOrEmptyString($pr)){
1062: if (preg_match('/^(?!([ \d]*-){2})\d+(?: *[-,] *\d+)*$/', $pr))
1063: {
1064:
1065: $ranges = explode(',',str_replace(' ', '', $pr));
1066:
1067: for ($i = 0; $i < count($ranges); $i++)
1068: {
1069: if (strpos($ranges[$i], '-') > 0)
1070: {
1071: $pages = explode('-', $ranges[$i]);
1072: if (intval($pages[0]) > intval($pages[1]))
1073: {
1074: throw new Exception("The specified PageRange is not valid.");
1075: }
1076: }
1077: }
1078: }
1079: else{
1080: throw new Exception("The specified PageRange is not valid.");
1081: }
1082: }
1083:
1084: $metadata = ($this->printAsGrayscale ? '1' : '0');
1085: $metadata .= Utils::SER_SEP.($this->printAnnotations ? '1' : '0');
1086: $metadata .= Utils::SER_SEP.(Utils::isNullOrEmptyString($pr) ? 'A' : $pr);
1087: $metadata .= Utils::SER_SEP.($this->printInReverseOrder ? '1' : '0');
1088: $metadata .= Utils::SER_SEP.$this->printRotation;
1089: $metadata .= Utils::SER_SEP;
1090:
1091: $this->fileIsPasswordProtected = !Utils::isNullOrEmptyString($this->password);
1092:
1093: if ($this->fileIsPasswordProtected == false){
1094: $metadata .= 'N';
1095: } else {
1096: if (Utils::isNullOrEmptyString($this->encryptMetadata->publicKeyBase64) == false) {
1097: $metadata .= base64_encode(SecUtils::rsaVerifyAndEncrypt($this->encryptMetadata->publicKeyBase64, $this->encryptMetadata->publicKeySignatureBase64, $this->password));
1098: } else {
1099: $metadata .= base64_encode($this->password);
1100: }
1101: }
1102:
1103: $metadata .= Utils::SER_SEP.($this->duplexPrinting ? '1' : '0');
1104: $metadata .= Utils::SER_SEP.(Utils::isNullOrEmptyString($this->duplexPrintingDialogMessage) ? 'D' : base64_encode($this->duplexPrintingDialogMessage));
1105: $metadata .= Utils::SER_SEP.($this->autoRotate ? '1' : '0');
1106: $metadata .= Utils::SER_SEP.($this->autoCenter ? '1' : '0');
1107: $metadata .= Utils::SER_SEP.(strval(Sizing::parse($this->sizing)));
1108:
1109: $metadataLength = strlen($metadata);
1110: $metadata .= Utils::SER_SEP;
1111: $metadataLength++;
1112: $metadataLength += strlen(strval($metadataLength));
1113: $metadata .= strval($metadataLength);
1114:
1115: if(!Utils::isNullOrEmptyString($this->filePath)){
1116: $handle = fopen($this->filePath, 'rb');
1117: $content = fread($handle, filesize($this->filePath));
1118: fclose($handle);
1119: } else {
1120: $content = $this->fileBinaryContent;
1121: }
1122: return $content.$metadata;
1123: }
1124: }
1125:
1126: 1127: 1128:
1129: class PrintFileTIF extends PrintFile{
1130:
1131: 1132: 1133: 1134:
1135: public $printAsGrayscale = false;
1136:
1137: 1138: 1139: 1140:
1141: public $pagesRange = '';
1142:
1143: 1144: 1145: 1146:
1147: public $printInReverseOrder = false;
1148:
1149: 1150: 1151: 1152:
1153: public $printRotation = PrintRotation::None;
1154:
1155: 1156: 1157: 1158:
1159: public $duplexPrinting = false;
1160:
1161: 1162: 1163: 1164:
1165: public $duplexPrintingDialogMessage = '';
1166:
1167: 1168: 1169: 1170:
1171: public $autoRotate = false;
1172:
1173: 1174: 1175: 1176:
1177: public $autoCenter = false;
1178:
1179: 1180: 1181: 1182:
1183: public $sizing = Sizing::Fit;
1184:
1185:
1186: public function serialize() {
1187:
1188: $this->fileExtension = '.wtif';
1189:
1190: return parent::serialize();
1191: }
1192:
1193: public function getFileContent(){
1194:
1195: $pr = urldecode($this->pagesRange);
1196: if (!Utils::isNullOrEmptyString($pr)){
1197: if (preg_match('/^(?!([ \d]*-){2})\d+(?: *[-,] *\d+)*$/', $pr))
1198: {
1199:
1200: $ranges = explode(',',str_replace(' ', '', $pr));
1201:
1202: for ($i = 0; $i < count($ranges); $i++)
1203: {
1204: if (strpos($ranges[$i], '-') > 0)
1205: {
1206: $pages = explode('-', $ranges[$i]);
1207: if (intval($pages[0]) > intval($pages[1]))
1208: {
1209: throw new Exception("The specified PageRange is not valid.");
1210: }
1211: }
1212: }
1213: }
1214: else{
1215: throw new Exception("The specified PageRange is not valid.");
1216: }
1217: }
1218:
1219: $metadata = ($this->printAsGrayscale ? '1' : '0');
1220: $metadata .= Utils::SER_SEP.(Utils::isNullOrEmptyString($pr) ? 'A' : $pr);
1221: $metadata .= Utils::SER_SEP.($this->printInReverseOrder ? '1' : '0');
1222: $metadata .= Utils::SER_SEP.$this->printRotation;
1223: $metadata .= Utils::SER_SEP.($this->duplexPrinting ? '1' : '0');
1224: $metadata .= Utils::SER_SEP.(Utils::isNullOrEmptyString($this->duplexPrintingDialogMessage) ? 'D' : base64_encode($this->duplexPrintingDialogMessage));
1225: $metadata .= Utils::SER_SEP.($this->autoRotate ? '1' : '0');
1226: $metadata .= Utils::SER_SEP.($this->autoCenter ? '1' : '0');
1227: $metadata .= Utils::SER_SEP.(strval(Sizing::parse($this->sizing)));
1228:
1229: $metadataLength = strlen($metadata);
1230: $metadata .= Utils::SER_SEP;
1231: $metadataLength++;
1232: $metadataLength += strlen(strval($metadataLength));
1233: $metadata .= strval($metadataLength);
1234:
1235: if(!Utils::isNullOrEmptyString($this->filePath)){
1236: $handle = fopen($this->filePath, 'rb');
1237: $content = fread($handle, filesize($this->filePath));
1238: fclose($handle);
1239: } else {
1240: $content = $this->fileBinaryContent;
1241: }
1242: return $content.$metadata;
1243: }
1244: }
1245:
1246:
1247: 1248: 1249:
1250: class PrintOrientation
1251: {
1252: 1253: 1254:
1255: const Portrait = 0;
1256: 1257: 1258:
1259: const Landscape = 1;
1260:
1261: public static function parse($val){
1262: if($val === 'Portrait') return 0;
1263: if($val === 'Landscape') return 1;
1264: return 0;
1265: }
1266: }
1267:
1268: 1269: 1270:
1271: class TextAlignment
1272: {
1273: 1274: 1275:
1276: const Left = 0;
1277: 1278: 1279:
1280: const Right = 2;
1281: 1282: 1283:
1284: const Center = 1;
1285: 1286: 1287:
1288: const Justify = 3;
1289: 1290: 1291:
1292: const None = 4;
1293:
1294:
1295: public static function parse($val){
1296: if($val === 'Left') return 0;
1297: if($val === 'Center') return 1;
1298: if($val === 'Right') return 2;
1299: if($val === 'Justify') return 3;
1300: if($val === 'None') return 4;
1301: return 0;
1302: }
1303: }
1304:
1305: 1306: 1307:
1308: class PrintFileTXT extends PrintFile{
1309:
1310: 1311: 1312: 1313:
1314: public $textContent = '';
1315:
1316: 1317: 1318: 1319:
1320: public $textAlignment = TextAlignment::Left;
1321:
1322: 1323: 1324: 1325:
1326: public $fontName = 'Arial';
1327:
1328: 1329: 1330: 1331:
1332: public $fontBold = false;
1333:
1334: 1335: 1336: 1337:
1338: public $fontItalic = false;
1339:
1340: 1341: 1342: 1343:
1344: public $fontUnderline = false;
1345:
1346: 1347: 1348: 1349:
1350: public $fontStrikeThrough = false;
1351:
1352: 1353: 1354: 1355:
1356: public $fontSizeInPoints = 10.0;
1357:
1358: 1359: 1360: 1361:
1362: public $textColor = "#000000";
1363:
1364: 1365: 1366: 1367:
1368: public $printOrientation = PrintOrientation::Portrait;
1369:
1370: 1371: 1372: 1373:
1374: public $marginLeft = 0.5;
1375:
1376: 1377: 1378: 1379:
1380: public $marginRight = 0.5;
1381:
1382: 1383: 1384: 1385:
1386: public $marginTop = 0.5;
1387:
1388: 1389: 1390: 1391:
1392: public $marginBottom = 0.5;
1393:
1394:
1395: public function serialize() {
1396: $this->fileIsPasswordProtected = false;
1397:
1398: $this->fileExtension = '.wtxt';
1399:
1400: return parent::serialize();
1401: }
1402:
1403: public function getFileContent(){
1404:
1405: $metadata = $this->printOrientation;
1406: $metadata .= Utils::SER_SEP.$this->textAlignment;
1407: $metadata .= Utils::SER_SEP.$this->fontName;
1408: $metadata .= Utils::SER_SEP.strval($this->fontSizeInPoints);
1409: $metadata .= Utils::SER_SEP.($this->fontBold ? '1' : '0');
1410: $metadata .= Utils::SER_SEP.($this->fontItalic ? '1' : '0');
1411: $metadata .= Utils::SER_SEP.($this->fontUnderline ? '1' : '0');
1412: $metadata .= Utils::SER_SEP.($this->fontStrikeThrough ? '1' : '0');
1413: $metadata .= Utils::SER_SEP.$this->textColor;
1414: $metadata .= Utils::SER_SEP.strval($this->marginLeft);
1415: $metadata .= Utils::SER_SEP.strval($this->marginTop);
1416: $metadata .= Utils::SER_SEP.strval($this->marginRight);
1417: $metadata .= Utils::SER_SEP.strval($this->marginBottom);
1418:
1419: $content = $this->textContent;
1420: if (Utils::isNullOrEmptyString($content)){
1421: if(!Utils::isNullOrEmptyString($this->filePath)){
1422: $handle = fopen($this->filePath, 'rb');
1423: $content = fread($handle, filesize($this->filePath));
1424: fclose($handle);
1425: } else {
1426: $content = $this->fileBinaryContent;
1427: }
1428: }
1429:
1430: if (Utils::isNullOrEmptyString($content)){
1431: throw new Exception('The specified Text file is empty and cannot be printed.');
1432: }
1433:
1434: return $metadata.chr(10).$content;
1435: }
1436: }
1437:
1438:
1439: 1440: 1441:
1442: class PrintFileDOC extends PrintFile{
1443:
1444: 1445: 1446: 1447:
1448: public $pagesRange = '';
1449:
1450: 1451: 1452: 1453:
1454: public $printInReverseOrder = false;
1455:
1456: 1457: 1458: 1459:
1460: public $password = '';
1461:
1462: 1463: 1464: 1465:
1466: public $duplexPrinting = false;
1467:
1468: 1469: 1470: 1471:
1472: public $duplexPrintingDialogMessage = '';
1473:
1474:
1475: public function serialize() {
1476: $this->fileExtension = '.wdoc';
1477:
1478: return parent::serialize();
1479: }
1480:
1481: public function getFileContent(){
1482:
1483: $pr = urldecode($this->pagesRange);
1484: if (!Utils::isNullOrEmptyString($pr)){
1485: if (preg_match('/^(?!([ \d]*-){2})\d+(?: *[-,] *\d+)*$/', $pr))
1486: {
1487:
1488: $ranges = explode(',',str_replace(' ', '', $pr));
1489:
1490: for ($i = 0; $i < count($ranges); $i++)
1491: {
1492: if (strpos($ranges[$i], '-') > 0)
1493: {
1494: $pages = explode('-', $ranges[$i]);
1495: if (intval($pages[0]) > intval($pages[1]))
1496: {
1497: throw new Exception("The specified PageRange is not valid.");
1498: }
1499: }
1500: }
1501: }
1502: else
1503: throw new Exception("The specified PageRange is not valid.");
1504:
1505: }
1506:
1507: $metadata = (Utils::isNullOrEmptyString($pr) ? 'A' : $pr);
1508: $metadata .= Utils::SER_SEP.($this->printInReverseOrder ? '1' : '0');
1509: $metadata .= Utils::SER_SEP;
1510:
1511: $this->fileIsPasswordProtected = !Utils::isNullOrEmptyString($this->password);
1512:
1513: if ($this->fileIsPasswordProtected == false){
1514: $metadata .= 'N';
1515: } else {
1516: if (Utils::isNullOrEmptyString($this->encryptMetadata->publicKeyBase64) == false) {
1517: $metadata .= base64_encode(SecUtils::rsaVerifyAndEncrypt($this->encryptMetadata->publicKeyBase64, $this->encryptMetadata->publicKeySignatureBase64, $this->password));
1518: } else {
1519: $metadata .= base64_encode($this->password);
1520: }
1521: }
1522:
1523: $metadata .= Utils::SER_SEP.($this->duplexPrinting ? '1' : '0');
1524: $metadata .= Utils::SER_SEP.(Utils::isNullOrEmptyString($this->duplexPrintingDialogMessage) ? 'D' : base64_encode($this->duplexPrintingDialogMessage));
1525:
1526: $metadataLength = strlen($metadata);
1527: $metadata .= Utils::SER_SEP;
1528: $metadataLength++;
1529: $metadataLength += strlen(strval($metadataLength));
1530: $metadata .= strval($metadataLength);
1531:
1532:
1533: if(!Utils::isNullOrEmptyString($this->filePath)){
1534: $handle = fopen($this->filePath, 'rb');
1535: $content = fread($handle, filesize($this->filePath));
1536: fclose($handle);
1537: } else {
1538: $content = $this->fileBinaryContent;
1539: }
1540:
1541: return $content.$metadata;
1542: }
1543: }
1544:
1545:
1546: 1547: 1548:
1549: class PrintFileXLS extends PrintFile{
1550:
1551: 1552: 1553: 1554:
1555: public $pagesFrom = 0;
1556:
1557: 1558: 1559: 1560:
1561: public $pagesTo = 0;
1562:
1563:
1564: 1565: 1566: 1567:
1568: public $password = '';
1569:
1570: 1571: 1572: 1573:
1574: public $duplexPrinting = false;
1575:
1576: 1577: 1578: 1579:
1580: public $duplexPrintingDialogMessage = '';
1581:
1582:
1583: public function serialize() {
1584: $this->fileExtension = '.wxls';
1585:
1586: return parent::serialize();
1587: }
1588:
1589: public function getFileContent(){
1590:
1591: $metadata = strval($this->pagesFrom);
1592: $metadata .= Utils::SER_SEP.strval($this->pagesTo);
1593: $metadata .= Utils::SER_SEP;
1594:
1595: $this->fileIsPasswordProtected = !Utils::isNullOrEmptyString($this->password);
1596:
1597: if ($this->fileIsPasswordProtected == false){
1598: $metadata .= 'N';
1599: } else {
1600: if (Utils::isNullOrEmptyString($this->encryptMetadata->publicKeyBase64) == false) {
1601: $metadata .= base64_encode(SecUtils::rsaVerifyAndEncrypt($this->encryptMetadata->publicKeyBase64, $this->encryptMetadata->publicKeySignatureBase64, $this->password));
1602: } else {
1603: $metadata .= base64_encode($this->password);
1604: }
1605: }
1606:
1607: $metadata .= Utils::SER_SEP.($this->duplexPrinting ? '1' : '0');
1608: $metadata .= Utils::SER_SEP.(Utils::isNullOrEmptyString($this->duplexPrintingDialogMessage) ? 'D' : base64_encode($this->duplexPrintingDialogMessage));
1609:
1610: $metadataLength = strlen($metadata);
1611: $metadata .= Utils::SER_SEP;
1612: $metadataLength++;
1613: $metadataLength += strlen(strval($metadataLength));
1614: $metadata .= strval($metadataLength);
1615:
1616: if(!Utils::isNullOrEmptyString($this->filePath)){
1617: $handle = fopen($this->filePath, 'rb');
1618: $content = fread($handle, filesize($this->filePath));
1619: fclose($handle);
1620: } else {
1621: $content = $this->fileBinaryContent;
1622: }
1623:
1624: return $content.$metadata;
1625: }
1626: }
1627:
1628: 1629: 1630:
1631: class SecUtils{
1632:
1633: private static function getPubKey(){
1634: return '<RSAKeyValue><Modulus>reXqa092+txbh684R9kUsMMIG2UTEJQChhFkZ3u/kg1OsPAspaWnjRgecq1lTKIbppPXa4NztFNPw5c7W6sN+3GiuRAbOT6E+ynQIyo298znCoeW+W93WZ8imF32HwWn9lUvI6VFJULwjZ16G91ok/YPTuREc8ri7jclC3ie8g0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>';
1635: }
1636:
1637: public static function rsaVerifyAndEncrypt($pubKeyBase64, $pubKeySignatureBase64, $dataToEncrypt){
1638: $rsa = new \phpseclib\Crypt\RSA();
1639: $rsa->loadKey(self::getPubKey());
1640: $rsa->setSignatureMode(2);
1641: if ($rsa->verify(base64_decode($pubKeyBase64), base64_decode($pubKeySignatureBase64))) {
1642: $rsa->loadKey(base64_decode($pubKeyBase64));
1643: $rsa->setEncryptionMode(2);
1644: return $rsa->encrypt($dataToEncrypt);
1645: }
1646: else{
1647: throw new Exception('Cannot verify the provided RSA Public Key.');
1648: }
1649: }
1650:
1651: public static function aesEncrypt($dataToEncrypt, $password, $salt, $iv, $iterations){
1652: $aes = new \phpseclib\Crypt\AES(\phpseclib\Crypt\AES::MODE_CBC);
1653: $aes->setPassword($password,
1654: 'pbkdf2' ,
1655: 'sha1' ,
1656: $salt,
1657: $iterations,
1658: 256 / 8
1659: );
1660: $aes->setIV($iv);
1661: return $aes->encrypt($dataToEncrypt);
1662: }
1663:
1664: }
1665:
1666: 1667: 1668:
1669: class Utils{
1670: const SER_SEP = '|';
1671:
1672: static function isNullOrEmptyString($s){
1673: return (!isset($s) || trim($s)==='');
1674: }
1675:
1676: static function formatHexValues($s){
1677:
1678: $buffer = '';
1679:
1680: $l = strlen($s);
1681: $i = 0;
1682:
1683: while ($i < $l)
1684: {
1685: if ($s[$i] == '0')
1686: {
1687: if ($i + 1 < $l && ($s[$i] == '0' && $s[$i + 1] == 'x'))
1688: {
1689: if ($i + 2 < $l &&
1690: (($s[$i + 2] >= '0' && $s[$i + 2] <= '9') || ($s[$i + 2] >= 'a' && $s[$i + 2] <= 'f') || ($s[$i + 2] >= 'A' && $s[$i + 2] <= 'F')))
1691: {
1692: if ($i + 3 < $l &&
1693: (($s[$i + 3] >= '0' && $s[$i + 3] <= '9') || ($s[$i + 3] >= 'a' && $s[$i + 3] <= 'f') || ($s[$i + 3] >= 'A' && $s[$i + 3] <= 'F')))
1694: {
1695: try{
1696: $buffer .= chr(intval(substr($s, $i, 4),16));
1697: $i += 4;
1698: continue;
1699:
1700: } catch (Exception $ex) {
1701: throw new Exception("Invalid hex notation in the specified printer commands at index: ".$i);
1702: }
1703:
1704:
1705: }
1706: else
1707: {
1708: try{
1709:
1710: $buffer .= chr(intval(substr($s, $i, 3),16));
1711: $i += 3;
1712: continue;
1713:
1714: } catch (Exception $ex) {
1715: throw new ArgumentException("Invalid hex notation in the specified printer commands at index: ".$i);
1716: }
1717: }
1718: }
1719: }
1720: }
1721:
1722: $buffer .= substr($s, $i, 1);
1723:
1724: $i++;
1725: }
1726:
1727: return $buffer;
1728:
1729: }
1730:
1731: public static function intToArray($i){
1732: return pack('C4',
1733: ($i >> 0) & 0xFF,
1734: ($i >> 8) & 0xFF,
1735: ($i >> 16) & 0xFF,
1736: ($i >> 24) & 0xFF
1737: );
1738: }
1739:
1740: public static function strleft($s1, $s2) {
1741: return substr($s1, 0, strpos($s1, $s2));
1742: }
1743:
1744: public static function strContains($s1, $s2){
1745: return (strpos($s1, $s2) !== false);
1746: }
1747:
1748: public static function strEndsWith($s1, $s2)
1749: {
1750: return substr($s1, -strlen($s2)) === $s2;
1751: }
1752:
1753: public static function strStartsWith($s1, $s2)
1754: {
1755: return substr($s1, 0, strlen($s2)) === $s2;
1756: }
1757:
1758: public static function genRandomString($asciiCharStart = 33, $asciiCharEnd = 126, $charsCount = 32) {
1759:
1760: $allowed_chars = '';
1761: for($i = $asciiCharStart; $i <= $asciiCharEnd; $i++) {
1762: $allowed_chars .= chr($i);
1763: }
1764:
1765: $len = strlen($allowed_chars);
1766: $random_string = '';
1767: for($i = 0; $i < $charsCount; $i++) {
1768: $random_string .= $allowed_chars[mt_rand(0, $len - 1)];
1769: }
1770:
1771: return $random_string;
1772: }
1773:
1774: public static function getLicense()
1775: {
1776: $lo = WebClientPrint::$licenseOwner;
1777: $lk = WebClientPrint::$licenseKey;
1778:
1779: $uid = substr(uniqid(), 0, 8);
1780:
1781: $buffer = 'php>';
1782:
1783: if (Utils::isNullOrEmptyString($lo)){
1784: $buffer .= substr(uniqid(), 0, 8);
1785: } else {
1786: $buffer .= $lo;
1787: }
1788:
1789: $buffer .= chr(124);
1790:
1791: $license_hash = '';
1792:
1793: if (Utils::isNullOrEmptyString($lk)){
1794: $license_hash = substr(uniqid(), 0, 8);
1795: } else {
1796: $license_hash = hash('sha256', $lk . $uid, false);
1797: }
1798:
1799: $buffer .= $license_hash;
1800: $buffer .= chr(124);
1801: $buffer .= $uid;
1802:
1803: return $buffer;
1804: }
1805: }
1806:
1807: 1808: 1809:
1810: class ClientPrintJob{
1811:
1812: 1813: 1814: 1815: 1816: 1817: 1818: 1819: 1820: 1821:
1822: public $clientPrinter = null;
1823: 1824: 1825: 1826:
1827: public $printerCommands = '';
1828: 1829: 1830: 1831: 1832: 1833: 1834:
1835: public $printerCommandsCopies = 1;
1836: 1837: 1838: 1839: 1840: 1841: 1842: 1843: 1844:
1845: public $formatHexValues = false;
1846: 1847: 1848: 1849:
1850: public $printFile = null;
1851: 1852: 1853: 1854:
1855: public $printFileGroup = null;
1856:
1857:
1858: 1859: 1860: 1861: 1862:
1863: public function sendToClient(){
1864:
1865: $cpjHeader = chr(99).chr(112).chr(106).chr(2);
1866:
1867: $buffer = '';
1868:
1869: if (!Utils::isNullOrEmptyString($this->printerCommands)){
1870: if ($this->printerCommandsCopies > 1){
1871: $buffer .= 'PCC='.$this->printerCommandsCopies.Utils::SER_SEP;
1872: }
1873: if($this->formatHexValues){
1874: $buffer .= Utils::formatHexValues ($this->printerCommands);
1875: } else {
1876: $buffer .= $this->printerCommands;
1877: }
1878: } else if (isset ($this->printFile)){
1879: $buffer = $this->printFile->serialize();
1880: } else if (isset ($this->printFileGroup)){
1881: $buffer = 'wcpPFG:';
1882: $zip = new ZipArchive;
1883: $cacheFileName = (Utils::strEndsWith(WebClientPrint::$wcpCacheFolder, '/')?WebClientPrint::$wcpCacheFolder:WebClientPrint::$wcpCacheFolder.'/').'PFG'.uniqid().'.zip';
1884: $res = $zip->open($cacheFileName, ZipArchive::CREATE);
1885: if ($res === TRUE) {
1886: foreach ($this->printFileGroup as $printFile) {
1887: $file = $printFile->fileName;
1888: if($printFile->copies > 1){
1889: $pfc = 'PFC='.$printFile->copies;
1890: $file = substr($file, 0, strrpos($file, '.')).$pfc.substr($file, strrpos($file, '.'));
1891: }
1892: if(is_a($printFile, 'PrintFilePDF')) $file .= '.wpdf';
1893: if(is_a($printFile, 'PrintFileTXT')) $file .= '.wtxt';
1894: if(is_a($printFile, 'PrintFileDOC')) $file .= '.wdoc';
1895: if(is_a($printFile, 'PrintFileXLS')) $file .= '.wxls';
1896: if(is_a($printFile, 'PrintFileTIF')) $file .= '.wtif';
1897:
1898: $zip->addFromString($file, $printFile->getFileContent());
1899: }
1900: $zip->close();
1901: $handle = fopen($cacheFileName, 'rb');
1902: $buffer .= fread($handle, filesize($cacheFileName));
1903: fclose($handle);
1904: unlink($cacheFileName);
1905: } else {
1906: $buffer='Creating PrintFileGroup failed. Cannot create zip file.';
1907: }
1908: }
1909:
1910: $arrIdx1 = Utils::intToArray(strlen($buffer));
1911:
1912: if (!isset($this->clientPrinter)){
1913: $this->clientPrinter = new UserSelectedPrinter();
1914: }
1915:
1916: $buffer .= $this->clientPrinter->serialize();
1917:
1918: $arrIdx2 = Utils::intToArray(strlen($buffer));
1919:
1920: $buffer .= Utils::getLicense();
1921:
1922: return $cpjHeader.$arrIdx1.$arrIdx2.$buffer;
1923: }
1924:
1925: }
1926:
1927: 1928: 1929:
1930: class ClientPrintJobGroup{
1931:
1932: 1933: 1934: 1935:
1936: public $clientPrintJobGroup = null;
1937:
1938: 1939: 1940: 1941: 1942:
1943: public function sendToClient(){
1944:
1945: if (isset ($this->clientPrintJobGroup)){
1946: $groups = count($this->clientPrintJobGroup);
1947:
1948: $dataPartIndexes = Utils::intToArray($groups);
1949:
1950: $cpjgHeader = chr(99).chr(112).chr(106).chr(103).chr(2);
1951:
1952: $buffer = '';
1953:
1954: $cpjBytesCount = 0;
1955:
1956: foreach ($this->clientPrintJobGroup as $cpj) {
1957: $cpjBuffer = '';
1958:
1959: if (!Utils::isNullOrEmptyString($cpj->printerCommands)){
1960: if ($cpj->printerCommandsCopies > 1){
1961: $cpjBuffer .= 'PCC='.$cpj->printerCommandsCopies.Utils::SER_SEP;
1962: }
1963: if($cpj->formatHexValues){
1964: $cpjBuffer .= Utils::formatHexValues ($cpj->printerCommands);
1965: } else {
1966: $cpjBuffer .= $cpj->printerCommands;
1967: }
1968: } else if (isset ($cpj->printFile)){
1969: $cpjBuffer = $cpj->printFile->serialize();
1970: } else if (isset ($cpj->printFileGroup)){
1971: $cpjBuffer = 'wcpPFG:';
1972: $zip = new ZipArchive;
1973: $cacheFileName = (Utils::strEndsWith(WebClientPrint::$wcpCacheFolder, '/')?WebClientPrint::$wcpCacheFolder:WebClientPrint::$wcpCacheFolder.'/').'PFG'.uniqid().'.zip';
1974: $res = $zip->open($cacheFileName, ZipArchive::CREATE);
1975: if ($res === TRUE) {
1976: foreach ($cpj->printFileGroup as $printFile) {
1977: $file = $printFile->fileName;
1978: if($printFile->copies > 1){
1979: $pfc = 'PFC='.$printFile->copies;
1980: $file = substr($file, 0, strrpos($file, '.')).$pfc.substr($file, strrpos($file, '.'));
1981: }
1982: if(is_a($printFile, 'PrintFilePDF')) $file .= '.wpdf';
1983: if(is_a($printFile, 'PrintFileTXT')) $file .= '.wtxt';
1984: if(is_a($printFile, 'PrintFileDOC')) $file .= '.wdoc';
1985: if(is_a($printFile, 'PrintFileXLS')) $file .= '.wxls';
1986: if(is_a($printFile, 'PrintFileTIF')) $file .= '.wtif';
1987:
1988: $zip->addFromString($file, $printFile->getFileContent());
1989: }
1990: $zip->close();
1991: $handle = fopen($cacheFileName, 'rb');
1992: $cpjBuffer .= fread($handle, filesize($cacheFileName));
1993: fclose($handle);
1994: unlink($cacheFileName);
1995: } else {
1996: $cpjBuffer='Creating PrintFileGroup failed. Cannot create zip file.';
1997: }
1998: }
1999:
2000: $arrIdx1 = Utils::intToArray(strlen($cpjBuffer));
2001:
2002: if (!isset($cpj->clientPrinter)){
2003: $cpj->clientPrinter = new UserSelectedPrinter();
2004: }
2005:
2006: $cpjBuffer .= $cpj->clientPrinter->serialize();
2007:
2008: $cpjBytesCount += strlen($arrIdx1.$cpjBuffer);
2009:
2010: $dataPartIndexes .= Utils::intToArray($cpjBytesCount);
2011:
2012: $buffer .= $arrIdx1.$cpjBuffer;
2013: }
2014:
2015:
2016: $buffer .= Utils::getLicense();
2017:
2018: return $cpjgHeader.$dataPartIndexes.$buffer;
2019:
2020:
2021: } else {
2022:
2023: return NULL;
2024: }
2025:
2026:
2027: }
2028: }