~quam-plures-core/quam-plures/qp5_colls-blogs_chaps-cats

« back to all changes in this revision

Viewing changes to qp_plugins/captcha_img_plugin/_captcha_img.plugin.php

  • Committer: EdB
  • Date: 2013-03-12 06:26:03 UTC
  • Revision ID: 1912webworks@gmail.com-20130312062603-tnlb5zco5mglydqj
lots of changes in this branch. tested and functional, but not going into merge just yet ...

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
<?php
2
2
/**
3
 
 * This file implements the Captcha Images plugin.
 
3
 * This file implements the CaptchaImage plugin
4
4
 *
5
5
 * It displays a captcha image through {@link CaptchaValidated()} and validates
6
 
 * it in {@link CaptchaValidated()}.
7
 
 *
8
 
 * The image gets served by an srvc method ({@link srvc_display_captcha()} and the
9
 
 * private/public keys get stored in the user's Session.
10
 
 * 
11
 
 * The core functionality was provided by Ben Franske and then converted and improved
12
 
 * by Daniel HAHLER - {@link http://daniel.hahler.de/} into a plugin for b2evolution.
13
 
 *
14
 
 * Plugin ported to Quam Plures by Bush League Critic.
 
6
 * it in {@link CaptchaValidated()}. The image gets served by an srvc method
 
7
 * ({@link srvc_display_captcha()} and the private/public keys get stored in the
 
8
 * user's Session.
 
9
 *
 
10
 * The core functionality was provided by Ben Franske and then converted and
 
11
 * improved by Daniel HAHLER - {@link http://daniel.hahler.de/} into a plugin
 
12
 * for b2evolution, and ported to Quam Plures by Bush League Critic.
15
13
 *
16
14
 * Based on hn_captcha Version 1.2 by Horst Nogajski
17
15
 * - hn_captcha is a fork of ocr_captcha by Julien Pachet
18
16
 *
19
 
 * Quam Plures - {@link http://quamplures.net/}
20
 
 * Released under GNU GPL License - {@link http://quamplures.net/license.html}
21
 
 * @copyright (c) 2010 by the Quam Plures developers - {@link http://quamplures.net/}
22
 
 *
 
17
 * @author {@link http://wonderwinds.com/ Ed Bennett}
 
18
 * @author {@link http://www.bushleaguecritic.com/ Bush League Critic}
 
19
 * @author {@link http://daniel.hahler.de/ Daniel HAHLER}
 
20
 * @author Ben Franske
 
21
 * @copyright (c) 2010 by {@link http://quamplures.net/ the Quam Plures project}
 
22
 * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3
23
23
 * @package plugins
24
24
 * @subpackage CaptchaImage
25
 
 *
26
25
 */
27
 
if( !defined('QP_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
28
 
 
 
26
if(!defined('QP_MAIN_INIT')) die('fail');
29
27
 
30
28
/**
31
29
 * @package plugins
39
37
        var $group = 'antispam';
40
38
        var $number_of_installs = 1;
41
39
        var $priority = 20;
42
 
        var $version = '0.1';
43
 
 
 
40
        var $version = '1.0';
44
41
 
45
42
        /**
46
43
         * @see Plugin::PluginInit()
48
45
        function PluginInit( & $params )
49
46
        {
50
47
                $this->name = $this->T_('Captcha Images');
51
 
                $this->short_desc = $this->T_('Use generated images to tell humans and robots apart.');
52
 
                $this->long_desc = $this->T_('Use generated images to tell humans and robots apart.');
 
48
                $this->short_desc = $this->T_('Generates images to tell humans and robots apart.');
 
49
                $this->long_desc = $this->T_('A <a href="http://www.captcha.net/">CAPTCHA</a> is a program that protects websites against bots by generating and grading tests that humans can pass but current computer programs cannot.');
53
50
 
54
51
                if( $params['is_installed'] && rand(0, 100) == 42 )
55
52
                {
61
58
 
62
59
 
63
60
        /**
 
61
         * @see Plugin::BeforeEnable()
 
62
         */
 
63
        function BeforeEnable()
 
64
        {
 
65
                if( $error = $this->validate_gd_requirements() )
 
66
                {
 
67
                        return $error;
 
68
                }
 
69
 
 
70
                if( $error = $this->load_fonts() )
 
71
                {
 
72
                        return $error;
 
73
                }
 
74
 
 
75
                return true;
 
76
        }
 
77
 
 
78
 
 
79
        /**
 
80
         * @see Plugin::AfterInstall()
 
81
         */
 
82
        function AfterInstall()
 
83
        {
 
84
                $this->Settings->set( 'public_key_salt', md5( mt_rand() ) );
 
85
                $this->Settings->dbupdate();
 
86
        }
 
87
 
 
88
 
 
89
        /**
 
90
         * @see Plugin::GetDbLayout()
 
91
         */
 
92
        function GetDbLayout()
 
93
        {
 
94
                return array(
 
95
                        "CREATE TABLE IF NOT EXISTS ".$this->get_sql_table('data')." (
 
96
                                cpt_public VARCHAR( 32 ) NOT NULL,
 
97
                                cpt_private VARCHAR( 50 ) NOT NULL,
 
98
                                cpt_sess_ID INT UNSIGNED NOT NULL,
 
99
                                cpt_timestamp TIMESTAMP NOT NULL,
 
100
                                cpt_invalid TINYINT UNSIGNED NOT NULL DEFAULT 0,
 
101
                                PRIMARY KEY( cpt_public ),
 
102
                                KEY cpt_timestamp( cpt_timestamp )
 
103
                        )",
 
104
 
 
105
                        // Holds keys for whitelisted trackback URLs:
 
106
                        "CREATE TABLE IF NOT EXISTS ".$this->get_sql_table('trackbacks_wl')." (
 
107
                                tbwl_ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
 
108
                                tbwl_item_ID INT UNSIGNED NOT NULL,
 
109
                                tbwl_key VARCHAR( 32 ) NOT NULL,
 
110
                                tbwl_timestamp TIMESTAMP NOT NULL,
 
111
                                PRIMARY KEY( tbwl_ID )
 
112
                        )",
 
113
                );
 
114
        }
 
115
 
 
116
 
 
117
        /**
 
118
         * @see Plugin::GetDependencies()
 
119
         */
 
120
        function GetDependencies()
 
121
        {
 
122
                return array(
 
123
                        'requires' => array(
 
124
                                'app_min' => '0.0.0'
 
125
                        )
 
126
                );
 
127
        }
 
128
 
 
129
 
 
130
        /**
64
131
         * @see Plugin::GetDefaultSettings()
65
132
         */
66
133
        function GetDefaultSettings( & $params )
70
137
                $default_settings = array(
71
138
                        'use_for_start' => array(
72
139
                                'label' => $this->T_('Use For'),
 
140
                                'type' => 'layout',
73
141
                                'layout' => 'begin_fieldset',
74
142
                        ),
75
143
                        'use_for_members_level_below' => array(
76
144
                                'label' => $this->T_('Blog Members'),
 
145
                                'type' => 'integer',
77
146
                                'defaultvalue' => 0,
 
147
                                'size' => 3,
 
148
                                'valid_range' => array( 'min' => 0, 'max' => 11),
78
149
                                'note' => $this->T_('Use this plugin for members of the target blog, if their level is below this.'),
79
 
                                'type' => 'integer',
80
 
                                'size' => 3,
81
 
                                'valid_range' => array( 'min'=>0, 'max'=>11),
82
150
                        ),
83
151
                        'use_for_level_below' => array(
84
152
                                'label' => $this->T_('Registered Users'),
85
 
                                'defaultvalue' => 2, // new users can not bypass the captcha ... was ($Settings->get('newusers_level') + 1) but can't do that during installation
 
153
                                'type' => 'integer',
 
154
                                'defaultvalue' => 2, // new users can not bypass the captcha ... was ( $Settings->get( 'newusers_level' ) + 1) but can't do that during installation
 
155
                                'size' => 3,
 
156
                                'valid_range' => array( 'min' => 0, 'max' => 11),
86
157
                                'note' => $this->T_('Use this plugin for registered users, if their level is below this.'),
87
 
                                'type' => 'integer',
88
 
                                'size' => 3,
89
 
                                'valid_range' => array( 'min'=>0, 'max'=>11),
90
 
                        ),
91
 
                        'use_for_end' => array(
92
 
                                'layout' => 'end_fieldset',
93
 
                        ),
 
158
                        ),
 
159
                        'use_for_end' => array( 'layout' => 'end_fieldset' ),
94
160
                        'random_start' => array(
95
161
                                'label' => $this->T_('Randomizer settings'),
 
162
                                'type' => 'layout',
96
163
                                'layout' => 'begin_fieldset',
97
164
                        ),
98
165
                        'timeout_key' => array(
99
166
                                'label' => $this->T_('Timeout for keys'),
 
167
                                'type' => 'integer',
100
168
                                'defaultvalue' => 120, // timeout: 2 hours
 
169
                                'size' => 5,
101
170
                                'note' => $this->T_('in minutes. When does the generated captcha expire?'),
102
 
                                'size' => 5,
103
 
                                'type' => 'integer',
104
171
                        ),
105
172
                        'use_websafecolors' => array(
106
173
                                'label' => $this->T_('Websafe colors'),
 
174
                                'type' => 'checkbox',
107
175
                                'defaultvalue' => 0,
108
176
                                'note' => $this->T_('Use web safe colors (only 216 colors)?'),
109
 
                                'type' => 'checkbox',
110
177
                        ),
111
178
                        'noise' => array(
112
179
                                'label' => $this->T_('Noise'),
 
180
                                'type' => 'checkbox',
113
181
                                'defaultvalue' => 1,
114
182
                                'note' => $this->T_('Use background noise characters instead of a grid.'),
115
 
                                'type' => 'checkbox',
116
183
                        ),
117
184
                        'noisefactor' => array(
118
185
                                'label' => $this->T_('Noise factor'),
 
186
                                'type' => 'integer',
119
187
                                'defaultvalue' => 9,
 
188
                                'size' => 5,
120
189
                                'note' => $this->T_('Noise multiplier (number of characters gets multipled by this to define noise).'),
121
 
                                'type' => 'integer',
122
 
                                'size' => 5,
123
190
                        ),
124
191
                        'minchars' => array(
125
192
                                'label' => $this->T_('Min chars'),
 
193
                                'type' => 'integer',
126
194
                                'defaultvalue' => 4,
 
195
                                'size' => 4,
127
196
                                'note' => $this->T_('The minimum number of characters to use.'),
128
 
                                'type' => 'integer',
129
 
                                'size' => 4,
130
197
                        ),
131
198
                        'maxchars' => array(
132
199
                                'label' => $this->T_('Max chars'),
 
200
                                'type' => 'integer',
133
201
                                'defaultvalue' => 6,
 
202
                                'size' => 5,
134
203
                                'note' => $this->T_('The maximum number of characters to use.'),
135
 
                                'type' => 'integer',
136
 
                                'size' => 5,
137
204
                        ),
138
205
                        'min_fontsize' => array(
139
206
                                'label' => $this->T_('Min font size'),
 
207
                                'type' => 'integer',
140
208
                                'defaultvalue' => 20,
 
209
                                'size' => 5,
141
210
                                'note' => $this->T_('The minimum font size to use.'),
142
 
                                'type' => 'integer',
143
 
                                'size' => 5,
144
211
                        ),
145
212
                        'max_fontsize' => array(
146
213
                                'label' => $this->T_('Max font size'),
 
214
                                'type' => 'integer',
147
215
                                'defaultvalue' => 30,
 
216
                                'size' => 5,
148
217
                                'note' => $this->T_('The maximum font size to use.'),
149
 
                                'type' => 'integer',
150
 
                                'size' => 5,
151
218
                        ),
152
219
                        'max_rotation' => array(
153
220
                                'label' => $this->T_('Max rotation'),
 
221
                                'type' => 'integer',
154
222
                                'defaultvalue' => 25,
 
223
                                'size' => 5,
155
224
                                'note' => $this->T_('The maximum degrees a char should be rotated. 25 means a random rotation between -25 and 25.'),
156
 
                                'type' => 'integer',
157
 
                                'size' => 5,
158
225
                        ),
159
226
                        'jpegquality' => array(
160
227
                                'label' => $this->T_('JPEG quality'),
 
228
                                'type' => 'integer',
161
229
                                'defaultvalue' => 80,
 
230
                                'maxlength' => 3,
 
231
                                'size' => 5,
162
232
                                'note' => $this->T_('JPEG image quality.'),
163
 
                                'type' => 'integer',
164
 
                                'size' => 5,
165
 
                                'maxlength' => 3,
166
 
                        ),
167
 
                        'random_end' => array(
168
 
                                'layout' => 'end_fieldset',
169
 
                        ),
 
233
                        ),
 
234
                        'random_end' => array( 'layout' => 'end_fieldset' ),
170
235
                        'advanced_start' => array(
171
236
                                'label' => $this->T_('Advanced settings'),
 
237
                                'type' => 'layout',
172
238
                                'layout' => 'begin_fieldset',
173
239
                        ),
174
240
                        'validchars' => array(
175
241
                                'label' => $this->T_('Valid characters'),
176
242
                                'defaultvalue' => 'abcdefghjkmnpqrstuvwxyz23456789@#$%&ABCDEFGHJKLMNPQRSTUVWXYZ23456789@#$%&',
 
243
                                'size' => 50,
177
244
                                'note' => $this->T_('Valid characters to use in generated images.'),
178
 
                                'size' => 50,
179
245
                        ),
180
246
                        'case_sensitive' => array(
181
247
                                'label' => $this->T_('Case sensitive'),
 
248
                                'type' => 'checkbox',
182
249
                                'defaultvalue' => 0,
183
250
                                'note' => $this->T_('Use case sensitive keys?'),
184
 
                                'type' => 'checkbox',
185
251
                        ),
186
252
                        'TTF_folder' => array(
187
 
                                'label' => $this->T_( 'Fonts folder' ),
 
253
                                'label' => $this->T_('Fonts folder'),
188
254
                                'defaultvalue' => 'fonts/',
 
255
                                'size' => 20,
189
256
                                'note' => $this->T_('Path to a folder with TrueType fonts for captcha text, relative to the plugin file.'),
190
 
                                'size' => 20,
191
257
                        ),
192
258
                        'separator' => array(
 
259
                                'type' => 'layout',
193
260
                                'layout' => 'separator',
194
261
                        ),
195
262
                        'post_process_cmd' => array(
196
263
                                'label' => $this->T_('Post-process'),
 
264
                                'type' => 'textarea',
197
265
                                'defaultvalue' => '',
 
266
                                'size' => 50,
198
267
                                'note' => $this->T_('A command to post-process the image.'),
199
 
                                'size' => 50,
200
 
                                'type' => 'textarea',
201
 
                        ),
202
 
                        'advanced_end' => array(
203
 
                                'layout' => 'end_fieldset',
204
 
                        ),
 
268
                        ),
 
269
                        'advanced_end' => array( 'layout' => 'end_fieldset' ),
205
270
                );
206
271
                return $default_settings;
207
272
        }
208
273
 
209
274
 
210
275
        /**
211
 
         * @see Plugin::GetDbLayout()
212
 
         */
213
 
        function GetDbLayout()
214
 
        {
215
 
                return array(
216
 
                        "CREATE TABLE IF NOT EXISTS ".$this->get_sql_table('data')." (
217
 
                                cpt_public VARCHAR( 32 ) NOT NULL,
218
 
                                cpt_private VARCHAR( 50 ) NOT NULL,
219
 
                                cpt_sess_ID INT UNSIGNED NOT NULL,
220
 
                                cpt_timestamp TIMESTAMP NOT NULL,
221
 
                                cpt_invalid TINYINT UNSIGNED NOT NULL DEFAULT 0,
222
 
                                PRIMARY KEY( cpt_public ),
223
 
                                KEY cpt_timestamp( cpt_timestamp )
224
 
                        )",
225
 
 
226
 
                        // Holds keys for whitelisted trackback URLs:
227
 
                        "CREATE TABLE IF NOT EXISTS ".$this->get_sql_table('trackbacks_wl')." (
228
 
                                tbwl_ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
229
 
                                tbwl_item_ID INT UNSIGNED NOT NULL,
230
 
                                tbwl_key VARCHAR( 32 ) NOT NULL,
231
 
                                tbwl_timestamp TIMESTAMP NOT NULL,
232
 
                                PRIMARY KEY( tbwl_ID )
233
 
                        )",
234
 
                );
235
 
        }
236
 
 
237
 
 
238
 
        /**
239
 
         * @see Plugin::GetDependencies()
240
 
         */
241
 
        function GetDependencies()
242
 
        {
243
 
                return array(
244
 
                        'requires' => array(
245
 
                                'app_min' => '0.0.0'
246
 
                        )
247
 
                );
248
 
        }
249
 
 
250
 
 
251
 
        /**
252
 
         * @see Plugin::PluginVersionChanged()
253
 
         */
254
 
        function PluginVersionChanged( & $params )
255
 
        {
256
 
                // leave for future plugin requirements
 
276
         * @see Plugin::GetDefaultBlogSettings()
 
277
         */
 
278
        function GetDefaultBlogSettings( & $params )
 
279
        {
 
280
                global $Blog;
 
281
 
 
282
                $blog_settings = array(
 
283
                        'enable_comment' => array(
 
284
                                'label' => $this->T_('Comments'),
 
285
                                'type' => 'checkbox',
 
286
                                'defaultvalue' => 1,
 
287
                                'note' => sprintf( $this->T_('Check this to enable the %s plugin for comments on this blog.'), $this->name ),
 
288
                        ),
 
289
                        'enable_trackback' => array(
 
290
                                'label' => $this->T_('Trackbacks'),
 
291
                                'type' => 'checkbox',
 
292
                                'defaultvalue' => 1,
 
293
                                'note' => sprintf( $this->T_('Check this to enable the %s plugin for trackbacks on this blog.'), $this->name ),
 
294
                        ),
 
295
                        'enable_contact' => array(
 
296
                                'label' => $this->T_('Contact forms'),
 
297
                                'type' => 'checkbox',
 
298
                                'defaultvalue' => 1,
 
299
                                'note' => sprintf( $this->T_('Check this to enable the %s plugin for contact forms on this blog.'), $this->name ),
 
300
                        ),
 
301
                );
 
302
 
 
303
                // uncheck and disable the comments options if comments are not allowed on this blog
 
304
                if( isset( $Blog ) )
 
305
                {
 
306
                        if( $Blog->get( 'allowcomments' ) == 'never' )
 
307
                        {
 
308
                                $blog_settings['enable_comment']['defaultvalue'] = 0;
 
309
                                $blog_settings['enable_comment']['note'] = $this->T_('Comments are not allowed on this blog.');
 
310
                                $blog_settings['enable_comment'] += array( 'disabled' => true );
 
311
                        }
 
312
 
 
313
                        // uncheck and disable the trackback options if trackbacks are not allowed on this blog
 
314
                        if( ! $Blog->get( 'allowtrackbacks' ) )
 
315
                        {
 
316
                                $blog_settings['enable_trackback']['defaultvalue'] = 0;
 
317
                                $blog_settings['enable_trackback']['note'] = $this->T_('Trackbacks are disabled on this blog.');
 
318
                                $blog_settings['enable_trackback'] += array( 'disabled' => true );
 
319
                        }
 
320
                }
 
321
 
 
322
                return $blog_settings;
257
323
        }
258
324
 
259
325
 
303
369
                        // Cleanup Trackback whitelist keys:
304
370
                        $result1 = $DB->query( '
305
371
                                DELETE FROM '.$this->get_sql_table('trackbacks_wl').'
306
 
                                WHERE UNIX_TIMESTAMP(tbwl_timestamp) < '.( $localtimenow - $this->Settings->get('timeout_key')*60 ) );
 
372
                                WHERE UNIX_TIMESTAMP(tbwl_timestamp) < '.( $localtimenow - $this->Settings->get( 'timeout_key' ) * 60 ) );
307
373
                        $this->debug_log( 'Captcha Trackback whitelist cleanup - rows affected: '.$result1 );
308
374
 
309
375
                        // Cleanup Captcha data:
310
376
                        $result2 = $DB->query( '
311
377
                                DELETE FROM '.$this->get_sql_table('data').'
312
 
                                WHERE UNIX_TIMESTAMP(cpt_timestamp) < '.( $localtimenow - $this->Settings->get('timeout_key')*60 ) );
 
378
                                WHERE UNIX_TIMESTAMP(cpt_timestamp) < '.( $localtimenow - $this->Settings->get( 'timeout_key' ) * 60 ) );
313
379
                        $this->debug_log( 'Captcha data cleanup rows - affected: '.$result2 );
314
 
                        if ( $result1 = false || $result2 = false )
 
380
                        if( $result1 = false || $result2 = false )
315
381
                        {
316
382
                                return array( 'code' => 1, 'message' => $this->T_('Error: Captcha cleanup unsuccessful!') );
317
383
                        }
330
396
 
331
397
 
332
398
        /**
333
 
         * @see Plugin::BeforeEnable()
334
 
         */
335
 
        function BeforeEnable()
336
 
        {
337
 
                if( $error = $this->validate_gd_requirements() )
338
 
                {
339
 
                        return $error;
340
 
                }
341
 
 
342
 
                if( $error = $this->load_fonts() )
343
 
                {
344
 
                        return $error;
345
 
                }
346
 
 
347
 
                return true;
348
 
        }
349
 
 
350
 
 
351
 
        /**
352
399
         * @see Plugin::PluginSettingsValidateSet()
353
400
         */
354
401
        function PluginSettingsValidateSet( & $params )
357
404
 
358
405
                if( $params['name'] == 'TTF_folder' )
359
406
                { // check new path
360
 
                        $params['value'] = trailing_slash($params['value']);
 
407
                        $params['value'] = trailing_slash( $params['value'] );
361
408
                        $error = $this->load_fonts( $params['value'] );
362
409
                }
363
410
 
364
 
                // TODO: min-max ordering, ...
365
 
                // TODO: post-process
 
411
                // @todo (0000) min-max ordering, ...
 
412
                // @todo (0000) post-process
366
413
 
367
414
                if( $error )
368
415
                {
372
419
 
373
420
 
374
421
        /**
375
 
         * @see Plugin::AfterInstall()
376
 
         */
377
 
        function AfterInstall()
378
 
        {
379
 
                $this->Settings->set( 'public_key_salt', md5( mt_rand() ) );
380
 
                $this->Settings->dbupdate();
381
 
        }
382
 
 
383
 
 
384
 
        /**
385
422
         * @see Plugin::CaptchaValidated()
386
423
         */
387
424
        function CaptchaValidated( & $params )
388
425
        {
389
426
                global $DB, $localtimenow, $Session;
390
427
 
391
 
                $prefix = isset($params['prefix']) ? $params['prefix'] : 'captcha_img_'.$this->ID;
 
428
                $prefix = isset( $params['prefix'] ) ? $params['prefix'] : 'captcha_img_'.$this->ID;
392
429
 
393
430
                $this->posted_public = param( $prefix.'_key', 'string', '', true );
394
 
                if( empty($this->posted_public) )
 
431
                if( empty( $this->posted_public ) )
395
432
                {
396
433
                        $this->debug_log( 'CaptchaValidated: $posted_public is empty!' );
397
434
                        $params['validate_error'] = $this->T_('You do not seem to come from the intended page!');
401
438
                $this->posted_private = param( $prefix.'_private', 'string', '', true );
402
439
                $saved_private = $DB->get_var( '
403
440
                                SELECT cpt_private FROM '.$this->get_sql_table('data').'
404
 
                                 WHERE cpt_public = '.$DB->quote($this->posted_public).'
 
441
                                 WHERE cpt_public = '.$DB->quote( $this->posted_public ).'
405
442
                                   AND cpt_sess_ID = '.$Session->ID.'
406
 
                                   AND UNIX_TIMESTAMP(cpt_timestamp) > '.( $localtimenow - $this->Settings->get('timeout_key')*60 ) );
 
443
                                   AND UNIX_TIMESTAMP(cpt_timestamp) > '.( $localtimenow - $this->Settings->get( 'timeout_key' ) * 60 ) );
407
444
 
408
 
                if( empty($saved_private) )
 
445
                if( empty( $saved_private ) )
409
446
                {
410
447
                        $this->debug_log( 'No private key found!' );
411
 
                        $params['validate_error'] = sprintf( $this->T_('No stored private key has been found. You probably do not have cookies enabled or the timeout of %d minutes has expired.'), $this->Settings->get('timeout_key')*60 );
 
448
                        $params['validate_error'] = sprintf( $this->T_('No stored private key has been found. You probably do not have cookies enabled or the timeout of %d minutes has expired.'), $this->Settings->get( 'timeout_key' ) * 60 );
412
449
                        return false;
413
450
                }
414
451
 
415
 
                if( $this->Settings->get('case_sensitive') )
 
452
                if( $this->Settings->get( 'case_sensitive' ) )
416
453
                {
417
454
                        $posted_private = $this->posted_private;
418
455
                }
428
465
                        $params['validate_error'] = $this->T_('The entered code does not match the expected one.');
429
466
                        $DB->query( '
430
467
                                UPDATE '.$this->get_sql_table('data').'
431
 
                                   SET cpt_invalid = cpt_invalid + 1
432
 
                                 WHERE cpt_public = '.$DB->quote($this->posted_public) );
 
468
                                SET cpt_invalid = cpt_invalid + 1
 
469
                                WHERE cpt_public = '.$DB->quote( $this->posted_public ) );
433
470
                        return false;
434
471
                }
435
472
 
446
483
        {
447
484
                global $DB, $Session;
448
485
 
449
 
                $prefix = isset($params['prefix']) ? $params['prefix'] : 'captcha_img_'.$this->ID;
 
486
                $prefix = isset( $params['prefix'] ) ? $params['prefix'] : 'captcha_img_'.$this->ID;
450
487
 
451
488
                $posted_public = param( $prefix.'_key', 'string', '', true );
452
489
 
453
490
                $DB->query( '
454
491
                        DELETE FROM '.$this->get_sql_table('data').'
455
 
                         WHERE cpt_public = '.$DB->quote($posted_public).'
456
 
                           AND cpt_sess_ID = '.$Session->ID );
 
492
                        WHERE cpt_public = '.$DB->quote( $posted_public ).'
 
493
                        AND cpt_sess_ID = '.$Session->ID );
457
494
        }
458
495
 
459
496
 
470
507
                        return false;
471
508
                }
472
509
 
473
 
                $prefix = isset($params['prefix']) ? $params['prefix'] : 'captcha_img_'.$this->ID;
 
510
                $prefix = isset( $params['prefix'] ) ? $params['prefix'] : 'captcha_img_'.$this->ID;
474
511
 
475
512
                $this->private_key = $this->generate_private_key();
476
513
                $this->public_key = md5( mt_rand() );
479
516
                        $this->public_key = md5( mt_rand() );
480
517
                }
481
518
 
482
 
                // TODO: here's a minor timing issue, which _may_ resolve in a SQL error below (duplicate KEY)
 
519
                // @todo (0000) here's a minor timing issue, which _may_ resolve in a SQL error below (duplicate KEY)
483
520
                // Use MySQL's RAND() function for the public key ("insert into foo select MD5(RAND()*100000000") and retry on duplicate key!?
484
521
 
485
522
                // Save the private and public key to DB
496
533
                        $Form->begin_form();
497
534
 
498
535
                        // Include previous $_POST and $_GET params (to come to the same page again):
499
 
                        $Form->hiddens_by_key( array_merge($_GET, $_POST),
 
536
                        $Form->hiddens_by_key( array_merge( $_GET, $_POST ),
500
537
                                // exclude, because used as hidden or input field:
501
 
                                array($prefix.'_private', $prefix.'_key') );
 
538
                                array( $prefix.'_private', $prefix.'_key' ) );
502
539
                }
503
540
                else
504
541
                {
505
542
                        $Form = & $params['Form'];
506
 
                        if( ! isset($params['form_use_fieldset']) || $params['form_use_fieldset'] )
 
543
                        if( ! isset( $params['form_use_fieldset'] ) || $params['form_use_fieldset'] )
507
544
                        {
508
545
                                $Form->begin_fieldset();
509
546
                        }
514
551
                        {
515
552
                                if( strpos( $v, 'name="'.$prefix.'_' ) )
516
553
                                { // exclude own hidden field (added by Form::hiddens_by_key())
517
 
                                        unset($Form->hiddens[$k]);
 
554
                                        unset( $Form->hiddens[$k] );
518
555
                                }
519
556
                        }
520
557
 
522
559
 
523
560
                $Form->hidden( $prefix.'_key', $this->public_key );
524
561
 
525
 
                $img_src = $this->get_srvc_url('display_captcha', array('pubkey'=>$this->public_key));
 
562
                $img_src = $this->get_srvc_url( 'display_captcha', array( 'pubkey' => $this->public_key ) );
526
563
                $captcha_img = '<img src="'.$img_src.'"  alt="'.$this->T_('This is a captcha-picture. It is used to prevent mass-access by robots.').'" id="'.$prefix.'_'.$this->public_key.'"';
527
564
                if( ! $this->post_process_alters_dimensions() )
528
565
                {
529
 
                        list($width, $height) = $this->get_image_dimensions($this->private_key);
 
566
                        list( $width, $height ) = $this->get_image_dimensions( $this->private_key );
530
567
                        $captcha_img .= ' width="'.$width.'" height="'.$height.'" class="captcha"';
531
568
                }
532
569
                $captcha_img .= ' />';
535
572
                $captcha_img .= '<script type="text/javascript">
536
573
                        //<![CDATA[
537
574
                        document.write( \' <a href="#" onclick="document.getElementById(\\\''.$prefix.'_'.$this->public_key.'\\\').src = \\\''.$img_src.'&amp;reload=\\\'+(new Date()).getTime(); return false;">'
538
 
                                .get_icon('reload', 'imgtag', array('alt'=>$this->T_('Reload'), 'title'=>$this->T_('Reload image!'))).'<\/a>\' );
 
575
                                .get_icon( 'reload', 'imgtag', array('alt' => $this->T_('Reload'), 'title' => $this->T_('Reload image!') ) ).'<\/a>\' );
539
576
                        //]]>
540
577
                        </script>
541
578
                        ';
542
579
                $captcha_img .= "<br />\n";
543
580
 
544
 
                $note = $this->T_( '<br />Please enter the characters from the image above.' )
545
 
                        .' '.( $this->Settings->get('case_sensitive') ? '('.$this->T_('case sensitive').')<br />' : '('.$this->T_('case insensitive').')<br />' );
 
581
                $note = $this->T_('<br />Please enter the characters from the image above.')
 
582
                        .' '.( $this->Settings->get( 'case_sensitive' ) ? '('.$this->T_('case sensitive').')<br />' : '('.$this->T_('case insensitive').')<br />' );
546
583
 
547
584
                $Form->text_input( $prefix.'_private', '', 7, $this->T_('Captcha'), $note, array( 'maxlength' => '', 'id' => $prefix.'_'.$this->public_key.'_private', 'input_prefix' => $captcha_img, 'class' => 'bComment' ) );
548
585
 
549
 
                if( ! isset($params['Form']) )
 
586
                if( ! isset( $params['Form'] ) )
550
587
                { // there's no Form where we add to, but our own form:
551
588
                        $Form->end_form( array( array( 'submit', 'submit', $this->T_('Validate me'), 'ActionButton' ) ) );
552
589
                }
553
590
                else
554
591
                {
555
 
                        if( ! isset($params['form_use_fieldset']) || $params['form_use_fieldset'] )
 
592
                        if( ! isset( $params['form_use_fieldset'] ) || $params['form_use_fieldset'] )
556
593
                        {
557
594
                                $Form->end_fieldset();
558
595
                        }
576
613
                $prefix = 'captcha_img_'.$this->ID;
577
614
                $params['prefix'] = & $prefix;
578
615
 
579
 
                if( $v = $this->session_get('validated_in_preview') )
 
616
                if( $v = $this->session_get( 'validated_in_preview' ) )
580
617
                { // Captcha has been validated in preview: insert just the hidden fields:
581
618
                        $this->session_delete('validated_in_preview');
582
619
                        $this->debug_log('DisplayCommentFormFieldset: validated in preview');
583
 
                        $params['Form']->hidden($prefix.'_key', $v['posted_public']);
584
 
                        $params['Form']->hidden($prefix.'_private', $v['posted_private']);
 
620
                        $params['Form']->hidden( $prefix.'_key', $v['posted_public'] );
 
621
                        $params['Form']->hidden( $prefix.'_private', $v['posted_private'] );
585
622
                        return;
586
623
                }
587
624
 
714
751
                                'wlkey_'.$this->ID.'='.$wl_key );
715
752
 
716
753
                        // Display URL:
717
 
                        echo '<p class="trackback_url"><a href="',$url,'">Trackback URL (right click and copy shortcut/link location)</a></p>';
 
754
                        echo '<p class="trackback_url"><a href="'.$url.'">Trackback URL (right click and copy shortcut/link location)</a></p>';
718
755
                }
719
756
                else
720
757
                {
721
 
                        // TODO: Provide fieldset with explanation
722
758
                        $Form = new Form( regenerate_url().'#trackbacks' );
723
759
                        $Form->switch_layout('inline');
724
760
                        $Form->begin_form('bComment captcha', '', '');
725
761
                        $params['Form'] = & $Form;
726
762
                        $params['form_use_fieldset'] = true;
727
 
                        $r = $this->CaptchaPayload($params);
 
763
                        $r = $this->CaptchaPayload( $params );
728
764
 
729
765
                        $Form->button( array( 'submit', 'submit', $this->T_('Display trackback URL'), 'ActionButton' ) );
730
766
                        $Form->hiddens_by_key( get_memorized() );
751
787
 
752
788
                $wl_key = param( 'wlkey_'.$this->ID, 'string', '', true );
753
789
 
754
 
                if( strlen($wl_key) != 32 )
 
790
                if( strlen( $wl_key ) != 32 )
755
791
                {
756
792
                        $this->msg( $this->T_('Invalid trackback URL!'), 'error' );
757
793
                }
758
794
                elseif( ! $DB->get_var( '
759
795
                                SELECT COUNT(*) FROM '.$this->get_sql_table('trackbacks_wl').'
760
 
                                 WHERE tbwl_key = '.$DB->quote($wl_key).'
 
796
                                 WHERE tbwl_key = '.$DB->quote( $wl_key ).'
761
797
                                   AND tbwl_item_ID = '.$params['Comment']->Item->ID ) )
762
798
                {
763
799
                        $this->msg( $this->T_('Invalid key in trackback URL!'), 'error' );
766
802
                { // OK. Delete whitelist key:
767
803
                        $DB->query( '
768
804
                                DELETE FROM '.$this->get_sql_table('trackbacks_wl').'
769
 
                                 WHERE tbwl_key = '.$DB->quote($wl_key).'
 
805
                                 WHERE tbwl_key = '.$DB->quote( $wl_key ).'
770
806
                                   AND tbwl_item_ID = '.$params['Comment']->Item->ID );
771
807
                }
772
808
        }
780
816
                global $current_User;
781
817
 
782
818
                echo '<div class="input"><a target="b2evo_plug'.$this->ID.'_test" href="'.$this->get_srvc_url( 'test_page',
783
 
                        array( 'test_captcha_valid' => md5($this->Settings->get('public_key_salt').$current_User->ID) ) ).'">'
 
819
                        array( 'test_captcha_valid' => md5( $this->Settings->get( 'public_key_salt' ).$current_User->ID ) ) ).'">'
784
820
                        .$this->T_('Create test image... (please save any changes before)').'</a></div>';
785
821
        }
786
822
 
787
823
 
788
824
        /**
789
 
         * @see Plugin::GetDefaultBlogSettings()
790
 
         */
791
 
        function GetDefaultBlogSettings( & $params )
792
 
        {
793
 
                global $Blog;
794
 
 
795
 
                $blog_settings = array(
796
 
                        'enable_comment' => array(
797
 
                                'label' => $this->T_('Comments'),
798
 
                                'type' => 'checkbox',
799
 
                                'defaultvalue' => 1,
800
 
                                'note' => sprintf( $this->T_('Check this to enable the %s plugin for comments on this blog.'), $this->name ),
801
 
                        ),
802
 
                        'enable_trackback' => array(
803
 
                                'label' => $this->T_('Trackbacks'),
804
 
                                'type' => 'checkbox',
805
 
                                'defaultvalue' => 1,
806
 
                                'note' => sprintf( $this->T_('Check this to enable the %s plugin for trackbacks on this blog.'), $this->name ),
807
 
                        ),
808
 
                        'enable_contact' => array(
809
 
                                'label' => $this->T_('Contact forms'),
810
 
                                'type' => 'checkbox',
811
 
                                'defaultvalue' => 1,
812
 
                                'note' => sprintf( $this->T_('Check this to enable the %s plugin for contact forms on this blog.'), $this->name ),
813
 
                        ),
814
 
                );
815
 
 
816
 
                // uncheck and disable the comments options if comments are not allowed on this blog
817
 
                if( isset( $Blog ) )
818
 
                {
819
 
                        if( $Blog->get( 'allowcomments' ) == 'never' )
820
 
                        {
821
 
                                $blog_settings['enable_comment']['defaultvalue'] = 0;
822
 
                                $blog_settings['enable_comment']['note'] = $this->T_('Comments are not allowed on this blog.');
823
 
                                $blog_settings['enable_comment'] += array( 'disabled' => true );
824
 
                        }
825
 
 
826
 
                        // uncheck and disable the trackback options if trackbacks are not allowed on this blog
827
 
                        if( ! $Blog->get( 'allowtrackbacks' ) )
828
 
                        {
829
 
                                $blog_settings['enable_trackback']['defaultvalue'] = 0;
830
 
                                $blog_settings['enable_trackback']['note'] = $this->T_('Trackbacks are disabled on this blog.');
831
 
                                $blog_settings['enable_trackback'] += array( 'disabled' => true );
832
 
                        }
833
 
                }
834
 
 
835
 
                return $blog_settings;
836
 
        }
837
 
 
838
 
 
839
 
        /**
840
825
         * Delete obsolete captcha data from DB table.
841
826
         *
842
827
         * Gets called as a shutdown function.
843
 
         *
844
 
         * @todo Optimize table from time to time
 
828
         * @todo (0000) Optimize table from time to time
845
829
         * @see PluginInit()
846
830
         */
847
831
        function purge_obsolete_db_data()
851
835
                // Trackback whitelist keys:
852
836
                $DB->query( '
853
837
                                DELETE FROM '.$this->get_sql_table('trackbacks_wl').'
854
 
                                 WHERE UNIX_TIMESTAMP(tbwl_timestamp) < '.( $localtimenow - $this->Settings->get('timeout_key')*60 ) );
 
838
                                 WHERE UNIX_TIMESTAMP(tbwl_timestamp) < '.( $localtimenow - $this->Settings->get( 'timeout_key' ) * 60 ) );
855
839
 
856
840
                // Captcha data:
857
841
                $DB->query( '
858
842
                                DELETE FROM '.$this->get_sql_table('data').'
859
 
                                 WHERE UNIX_TIMESTAMP(cpt_timestamp) < '.( $localtimenow - $this->Settings->get('timeout_key')*60 ) );
 
843
                                 WHERE UNIX_TIMESTAMP(cpt_timestamp) < '.( $localtimenow - $this->Settings->get( 'timeout_key' ) * 60 ) );
860
844
        }
861
845
 
862
846
 
874
858
        {
875
859
                global $DB, $Session;
876
860
 
877
 
                if( ! isset($params['pubkey']) )
 
861
                if( ! isset( $params['pubkey'] ) )
878
862
                {
879
863
                        $this->debug_log( 'Public key not provided!' );
880
864
                        return false;
885
869
                                SELECT cpt_private FROM '.$this->get_sql_table('data').'
886
870
                                 WHERE cpt_public = '.$DB->quote( $params['pubkey'] ).'
887
871
                                   AND cpt_sess_ID = '.$Session->ID );
888
 
                if( empty($private_key) )
 
872
                if( empty( $private_key ) )
889
873
                {
890
874
                        $this->debug_log( 'Private key is empty!' );
891
875
                        return false;
895
879
 
896
880
                if( ! $image )
897
881
                {
898
 
                        $this->debug_log( 'get_captcha_img() returned '.var_export($image, true) );
 
882
                        $this->debug_log( 'get_captcha_img() returned '.var_export( $image, true ) );
899
883
                        return false;
900
884
                }
901
885
 
902
886
                header( 'Content-Type: image/jpeg' );
903
 
                header( 'Content-Length: '.strlen($image) );
 
887
                header( 'Content-Length: '.strlen( $image ) );
904
888
                echo $image;
905
889
                die;
906
890
        }
926
910
 
927
911
                $output_ID = mt_rand();
928
912
 
929
 
                if( ! isset($current_User->ID) // no user logged in
930
 
                        || empty( $params['test_captcha_valid'] ) || $params['test_captcha_valid'] != md5($this->Settings->get('public_key_salt').$current_User->ID) )
 
913
                if( ! isset( $current_User->ID ) // no user logged in
 
914
                        || empty( $params['test_captcha_valid'] ) || $params['test_captcha_valid'] != md5( $this->Settings->get( 'public_key_salt' ).$current_User->ID ) )
931
915
                {
932
916
                        return false;
933
917
                }
936
920
                global $Debuglog;
937
921
                $Debuglog = new Log( 'note' );
938
922
 
939
 
                $this->debug_log( 'params: '.var_export($params, true) );
 
923
                $this->debug_log( 'params: '.var_export( $params, true ) );
940
924
 
941
925
                $private_key = $this->generate_private_key();
942
926
                $image = $this->get_captcha_img( $private_key );
943
 
                $image = base64_encode($image); // workaround, because sess_data is not binary (BLOB before b2evo 1.10)
 
927
                $image = base64_encode( $image ); // workaround, because sess_data is not binary (BLOB before b2evo 1.10)
944
928
 
945
929
                $this->session_set( 'test_img_'.$output_ID, $image, 30, true ); // timeout: 30s and save immediately
946
 
                unset($image);
 
930
                unset( $image );
947
931
                ?>
948
932
                <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
949
933
                <html>
961
945
                                                .'" alt="Captcha test image" style="border:2px solid black; padding:10px;" ';
962
946
                                        if( ! $this->post_process_alters_dimensions() )
963
947
                                        {
964
 
                                                list($width, $height) = $this->get_image_dimensions($private_key);
 
948
                                                list( $width, $height ) = $this->get_image_dimensions( $private_key );
965
949
                                                echo ' width="'.$width.'" height="'.$height.'"';
966
950
                                        }
967
951
                                        echo ' />';
983
967
                </html>
984
968
 
985
969
                <?php
986
 
                error_reporting($old_error_reporting);
 
970
                error_reporting( $old_error_reporting );
987
971
                ini_set('display_errors', $old_display_errors);
988
972
        }
989
973
 
1002
986
                global $Session, $current_User;
1003
987
 
1004
988
                // Check perms:
1005
 
                if( empty($params['test_output_ID']) || empty( $params['test_captcha_valid'] ) )
 
989
                if( empty( $params['test_output_ID'] ) || empty( $params['test_captcha_valid'] ) )
1006
990
                {
1007
991
                        debug_die( 'Invalid request!' );
1008
992
                }
1009
 
                if( empty($current_User)
1010
 
                        || $params['test_captcha_valid'] != md5($this->Settings->get('public_key_salt').$current_User->ID) )
 
993
                if( empty( $current_User )
 
994
                        || $params['test_captcha_valid'] != md5( $this->Settings->get( 'public_key_salt' ).$current_User->ID ) )
1011
995
                {
1012
996
                        debug_die( 'Invalid request (not authenticated)!' );
1013
997
                }
1022
1006
                }
1023
1007
                $this->session_delete( 'test_img_'.$params['test_output_ID'] ); // delete not needed data
1024
1008
 
1025
 
                $image = base64_decode($image);
1026
 
                if( empty($image) )
 
1009
                $image = base64_decode( $image );
 
1010
                if( empty( $image ) )
1027
1011
                {
1028
1012
                        debug_die( 'Failed to get test image from session data!' );
1029
1013
                }
1031
1015
                header( 'Content-Type: image/jpeg' );
1032
1016
                echo $image;
1033
1017
 
1034
 
                exit();
 
1018
                exit(0);
1035
1019
        }
1036
1020
 
1037
1021
 
1046
1030
                { // User is registered.
1047
1031
                        if( $current_User->check_perm( 'blog_ismember', 'any', false, $blog_context ) )
1048
1032
                        { // Registered user is member of this blog
1049
 
                                return ( $current_User->level < $this->Settings->get('use_for_members_level_below') );
 
1033
                                return ( $current_User->level < $this->Settings->get( 'use_for_members_level_below' ) );
1050
1034
                        }
1051
 
                        return ( $current_User->level < $this->Settings->get('use_for_level_below') );
 
1035
                        return ( $current_User->level < $this->Settings->get( 'use_for_level_below' ) );
1052
1036
                }
1053
1037
                // User is anonymous
1054
1038
                return true;
1075
1059
                if( ! empty( $tmp_Blog ))
1076
1060
                {
1077
1061
                        return array(
1078
 
                                'comments' => $this->get_coll_setting( 'enable_comment', $tmp_Blog ),
1079
 
                                'trackbacks' => $this->get_coll_setting( 'enable_trackback', $tmp_Blog ),
1080
 
                                'contacts' => $this->get_coll_setting( 'enable_contact', $tmp_Blog ),
 
1062
                                'comments' => $this->get_blog_setting( 'enable_comment', $tmp_Blog ),
 
1063
                                'trackbacks' => $this->get_blog_setting( 'enable_trackback', $tmp_Blog ),
 
1064
                                'contacts' => $this->get_blog_setting( 'enable_contact', $tmp_Blog ),
1081
1065
                                'blog_context' => $tmp_Blog->ID,
1082
1066
                        );
1083
1067
                }
1084
1068
 
1085
1069
                return array(
1086
 
                        'comments' => $this->get_coll_setting( 'enable_comment', $Blog ),
1087
 
                        'trackbacks' => $this->get_coll_setting( 'enable_trackback', $Blog ),
1088
 
                        'contacts' => $this->get_coll_setting( 'enable_contact', $Blog ),
 
1070
                        'comments' => $this->get_blog_setting( 'enable_comment', $Blog ),
 
1071
                        'trackbacks' => $this->get_blog_setting( 'enable_trackback', $Blog ),
 
1072
                        'contacts' => $this->get_blog_setting( 'enable_contact', $Blog ),
1089
1073
                        'blog_context' => $Blog->ID,
1090
1074
                );
1091
1075
        }
1146
1130
                $validchars = $this->Settings->get( 'validchars' );
1147
1131
 
1148
1132
                $number_of_chars = mt_rand( $minchars, $maxchars );
1149
 
                $validchars_max_index = strlen($validchars)-1;
 
1133
                $validchars_max_index = strlen( $validchars ) - 1;
1150
1134
                for( $i = 0; $i < $number_of_chars; $i++ )
1151
1135
                {
1152
 
                        $key .= $validchars{mt_rand(0, $validchars_max_index)};
 
1136
                        $key .= $validchars{ mt_rand( 0, $validchars_max_index ) };
1153
1137
                }
1154
1138
 
1155
 
                if( ! $this->Settings->get('case_sensitive') )
 
1139
                if( ! $this->Settings->get( 'case_sensitive' ) )
1156
1140
                {
1157
 
                        $key = strtoupper($key);
 
1141
                        $key = strtoupper( $key );
1158
1142
                }
1159
1143
 
1160
1144
                return $key;
1166
1150
         * @param string private key
1167
1151
         * @return array (width, height)
1168
1152
         */
1169
 
        function get_image_dimensions($private_key)
 
1153
        function get_image_dimensions( $private_key )
1170
1154
        {
1171
 
                $min_fontsize = $this->Settings->get('min_fontsize');
1172
 
                $max_fontsize = $this->Settings->get('max_fontsize');
1173
 
 
1174
 
                // TODO: make this (more) configurable..?!
1175
 
                $width = (strlen($private_key) + 1) * (int)(($max_fontsize + $min_fontsize) / 1.5);
1176
 
                $height = (int)(2.4 * $max_fontsize);
1177
 
                return array($width, $height);
 
1155
                $min_fontsize = $this->Settings->get( 'min_fontsize' );
 
1156
                $max_fontsize = $this->Settings->get( 'max_fontsize' );
 
1157
                $width = (strlen( $private_key ) + 1) * (int)( ( $max_fontsize + $min_fontsize ) / 1.5 );
 
1158
                $height = (int)( 2.4 * $max_fontsize );
 
1159
                return array( $width, $height );
1178
1160
        }
1179
1161
 
1180
1162
 
1188
1170
                $this->debug_log( 'Private key: ['.$private_key.']' );
1189
1171
                $this->load_fonts();
1190
1172
 
1191
 
                $min_fontsize = $this->Settings->get('min_fontsize');
1192
 
                $max_fontsize = $this->Settings->get('max_fontsize');
 
1173
                $min_fontsize = $this->Settings->get( 'min_fontsize' );
 
1174
                $max_fontsize = $this->Settings->get( 'max_fontsize' );
1193
1175
 
1194
1176
                // set dimension of image
1195
 
                list( $this->lx, $this->ly ) = $this->get_image_dimensions($private_key);
 
1177
                list( $this->lx, $this->ly ) = $this->get_image_dimensions( $private_key );
1196
1178
                $this->debug_log( 'Set image dimension to: ('.$this->lx.' x '.$this->ly.')' );
1197
1179
 
1198
 
                $this->use_websafecolors = $this->Settings->get('use_websafecolors');
 
1180
                $this->use_websafecolors = $this->Settings->get( 'use_websafecolors' );
1199
1181
 
1200
1182
                // set number of noise-chars for background if it is enabled
1201
 
                $nb_noise = $this->Settings->get('noise') ? ( strlen($private_key) * $this->Settings->get('noisefactor')) : 0;
 
1183
                $nb_noise = $this->Settings->get( 'noise' ) ? ( strlen( $private_key ) * $this->Settings->get( 'noisefactor' ) ) : 0;
1202
1184
                $this->debug_log( 'Number of noise characters: '.$nb_noise );
1203
1185
 
1204
1186
                // seed the random number generator if less than php 4.2.0
1227
1209
                // Set Backgroundcolor
1228
1210
                $this->random_color(224, 255);
1229
1211
                $this->bg_color = array( $this->rand_R, $this->rand_G, $this->rand_B ); // used for substitution in post_process_image()
1230
 
                $back =  imagecolorallocate($image, $this->rand_R, $this->rand_G, $this->rand_B);
1231
 
                imagefilledrectangle($image,0,0,$this->lx,$this->ly,$back);
 
1212
                $back =  imagecolorallocate( $image, $this->rand_R, $this->rand_G, $this->rand_B );
 
1213
                imagefilledrectangle( $image, 0, 0, $this->lx, $this->ly, $back );
1232
1214
                $this->debug_log( 'We allocate one color for Background: ('.$this->rand_R.'-'.$this->rand_G.'-'.$this->rand_B.')' );
1233
1215
 
1234
1216
                // allocates the 216 websafe color palette to the image
1235
 
                if($gd_version < 2 || $this->use_websafecolors)
 
1217
                if( $gd_version < 2 || $this->use_websafecolors )
1236
1218
                {
1237
1219
                        $this->makeWebsafeColors( $image );
1238
1220
                }
1243
1225
                        $this->debug_log( 'Fill background with noise' );
1244
1226
 
1245
1227
                        $validchars = $this->Settings->get( 'validchars' );
1246
 
                        $validchars_max_index = strlen($validchars)-1;
 
1228
                        $validchars_max_index = strlen( $validchars ) - 1;
1247
1229
 
1248
1230
                        for( $i = 0; $i < $nb_noise; $i++ )
1249
1231
                        {
1250
 
                                $size  = intval(mt_rand((int)($min_fontsize / 2.3), (int)($max_fontsize / 1.7)));
1251
 
                                $angle = intval(mt_rand(0, 360));
1252
 
                                $x     = intval(mt_rand(0, $this->lx));
1253
 
                                $y     = intval(mt_rand(0, (int)($this->ly - ($size / 5))));
 
1232
                                $size  = intval( mt_rand((int)( $min_fontsize / 2.3 ), (int)( $max_fontsize / 1.7 ) ) );
 
1233
                                $angle = intval( mt_rand( 0, 360 ) );
 
1234
                                $x     = intval( mt_rand( 0, $this->lx ) );
 
1235
                                $y     = intval( mt_rand( 0, (int)( $this->ly - ( $size / 5 ) ) ) );
1254
1236
                                $this->random_color(160, 224);
1255
 
                                $color = $func_alloc($image, $this->rand_R, $this->rand_G, $this->rand_B);
 
1237
                                $color = $func_alloc( $image, $this->rand_R, $this->rand_G, $this->rand_B );
1256
1238
                                $text  = $validchars{mt_rand(0, $validchars_max_index)};
1257
 
                                ImageTTFText($image, $size, $angle, $x, $y, $color, $this->change_TTF(), $text);
 
1239
                                ImageTTFText( $image, $size, $angle, $x, $y, $color, $this->change_TTF(), $text );
1258
1240
                        }
1259
1241
                }
1260
1242
                else
1261
1243
                { // generate grid
1262
 
                        $this->debug_log( 'Fill background with x-gridlines: ('.(int)($this->lx / (int)($min_fontsize / 1.5)).')' );
1263
 
                        for( $i = 0; $i < $this->lx; $i += (int)($min_fontsize / 1.5) )
 
1244
                        $this->debug_log( 'Fill background with x-gridlines: ('.(int)( $this->lx / (int)( $min_fontsize / 1.5 ) ).')' );
 
1245
                        for( $i = 0; $i < $this->lx; $i += (int)( $min_fontsize / 1.5 ) )
1264
1246
                        {
1265
1247
                                $this->random_color(160, 224);
1266
 
                                $color = $func_alloc($image, $this->rand_R, $this->rand_G, $this->rand_B);
1267
 
                                imageline($image, $i, 0, $i, $this->ly, $color);
 
1248
                                $color = $func_alloc( $image, $this->rand_R, $this->rand_G, $this->rand_B );
 
1249
                                imageline( $image, $i, 0, $i, $this->ly, $color );
1268
1250
                        }
1269
 
                        $this->debug_log( 'Fill background with y-gridlines: ('.(int)($this->ly / (int)(($min_fontsize / 1.8))).')' );
1270
 
                        for( $i = 0 ; $i < $this->ly; $i += (int)($min_fontsize / 1.8) )
 
1251
                        $this->debug_log( 'Fill background with y-gridlines: ('.(int)( $this->ly / (int)(( $min_fontsize / 1.8 )) ).')' );
 
1252
                        for( $i = 0 ; $i < $this->ly; $i += (int)( $min_fontsize / 1.8 ) )
1271
1253
                        {
1272
1254
                                $this->random_color(160, 224);
1273
 
                                $color = $func_alloc($image, $this->rand_R, $this->rand_G, $this->rand_B);
1274
 
                                imageline($image, 0, $i, $this->lx, $i, $color);
 
1255
                                $color = $func_alloc( $image, $this->rand_R, $this->rand_G, $this->rand_B );
 
1256
                                imageline( $image, 0, $i, $this->lx, $i, $color );
1275
1257
                        }
1276
1258
                }
1277
1259
 
1278
1260
                // generate Text
1279
 
                $max_rotation = $this->Settings->get('max_rotation');
 
1261
                $max_rotation = $this->Settings->get( 'max_rotation' );
1280
1262
                $this->debug_log( 'Fill foreground with chars and shadows.' );
1281
 
                for( $i = 0, $x = intval(mt_rand($min_fontsize,$max_fontsize)); $i < strlen($private_key); $i++ )
 
1263
                for( $i = 0, $x = intval( mt_rand( $min_fontsize,$max_fontsize ) ); $i < strlen( $private_key ); $i++ )
1282
1264
                {
1283
 
                        $text  = substr($private_key, $i, 1);
1284
 
                        $angle = intval(mt_rand(($max_rotation * -1), $max_rotation));
1285
 
                        $size  = intval(mt_rand($min_fontsize, $max_fontsize));
1286
 
                        $y     = intval(mt_rand((int)($size * 1.5), (int)($this->ly - ($size / 7))));
1287
 
                        $this->random_color(0, 127);
1288
 
                        $color =  $func_alloc($image, $this->rand_R, $this->rand_G, $this->rand_B);
1289
 
                        $this->random_color(0, 127);
1290
 
                        $shadow = $func_alloc($image, $this->rand_R + 127, $this->rand_G + 127, $this->rand_B + 127);
 
1265
                        $text  = substr( $private_key, $i, 1 );
 
1266
                        $angle = intval( mt_rand( ( $max_rotation * -1 ), $max_rotation ) );
 
1267
                        $size  = intval( mt_rand( $min_fontsize, $max_fontsize));
 
1268
                        $y     = intval( mt_rand( (int)( $size * 1.5 ), (int)( $this->ly - ( $size / 7 ) ) ) );
 
1269
                        $this->random_color(0, 127);
 
1270
                        $color =  $func_alloc( $image, $this->rand_R, $this->rand_G, $this->rand_B );
 
1271
                        $this->random_color(0, 127);
 
1272
                        $shadow = $func_alloc( $image, $this->rand_R + 127, $this->rand_G + 127, $this->rand_B + 127 );
1291
1273
                        $this->change_TTF();
1292
 
                        $this->debug_log( 'Using font "'.basename($this->TTF_file).'" for letter "'.$text.'".' );
1293
 
                        ImageTTFText($image, $size, $angle, $x + (int)($size / 15), $y, $shadow, $this->TTF_file, $text);
1294
 
                        ImageTTFText($image, $size, $angle, $x, $y - (int)($size / 15), $color, $this->TTF_file, $text);
1295
 
                        $x += (int)($size + ($min_fontsize / 5));
 
1274
                        $this->debug_log( 'Using font "'.basename( $this->TTF_file ).'" for letter "'.$text.'".' );
 
1275
                        ImageTTFText( $image, $size, $angle, $x + (int)( $size / 15 ), $y, $shadow, $this->TTF_file, $text);
 
1276
                        ImageTTFText( $image, $size, $angle, $x, $y - (int)( $size / 15 ), $color, $this->TTF_file, $text);
 
1277
                        $x += (int)( $size + ( $min_fontsize / 5 ) );
1296
1278
                }
1297
1279
 
1298
1280
                ob_start();
1299
 
                ImageJPEG($image, NULL, $this->Settings->get('jpegquality'));
 
1281
                ImageJPEG( $image, NULL, $this->Settings->get( 'jpegquality' ) );
1300
1282
                $image_data = ob_get_contents();
1301
1283
                ob_end_clean();
1302
 
                ImageDestroy($image);
 
1284
                ImageDestroy( $image );
1303
1285
 
1304
1286
                $this->post_process_image( $image_data );
1305
1287
 
1316
1298
        function post_process_image( & $image )
1317
1299
        {
1318
1300
                $post_process_cmd = $this->Settings->get( 'post_process_cmd' );
1319
 
                if( ! strlen($post_process_cmd) )
 
1301
                if( ! strlen( $post_process_cmd ) )
1320
1302
                {
1321
1303
                        return;
1322
1304
                }
1334
1316
 
1335
1317
                                                case \'arand\':
1336
1318
                                                        $options = preg_split( \'~|~\', $match[2] );
1337
 
                                                        return $options[array_rand($options)];
 
1319
                                                        return $options[array_rand( $options )];
1338
1320
 
1339
1321
                                                case \'rgb\':
1340
1322
                                                        switch( $match[2] )
1359
1341
                {
1360
1342
                        fwrite( $pipes[0], $image );
1361
1343
                        fclose( $pipes[0] );
1362
 
                        $this->debug_log( 'Written '.strlen($image).' bytes to post-process (stdin).' );
 
1344
                        $this->debug_log( 'Written '.strlen( $image ).' bytes to post-process (stdin).' );
1363
1345
 
1364
1346
                        $stderr = '';
1365
1347
                        while( ! feof( $pipes[2] ) )
1368
1350
                        }
1369
1351
                        $this->debug_log( 'Stderr returned: '.$stderr );
1370
1352
 
1371
 
                        if( empty($stderr) )
 
1353
                        if( empty( $stderr ) )
1372
1354
                        {
1373
1355
                                $image = '';
1374
1356
                                while( ! feof( $pipes[1] ) )
1376
1358
                                        $image .= fread( $pipes[1], 8192 );
1377
1359
                                }
1378
1360
                                fclose( $pipes[1] );
1379
 
                                $this->debug_log( 'Read '.strlen($image).' bytes from post-process (stdout).' );
 
1361
                                $this->debug_log( 'Read '.strlen( $image ).' bytes from post-process (stdout).' );
1380
1362
                        }
1381
1363
                        else
1382
1364
                        {
1405
1387
        {
1406
1388
                static $gd_version_number;
1407
1389
 
1408
 
                if( ! isset($gd_version_number) )
 
1390
                if( ! isset( $gd_version_number ) )
1409
1391
                {
1410
1392
                        ob_start();
1411
1393
                        phpinfo(8);
1425
1407
 
1426
1408
 
1427
1409
        /**
1428
 
         * dummy docblock makes error-free autodocs
 
1410
         * dummy docblock
1429
1411
         */
1430
1412
        function makeWebsafeColors(&$image)
1431
1413
        {
1432
1414
                //$a = array();
1433
 
                for($r = 0; $r <= 255; $r += 51)
 
1415
                for( $r = 0; $r <= 255; $r += 51 )
1434
1416
                {
1435
 
                        for($g = 0; $g <= 255; $g += 51)
 
1417
                        for( $g = 0; $g <= 255; $g += 51 )
1436
1418
                        {
1437
 
                                for($b = 0; $b <= 255; $b += 51)
 
1419
                                for( $b = 0; $b <= 255; $b += 51 )
1438
1420
                                {
1439
 
                                        $color = imagecolorallocate($image, $r, $g, $b);
1440
 
                                        //$a[$color] = array('r'=>$r,'g'=>$g,'b'=>$b);
 
1421
                                        $color = imagecolorallocate( $image, $r, $g, $b );
 
1422
                                        //$a[$color] = array('r' => $r,'g' => $g,'b' => $b);
1441
1423
                                }
1442
1424
                        }
1443
1425
                }
1444
 
                $this->debug_log( 'Allocate 216 websafe colors to image: ('.imagecolorstotal($image).')' );
 
1426
                $this->debug_log( 'Allocate 216 websafe colors to image: ('.imagecolorstotal( $image ).')' );
1445
1427
                //return $a;
1446
1428
        }
1447
1429
 
1448
1430
 
1449
1431
        /**
1450
 
         * dummy docblock makes error-free autodocs
 
1432
         * dummy docblock
1451
1433
         */
1452
 
        function random_color($min,$max)
 
1434
        function random_color( $min, $max )
1453
1435
        {
1454
 
                $this->rand_R = intval(mt_rand($min,$max));
1455
 
                $this->rand_G = intval(mt_rand($min,$max));
1456
 
                $this->rand_B = intval(mt_rand($min,$max));
 
1436
                $this->rand_R = intval( mt_rand( $min, $max ) );
 
1437
                $this->rand_G = intval( mt_rand( $min, $max ) );
 
1438
                $this->rand_B = intval( mt_rand( $min, $max ) );
1457
1439
        }
1458
1440
 
1459
1441
 
1460
1442
        /**
1461
 
         * dummy docblock makes error-free autodocs
 
1443
         * dummy docblock
1462
1444
         */
1463
1445
        function change_TTF()
1464
1446
        {
1465
 
                $key = array_rand($this->TTF_RANGE);
 
1447
                $key = array_rand( $this->TTF_RANGE );
1466
1448
                $this->TTF_file = $this->TTF_RANGE[$key];
1467
1449
 
1468
1450
                return $this->TTF_file;
1476
1458
        {
1477
1459
                if( ! $this->get_gd_version() )
1478
1460
                {
1479
 
                        return $this->T_( 'The GD library does not seem to be installed.' );
 
1461
                        return $this->T_('The GD library does not seem to be installed.');
1480
1462
                }
1481
1463
                if( !function_exists('imagejpeg') )
1482
1464
                {
1483
 
                        return $this->T_( 'No JPEG support. (Function imagejpeg does not exist)' );
 
1465
                        return $this->T_('No JPEG support. (Function imagejpeg does not exist)');
1484
1466
                }
1485
1467
                if( !function_exists('imagettftext') )
1486
1468
                {
1487
 
                        return $this->T_( 'FreeType library not available. (Function imagettftext does not exist)' );
 
1469
                        return $this->T_('FreeType library not available. (Function imagettftext does not exist)');
1488
1470
                }
1489
1471
        }
1490
1472
 
1498
1480
        {
1499
1481
                static $loaded = array();
1500
1482
 
1501
 
                if( ! isset($use_folder) )
 
1483
                if( ! isset( $use_folder ) )
1502
1484
                {
1503
1485
                        $use_folder = $this->Settings->get( 'TTF_folder' );
1504
1486
                }
1505
1487
 
1506
1488
                $this->TTF_folder = dirname(__FILE__).'/'.$use_folder;
1507
1489
 
1508
 
                if( isset($loaded[$use_folder]) )
 
1490
                if( isset( $loaded[$use_folder] ) )
1509
1491
                {
1510
1492
                        $this->TTF_RANGE = $loaded[$use_folder]['TTF_RANGE'];
1511
1493
                        return $loaded[$use_folder]['return'];
1513
1495
 
1514
1496
                $this->TTF_RANGE = array();
1515
1497
 
1516
 
                if( $handle = @opendir($this->TTF_folder) )
 
1498
                if( $handle = @opendir( $this->TTF_folder ) )
1517
1499
                {
1518
 
                        while( false !== ($file = readdir($handle)) )
 
1500
                        while( false !== ( $file = readdir( $handle ) ) )
1519
1501
                        {
1520
1502
                                if( $file != '.' && $file != '..' && preg_match( '~\.ttf$~i', $file ) )
1521
1503
                                {
1525
1507
                                        $this->debug_log( 'Skipping non-font file ('.$this->TTF_folder.$file.')' );
1526
1508
                                }
1527
1509
                        }
1528
 
                        closedir($handle);
 
1510
                        closedir( $handle );
1529
1511
                }
1530
1512
                else
1531
1513
                {
1532
 
                        $error = sprintf( $this->T_( 'Fonts folder %s is not readable or does not exist!' ), rel_path_to_base($this->TTF_folder) );
 
1514
                        $error = sprintf( $this->T_('Fonts folder %s is not readable or does not exist!'), rel_path_to_base( $this->TTF_folder ) );
1533
1515
                        $this->debug_log( $error );
1534
1516
                        $loaded[$use_folder]['TTF_RANGE'] = $this->TTF_RANGE;
1535
1517
                        $loaded[$use_folder]['return'] = $error;
1536
1518
                        return $error;
1537
1519
                }
1538
1520
 
1539
 
                if( ! empty($this->TTF_RANGE) )
 
1521
                if( ! empty( $this->TTF_RANGE ) )
1540
1522
                {
1541
 
                        $this->debug_log( 'Checking given TrueType-Array: ('.count($this->TTF_RANGE).')' );
 
1523
                        $this->debug_log( 'Checking given TrueType-Array: ('.count( $this->TTF_RANGE ).')' );
1542
1524
                        $temp = array();
1543
1525
                        foreach( $this->TTF_RANGE as $k => $v )
1544
1526
                        {
1545
 
                                if( ! is_readable($v) )
 
1527
                                if( ! is_readable( $v ) )
1546
1528
                                {
1547
1529
                                        $this->debug_log( 'TrueTypeFont '.$v.' is not readable!' );
1548
1530
                                        unset( $this->TTF_RANGE[$k] );
1549
1531
                                }
1550
1532
                        }
1551
 
                        $this->debug_log( 'Valid TrueType-files: ('.count($this->TTF_RANGE).')' );
 
1533
                        $this->debug_log( 'Valid TrueType-files: ('.count( $this->TTF_RANGE ).')' );
1552
1534
                }
1553
1535
 
1554
1536
                if( empty( $this->TTF_RANGE ) )
1569
1551
 
1570
1552
        /**
1571
1553
         * Do we use post-processing for images?
1572
 
         * @todo Make this a setting!
 
1554
         *
1573
1555
         * @return bool
1574
1556
         */
1575
1557
        function post_process_alters_dimensions()
1576
1558
        {
1577
 
                return strlen($this->Settings->get('post_process_cmd'));
 
1559
                return strlen( $this->Settings->get( 'post_process_cmd' ) );
1578
1560
        }
1579
1561
 
1580
1562
}