~chroot64bit/zivios/gentoo-experimental

« back to all changes in this revision

Viewing changes to application/library/Zend/Captcha/Image.php

  • Committer: Mustafa A. Hashmi
  • Date: 2008-12-04 13:32:21 UTC
  • Revision ID: mhashmi@zivios.org-20081204133221-0nd1trunwevijj38
Inclusion of new installation framework with ties to zend layout and dojo layout

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Zend Framework
 
4
 *
 
5
 * LICENSE
 
6
 *
 
7
 * This source file is subject to the new BSD license that is bundled
 
8
 * with this package in the file LICENSE.txt.
 
9
 * It is also available through the world-wide-web at this URL:
 
10
 * http://framework.zend.com/license/new-bsd
 
11
 * If you did not receive a copy of the license and are unable to
 
12
 * obtain it through the world-wide-web, please send an email
 
13
 * to license@zend.com so we can send you a copy immediately.
 
14
 *
 
15
 * @category   Zend
 
16
 * @package    Zend_Captcha
 
17
 * @subpackage Adapter
 
18
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
19
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 
20
 */
 
21
 
 
22
/** Zend_Captcha_Word */
 
23
require_once 'Zend/Captcha/Word.php';
 
24
 
 
25
/**
 
26
 * Image-based captcha element 
 
27
 * 
 
28
 * Generates image displaying random word
 
29
 * 
 
30
 * @category   Zend
 
31
 * @package    Zend_Captcha
 
32
 * @subpackage Adapter
 
33
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
34
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 
35
 * @version    $Id: $
 
36
 */
 
37
class Zend_Captcha_Image extends Zend_Captcha_Word
 
38
{
 
39
    /**
 
40
     * Directory for generated images
 
41
     *
 
42
     * @var string
 
43
     */
 
44
    protected $_imgDir = "./images/captcha/";
 
45
 
 
46
    /**
 
47
     * URL for accessing images
 
48
     *
 
49
     * @var string
 
50
     */
 
51
    protected $_imgUrl = "/images/captcha/";
 
52
    
 
53
    /**
 
54
     * Image's alt tag content
 
55
     *
 
56
     * @var string
 
57
     */
 
58
    protected $_imgAlt = "";
 
59
 
 
60
    /**
 
61
     * Image suffix (including dot)
 
62
     *
 
63
     * @var string
 
64
     */
 
65
    protected $_suffix = ".png";
 
66
 
 
67
    /**
 
68
     * Image width
 
69
     *
 
70
     * @var int
 
71
     */
 
72
    protected $_width = 200;
 
73
 
 
74
    /**
 
75
     * Image height
 
76
     *
 
77
     * @var int
 
78
     */
 
79
    protected $_height = 50;
 
80
 
 
81
    /**
 
82
     * Font size
 
83
     *
 
84
     * @var int
 
85
     */
 
86
    protected $_fsize = 24;
 
87
 
 
88
    /**
 
89
     * Image font file
 
90
     *
 
91
     * @var string
 
92
     */
 
93
    protected $_font;
 
94
 
 
95
    /**
 
96
     * Image to use as starting point
 
97
     * Default is blank image. If ptovided, should be PNG image.
 
98
     *
 
99
     * @var string
 
100
     */
 
101
    protected $_startImage;
 
102
    /**
 
103
     * How frequently to execute garbage collection
 
104
     *
 
105
     * @var int
 
106
     */
 
107
    protected $_gcFreq = 10;
 
108
    
 
109
    /**
 
110
     * How long to keep generated images
 
111
     *
 
112
     * @var int
 
113
     */
 
114
    protected $_expiration = 600;
 
115
 
 
116
    /**
 
117
     * Number of noise dots on image 
 
118
     * Used twice - before and after transform
 
119
     *
 
120
     * @var int
 
121
     */
 
122
    protected $_dotNoiseLevel = 100;
 
123
    /**
 
124
     * Number of noise lines on image
 
125
     * Used twice - before and after transform
 
126
     *
 
127
     * @var int
 
128
     */
 
129
    protected $_lineNoiseLevel = 5;
 
130
    /**
 
131
     * @return string
 
132
     */
 
133
    public function getImgAlt ()
 
134
    {
 
135
        return $this->_imgAlt;
 
136
    }
 
137
    /**
 
138
     * @return string
 
139
     */
 
140
    public function getStartImage ()
 
141
    {
 
142
        return $this->_startImage;
 
143
    }
 
144
    /**
 
145
     * @return int
 
146
     */
 
147
    public function getDotNoiseLevel ()
 
148
    {
 
149
        return $this->_dotNoiseLevel;
 
150
    }
 
151
    /**
 
152
     * @return int
 
153
     */
 
154
    public function getLineNoiseLevel ()
 
155
    {
 
156
        return $this->_lineNoiseLevel;
 
157
    }
 
158
    /**
 
159
     * Get captcha expiration
 
160
     *
 
161
     * @return int
 
162
     */
 
163
    public function getExpiration() 
 
164
    {
 
165
        return $this->_expiration;
 
166
    }
 
167
    
 
168
    /**
 
169
     * Get garbage collection frequency
 
170
     *
 
171
     * @return int
 
172
     */
 
173
    public function getGcFreq() 
 
174
    {
 
175
        return $this->_gcFreq;
 
176
    }
 
177
    /**
 
178
     * Get font to use when generating captcha
 
179
     *
 
180
     * @return string
 
181
     */
 
182
    public function getFont() 
 
183
    {
 
184
        return $this->_font;
 
185
    }
 
186
    
 
187
    /**
 
188
     * Get font size
 
189
     *
 
190
     * @return int
 
191
     */
 
192
    public function getFontSize() 
 
193
    {
 
194
        return $this->_fsize;
 
195
    }
 
196
    
 
197
    /**
 
198
     * Get captcha image height
 
199
     *
 
200
     * @return int
 
201
     */
 
202
    public function getHeight() 
 
203
    {
 
204
        return $this->_height;
 
205
    }
 
206
    
 
207
    /**
 
208
     * Get captcha image directory
 
209
     *
 
210
     * @return string
 
211
     */
 
212
    public function getImgDir() 
 
213
    {
 
214
        return $this->_imgDir;
 
215
    }
 
216
    /**
 
217
     * Get captcha image base URL
 
218
     *
 
219
     * @return string
 
220
     */
 
221
    public function getImgUrl() 
 
222
    {
 
223
        return $this->_imgUrl;
 
224
    }
 
225
    /**
 
226
     * Get captcha image file suffix
 
227
     *
 
228
     * @return string
 
229
     */
 
230
    public function getSuffix() 
 
231
    {
 
232
        return $this->_suffix;
 
233
    }
 
234
    /**
 
235
     * Get captcha image width
 
236
     *
 
237
     * @return int
 
238
     */
 
239
    public function getWidth() 
 
240
    {
 
241
        return $this->_width;
 
242
    }
 
243
    /**
 
244
     * @param string $startImage
 
245
     */
 
246
    public function setStartImage ($startImage)
 
247
    {
 
248
        $this->_startImage = $startImage;
 
249
        return $this;
 
250
    }
 
251
    /**
 
252
     * @param int $dotNoiseLevel
 
253
     */
 
254
    public function setDotNoiseLevel ($dotNoiseLevel)
 
255
    {
 
256
        $this->_dotNoiseLevel = $dotNoiseLevel;
 
257
        return $this;
 
258
    }
 
259
   /**
 
260
     * @param int $lineNoiseLevel
 
261
     */
 
262
    public function setLineNoiseLevel ($lineNoiseLevel)
 
263
    {
 
264
        $this->_lineNoiseLevel = $lineNoiseLevel;
 
265
        return $this;
 
266
    }
 
267
    
 
268
    /**
 
269
     * Set captcha expiration
 
270
     *
 
271
     * @param int $expiration
 
272
     * @return Zend_Captcha_Image
 
273
     */
 
274
    public function setExpiration($expiration)
 
275
    {
 
276
        $this->_expiration = $expiration;
 
277
        return $this;
 
278
    }
 
279
    
 
280
    /**
 
281
     * Set garbage collection frequency
 
282
     *
 
283
     * @param int $gcFreq
 
284
     * @return Zend_Captcha_Image
 
285
     */
 
286
    public function setGcFreq($gcFreq) 
 
287
    {
 
288
        $this->_gcFreq = $gcFreq;
 
289
        return $this;
 
290
    }
 
291
 
 
292
    /**
 
293
     * Set captcha font
 
294
     *
 
295
     * @param  string $font
 
296
     * @return Zend_Captcha_Image
 
297
     */
 
298
    public function setFont($font) 
 
299
    {
 
300
        $this->_font = $font;
 
301
        return $this;
 
302
    }
 
303
    
 
304
    /**
 
305
     * Set captcha font size
 
306
     *
 
307
     * @param  int $fsize
 
308
     * @return Zend_Captcha_Image
 
309
     */
 
310
    public function setFontSize($fsize) 
 
311
    {
 
312
        $this->_fsize = $fsize;
 
313
        return $this;
 
314
    }
 
315
    
 
316
    /**
 
317
     * Set captcha image height
 
318
     *
 
319
     * @param  int $height
 
320
     * @return Zend_Captcha_Image
 
321
     */
 
322
    public function setHeight($height) 
 
323
    {
 
324
        $this->_height = $height;
 
325
        return $this;
 
326
    }
 
327
    
 
328
    /**
 
329
     * Set captcha image storage directory
 
330
     *
 
331
     * @param  string $imgDir
 
332
     * @return Zend_Captcha_Image
 
333
     */
 
334
    public function setImgDir($imgDir) 
 
335
    {
 
336
        $this->_imgDir = rtrim($imgDir, "/\\") . '/';
 
337
        return $this;
 
338
    }
 
339
    
 
340
    /**
 
341
     * Set captcha image base URL
 
342
     *
 
343
     * @param  string $imgUrl
 
344
     * @return Zend_Captcha_Image
 
345
     */
 
346
    public function setImgUrl($imgUrl) 
 
347
    {
 
348
        $this->_imgUrl = rtrim($imgUrl, "/\\") . '/';
 
349
        return $this;
 
350
    }
 
351
    /**
 
352
     * @param string $imgAlt
 
353
     */
 
354
    public function setImgAlt ($imgAlt)
 
355
    {
 
356
        $this->_imgAlt = $imgAlt;
 
357
        return $this;
 
358
    }
 
359
    
 
360
    /**
 
361
     * Set captch image filename suffix
 
362
     *
 
363
     * @param  string $suffix
 
364
     * @return Zend_Captcha_Image
 
365
     */
 
366
    public function setSuffix($suffix) 
 
367
    {
 
368
        $this->_suffix = $suffix;
 
369
        return $this;
 
370
    }
 
371
    
 
372
    /**
 
373
     * Set captcha image width
 
374
     *
 
375
     * @param  int $width
 
376
     * @return Zend_Captcha_Image
 
377
     */
 
378
    public function setWidth($width) 
 
379
    {
 
380
        $this->_width = $width;
 
381
        return $this;
 
382
    }
 
383
    
 
384
    /**
 
385
     * Generate random frequency
 
386
     * 
 
387
     * @return float
 
388
     */
 
389
    protected function _randomFreq() 
 
390
    {
 
391
        return mt_rand(700000, 1000000) / 15000000;
 
392
    }
 
393
 
 
394
    /**
 
395
     * Generate random phase
 
396
     * 
 
397
     * @return float
 
398
     */
 
399
    protected function _randomPhase() 
 
400
    {
 
401
        // random phase from 0 to pi
 
402
        return mt_rand(0, 3141592) / 1000000;
 
403
    }
 
404
 
 
405
    /**
 
406
     * Generate random character size
 
407
     * 
 
408
     * @return int
 
409
     */
 
410
    protected function _randomSize() 
 
411
    {
 
412
        return mt_rand(300, 700) / 100;
 
413
    }
 
414
    
 
415
    /**
 
416
     * Generate captcha
 
417
     * 
 
418
     * @return string captcha ID
 
419
     */
 
420
    public function generate()
 
421
    {
 
422
        $id = parent::generate();
 
423
        $this->_generateImage($id, $this->getWord());
 
424
        
 
425
        if (mt_rand(0, $this->getGcFreq()) == 1) {
 
426
            $this->_gc();
 
427
        }
 
428
        return $id;
 
429
    }
 
430
    
 
431
    /**
 
432
     * Generate image captcha
 
433
     * 
 
434
     * Override this function if you want different image generator
 
435
     * Wave transform from http://www.captcha.ru/captchas/multiwave/
 
436
     *
 
437
     * @param string $id Captcha ID
 
438
     * @param string $word Captcha word
 
439
     */
 
440
    protected function _generateImage($id, $word) 
 
441
    { 
 
442
        if (!extension_loaded("gd")) {
 
443
            require_once 'Zend/Captcha/Exception.php';
 
444
            throw new Zend_Captcha_Exception("Image CAPTCHA requires GD extension");
 
445
        }
 
446
 
 
447
        if (!function_exists("imagepng")) {
 
448
            require_once 'Zend/Captcha/Exception.php';
 
449
            throw new Zend_Captcha_Exception("Image CAPTCHA requires PNG support");
 
450
        }
 
451
 
 
452
        if (!function_exists("imageftbbox")) {
 
453
            require_once 'Zend/Captcha/Exception.php';
 
454
            throw new Zend_Captcha_Exception("Image CAPTCHA requires FT fonts support");
 
455
        }
 
456
 
 
457
        $font = $this->getFont();
 
458
 
 
459
        if (empty($font)) {
 
460
            require_once 'Zend/Captcha/Exception.php';
 
461
            throw new Zend_Captcha_Exception("Image CAPTCHA requires font");
 
462
        }
 
463
        
 
464
        $w     = $this->getWidth();
 
465
        $h     = $this->getHeight();
 
466
        $fsize = $this->getFontSize();
 
467
        
 
468
        $img_file   = $this->getImgDir() . $id . $this->getSuffix();
 
469
        if(empty($this->_startImage)) {
 
470
            $img        = imagecreatetruecolor($w, $h);
 
471
        } else {
 
472
            $img = imagecreatefrompng($this->_startImage);
 
473
            if(!$img) {
 
474
                require_once 'Zend/Captcha/Exception.php';
 
475
                throw new Zend_Captcha_Exception("Can not load start image");                
 
476
            }
 
477
            $w = imagesx($img);
 
478
            $h = imagesy($img);
 
479
        }
 
480
        $text_color = imagecolorallocate($img, 0, 0, 0);
 
481
        $bg_color   = imagecolorallocate($img, 255, 255, 255);
 
482
        imagefilledrectangle($img, 0, 0, $w-1, $h-1, $bg_color);
 
483
        $textbox = imageftbbox($fsize, 0, $font, $word);
 
484
        $x = ($w - ($textbox[2] - $textbox[0])) / 2;
 
485
        $y = ($h - ($textbox[7] - $textbox[1])) / 2;
 
486
        imagefttext($img, $fsize, 0, $x, $y, $text_color, $font, $word);
 
487
        
 
488
       // generate noise
 
489
        for ($i=0; $i<$this->_dotNoiseLevel; $i++) {
 
490
           imagefilledellipse($img, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color);
 
491
        }
 
492
        for($i=0; $i<$this->_lineNoiseLevel; $i++) {
 
493
           imageline($img, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color);
 
494
        }
 
495
        
 
496
        // transformed image
 
497
        $img2     = imagecreatetruecolor($w, $h);
 
498
        $bg_color = imagecolorallocate($img2, 255, 255, 255);
 
499
        imagefilledrectangle($img2, 0, 0, $w-1, $h-1, $bg_color);
 
500
        // apply wave transforms
 
501
        $freq1 = $this->_randomFreq();
 
502
        $freq2 = $this->_randomFreq();
 
503
        $freq3 = $this->_randomFreq();
 
504
        $freq4 = $this->_randomFreq();
 
505
 
 
506
        $ph1 = $this->_randomPhase();
 
507
        $ph2 = $this->_randomPhase();
 
508
        $ph3 = $this->_randomPhase();
 
509
        $ph4 = $this->_randomPhase();
 
510
 
 
511
        $szx = $this->_randomSize();
 
512
        $szy = $this->_randomSize();
 
513
 
 
514
        for ($x = 0; $x < $w; $x++) {
 
515
            for ($y = 0; $y < $h; $y++) {
 
516
                $sx = $x + (sin($x*$freq1 + $ph1) + sin($y*$freq3 + $ph3)) * $szx;
 
517
                $sy = $y + (sin($x*$freq2 + $ph2) + sin($y*$freq4 + $ph4)) * $szy;
 
518
    
 
519
                if ($sx < 0 || $sy < 0 || $sx >= $w - 1 || $sy >= $h - 1) { 
 
520
                    continue;
 
521
                } else {
 
522
                    $color    = (imagecolorat($img, $sx, $sy) >> 16)         & 0xFF;
 
523
                    $color_x  = (imagecolorat($img, $sx + 1, $sy) >> 16)     & 0xFF;
 
524
                    $color_y  = (imagecolorat($img, $sx, $sy + 1) >> 16)     & 0xFF;
 
525
                    $color_xy = (imagecolorat($img, $sx + 1, $sy + 1) >> 16) & 0xFF;
 
526
                }
 
527
                if ($color == 255 && $color_x == 255 && $color_y == 255 && $color_xy == 255) {
 
528
                    // ignore background
 
529
                    continue;
 
530
                } elseif ($color == 0 && $color_x == 0 && $color_y == 0 && $color_xy == 0) {
 
531
                    // transfer inside of the image as-is
 
532
                    $newcolor = 0;
 
533
                } else {
 
534
                    // do antialiasing for border items
 
535
                    $frac_x  = $sx-floor($sx);
 
536
                    $frac_y  = $sy-floor($sy);
 
537
                    $frac_x1 = 1-$frac_x;
 
538
                    $frac_y1 = 1-$frac_y;
 
539
 
 
540
                    $newcolor = $color    * $frac_x1 * $frac_y1
 
541
                              + $color_x  * $frac_x  * $frac_y1
 
542
                              + $color_y  * $frac_x1 * $frac_y
 
543
                              + $color_xy * $frac_x  * $frac_y;
 
544
                }
 
545
                imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newcolor, $newcolor, $newcolor));
 
546
            }
 
547
        }
 
548
       
 
549
        // generate noise
 
550
        for ($i=0; $i<$this->_dotNoiseLevel; $i++) {
 
551
            imagefilledellipse($img2, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color);
 
552
        }
 
553
        for ($i=0; $i<$this->_lineNoiseLevel; $i++) {
 
554
           imageline($img2, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color);
 
555
        }
 
556
        
 
557
        imagepng($img2, $img_file);
 
558
        imagedestroy($img);
 
559
        imagedestroy($img2);
 
560
    }
 
561
    
 
562
    /**
 
563
     * Remove old files from image directory
 
564
     *
 
565
     */
 
566
    protected function _gc()
 
567
    {
 
568
        $expire = time() - $this->getExpiration();
 
569
        foreach (new DirectoryIterator($this->getImgDir()) as $file) {
 
570
            if (!$file->isDot() && !$file->isDir()) {
 
571
                if ($file->getMTime() < $expire) {
 
572
                    unlink($file->getPathname());
 
573
                }
 
574
            }
 
575
        }
 
576
    }
 
577
    
 
578
    /**
 
579
     * Display the captcha
 
580
     *
 
581
     * @param Zend_View $view
 
582
     * @param mixed $element
 
583
     * @return string
 
584
     */
 
585
    public function render(Zend_View_Interface $view, $element = null)
 
586
    {
 
587
        return '<img alt="'.$this->getImgAlt().'" src="' . $this->getImgUrl() . $this->getId() . $this->getSuffix() . '"/><br/>';
 
588
    }
 
589
}