Merge branch 'bug-1177' into bug-1137
[cacert-devel.git] / www / capnew.php
1 <?php
2 /*
3 LibreSSL - CAcert web application
4 Copyright (C) 2004-2008 CAcert Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; version 2 of the License.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 // $Id: capnew.php,v 1.4 2012-01-24 14:26:05 root Exp $
21 define('REV', '$Revision: 1.4 $');
22
23 /*
24 ** Created from old cap.php 2003, which used the now obsoleted ftpdf package
25 ** First created: 12 July 2008
26 ** Last change: see Revision date
27 ** Reviews:
28 ** printed text by Ian Grigg and Teus Hagen (July 2008)
29 ** layout/design by Teus Hagen and Johan Vromans (July 2008)
30 ** coding by Teus Hagen and ...
31 **
32 ** Installation:
33 ** std PHP lib:
34 ** recode_string(), zcompress() (PHP-ZLIB) only used if present
35 ** zcompress (pdf compression) gives performance loss, disable it?
36 ** PDF generation package (tcpdf/tcpdf.php):
37 ** TCPDF package + define the TCPDF_DIR install directory (GPL)
38 ** tcpdf package is patched for text subtypes see tcpdf diff file.
39 ** Add free embedding zapfdingbat font
40 ** ttf2pt1 -F zapfdinbats.ttf -> zapfdingbats.utf metrics file
41 ** php -q makefont.php zapfsdingbats.ttf zapfdingbats.utf -> .php,.ctg.z,.z
42 ** install files: zapfdingbats.{php,z,ctg.z} in tcpdf/fonts dir
43 ** UTF8 package for unicode (utf8/native/core.php):
44 ** utf8_substr() only when package is found and needs to be used
45 ** transliteration (and abbreviation):
46 ** if full name has non-ascii char(s) try to use: utf8_to_ascii()
47 ** First from transtab.php package which is Markus Kuhn compliant
48 ** transtab.php is CAcert php package.
49 ** Transtab depends on on its turn on UTF8 package.
50 ** Secondly if not found utf8ascii lib tried (artistic license)
51 ** http://sourceforge.net/projects/phputf8
52 ** .../utf8_to_ascii-0.3.tar.gz
53 ** see UTF8_ASCII definition for location requirements
54 ** Thirdly: if not found transliteration feature is disabled.
55 **
56 ** policy documents for pdf inclusion:
57 ** define CCA file (default policy)
58 ** LOGO: CAcert logo logos directory is LOGO
59 **
60 ** Functionality:
61 ** Test: use environment variable settings as parameters for
62 ** Assuree: names, dob, sign date, id types, email
63 ** if name gets too long font size is increased to get it on one line
64 ** Assurer: name, email, dob (mutual ass), sign date
65 ** Assurance: location, date of assurance
66 ** Form fields: javascript form fields with fields for printout and change
67 ** Printout: printed, and completed for final signatures
68 ** On transliteration and abbreviation of a name:
69 ** if shoes a std way show accepted conversion as pdf comment
70 ** Orientation: on landscape (dflt) print 2-up
71 ** PDF URL links are used to web, wiki, and faq for more info search
72 ** Only on non-ascii chars in a name the utf8 routines are loaded
73 ** PDF reader has wiki info url's and easy email feedback
74 ** ENABLED:
75 ** included is the CCA generates 2 extra pages (needs work to limit vert spacing)
76 **
77 ** For other re-use of some routines:
78 ** abbreviate() abbreviate a name on std way
79 ** transliterate() provide name in translated format in std way
80 **
81 ** For tests:
82 ** environment settings (FORM, FORMAT, CCA, ...) define used test data
83 ** In test modus variable path_url from tcpdf package unset warnings
84 ** Set for operation modus TEST on false (or comment code out)
85 **
86 ** Future:
87 ** digitally sign form and process it via network
88 **
89 ** unicode and UTF-8 support:
90 ** php4/5 recode() is alias of recode_string() of PHP library
91 ** If not provided: should check every string is transcoded?
92 ** recode(), recode_string(0 is said to have too many (japanese) defeats
93 ** recode_string() is only used on GET[] input (html->utf-8),
94 ** UTF-8 use routines from http://www.sourceforge.net/projects/phputf8
95 ** which replaces php recode() package.
96 ** on many places own utf-8 handling code exists and is loaded (tcpdf problem)
97 ** _() translation routine. The returned HTML string is translated to utf-8 string.
98 ** the GET() routines expects utf-8 code (see test defs) but might be changed
99 ** to use html entity conversion routine of PHP (5.2 has a problem...).
100 **
101 ** PDF compression zlib: (now disabled)
102 ** if PHP lib zcompress() is present, generated PDF is compressed
103 **
104 ** FONTS future use ? http://www.slovo.info/unifonts.htm? (not used now)
105 ** or Bitstream Cyberbit http://www.orwell.ru/download/cyberbit.zip
106 ** Latter font is no longer for free download
107 ** For now: FreeVeraSans is used now and embedded (std in TCPDF package)
108 ** ZapfDingbat font: some Open Source readers have bad font handling or
109 ** no zapfdingbat font. So one is embedded
110 ** To be generated with tooling in util directory.
111 **
112 ** TO DO, to CHECK and KNOWN PROBLEMS:
113 ** Japanse package (maybe not needed with TCPDF?)
114 ** CCA informal should be on one page (no CCA printed yet)
115 ** form field checks, print button (Java script)
116 ** data structs in Java script and globalize property settings
117 ** XML
118 ** timestamping, signatures and certificate usage
119 ** list of recipients, encrypt the document and send it off
120 ** On Acrobat 7.0: first form field call error (have work around)
121 ** eps problem with logo (no eps logo yet)
122 ** multi selection of ID types in form fields (value editable now)
123 ** ugly capital char use in intro to bold or italic lowercase
124 ** tables over page boundaries do not fully work yet
125 **
126 ** DEPENDENCIES:
127 ** This PDF GENERATION package relies on the PHP PDF generation
128 ** package of TCPDF source force project:
129 ** http://sourceforge.net/projects/tcpdf/ V 4.0.007 18th July 2008
130 ** The tcpdf software supports encryption, signatures, and form fields
131 ** TCPDF is using URF-8 code (good!)
132 ** The TRANSLITERATE code tables db (utf8ascii) is not compliant (!?) with
133 ** Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> -- 2001-09-02
134 ** First is tried to use Markus his tables
135 ** For a test file with all chars see there (it is also in tcpdf package).
136 ** Both transliteration packages rely on UTF-8 code, only loaded when available and
137 ** when really needed.
138 ** PDF generation: The alternative is the one from the std PHP library.
139 **
140 ** SECURITY:
141 ** PHP libs: packages seems to download files on the fly into local filesystem!!!
142 **
143 ** All sizes (in mm) is related to A5 base, so other page formats are scaled.
144 **
145 ** Parameters (API):
146 ** $_GET['date'] date of assurance and signature assuree
147 ** $_GET['name'] first full name assuree default empty for upward compatibility
148 ** $_GET['name1'] first full name assuree default empty equal to 'name' (new)
149 ** $_GET['name<%d>'] etc. %d = 1-9 (new)
150 ** $_GET['name1ID'] ID of first name (new)
151 ** $_GET['name<%d>ID'] ID of second name (new)
152 ** $_GET['name1Pnts'] assurance points for first name (new)
153 ** $_GET['name<%d>Pnts'] assurance points for second name (new)
154 ** $_GET['dob'] date of birth assuree default empty
155 ** $_GET['document1'] ID type assuree default empty (deprecated)
156 ** $_GET['document2'] second ID type assuree default empty (deprecated)
157 ** $_GET['email'] email address assuree default empty
158 ** $_GET['assurer'] full name assurer default empty
159 ** $_GET['assurerdob'] date of birth assurer default empty (new)
160 ** $_GET['assureremail'] email address assurer default empty (new)
161 ** $_GET['assurerdate'] date of signature assurer (new)
162 ** $_GET['assurancedate'] date of assurance (new)
163 ** $_GET['location'] location of assurance
164 ** $_GET['maxpoints'] max points allocated depends on assurer default 35
165 ** $_GET['nocca'] do not print CCA on back side (dflt: false)
166 ** $_GET['policy<%d>'] to include policy document(s) in pdf file %d = 1-9 (new)
167 ** $_GET['noform'] do not print form (dflt: true) (new)
168 ** $_GET['format'] paper format required A0-A6,Letter, Folio, B0-B6 (dflt A4)
169 ** $_GET['watermark'] watermark on the page
170 ** $_GET['orientation'] paper orientation default 'portrait'
171 ** $_SESSION['_config']['language'] for 'ja' japanese default != ja
172 ** $_SESSION['_config']['recode'] = 'format' recode() uses it: needed ?
173 ** recode() is aliased to php lib function recode_string()
174 ** $_REQUEST['bw'] if exists use black/white, default use colour
175 **
176 ** Output, package generates:
177 ** PDF display screen is scaled to 150% A5 size
178 ** PDF property fields have CAcert info
179 ** on non empty _GET strings, the package generates prefilled form fields.
180 ** PDF form field variables (Java Script):
181 ** Assuree
182 ** Assuree.Names[].Name 1..9
183 ** Assuree.Names[].TypeID 1..9 language dependant (passport, ID card, etc.)
184 ** Assuree.Names[].Points 1..9 points:empty, 0..max points (dflt max 35)
185 ** Assuree.Email
186 ** Assuree.DoB
187 ** Assuree.Date date of signature
188 ** Assurer
189 ** Assurer.Name string may have Assurer email address
190 ** Assurer.Email
191 ** Assurer.DoB
192 ** Assurer.Date date of signature
193 ** Assurance
194 ** Assurance.Location string may have date of meeting
195 ** Assurance.Date date of assurance
196 ** Form Revision string is generated from RCS revision string.
197 ** More info on PDF fields:
198 ** http://www.adobe.com/devnet/acrobat/pdfs/js_developer_guide.pdf
199 **
200 */
201
202 // use next define if you test this code
203 define( 'TEST', true );
204 // INSTALLATION DIRS OF PACKAGES ==============================
205 // make sure packages are installed here
206 define('RT','./');
207 define('TCPDF_DIR', '/usr/share/tcpdf_php4');
208 define('UTF8',RT.'/utf8/native/core.php');
209 if( file_exists(RT.'/transtab.php') ) // wherever it is
210 define('UTF8_ASCII', RT.'/transtab.php');
211 else
212 define('UTF8_ASCII', RT.'/utf8_to_ascii/utf8_to_ascii.php'); // optional
213 // end operational special code defs
214
215 if( defined( 'TEST' ) ) {
216 // ONLY FOR TEST PURPOSES =====================================
217 /* test data */
218
219 $_SESSION['_config']['recode'] = 'html..utf-8'; // ????
220 if( isset($_SERVER['LANG']) )
221 $_SESSION['_config']['language'] = $_SERVER['LANG'];
222
223 if( array_key_exists('FORMAT',$_SERVER) AND $_SERVER['FORMAT'] )
224 $_GET['format'] = $_SERVER['FORMAT'];
225 else {
226 //$_GET['format'] = 'A5'; // ok, default
227 //$_GET['format'] = 'Legal'; // ok
228 //$_GET['format'] = 'Folio'; // ok
229 //$_GET['format'] = 'Letter'; // letter little margin problem
230 //$_GET['format'] = 'A4'; // ok
231 }
232 if( array_key_exists('ORIENTATION',$_SERVER) AND $_SERVER['ORIENTATION'] )
233 $_GET['orientation'] = $_SERVER['ORIENTATION'];
234 else {
235 //$_GET['orientation'] = 'portrait'; // default 2 pages, or portrait
236 }
237 $_GET['nocca'] = isset($_SERVER['CCA']) ? $_SERVER['CCA'] : '';
238 //$_GET['policy1'] = 'policy/PolicyOnPolicy.php';
239 if( isset($_SERVER['FORM']) AND $_SERVER['FORM'] == 'noform' )
240 $_GET['noform'] = 'true';
241
242 if( array_key_exists('FORM',$_SERVER) AND $_SERVER['FORM'] != 'empty' ){
243 // assuree info part
244 $_GET['date'] = '2008-11-04';
245 $_GET['name'] = 'drs. T. Fabrice Ghuege-Denis'; // upwards competable
246 $_GET['name1'] = $_GET['name']; // will void 'name'
247 $_GET['name1ID'] = 'rijbewijs';
248 //$_GET['name1Pnts'] = '';
249 $_GET['name2'] = 'drs. Teus F. Ghuege-Denis'; // second name
250 //$_GET['name2ID'] = '';
251 $_GET['name2Pnts'] = '10'; // seems not to work properly yet
252 $_GET['name3'] = 'Tänўs Iʼntèrnątiœñalîsàtïǿn Ĝügé'; // third, show of javascript error
253 $_GET['name3ID'] = 'paspoort';
254 $_GET['name3Pnts'] = '12';
255 $_GET['name8'] = 'This Should Be invisible';
256 $_GET['dob'] = '1945-10-06';
257 $_GET['document1'] = 'führerschein';
258 $_GET['document2'] = 'paspoort';
259 $_GET['email'] = 'tesu.hagaen@thesu.xs4all.eu';
260 // assurer info
261 $_GET['assurer'] = 'mr A. B. C. Äßurer';// one name only
262 $_GET['assurerdob'] = '2010-12-32'; // for mutual assurance
263 $_GET['assureremail'] = 'assurer.email@cacert.org'; // for mutual assurance
264 // meeting info
265 $_GET['location'] = 'Grubbenvorst, the Carabiën';
266 $_GET['assurerdate'] = '';
267 $_GET['assurancedate'] = '2008-12-31';
268 $_GET['maxpoints'] = '20';
269 $_GET['watermark'] = 'just an EXAMPLE';
270 } else {
271 //$_GET['ALL'] = 'empty';
272 }
273
274 //$_REQUEST[bw] = true;
275
276 } // end of TEST code ===========================================================
277
278 /* Directory settings for installation */
279 // change next for directory settings for packages !!!!!!!!!!!!!!!!!!!!!!
280 // set to correct internal path to TCPDF pakage installation
281 // Make sure pdf generation package is not connecting internet for
282 // whatever reason and downloading files into this host!!!!
283 // UCPDF as well PHP PDF std package have unsecure code as well....
284 require_once(TCPDF_DIR . '/config/lang/eng.php');
285 require_once(TCPDF_DIR . '/tcpdf.php');
286
287 // CAcert logo path/file name is extended with eg color, mono and format type
288 define( 'LOGO','logos/CAcert-logo-');
289 // eps should give better quality, LOGO_TYPE -> .eps
290 // eps does not work with CAcert logo, set to .eps when ok
291 define( 'LOGO_DPI', '1000');
292 define( 'LOGO_TYPE','-'.LOGO_DPI.'.png');
293 // logo colors RGB hex
294 define('BLUE', '#11568C'); // RGB 17 86 140
295 define('LBLUE', '#ADC5D7'); // RGB 112 154 186
296 define('LLBLUE','#D6E2EB'); // lighhter blue RGB 173 197 215
297 define('LIME', '#C7FF00'); // RGB 199 255 0
298 define('GREEN', '#00BE00'); // 0 190 0
299
300 define('POBOX','CAcert Inc. - P.O. Box 4107 - Denistone East NSW 2112 - Australia');
301 define('WEB', 'http://www.cacert.org');
302 define('WIKI','http://wiki.cacert.org/wiki');
303 define('ROOTKEYS','http://www.cacert.org/index.php?id=3');
304 define('ASSCAP', WIKI.'/FAQ/AssuranceByCAP');
305 define('ASSHBK', WIKI.'/AssuranceHandbook');
306 define('ASSINFO', WIKI.'/FAQ/AssuranceInformationForCAP');
307 define('ASSINTRO', WIKI.'/FAQ/AssuranceIntroduction');
308 define('ASSORG', WIKI.'/OrganisationAssurance');
309 define('ARBIT', WIKI.'/ArbitrationForum');
310 // CAcert Community Agreement
311 define('CCA', 'CAcertCommunityAgreement'); // default policy to print
312 define('POLICY','policy/'); // default polciy doc directory
313 define('EXT','.php'); // default polciy doc extention, should be html
314 /* finger print CAcert Root Key */ // should obtain this automatically
315 define('CLASS1_SHA1','135C EC36 F49C B8E9 3B1A B270 CD80 8846 76CE 8F33');
316 define('CLASS3_SHA1','AD7C 3F64 FC44 39FE F4E9 0BE8 F47C 6CFA 8AAD FDCE');
317 // next two are not used on the form
318 define('CLASS1_MD5','A6:1B:37:5E:39:0D:9C:36:54:EE:BD:20:31:46:1F:6B');
319 define('CLASS3_MD5','F7:25:12:82:4E:67:B5:D0:8D:92:B7:7C:0B:86:7A:42');
320 // if on draft provide std message
321 define('WATERMARK','');
322
323 // other definitions for the form
324 define('MAX_COLS', 2); // max coulumns per page Landscape is printed with 2-up
325 // put next to 200 and it will disable printout
326 define('MINH', 98.5); // in A5 mm is current estimated left over space on one page
327 define('H', 5); // height of a name entry field
328 //set margins
329 define('MARGIN',11.296); // 2-up will be scaled
330 // base of font size
331 define( 'F_SIZE', 7 );
332
333 define('DFL_FORMAT', 'html..utf-8');
334
335 // enviroment dependent constants
336 // Japanese is not supported?
337 if( array_key_exists('_config', $_SESSION) ) {
338 if( isset($_SESSION['_config']['language']) ) {
339 if($_SESSION['_config']['language'] == 'ja')
340 define('FONT','SJIS');
341 else define( 'FONT', 'freesans');
342 }
343 else define( 'FONT', 'freesans');
344 }
345 else
346 //define( 'FONT', 'dejavusans');
347 define( 'FONT', 'freesans');
348
349 // generate black/white?
350 if(array_key_exists('bw',$_REQUEST))
351 define('BW', true);
352 else
353 define('BW', false);
354
355 // function is left in tact, but to new tcpdf code UFT-8 is fully supported now.
356 function my_recode($strg = NULL )
357 {
358 static $format = NULL;
359 if( $strg == NULL OR !$strg ) return ( '' );
360 if( $format == NULL ) {
361 if( array_key_exists('_config', $_SESSION) ) {
362 if( isset( $_SESSION['_config']['recode']) )
363 $format = $_SESSION['_config']['recode'];
364 else $format = DFL_FORMAT;
365 }
366 else $format = DFL_FORMAT;
367 }
368 // newer tcpdf package is full UTF-8 Voided by this package?
369 if( function_exists('recode_string' ) )
370 return ( recode_string($format, $strg) );
371 else return( $strg );
372 }
373
374 // return TRUE if string is ascii and not device control chars specialized for
375 // personal names (no device controls)
376 function utf8_is_ascii_ctrl($str) {
377 if ( strlen($str) > 0 ) {
378 // Search for any bytes which are outside the ASCII range,
379 // or are device control codes
380 //return (preg_match('/[^\x09\x0A\x0D\x20-\x7E]/',$str) !== 1); deleted \r and \n
381 return (preg_match('/[^\x09\x20-\x7E]/',$str) !== 1);
382 }
383 return FALSE;
384 }
385
386
387 // extend TCPF with custom functions
388 class CAPPDF extends TCPDF {
389
390 // do cap form version numbering automatically '$Revision: 1.4 $'
391 /*public*/ function Version() {
392 strtok(REV, ' ');
393 return(strtok(' '));
394 }
395
396 /*public*/ function myHeader( $msg = NULL, $url = NULL )
397 {
398 static $my_url = NULL;
399 if( $msg != NULL ) {
400 $this->my_header_msg = $msg; $my_url = $url; return;
401 }
402 if( $this->my_header_msg == NULL ) return;
403 if( $this->msg_page_nr > 0 ) {
404 $font_fam = $this->FontFamily;
405 $font_style = $this->FontStyle.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '');
406 $font_size = $this->getFontSize();
407 $this->SetFont(FONT,'', F_SIZE-1);
408 $this->setXY($this->lMargin, MARGIN-3);
409 $this->Cell($this->colwidth, 3,$this->my_header_msg, 0, 0, 'R');
410 if( !empty($font_fam ) )
411 $this->SetFont($font_fam,$font_style,$font_size);
412 if( $my_url != NULL AND $my_url != '' )
413 $this->myLink($this->lMargin+$this->colwidth/2,$this->lMargin-4,$this->colwidth,(F_SIZE+5)/2.9,$my_url);
414 }
415 $this->setXY($this->lMargin, MARGIN+3);
416 $this->y0 = $this->getY();
417 }
418
419 // undefine default header and footer handling
420 // default routines do not handle columns
421 function Footer() { }
422 function Header() { }
423 function Mark( $string = '' ) {
424 return array( $string, 1+substr_count($string,'.') );
425 }
426
427 /*public*/ function myFooter( $msg = NULL, $url = NULL )
428 {
429 static $my_url = NULL;
430 if( $msg != NULL ) {
431 $this->my_footer_msg = $msg; $this->msg_page_nr = 0;
432 $my_url = $url; return;
433 }
434 if( $this->my_footer_msg == NULL ) return;
435 $this->InFooter = true;
436 $this->msg_page_nr++;
437 $font_fam = $this->FontFamily;
438 $font_style = $this->FontStyle.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '');
439 $font_size = $this->getFontSize();
440 $this->SetFont(FONT,'', F_SIZE-1);
441 if( $this->msg_page_nr > 1 ) {
442 $this->SetXY($this->lMargin, $this->GetPageHeight()/$this->scale*100.0-6);
443 $this->Cell($this->colwidth, 3,
444 sprintf("%s %d", $this->unhtmlentities( _('page') ), $this->msg_page_nr),
445 0, 0, 'C');
446 }
447 if( $this->my_footer_msg != '' ) {
448 $strg = '© '. date('Y'). ' CAcert Inc.'.', '. $this->my_footer_msg;
449 $this->SetXY($this->lMargin+MARGIN/2, $this->GetPageHeight()/$this->scale*100.0-6);
450 $this->Cell($this->colwidth, 3, $strg, 0, 0, 'R');
451 if( $my_url != NULL AND $my_url != '' )
452 $this->myLink($this->lMargin+MARGIN/2,$this->GetPageHeight()/$this->scale*100.0-6,$this->colwidth,(F_SIZE+5)/2.9,$my_url);
453 }
454 if( $this->Watermark != '' ) {
455 $this->StartTransform();
456 $savex = $this->GetX(); $savey = $this->GetY();
457 $this->SetFont(FONT,'', F_SIZE*7);
458 $l = $this->GetStringWidth($this->Watermark);
459 $h = $this->GetPageHeight()/$this->scale*100.0/2;
460 $w = $this->colwidth/2+MARGIN;
461 $this->SetXY(0,0);
462 $this->TranslateY($h+(F_SIZE*7)/2.9);
463 $this->TranslateX($w-MARGIN+$this->lMargin);
464 $this->Rotate(rad2deg(atan($h/$w)));
465 $this->Text(-$l/2,0,$this->Watermark, 0.8);
466 $this->StopTransform();
467 $this->SetXY($savex,$savey);
468 }
469
470 if( !empty($font_fam ) )
471 $this->SetFont($font_fam,$font_style,$font_size);
472 $this->InFooter = false;
473 }
474
475 // user and print preferences
476 // NumCopies, PrintPageRange, DisplayDocTitle, HideMenuBar, HideToolBar, ...
477 /*public*/ var $ViewerPrefs = array(
478 'Duplex' => 'Simplex',
479 'NumCopies'=> 2,
480 'DisplayDocTitle' => 'CAcert Assurance Programme (CAP)',
481 'HideToolBar' => true,
482 'FitWindow' => true,
483 );
484
485 //number of colums
486 /*protected*/ var $ncols=1;
487
488 // columns width
489 /*protected*/ var $colwidth=0;
490
491 // space between columns
492 /*protected*/ var $column_space = 0;
493
494 //Current column
495 /*protected*/ var $col=0;
496
497 //Ordinate of column start
498 /*protected*/ var $y0;
499
500 // scaling factor
501 /*protected*/ var $scale = 100.0;
502
503 // print header and footer
504 /*protected*/ var $my_footer_msg = NULL;
505 /*protected*/ var $my_header_msg = NULL;
506 /*protected*/ var $msg_page_nr = 0;
507
508 // print short watermark on the page
509 /*public*/ var $Watermark = WATERMARK;
510
511 /*public*/ function SetFormat( $format = 'a5' ) {
512 switch( strtolower($format) ) {
513 // there is some scale problems with margins...
514 case 'a1':
515 case 'b1':
516 $this->scale *= 1.4142;
517 case 'a2':
518 case 'b2':
519 $this->scale *= 1.4142;
520 case 'a3':
521 case 'b3':
522 $this->scale *= 1.4142; break;
523 case 'a5':
524 case 'b5':
525 $this->scale /= 1.4142; break;
526 case 'letter':
527 $this->scale *= 0.97; break;
528 default: $format = 'a4';
529 case 'a4':
530 case 'b4':
531 case 'folio':
532 case 'legal':
533 break;
534 }
535 $this->SetDisplayMode(intval($this->scale), 'SinglePage', 'UseOC');
536 return( $format );
537 }
538
539 //Set position at a given column
540 /*private*/ function SetCol($col = -1) {
541 static $pagecolwidth = 1.0;
542 static $column_space = 1.0;
543
544 $this->InFooter = true;
545 if( $col == -1 ) $col = $this->col+1;
546 if( $this->colwidth == 0 ) {
547 // only once at start; set default values
548 //set margins
549 $this->addPage(); $col = 0; // reset to zero
550 $this->SetMargins(MARGIN, MARGIN, MARGIN);
551 if( $this->CurOrientation != 'L' ) {
552 $this->scale *= 1.4142;
553 $this->ScaleXY($this->scale,0,0);
554 } else {
555 $this->scale *= 1.0;
556 $this->ScaleXY($this->scale,0,0);
557 }
558 $this->ncols = $this->CurOrientation == 'L'? MAX_COLS : 1;
559 $this->colwidth = $this->w / $this->scale * 100 / $this->ncols - MARGIN*2;
560 $pagecolwidth = $this->w/$this->ncols;
561 // space between columns
562 if ($this->ncols > 1) {
563 $column_space = round((float)($this->w - ($this->ncols * $pagecolwidth)) / ($this->ncols - 1));
564 } else {
565 $column_space = 0;
566 }
567 $this->y0 = $this->GetY();
568 }
569 else {
570 if( $col == $this->col ) { // reset on close of this column
571 $x = MARGIN + $this->col*($pagecolwidth+$column_space);
572 $this->SetLeftMargin($x);
573 //$this->SetRightMargin($this->w - $x - $this->colwidth);
574 }
575 $this->PrintTable('', -1); // if pending table close up table
576 $this->myFooter(); // print footer msg if defined
577 }
578 if( $col >= $this->ncols ) {
579 $this->addPage(); $col = 0;
580 $this->ScaleXY($this->scale,0,0);
581 $this->y0 = 0; //no header/footer done...
582 } elseif ( $col > 0 AND $col < $this->ncols) {
583 // print column separator
584 $x = $this->w/$this->ncols*($this->col+1);
585 $y = $this->tMargin;
586 $this->SetLineWidth(0.1); $this->SetDrawColor(195);
587 $this->SetLineStyle(array('dash'=>'1,8') ); // gray dotted
588 $this->Line( $x, $y+27, $x, $y+185);
589 $this->SetLineWidth(0.2); $this->SetDrawColor(0);
590 $this->SetLineStyle(array('dash'=>'0') );
591 }
592 $this->col = $col;
593 // X position of the current column
594 $x = MARGIN + $col*($pagecolwidth+$column_space);
595 $this->SetLeftMargin($x);
596 $this->SetRightMargin($this->w - $x - $this->colwidth);
597 $this->SetXY($x, $this->y0);
598 $this->myHeader(); //print header msg if defined
599 $this->PrintTable('', 0); // if in table reprint title table
600 $this->InFooter = false;
601 }
602
603 //Method accepting or not automatic page break
604 /*public*/ function AcceptPageBreak() {
605 $this->SetCol();
606 return false;
607 }
608
609 // redefine this routine from tcpdf.php due to scaling bug
610 /*protected*/ function checkPageBreak($h) {
611 if (((($this->y + $h)*$this->scale/100.0) > $this->PageBreakTrigger) ) {
612 if ( !$this->InFooter ) {
613 if ( ($this->AcceptPageBreak())) {
614 $rs = '';
615 //Automatic page break
616 $x = $this->x;
617 $ws = $this->ws;
618 if ($ws > 0) {
619 $this->ws = 0;
620 $rs .= '0 Tw';
621 }
622 $this->AddPage($this->CurOrientation);
623 if ($ws > 0) {
624 $this->ws = $ws;
625 $rs .= sprintf('%.3f Tw', $ws * $k);
626 }
627 $this->_out($rs);
628 $this->y = $this->tMargin;
629 $this->x = $x;
630 }
631 }
632 }
633 }
634
635 /*private*/ function myLine( $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0 ) {
636 if ( BW ) {
637 $this->SetDrawColor(195);
638 } else {
639 $this->SetDrawColor(173,197,215);
640 }
641 $this->SetLineWidth(0.1); // small line in points collumn
642 $this->Line($x1, $y1, $x2, $y2 );
643 $this->SetLineWidth(0.2); $this->SetDrawColor(0);
644
645 }
646
647 /*private*/ function S( $value = 1.0 ) {
648 return( $value * $this->scale / 100.0 );
649 }
650
651 // put Link in user space
652 /*private*/ function myLink( $x, $y, $w, $h, $Lnk = NULL, $Type = array('SubType'=>'Link') ) {
653 if( $Lnk == NULL ) return;
654 if( $Lnk == '' ) $Lnk = WEB;
655 $this->Annotation( $this->S($x), $this->S($y), $this->S($w), $this->S($h), $Lnk, $Type);
656 }
657
658
659 //require_once('../utf8/native/core.php');
660 // only for to upper case //require_once('../utf8/utils/unicoe.php');
661
662 //setlocale(LC_ALL, 'de_DE');
663 // try to abbreviate a full name, returns name if abbreviation was/is done
664 // has pointers to sur name, first name, avoids titles and extentions
665 // is based that given names and family names starts with capital
666 // all names between first given name and surname are secondary names
667 // will use utf8 routines only when needed and available
668 /*private*/ function Abbreviate( $name = '') {
669 // need to change this for utf8 uppercase detection
670 // substr and strtoupper arte dependent of setlocale...
671 $substr = 'substr';
672 $strtoupper = 'strtoupper';
673 $tokens = array();
674 $cnt = preg_match_all('/([^\s\.]+\.|[^\s\.]+)/', $name, $tokens, PREG_SET_ORDER);
675 if( $cnt <= 0 ) return ( $name );
676 $fam = -1; $married = 0; $i = 0; $success = FALSE; $first_name = -1;
677 for( $j = 0; $j < $cnt ; $j++ ) {
678 $tk = $tokens[$j];
679 $nm = $tk[0]; if( $nm == '' ) continue;
680 // not utf8
681 $ltr = $substr( $nm, 0, 1 );
682 if(preg_match('/[^\x09\x20-\x7E]/',$ltr) !== 1 AND // it is utf8
683 function_exists( 'utf8_substr') ) {
684 $substr='utf8_substr';
685 //$strtoupper = 'utf8_strtoupper'; // requires utf8/utils/unicode.php
686 }
687 if( $strtoupper($ltr) != $ltr ) continue; // lower case setlocale dependent
688 elseif( preg_match('/\./', $nm ) ) {
689 if( $first_name < 0 ) $first_name = $j;
690 if( $first_name >= 0 ) $success = TRUE; // was abbreviated
691 continue; // title
692 }
693 if( $first_name < 0 ) $first_name = $j;
694 if( $married == 0 ) $fam = $j;
695 if( preg_match('/[-_]/', $nm ) ) {
696 // find special markers
697 if( $married == 0 ) $fam = $j;
698 $married++;
699 }
700 }
701 $name = '';
702 for( $j = 0; $j < $cnt; $j++ ){
703 $tk = $tokens[$j];
704 if( !isset($tk[0]) ) continue;
705 $nm = $tk[0]; if( $nm == '' ) continue;
706 if( $name != '') $name .= ' ';
707 $ltr = $substr( $nm, 0, 1 );
708 if( $j == $fam ) $name .= $nm;
709 elseif( $strtoupper($ltr) != $ltr ) $name .= $nm; // lower case
710 elseif( preg_match('/\./', $nm ) ) $name .= $nm;
711 elseif( $j < $fam ) { // need to abbreviate
712 // not utf8
713 // and abbreviate
714 if( $j == $first_name )
715 $abr = '('. $substr( $nm, 1 ) . ')';
716 else $abr = '.';
717 $name .= $ltr . $abr; $success = TRUE; // is abbreviated
718 } else $name .= $nm;
719 }
720 $ext = -1; for( $j = $cnt-1; $j >= 0 AND $j >= $fam; $j-- ) {
721 // try to find family names and see if there is abbreviation
722 $tk = $tokens[$j];
723 if( !isset($tk[0]) ) continue;
724 $nm = $tk[0];
725 if( $ext < 0 AND preg_match('/(^[^A-Z]|\.)/', $nm ) ) continue;
726 if( $ext < 0 ) $ext = $j+1;
727 if( preg_match('/\./', $nm ) ) { $success = TRUE; break; }
728 }
729 return( $success? $name : '' ); // and return abbriviated name
730 }
731
732 // set formfield coordinates
733 // this routine is needed due to field ordinates are not scaled and in user space
734 // to be called before form field call (or as width parameter)
735 // and just after with true argument to restore X Y ordinates.
736 /*private*/ function SetFieldXY( $x=NULL, $y=NULL, $w=0) {
737 static $savex;
738 static $savey;
739 static $restored = true;
740 $restoreXY = $x == NULL ? true : false;
741
742 if( $restored == $restoreXY )
743 $this->Error("internal Form Field save/restore error\n");
744 if( !$restoreXY ) {
745 /* save X Y ordinates */
746 $savex = $this->GetX(); $savey = $this->GetY();
747 // scale to user ordinates
748 $this->SetY( $this->S($y));
749 $this->SetX( $this->S($x));
750 } else {
751 /* restore X Y ordinates */
752 $this->SetY( $savey); // different from SetXY()
753 $this->SetX( $savex); // different from SetXY()
754 }
755 $restored = $restoreXY;
756 return( $this->S($w) );
757 }
758
759 // print Date on left or right side
760 /*private*/ function PrintDate( $x=10, $y=10, $dstrg='teus', $dvalue='1945-10-6', $field = NULL , $RL = 'L')
761 {
762 static $TextProps = array('strokeColor' => LLBLUE, 'value' => '', 'fillColor' => LBLUE , 'textSize' => '11', 'charLimit'=> 10);
763 // next statements will cause php to go into an infinite loop
764 //if( $dstrg != NULL AND $dstrg == '')
765 // $TextProps['userName'] = $this->unhtmlentities( _("On mutual assurance provide Assurer date of birth (yyyy-mm-dd)") );
766 //else
767 $TextProps['userName'] = $this->unhtmlentities( _("yyyy-mm-dd") );
768
769 $this->SetFont( FONT, '', F_SIZE);
770 $this->SetXY($RL == 'L'? $x : $x-50, $y);
771 $this->Cell(50, 3, $dstrg, 0, 0, $RL);
772 if($dvalue) {
773 $this->SetXY($RL == 'L'? $x :$x-50, $y+3.5);
774 $this->SetFont(FONT, 'B', F_SIZE);
775 $this->Cell(50, 3, $dvalue, 0 , 0, $RL);
776 }
777 if( $field == NULL ) return;
778 $TextProps['value'] = $dvalue;
779 $this->TextField($field, $this->SetFieldXY(($RL == 'L'? $x+1 : $x-17), ($y+3.5),17), 5, $TextProps );
780 $this->SetFieldXY();
781 }
782
783 // Add import HTML text eg from CCA
784 /*private*/ function PrintHTML( $url = NULL ) {
785 if( $url == NULL OR $url == '' ) return;
786 $error = ''; $title = ''; $url = POLICY.$url.EXT;
787 if( ! file_exists($url) ) $url = WEB.'/'.$url;
788 $data = file_get_contents($url);
789 if( !$data ) $error = "\nInternal Error: no ".$url.' found.';
790 else {
791 $regs = array();
792 preg_match('/<[Tt][Ii][Tt][Ll][Ee][^>]*>/', $data, $regs);
793 if( count($regs) < 1 ) $error .= "\nInternal Error: no open tag title found on $url.";
794 else {
795 $start = strpos($data, $regs[0]) + strlen($regs[0]);
796 $data = substr($data, $start);
797 }
798 $regs = array();
799 preg_match('/<\/[Tt][Ii][Tt][Ll][Ee][^>]*>/', $data, $regs);
800 if( count($regs) < 1 ) $error .= "\nInternal Error: no close title tag found on $url.";
801 else {
802 $end = strpos($data, $regs[0]);
803 $title = trim(substr($data,0,$end));
804 $data = substr($data, $end+strlen($regs[0]));
805 }
806 $regs = array();
807 preg_match('/<[Bb][oO][Dd][yY][^>]*>/', $data, $regs);
808 if( count($regs) < 1 ) $error .= "\nInternal Error: no open html body tag found on $url.";
809 else {
810 $start = strpos($data, $regs[0]) + strlen($regs[0]);
811 $data = substr($data, $start);
812 }
813 $regs = array();
814 preg_match('/<\/[Bb][oO][Dd][yY][^>]*>/', $data, $regs);
815 if( count($regs) < 1 ) $error .= "\nInternal Error: no closing html body tag found on $url.";
816 else {
817 $end = strpos($data, $regs[0])-1;
818 $data = substr($data, 1, $end);
819 }
820 }
821 if( !$title ) $title = $url;
822 $this->SetCol();
823 $this->setFont(FONT, F_SIZE);
824 if( !$error ) {
825 $this->PrintHeader($this->unhtmlentities( _($title) ), $this->unhtmlentities( _('policy document') ), strncmp($url,WEB,strlen(WEB))==0? $url : (WEB.'/'.$url));
826 if( $title ) $this->Bookmark($title,0);
827 $this->writeHTMLCell($this->colwidth,2.5,$this->lMargin+1,$this->GetY()+2.5,
828 $data, 0,2,0,'L');
829 }
830 else
831 $this->MultiCell($this->colwidth, 3, $error);
832 }
833
834 /*private*/ function PrintCAP($assuree = NULL, $assurer = NULL, $assurance = NULL, $page = NULL ) {
835 $this->SetCol();
836 $this->PrintHeader($this->unhtmlentities( _('CAcert Assurance Programme') ), $this->unhtmlentities( _('Identity Verification Form (CAP) form') ), defined('ASSCAP')?ASSCAP:'',defined('WEB')? WEB.substr(__FILE__, strrpos(__FILE__,'/')) : '');
837 // define slightly different footer message
838 $this->myFooter('V'. substr($this->Version(), 0, strpos($this->Version(), '.')).', '. $this->unhtmlentities( _('generated') ).' '.date('Y-n-j'), NULL);
839 $this->AssuranceInfo($assurance);
840 $this->InfoAssuree($assuree, $assurer, $assurance);
841 $this->StatementAssuree( $assuree['date']);
842 $this->StatementAssurer( $assurer, $assurance );
843 }
844
845 //Add form and/or CCA (on duplex only when more as one page is printed)
846 /*public*/ function PrintForm( $assuree = NULL, $assurer = NULL, $assurance = NULL, $page = NULL ) {
847
848 for($cnt=0 ; $cnt < $this->ncols; $cnt++ ) {
849 if( !isset( $page['form']) OR $page['form'] ) {
850 // the form is one page, use new room?
851 if ( $assuree == NULL OR $assurer == NULL OR $assurance == NULL )
852 $this->Error('Assuree or Assurer data records failure');
853 $this->PrintCap( $assuree, $assurer, $assurance);
854 }
855
856 // print off policy documents to be included in pdf file
857 foreach( $page['policies'] as $i => $file ) {
858 $this->Watermark = WATERMARK; // no watermark on these pages
859 if( $file ) $this->PrintHTML( $file );
860 }
861 if( $this->col > 0 OR $this->getPage() > 1 ) break;
862 }
863 if( $this->getPage() > 1 ) {
864 // and on duplex print back side with Community Agreement
865 if( $this->CurOrientation == 'P' )
866 $this->ViewerPrefs['Duplex'] = 'DuplexFlipLongEdge';
867 else
868 $this->ViewerPrefs['Duplex'] = 'DuplexFlipShortEdge';
869 }
870 // close up this column, make sure footer is printed.
871 $this->my_header_msg = NULL; $this->SetCol($this->col);
872 }
873
874 // Set form title (right align)
875 /*public*/ function PrintHeader($title1 = ' ', $title2 = ' ' , $url1 = NULL, $url2 = NULL) {
876 // store current top margin value
877 $tSide = $this->tMargin;
878
879 // CAcert logo
880 // eps should be better, but it does not seem to work with CAcert logo
881 $this->rMargin -= 1;
882 $this->myFooter($title1,$url1);
883 $this->myHeader($title2,$url2);
884 if( LOGO_TYPE == '.eps' )
885 $this->ImageEPS(BW?LOGO.'mono'.LOGO_TYPE:LOGO.'colour'.LOGO_TYPE,
886 ($this->lMargin+$this->colwidth)-51,$tSide-3,51);
887 else
888 // png image 1000 X 229 * 8 bits
889 $this->Image(BW?LOGO.'mono'.LOGO_TYPE:LOGO.'colour'.LOGO_TYPE,
890 ($this->lMargin+$this->colwidth)-51,$tSide-3,51,0,0,
891 NULL,0,true,intval(LOGO_DPI));
892 $this->myLink($this->lMargin+$this->colwidth-51, $tSide-3,51,51/1000*229,WEB);
893 // form type
894 $this->SetFont(FONT,'B',F_SIZE+5);
895 $this->SetY($tSide+5); $this->SetX($this->lMargin);
896 $l = $this->GetStringWidth($title1);
897 $this->Cell($this->colwidth+1,14,$title1,0,0,'R',0,NULL);
898 if( $url1 != NULL AND $url1 != '' )
899 $this->myLink($this->lMargin+$this->colwidth-$l,$this->GetY()+5,$l,(F_SIZE+5)/2.9,$url1);
900 $this->Ln(5); $this->SetX($this->lMargin);
901 $l = $this->GetStringWidth($title2);
902 $this->Cell($this->colwidth+1,14,$title2,0,0,'R',0,NULL);
903 if( $url2 != NULL AND $url2 != '' )
904 $this->myLink($this->lMargin+$this->colwidth-$l,$this->GetY()+5,$l,(F_SIZE+5)/2.9,$url2);
905
906 // CAcert Inc. postbox address
907 $this->Ln(6); $this->SetX($this->lMargin);
908 $this->SetFont(FONT,'',F_SIZE);
909 $savex = $this->GetX(); $savey = $this->GetY();
910 $strg = POBOX .' - '. WEB;
911 $this->SetXY($this->lMargin+$this->colwidth-$this->GetStringWidth($strg)-1.1,$this->GetY()+3.5); // right align
912 if( !BW ) $this->SetTextColor(17,86,140);
913 $ret = $this->Write(0, $strg, NULL);
914 $l = $this->GetStringWidth($strg);
915 $this->myLink($this->lMargin+$this->colwidth-$l,$this->GetY()+0.5,$l,F_SIZE/2.9,WEB);
916 $this->Ln();
917 if( !BW ) $this->SetTextColor(0);
918 $this->SetXY($savex,$savey);
919
920 // sha1 fingerprint CAcert rootkeys class 1 and class 3
921 $strg = $this->unhtmlentities( _("CAcert's Root Certificate sha1 fingerprints") ) . ', class 1: '. CLASS1_SHA1 . ', class 3: ' . CLASS3_SHA1;
922 $this->Ln(3); $this->SetX($this->lMargin);
923 $this->SetFont(FONT,'',F_SIZE * $this->colwidth / ($this->GetStringWidth($strg) +1));
924 $this->Cell($this->colwidth,10, $strg,0,0,'C',0,NULL);
925 $this->myLink($this->lMargin, $this->GetY()+4,$this->colwidth,F_SIZE/2.9,ROOTKEYS);
926 $this->SetLineWidth(0.1);
927 if ( BW ) { $this->SetDrawColor(195);
928 } else { $this->SetDrawColor(17,86,140);
929 }
930
931 $this->Line($this->lMargin, $tSide+25, $this->lMargin+$this->colwidth, $tSide+25);
932 $this->SetLineWidth(0.2); $this->SetDrawColor(0);
933 $this->rMargin += 1;
934 $this->SetXY($this->lMargin, $tSide+26); // top
935 }
936
937 // Set general form information
938 /*private*/ function PrintInfo( $strg = '', $url = '') {
939 // store current margin values
940
941 // Print text blurb paragraph at top of page
942 $this->SetFont(FONT,'',F_SIZE+0.5);
943 $this->SetXY($this->lMargin, $this->GetY()-1.5);
944 $y = $this->GetY(); $x = $this->GetX();
945 $cnt=$this->MultiCell($this->colwidth+1, 0, $strg,0,'L',0,2);
946 if ( $url != '' ) // link should be in user space
947 $this->myLink($x, $y, $this->colwidth, $this->GetY()-$y, $url);
948 return($cnt);
949 }
950
951 // print general CAP info
952 /*public*/ function AssuranceInfo( $assurance = NULL ) {
953 // store current margin values
954 $cellcnt = 0;
955 $this->SetY($this->GetY()+0.5);
956 $this->Bookmark($this->unhtmlentities( _('CAcert CAP form') ),0,$this->S($this->GetY()));
957
958 // Show text blurb at top of page
959 $strg = $this->unhtmlentities( _('The CAcert Assurance Programme (CAP) aims to verify the identities of Internet users through face to face witnessing of government-issued photo identity documents.') );
960 $strg .= ' '. $this->unhtmlentities( _("The Applicant asks the Assurer to verify to the CAcert Community that the Assurer has met and verified the Applicant's identity against original documents.") );
961 $strg .= ' '. $this->unhtmlentities( _('Assurer may leave a copy of the details with the Applicant, and may complete and sign her final form after the meeting.') );
962 $strg .= ' '. $this->unhtmlentities( _("If there are any doubts or concerns about the Applicant's identity, do not allocate points. You are encouraged to perform a mutual Assurance.") );
963 $cellcnt += $this->PrintInfo( $strg, defined('ASSINTRO')? ASSINTRO:'');
964 $cellcnt += $this->PrintInfo( $this->unhtmlentities( _('For more information about the CAcert Assurance Programme, including detailed guides for CAcert Assurers, please visit:') ).' '.WEB, defined('ASSCAP')?ASSCAP:'');
965 $cellcnt += $this->PrintInfo( $this->unhtmlentities( _('A CAcert Arbitrator can require the Assurer to deliver the completed form in the event of a dispute. After 7 years this form should be securely disposed of to prevent identity misuse. E.g. shred or burn the form. The Assurer does not retain copies of ID at all.') ),defined('ARBIT')?ARBIT:'');
966 $cellcnt += $this->PrintInfo( $this->unhtmlentities( _('For the CAcert Organisation Assurance Programme there is a separate special COAP form.') ),defined('ASSORG')?ASSORG:'');
967 $this->SetY($this->GetY()-0.1);
968 $this->PrintLocation( $assurance );
969 $this->SetY($this->GetY()+1);
970
971 }
972
973 // print empty table with title for statements (called twice per table)
974 /*private*/ function PrintTable( $strg = NULL, $height = -1, $ext = 0 ) {
975 // store current margin values
976 static $tSide = -1;
977 static $title = '';
978 if( $height < 0 ) { // mark table position, leave room for title
979 if( $strg != '' ) $title = $strg;
980 if( $title == '' ) return ($this->GetY()); // nothing to do
981 $tSide = $this->GetY()+1;
982 // background
983 if ( BW ) {
984 $this->SetFillColor(195);
985 $this->SetDrawColor(195);
986 } else {
987 $this->SetFillColor(173,197,215);
988 $this->SetDrawColor(173,197,215);
989 }
990 $this->Rect($this->lMargin-1,$tSide-1,1,9, 'F');
991 $this->Rect($this->lMargin-1,$tSide-1,$this->colwidth,1, 'F');
992 $this->SetFillColor(255);
993 if ( BW ) { $this->SetFillColor(125);
994 } else { $this->SetFillColor(17,86,140);
995 }
996 $this->Rect($this->lMargin,$tSide,$this->colwidth,7, 'DF');
997 $this->SetFillColor(255); $this->SetDrawColor(0);
998
999 $this->SetXY($this->lMargin+1, $tSide+0.6);
1000 $this->Bookmark($title,1,$this->S($tSide));
1001 $this->SetFont(FONT, '', F_SIZE+7);
1002 $this->SetTextColor(255);
1003 $this->Write(0, $title);
1004 $this->SetTextColor(0);
1005 $this->SetXY($this->lMargin+1, $tSide + 7);
1006 $tSide += 8; // save old top
1007 if ( $height != 0 ) return($this->GetY());
1008 }
1009 elseif( $tSide < 0 ) return( $this->GetY());
1010 if( $height == 0 ) { // interrupted bottum of column reached
1011 $height = $this-GetY() - $tSide; $save = $title;
1012 $this->PrintTable('', $height); // finish till bottumn page
1013 $tSide = $this->originalMargin;
1014 $title = $save;
1015 return( $this->GetY());
1016 }
1017 if( $strg != '' ) $title = $strg; // just to be defensive
1018
1019 // background
1020 if ( BW ) {
1021 $this->SetFillColor(195);
1022 $this->SetDrawColor(195);
1023 } else {
1024 $this->SetFillColor(173,197,215);
1025 $this->SetDrawColor(173,197,215);
1026 }
1027 $this->Rect($this->lMargin-1,$tSide,1,$height-1+$ext, 'F');
1028 if( $ext )
1029 $this->Rect($this->lMargin-1,$tSide+$height,$this->colwidth,$ext, 'F');
1030 $this->SetFillColor(255);
1031 // borders of the table left, bottumn, right
1032 $this->Line($this->lMargin,$tSide+$height-1, $this->lMargin, $tSide+$height);
1033 $this->Line($this->lMargin,$tSide+$height,$this->lMargin+$this->colwidth,$tSide+$height);
1034 $this->Line($this->lMargin+$this->colwidth,$tSide-1, $this->lMargin+$this->colwidth, $tSide+$height);
1035 $this->SetDrawColor(0);
1036 $this->SetY($tSide + $height + 1); // set Y ordinate to plus 7
1037 $tSide = -1; $title = '';
1038 return($this->GetY());
1039 }
1040
1041 // assuree information
1042 /*private*/ function PrintName( $names = NULL, $assurancemax = -1 ) {
1043 //$H = 5; // height of the name cell
1044 $name = $names == NULL ? '': $names['name'];
1045 $id_type = $names == NULL ? '' : $names['idtype'];
1046 // store current margin values
1047 static $nr = 0;
1048 static $idtypes = NULL;
1049 static $listpoints = NULL;
1050 static $ComboProps = array( 'fillColor'=> LBLUE, 'strokeColor'=> LLBLUE, 'editable'=> 'true', 'textSize' => 9, 'rotate'=> '0');
1051 static $TextProps = array('strokeColor'=> LLBLUE, 'value' => ' ', 'fillColor'=> LBLUE, 'doNotScrole'=> 'false', 'textSize' => 12, 'rotate'=> '0');
1052 static $TextBlankProps = array('strokeColor'=> 'white', 'fillColor'=> 'white', 'readonly' => 'true', 'doNotScrole'=> 'true', /* 'lineWidth'=> '0'*/);
1053 $TextProps['textSize'] = 12/6*H;
1054
1055 $nr++;
1056 $savey = $this->GetY();
1057
1058 $namepoints = intval($names == NULL? -1 : $names['points']);
1059 if( $namepoints <= 0 ) $namepoints = $assurancemax;
1060 if( $namepoints <= 0 OR $namepoints >= 35 ) $namepoints = 35;
1061 if( $listpoints == NULL ) {
1062 $listpoints = array( 0=> ' ');
1063 for ($i = 0; $i <= $namepoints; $i++)
1064 $listpoints += array( ($i+1) => sprintf("%d",$namepoints-$i) );
1065 }
1066 $points = sprintf("AssureeNames_%d_Points", $nr);
1067
1068 // just once to recover from Acrobat 7.0 problem !!!!!!!!!!!!!!!!!!!!!!!!!!
1069 // make sure before the first time form field JS is called the fake is done
1070 static $AcrobatName = array('strokeColor'=> LLBLUE, 'fillColor'=> LLBLUE, 'readonly' => 'true');
1071 if( $AcrobatName != NULL ) {
1072 $this->TextField( 'NameNone', $this->SetFieldXY(300, $this->GetY()+2, 0), 0, $AcrobatName);
1073 $this->SetFieldXY(); $AcrobatName = NULL;
1074 }
1075 static $AcrobatCombo = array( 'fillColor'=> LLBLUE, 'strokeColor'=> LLBLUE, 'editable'=> 'false');
1076 if( $AcrobatCombo != NULL ) {
1077 $this->ComboBox( 'PointsNone', $this->SetFieldXY(300, $this->GetY()+20, 0), 0, array(' '), $AcrobatCombo);
1078 $this->SetFieldXY(); $AcrobatCombo = NULL;
1079 }
1080 // end of Acrobat defeat !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1081
1082 $this->ComboBox( $points, $this->SetFieldXY($this->lMargin+$this->colwidth-15, $this->GetY()+2, 10),(5/6*H), $listpoints, $ComboProps);
1083 $this->SetFieldXY();
1084 // small line in points collumn
1085 $this->myLine($this->lMargin+$this->colwidth-8.5,$savey+H+0.3,$this->lMargin+$this->colwidth-8,$savey+H+0.3);
1086 if( $namepoints >= 0 ) {
1087 // this seems not to be visible: no points printed...
1088 $this->SetXY( $this->lMargin+$this->colwidth-17.5, $savey+1 );
1089 $this->SetFont(FONT, 'B', (F_SIZE+1)/6*H);
1090 $this->Cell( 15, sprintf("(%d)", $namepoints), 0, 0, 'C');
1091 }
1092
1093 $TextProps['value'] = $name ? $name : ' '; $TextProps['textSize'] = 14;
1094 $TextProps['userName'] = $this->unhtmlentities( _('Exact full name as on shown ID for this name.') );
1095 $this->TextField(sprintf('AssureeNames_%d_Name',$nr), $this->SetFieldXY($this->lMargin+2,$savey+0.9,$this->colwidth-40), 8/6*H, $TextProps);
1096 $this->SetFieldXY();
1097 $this->SetXY($this->lMargin+2, $savey);
1098 if($name) {
1099 $token = $name;
1100 $fnt = (F_SIZE+4)/6*H;
1101 $this->SetFont(FONT, 'B', $fnt);
1102 $lngth = $this->GetStringWidth($token);
1103 if( $lngth > $this->colwidth-35 ) $fnt *= ($this->colwidth-35) / $lngth;
1104 $this->SetFont(FONT, 'B', $fnt);
1105 $this->MultiCell($this->colwidth-25, 0, $token, 0, 'L');
1106 if( function_exists('utf8_to_ascii') AND
1107 !utf8_is_ascii_ctrl( $name) )
1108 $ascii = utf8_to_ascii($name);
1109 else
1110 $ascii = '';
1111 $abbr = $this->Abbreviate( $name );
1112 if( strcmp($ascii,$name) != 0 OR strcmp($abbr,$name) != 0) {
1113 $msg = $this->unhtmlentities( _('The exact name of the assuree may have transliterated characters and/or some given names may be abbreviated. If present the first given name will be shown abbreviated and parentheses around the last part of the given name.\n') );
1114 if( $ascii != '' AND strcmp($ascii,$name) != 0 ) $msg .= $this->unhtmlentities( _('transliterated: ') ). $ascii.'\n';
1115 if( $abbr != '' AND strcmp($abbr, $name) != 0 ) $msg .= $this->unhtmlentities( _('abbreviated: ') ). $abbr.'\n';
1116 $this->myLink($this->lMargin-7, $savey+1, 3, 3, $msg,
1117 array('subtype'=> 'Text', 'Open' => 'false',
1118 'c'=> array(173,197,215), 'name'=> 'Comment',
1119 'f'=> array( 'nozoom', 'readonly', 'norotate'),
1120 't'=> $this->unhtmlentities( _('On the assuree full name') )));
1121 }
1122 } else {
1123 $id_type = '';
1124 // no name, give a line to write on
1125 $this->myLine($this->lMargin+2,$savey+H+0.3,$this->lMargin+$this->colwidth-37,$savey+H+0.3); // line under name
1126 }
1127 $this->SetXY($this->lMargin+2, $savey);
1128 if ( !$name ) $idtypes = NULL ;
1129 if( $idtypes == NULL ) {
1130 $idtypes = array( ); $i = 0;
1131 if (!$name) $idtypes = array( $i++ => ' ');
1132 if( $id_type ) {
1133 $token = $id_type;
1134 $token = strtok($token,'/');
1135 for( ; $token != ''; $i++) {
1136 $idtypes += array( $i => $token ); $token = strtok('/');
1137 }
1138 }
1139 $idtypes += array( $i => $this->unhtmlentities( _('passport') ), $this->unhtmlentities( _('driver license') ), $this->unhtmlentities( _('ID card') ), $this->unhtmlentities( _('mil. ID') ), $this->unhtmlentities( _('certificate') ), $this->unhtmlentities( _('TTP') ) );
1140 }
1141 if( !$id_type ) {
1142 $this->myLine($this->lMargin+$this->colwidth-37,$savey+H+0.3,$this->lMargin+$this->colwidth -17,$savey+H+0.3);// line under ID
1143 $this->myLine($this->lMargin+$this->colwidth-37,$savey+H-0.7,$this->lMargin+$this->colwidth-37,$savey+H+0.1); // l small ID vert
1144 } else {
1145 $this->SetXY($this->lMargin+20, $savey+1);
1146 $this->SetFont(FONT, 'B', (F_SIZE+1)/6*H);
1147 $this->Cell($this->colwidth-37, 2, '('.$id_type .')', 0, 0, 'R');
1148 // hide id type print on screen with the formfields, just nicety
1149 // one could extend the name field, but this has more drawbacks
1150 $this->TextField(sprintf('AssureeNames_%d_None',$nr), $this->SetFieldXY($this->lMargin+$this->colwidth-38,$savey+0.5,20), 7/6*H, $TextBlankProps);
1151 $this->SetFieldXY();
1152 }
1153 $this->ComboBox( sprintf("AssureeNames_%d_TypeID",$nr), $this->SetFieldXY($this->lMargin+$this->colwidth-37, $savey+2, 19), 5/6*H, $idtypes, $ComboProps);
1154 $this->SetFieldXY();
1155 $this->SetXY($this->lMargin+2, $savey+H);
1156 return( $name );
1157 }
1158
1159 // All information of Assuree goes in one table
1160 /*public*/ function InfoAssuree( $assuree = NULL, $assurer = NULL, $assurance = NULL ) {
1161 $dob = $assuree['dob'];
1162 $email = $assuree['email'];
1163 $assurancemax = $assurance['maxpoints'];
1164 if( $assurancemax <= 0 ) $assurancemax = 35;
1165
1166 // Assuree Identity information part
1167 $tSide = $this->PrintTable($this->unhtmlentities( _("Applicant's Identity Information") ))+1;
1168
1169 $msg = $this->unhtmlentities( _('Some examples of possible standard transliterations in a full individual name. If more than one transliteration of a character is possible, it is denoted within parentheses.') );
1170 $msg .= $this->unhtmlentities( _('a and y umlaut, and o/slash examples of accepted transliterations for the full name(s)') ).':';
1171 $msg .= "\n* ". 'J(ae|a)hny G(oe|o)le McName';
1172 $msg .= "\n\n".$this->unhtmlentities( _('As an example standard abbreviation on given names is provided here. If a given name is counted as first given name part of the name is denoted with parentheses around the name.') );
1173 $msg .= $this->unhtmlentities( _('Examples of accepted abbreviation(s) for full name(s)') ).':';
1174 $msg .= "\n* ". 'sir J(ähnÿ) G. McName';
1175 $msg .= "\n";
1176 // put hint on comparing names on title table
1177 $this->myLink($this->lMargin-7, $tSide-7, 5, 5, $msg,
1178 array('subtype'=> 'Text', 'Open' => 'true',
1179 'c'=> array(173,197,215), 'name'=> 'Comment',
1180 'f'=> array( 'nozoom', 'readonly', 'norotate'),
1181 't'=> $this->unhtmlentities( _('On comparing names') )));
1182
1183 // names of applicant
1184 $this->SetXY($this->lMargin+1, $tSide);
1185 $this->SetFont(FONT, '', F_SIZE+1);
1186 $this->Write(0, $this->unhtmlentities( _('Exact full name on the ID') ).': ');
1187 $strg = '('. $this->unhtmlentities( _('type of ID shown') ).')';
1188 $this->SetFont(FONT, '', F_SIZE);
1189 $this->SetXY($this->lMargin+$this->colwidth-$this->GetStringwidth($strg)-19, $tSide);
1190 $this->Write(0, $strg);
1191 if( $assurancemax > 0 AND $assurancemax <= 50 ) {
1192 $strg = sprintf($this->unhtmlentities( _('max') ) . " %d", $assurancemax);
1193 $this->SetFont(FONT, F_SIZE);
1194 $strg = $strg;
1195 $this->SetXY($this->lMargin+$this->colwidth-19, $tSide);
1196 $this->Cell(20, 3, $strg, 0, 0, 'C');
1197 }
1198 $this->SetXY($this->lMargin+2, $tSide+3);
1199
1200 // all (max) three names with ID type right aligned.
1201 $cnt = $assuree['namecnt'];
1202 $space = $this->getPageHeight()/$this->scale*100.0 -MINH ; // margin
1203 for( $i = 0; $i < $cnt; $i++ ) { // names to be printed
1204 $this->PrintName( $assuree['names'][$i], $assurer['maxpoints'] < 0? 35: $assurer['maxpoints'] );
1205 if( $space < $this->getY() ) break;
1206 }
1207 for( $j=0 ; $j < $i+3; $j++ ) {
1208 // empty fields up to max 3 empty fields and allowed space
1209 if( $space < $this->getY() ) break;
1210 $this->PrintName( NULL, $assurer['maxpoints'] < 0? 35: $assurer['maxpoints']);
1211 }
1212
1213 // email address assuree
1214 $savey = $this->GetY()+1;
1215 $this->myLine($this->lMargin+$this->colwidth-17,$savey-0.7,$this->lMargin+$this->colwidth,$savey-0.7); // line above DoB
1216 $this->myLine($this->lMargin+$this->colwidth-17,$tSide+3,$this->lMargin+$this->colwidth-17,$savey-0.7); // left points column
1217 $this->SetXY($this->lMargin+1, $savey);
1218 $this->SetFont(FONT, '', F_SIZE);
1219 $strg = $this->unhtmlentities( _('Email address') ).': ';
1220 $l = $this->GetStringWidth($strg);
1221 $this->Write(0, $strg);
1222 if($email) {
1223 $this->SetFont(FONT, 'B', F_SIZE+1);
1224 if( !BW ) $this->SetTextColor(17,86,140); $this->SetXY($this->GetX(),$this->GetY()-0.35);
1225 $ret = $this->Write(0, $email);
1226 $this->myLink($this->lMargin+2,$this->GetY(),$l, F_SIZE/2, 'mailto:'.$email.'?subject=Your CAcert Assurance');
1227 $this->Ln();
1228 if( !BW ) $this->SetTextColor(0);
1229 }
1230 // somehow fields are not scaled....
1231 $TextProps = array('strokeColor'=> LLBLUE, 'value' => '', 'fillColor'=> LBLUE, 'doNotScrole'=> 'true', /* 'lineWidth'=> '0', */ 'textSize' => '11', 'rotate'=>0, 'userName'=> $this->unhtmlentities( _('email address as e.g. john.family@gmail.com') ) );
1232 $TextProps['value'] = $email;
1233 $this->TextField('AssureeEmail', $this->SetFieldXY($this->lMargin+2+$l, $savey,$this->colwidth-40-$l), 5, $TextProps);
1234 $this->SetFieldXY();
1235
1236 $this->SetXY($this->lMargin+$this->colwidth-25, $savey);
1237 // date of birth assuree
1238 $strg = $this->unhtmlentities( _('Date of Birth') );
1239 if( $dob == '' )
1240 $strg .= ' ('.$this->unhtmlentities( _("yyyy-mm-dd") ). ')';
1241 $this->PrintDate( $this->lMargin+$this->colwidth-3, $savey, $strg, $dob, 'AssureeDoB', 'R');
1242 $savey += 4;
1243
1244 $this->myLine($this->lMargin+$this->colwidth-16.9,$tSide-7.0,$this->lMargin+$this->colwidth-16.9,$tSide-2); // column left
1245 $this->SetXY($this->lMargin+$this->colwidth-14.95, $tSide-8.7);
1246 $this->SetFont(FONT, '', F_SIZE);
1247 $this->SetTextColor(255);
1248 $this->MultiCell(14.9,2, $this->unhtmlentities( _("points allocated") ), 0, 0, 'C');
1249 $this->SetTextColor(0);
1250 $this->SetXY($this->lMargin+1, $savey);
1251 $savey += 3; // save some room for DoB
1252 $next = $this->PrintTable( '', $savey-$tSide, 5);
1253 $this->SetY($next);
1254 }
1255
1256 // print marked paragraph in the table
1257 /*private*/ function PrintTicked( $strg = '', $tick = true ) {
1258 // store current margin values
1259 $savey = $this->GetY();
1260
1261 $celcnt = 0; $this->SetX($this->lMargin + 1);
1262 if( $tick ) {
1263 // use ✔ and ❑ of zapfdingbats font for OK tick
1264 $savex = $this->GetX();
1265 $this->SetXY($this->GetX(), $savey+0.9);
1266 $this->SetFont('zapfdingbats', F_SIZE+3);
1267 $this->Write(0,'q'); // ❑
1268 $this->SetXY($savex+0.1, $savey+0.1);
1269 if ( BW )
1270 $this->SetTextColor(80);
1271 else
1272 $this->SetTextColor(17, 86, 140);
1273 //$this->SetTextColor(0,92,0); // #00BE00 lime
1274 $this->Write(0,'4 ');// ✓
1275 $this->SetTextColor(0);
1276 }
1277 $this->SetXY($this->GetX(), $savey);
1278 $this->SetFont(FONT,'',F_SIZE+0.5);
1279 $celcnt = $this->MultiCell($this->lMargin+$this->colwidth-$this->GetX(), 3, $strg,0,'L');
1280 $this->SetXY($this->lMargin+1, $this->GetY()-1.5);
1281 return($celcnt);
1282 }
1283
1284 // assuree statement
1285 /*public*/ function StatementAssuree( $date = '' ) {
1286 // store current margin values
1287 $cellcnt = 0;
1288
1289 // assuree statement section
1290 $tSide = $this->PrintTable($this->unhtmlentities( _("Applicant's Statement") )); // mark table header
1291
1292 $cellcnt += $this->PrintTicked( $this->unhtmlentities( _("Make sure you have read and agreed with the CAcert Community Agreement") ), false /* no tick */);
1293 if( !BW ) $this->SetTextColor(17, 86, 140);
1294 $ret = $this->Write($this->lasth, WEB.'/'.POLICY.CCA.EXT, NULL);
1295 $this->myLink($this->lMargin+1, $this->GetY()-F_SIZE/2.9, $this->colwidth-2, F_SIZE*2.9/2.9, WEB.'/'.POLICY.CCA.EXT);
1296 $this->Ln(4);
1297 if( !BW ) $this->SetTextColor(0);
1298
1299 $cellcnt += $this->PrintTicked( $this->unhtmlentities( _('I hereby confirm that the information stating my Identity Information above is both true and correct, and request the CAcert Assurer (see below) to witness my identity in the CAcert Assurance Programme.') ), true /* tick */);
1300 $cellcnt += $this->PrintTicked( $this->unhtmlentities( _('I agree to the CAcert Community Agreement.') ), true /* tick */);
1301
1302 $this->Ln(0.5);
1303 $this->SetFont(FONT, F_SIZE+1); $savey = $this->GetY();
1304 $strg = $this->unhtmlentities( _('Date') );
1305 if($date == '')
1306 $strg .= ' ('. $this->unhtmlentities( _("yyyy-mm-dd") ) . ')';
1307 $strg = $strg;
1308 $this->PrintDate( $this->lMargin+1, $savey+1, $strg, $date, 'AssureeDate', 'L');
1309
1310 $strg = $this->unhtmlentities( _("Applicant's signature") );
1311 $this->SetFont(FONT, '', F_SIZE);
1312 $l = $this->GetStringWidth( $strg );
1313 $this->SetXY($this->lMargin+$this->colwidth-$l-3, $savey+1);
1314 $this->Write(0, $strg); $this->Ln(7) ; // and leave some room
1315
1316 // draw the table borders and header at marked ordinate
1317 $next = $this->PrintTable('', $this->GetY()-$tSide);
1318
1319 $this->SetY($next);
1320 }
1321
1322 // assurer statement
1323 /*public*/ function StatementAssurer( $assurer = NULL, $assurance = NULL ) {
1324 if( $assurer == NULL OR $assurance == NULL ) return;
1325
1326 // store current margin values
1327 $TextProps = array('strokeColor'=> LLBLUE, 'value' => '', 'fillColor'=> LBLUE, 'doNotScrole'=> 'true', 'textSize' => '14', 'rotate'=>0);
1328 $cellcnt = 0;
1329
1330 $tSide = $this->PrintTable($this->unhtmlentities( _("Assurer's Statement") )); // mark table ordinate
1331 // put hint on mutaul assurance in pdf file for mouse over
1332 $msg = $this->unhtmlentities( _('One is advised for a mutual assurance. If done so the exact full name, email address and date of birth of the Assurer is also required on a form. In this case the Assuree assures the Assurer as well. In this case two copies are needed of the CAP form.') );
1333 $this->myLink($this->lMargin-7, $tSide-6, 5, 5, $msg,
1334 array('subtype'=> 'Text', 'Open' => 'true',
1335 'c'=> array(173,197,215), 'name'=> 'Comment',
1336 'f'=> array( 'nozoom', 'readonly', 'norotate'),
1337 't'=> $this->unhtmlentities( _('On mutual assurance') )));
1338 // assurer identity info
1339 // name, meeting date, meeting location,
1340 // dob and email address string only is printed when info available
1341 $this->SetXY($this->lMargin+1, $tSide);
1342 $savey = $this->GetY()+2.5;
1343 $this->SetFont(FONT, '', F_SIZE);
1344 $strg = $this->unhtmlentities( _("Assurer's Name") ) . ': ';
1345 if( $assurer['name'] AND
1346 function_exists('utf8_to_ascii') AND
1347 !utf8_is_ascii_ctrl( $assurer['name']) )
1348 $ascii = utf8_to_ascii($assurer['name']);
1349 else
1350 $ascii = '';
1351 if( $ascii == $assurer['name'] ) $ascii = '';
1352 $abbr = $this->Abbreviate( $assurer[ 'name'] );
1353 if( $ascii != '' OR $abbr != '') {
1354 $msg = $this->unhtmlentities( _('The exact name of the assurer may have transliterated characters and/or some given names may be abbreviated. If present the first given name will be shown abbreviated and parentheses around the last part of the given name.\n') );
1355 if( $ascii != '' ) $msg .= '* '. $ascii . "\n";
1356 if( $abbr != '' ) $msg .= '* '. $abbr . "\n";
1357 $this->myLink($this->lMargin-7, $tSide+2, 3, 3, $msg,
1358 array('subtype'=> 'Text', 'Open' => 'false',
1359 'c'=> array(173,197,215), 'name'=> 'Comment',
1360 'f'=> array( 'nozoom', 'readonly', 'norotate'),
1361 't'=> $this->unhtmlentities( _('On the full name of the Assurer') )));
1362 }
1363 $this->Write(0, $strg);
1364 $strg = '';
1365 if( $assurer['dob'] ) $strg = $this->unhtmlentities( _('Date of Birth') );
1366 // if assurer dob is space we print format date
1367 if( $assurer['dob'] == ' ' ) {
1368 $strg .= ' ('. $this->unhtmlentities( _("yyyy-mm-dd") ) .')';
1369 $assurer['dob'] = '';
1370 }
1371 $this->PrintDate($this->lMargin+$this->colwidth-3, $savey-2.5, $strg, $assurer['dob'], 'AssurerDoB', 'R');
1372 $this->SetXY($this->lMargin+2, $savey);
1373 if($assurer[ 'name']) {
1374 $strg = $assurer[ 'name'];
1375 $this->SetFont(FONT, 'B', F_SIZE);
1376 $cellcnt += $this->MultiCell($this->colwidth-22, 3, $strg, 0, 1);
1377 $this->SetFont(FONT, '', F_SIZE);
1378 if( $assurer['email'] ) {
1379 $sx = $this->GetX(); $sy = $this->GetY();
1380 $sw = $this->GetStringWidth($strg) + 2;
1381 $this->SetXY( $this->lMargin+$sw+4, $sy-4.1);
1382 if( !BW ) $this->SetTextColor(17,86,140);
1383 $ret = $this->Write(0, $assurer[ 'email'], 'mailto:'. $assurer[ 'email']); $this->Ln();
1384 if( !BW ) $this->SetTextColor(0);
1385 }
1386 }
1387 $TextProps['value'] = $assurer[ 'name'] ? $assurer[ 'name'] : ' ';
1388 $TextProps['textSize'] = 11; $TextProps['userName'] = $this->unhtmlentities( _('Full exact name of Assurer. On mutual assurance provide date of birth as well.') );
1389 $this->TextField('AssurerName', $this->SetFieldXY($this->lMargin+2, $savey+1, $this->colwidth-60), 5, $TextProps );
1390 $this->SetFieldXY();
1391 $TextProps['value'] = $assurer['email'] ? $assurer['email'] : $this->unhtmlentities( _('email') ) . '?';
1392 $TextProps['userName'] = $this->unhtmlentities( _('On mutual assurance provide email address of Assurer.') );
1393 $this->TextField('AssurerEmail', $this->SetFieldXY($this->lMargin+68.5, $savey+1, 35), 5, $TextProps );
1394 $this->SetFieldXY();
1395 $this->SetXY($this->lMargin+2, $savey+5);
1396
1397 // assurer statements
1398 $cellcnt += $this->PrintTicked( $this->unhtmlentities( _("I, the Assurer, hereby confirm that I have verified the Applicant's Identity Information, I will witness the Applicant's identity in the CAcert Assurance Programme, and allocate Assurance Points.") ), true /* ticked */);
1399 $cellcnt += $this->PrintTicked( $this->unhtmlentities( _('I am a CAcert Community Member, have passed the Assurance Challenge, and have been assured with at least 100 Assurance Points.') ), true /* ticked */);
1400 $this->Ln(1); $savey = $this->GetY();
1401
1402 $strg = $this->unhtmlentities( _('Date') );
1403 if( $assurer['date'] == '' ) $strg .= ' (' . $this->unhtmlentities( _("yyyy-mm-dd") ) . ')';
1404 $strg = $strg;
1405 $this->PrintDate( $this->lMargin+1, $savey, $strg, $assurer['date'], 'AssurerDate', 'L');
1406
1407 $this->SetXY($this->lMargin+1, $savey);
1408 $this->SetFont(FONT, '',F_SIZE);
1409 $strg = $this->unhtmlentities( _("Assurer's signature") );
1410 $this->SetXY($this->lMargin+$this->colwidth-$this->GetStringWidth($strg)-3, $savey);
1411 $this->Write(0, $strg );
1412 $savey = $this->GetY()+7; // leave room for date and signature
1413 if( $this->GetPageHeight()/$this->scale*100.0-$savey > MARGIN+4)
1414 $savey += 2;
1415 $this->SetXY($this->lMargin+1, $savey);
1416 $l = $this->GetPageHeight()/$this->scale*100.0-$this->GetY() - MARGIN;
1417 if($l > 3 ) $l = 3; if( $l > 0 ) $this->Ln($l); // try to come close to margin
1418 $next = $this->PrintTable('', $this->GetY()-$tSide);
1419 $this->SetY($next);
1420 }
1421
1422 // location print within caller table
1423 /*private*/ function PrintLocation( $assurance = NULL ) {
1424 if( $assurance == NULL ) return;
1425 $savey = $this->GetY();
1426 //$this->SetXY($this->GetX(), $savey);
1427 $strg = $this->unhtmlentities( _('Date and location of the face-to-face meeting') ). ': ';
1428 $this->SetFont(FONT,'I', F_SIZE);
1429 $this->Write(0, $strg);
1430 $l = $this->GetStringWidth($strg);
1431 $strg = $assurance['location'];
1432 if( $strg) {
1433 if( $assurance['date'] ) $strg = $assurance['date'] . ', '. $strg;
1434 $strg = $strg;
1435 $this->SetFont(FONT, 'B', F_SIZE);
1436 $this->Write(0,$strg);
1437 }
1438 $TextProps['textSize'] = 11;
1439 $TextProps['value'] = $assurance['location'] ? $assurance['location'] : ' ';
1440 $TextProps['userName'] = $this->unhtmlentities( _('location of the assurance') );
1441 $this->TextField('AssuranceLocation', $this->SetFieldXY($this->lMargin+$l+19, $savey,$this->colwidth-$l-21), 5, $TextProps );
1442 $this->SetFieldXY();
1443 $TextProps['value'] = $assurance['date'] ? $assurance['date'] : ' ';
1444 $TextProps['charLimit'] = 10;
1445 $TextProps['userName'] = $this->unhtmlentities( _("yyyy-mm-dd") ).' '. $this->unhtmlentities( _('date of assurance') );
1446 $this->TextField('AssuranceDate', $this->SetFieldXY($this->lMargin+1+$l, $savey, 17), 5, $TextProps );
1447 $this->SetFieldXY();
1448 $this->SetXY($this->lMargin,$savey+3);
1449 }
1450
1451 // End of CAPPDF TCPDF class extension
1452 }
1453
1454
1455 // --------------------------------------------------------------------------------
1456 // import environmental data -------------------------------------------------------
1457 // get $form, $orientation, $assuree, $assurer, $assurance info
1458 // FONT and BW are set already
1459
1460 // import info
1461 function GET( $key = '' ) {
1462 return ( array_key_exists( $key, $_GET) ? $_GET[$key] : '');
1463 }
1464
1465 // form, CCA and page format info
1466 $page['format'] = strtolower(GET('format')); // A3, A4, A5, letter, legal, etc.
1467 if( !$page['format'] ) $page['format'] = 'a4'; // default
1468 // on landscape orientation we do two half pages
1469 $page['orientation'] = strtolower(GET('orientation'));
1470 if( $page['orientation'] != 'l' AND $page['orientation'] != 'landscape' ) {
1471 // default portrait 1-up
1472 $page['orientation'] = 'p'; // landscape implies 2-up
1473 }
1474 $page['form'] = GET('noform') != '' ? false : true;
1475 // dft is now true it should go to true
1476 $page['policies'] = array();
1477 if( GET('nocca') == '' ) {
1478 if( defined('CCA') ) $page['policies'][] = CCA;
1479 }
1480 // set $page['form'] on 'simplex' or 'duplex' to get CCA on pdf page
1481
1482 // Assurer info
1483 $assurer = array ( 'name' => my_recode(GET('assurer')) ,
1484 'dob' => my_recode(GET('assurerdob')),
1485 'email' => my_recode(GET('assureremail')),
1486 'maxpoints' => intval(my_recode(GET('maxpoints'))) < 0? -1 :
1487 intval(my_recode(GET('maxpoints'))),
1488 'date' => my_recode(GET('assurerdate')) ? my_recode(GET('assurerdate')) :
1489 my_recode(GET('date'))
1490 );
1491 if( $assurer['name'] != '' AND
1492 !utf8_is_ascii_ctrl($assurer['name']) AND
1493 !function_exists('utf8_to_ascii'))
1494 require_once ( UTF8_ASCII );
1495
1496 // assurance info
1497 $assurance = array ( 'location' => my_recode(GET('location')),
1498 'date' => my_recode(GET('assurancedate'))?my_recode(GET('assurancedate')):
1499 my_recode(GET('date')),
1500 'maxpoints'=> intval(my_recode(GET('maxpoints'))) < 0? -1 :
1501 intval(my_recode(GET('maxpoints'))),
1502 'notes' => '' // not yet used
1503 );
1504
1505 // Assuree info
1506 $assuree = array ( 'names' => array( ),
1507 'namecnt' => 0,
1508 'dob' => my_recode(GET('dob')),
1509 'email' => my_recode(GET('email')),
1510 'date' => my_recode(GET('date')) == 'now' ? date('Y-m-d') :
1511 my_recode(GET('date'))
1512 );
1513
1514 // defeats due to history
1515 if( $assuree['date'] == '' AND $assurer['date'] ) $assuree['date'] = $assurer['date'];
1516 if( $assurance['date'] == '' AND $assuree['date'] ) $assurance['date'] = $assuree['date'];
1517 if( $assurer['date'] == 'now' ) $assurer['date'] = date('Y-m-d');
1518 if( $assurance['date'] == 'now' ) $assurance['date'] = date('Y-m-d');
1519 $document = my_recode(GET('document1'));
1520 if( GET('document2') ) $document .= '/'. my_recode(GET('document2'));
1521 // for history sake do special, next can void other arguments...
1522 if( GET('name') ) $_GET['name1'] = GET('name');
1523 if( $document ) $_GET['name1ID'] = $document;
1524
1525 function Dstr( $strg = '', $cnt = 1 ) {
1526 return( sprintf("name%d%s", $cnt, $strg));
1527 }
1528 $j = 0; // after two successive empty names we stop
1529 for( $i = 1; $i <= 9 AND $j < 2; $i++) { // max 9 names we only print 4 max...
1530 $name = my_recode(GET(Dstr('', $i)));
1531 if( $name ) { $j = 0;
1532 $assuree[ 'namecnt' ]++;
1533 $assuree[ 'names' ] [] = array (
1534 'name' => $name ? $name : '',
1535 'idtype' => my_recode(GET(Dstr('ID',$i)))? my_recode(GET(Dstr('ID',$i))) : '',
1536 'points' => my_recode(GET(Dstr('Pnts',$i))) != '' ? intval(my_recode(GET(Dstr('Pnts',$i)))) : -1
1537 );
1538 if( $name != '' AND
1539 !utf8_is_ascii_ctrl($name) AND
1540 !function_exists('utf8_to_ascii'))
1541 require_once ( UTF8_ASCII );
1542 } else $j++;
1543 }
1544
1545 // try to get policy documents names to be printed off
1546 $j = 0; // after two successive empty name we stop searching
1547 for( $i = 1; $i <= 9 AND $j<2; $i++ ) {
1548 $name = GET(sprintf("policy%d", $i));
1549 if( $name != '' ) { $page['policies'][] = $name; $j = 0; }
1550 else $j++;
1551 }
1552
1553 unset( $document ); unset( $i ); unset( $j); // unset($_GET);
1554 // end of arguments imports
1555
1556 header('Expires: '.gmdate("D, j M Y G:i:s \G\M\T", time()+10800));
1557 header('Content-Disposition: attachment; filename=CAcert cap.pdf');
1558 header('Cache-Control: public, max-age=10800');
1559 header('Pragma: cache');
1560 // Content-Type and Content Length is done by tcpdf package
1561
1562 // create new PDF document =====================================================
1563 $pdf = new CAPPDF(
1564 /* PDF_PAGE_ORIENTATION */ $page['orientation'],
1565 PDF_UNIT /* mm */,
1566 /* PDF_PAGE_FORMAT */ $page['format'],
1567 true
1568 );
1569 $pdf->SetFormat( $page['format'] ); // set paper size scaling
1570
1571 // protection is encryption and this will cause 3.5 times performance loss
1572 // $pdf->SetProtection(array('print', 'annot-forms'));
1573
1574 // set document property information
1575 $pdf->SetCreator('LibreSSL - CAcert web application');
1576 $pdf->SetAuthor('© ' . date('Y') . ' CAcert Inc., Australia.');
1577 $pdf->SetKeywords('X.509, Assurance Programme, CAP form, Community Agreement, Digital Certificates, CAcert');
1578 $pdf->SetTitle('CAcert Assurance Programme');
1579 $pdf->SetSubject('CAP form V'.$pdf->Version().', generated ' . date("Y-n-j H:i:s T"));
1580 if( GET('watermark') != '') $pdf->Watermark = my_recode(GET('watermark'));
1581 // requires zlib and will decrease response time but increase bandwidth
1582 // if no zlib is found, automatically no compression is done
1583 $pdf->SetCompression(true); // turn it off when more pperformance is needed
1584
1585 // AddSJISFont function is not present in tcpdf package !!!!
1586
1587 //set auto page breaks
1588 $pdf->SetAutoPageBreak(TRUE, MARGIN*0.707);
1589
1590 //set image scale factor
1591 $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
1592
1593 //set some language-dependent strings
1594 $pdf->setLanguageArray($l);
1595
1596 //initialize document
1597 $pdf->AliasNbPages();
1598
1599 // AND GENERATE THE FORM ===================================
1600 // generation properties which have been set from environment:
1601 // deflt: BW (color), FONT (free Sans Vera), portrait 1-up, A5, duplex, with CCA
1602 // orientation landscape gives 2-up
1603 if ( FONT == 'SJIS') $pdf->AddSJISFont();
1604 $pdf->PrintForm($assuree, $assurer, $assurance, $page);
1605 $pdf->setViewerPreferences($pdf->ViewerPrefs);
1606
1607 //Close and output PDF document
1608 $pdf->Output('CAcert CAP.pdf', 'I');
1609
1610 //============================================================+
1611 // END OF FILE
1612 //============================================================+
1613 ?>