3
* This file implements the Captcha Images plugin.
3
* This file implements the CaptchaImage plugin
5
5
* It displays a captcha image through {@link CaptchaValidated()} and validates
6
* it in {@link CaptchaValidated()}.
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.
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.
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
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.
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
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/}
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}
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
24
24
* @subpackage CaptchaImage
27
if( !defined('QP_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
26
if(!defined('QP_MAIN_INIT')) die('fail');
61
* @see Plugin::BeforeEnable()
63
function BeforeEnable()
65
if( $error = $this->validate_gd_requirements() )
70
if( $error = $this->load_fonts() )
80
* @see Plugin::AfterInstall()
82
function AfterInstall()
84
$this->Settings->set( 'public_key_salt', md5( mt_rand() ) );
85
$this->Settings->dbupdate();
90
* @see Plugin::GetDbLayout()
92
function GetDbLayout()
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 )
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 )
118
* @see Plugin::GetDependencies()
120
function GetDependencies()
64
131
* @see Plugin::GetDefaultSettings()
66
133
function GetDefaultSettings( & $params )
70
137
$default_settings = array(
71
138
'use_for_start' => array(
72
139
'label' => $this->T_('Use For'),
73
141
'layout' => 'begin_fieldset',
75
143
'use_for_members_level_below' => array(
76
144
'label' => $this->T_('Blog Members'),
77
146
'defaultvalue' => 0,
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.'),
81
'valid_range' => array( 'min'=>0, 'max'=>11),
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
154
'defaultvalue' => 2, // new users can not bypass the captcha ... was ( $Settings->get( 'newusers_level' ) + 1) but can't do that during installation
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.'),
89
'valid_range' => array( 'min'=>0, 'max'=>11),
91
'use_for_end' => array(
92
'layout' => 'end_fieldset',
159
'use_for_end' => array( 'layout' => 'end_fieldset' ),
94
160
'random_start' => array(
95
161
'label' => $this->T_('Randomizer settings'),
96
163
'layout' => 'begin_fieldset',
98
165
'timeout_key' => array(
99
166
'label' => $this->T_('Timeout for keys'),
100
168
'defaultvalue' => 120, // timeout: 2 hours
101
170
'note' => $this->T_('in minutes. When does the generated captcha expire?'),
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',
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',
117
184
'noisefactor' => array(
118
185
'label' => $this->T_('Noise factor'),
119
187
'defaultvalue' => 9,
120
189
'note' => $this->T_('Noise multiplier (number of characters gets multipled by this to define noise).'),
124
191
'minchars' => array(
125
192
'label' => $this->T_('Min chars'),
126
194
'defaultvalue' => 4,
127
196
'note' => $this->T_('The minimum number of characters to use.'),
131
198
'maxchars' => array(
132
199
'label' => $this->T_('Max chars'),
133
201
'defaultvalue' => 6,
134
203
'note' => $this->T_('The maximum number of characters to use.'),
138
205
'min_fontsize' => array(
139
206
'label' => $this->T_('Min font size'),
140
208
'defaultvalue' => 20,
141
210
'note' => $this->T_('The minimum font size to use.'),
145
212
'max_fontsize' => array(
146
213
'label' => $this->T_('Max font size'),
147
215
'defaultvalue' => 30,
148
217
'note' => $this->T_('The maximum font size to use.'),
152
219
'max_rotation' => array(
153
220
'label' => $this->T_('Max rotation'),
154
222
'defaultvalue' => 25,
155
224
'note' => $this->T_('The maximum degrees a char should be rotated. 25 means a random rotation between -25 and 25.'),
159
226
'jpegquality' => array(
160
227
'label' => $this->T_('JPEG quality'),
161
229
'defaultvalue' => 80,
162
232
'note' => $this->T_('JPEG image quality.'),
167
'random_end' => array(
168
'layout' => 'end_fieldset',
234
'random_end' => array( 'layout' => 'end_fieldset' ),
170
235
'advanced_start' => array(
171
236
'label' => $this->T_('Advanced settings'),
172
238
'layout' => 'begin_fieldset',
174
240
'validchars' => array(
175
241
'label' => $this->T_('Valid characters'),
176
242
'defaultvalue' => 'abcdefghjkmnpqrstuvwxyz23456789@#$%&ABCDEFGHJKLMNPQRSTUVWXYZ23456789@#$%&',
177
244
'note' => $this->T_('Valid characters to use in generated images.'),
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',
186
252
'TTF_folder' => array(
187
'label' => $this->T_( 'Fonts folder' ),
253
'label' => $this->T_('Fonts folder'),
188
254
'defaultvalue' => 'fonts/',
189
256
'note' => $this->T_('Path to a folder with TrueType fonts for captcha text, relative to the plugin file.'),
192
258
'separator' => array(
193
260
'layout' => 'separator',
195
262
'post_process_cmd' => array(
196
263
'label' => $this->T_('Post-process'),
264
'type' => 'textarea',
197
265
'defaultvalue' => '',
198
267
'note' => $this->T_('A command to post-process the image.'),
200
'type' => 'textarea',
202
'advanced_end' => array(
203
'layout' => 'end_fieldset',
269
'advanced_end' => array( 'layout' => 'end_fieldset' ),
206
271
return $default_settings;
211
* @see Plugin::GetDbLayout()
213
function GetDbLayout()
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 )
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 )
239
* @see Plugin::GetDependencies()
241
function GetDependencies()
252
* @see Plugin::PluginVersionChanged()
254
function PluginVersionChanged( & $params )
256
// leave for future plugin requirements
276
* @see Plugin::GetDefaultBlogSettings()
278
function GetDefaultBlogSettings( & $params )
282
$blog_settings = array(
283
'enable_comment' => array(
284
'label' => $this->T_('Comments'),
285
'type' => 'checkbox',
287
'note' => sprintf( $this->T_('Check this to enable the %s plugin for comments on this blog.'), $this->name ),
289
'enable_trackback' => array(
290
'label' => $this->T_('Trackbacks'),
291
'type' => 'checkbox',
293
'note' => sprintf( $this->T_('Check this to enable the %s plugin for trackbacks on this blog.'), $this->name ),
295
'enable_contact' => array(
296
'label' => $this->T_('Contact forms'),
297
'type' => 'checkbox',
299
'note' => sprintf( $this->T_('Check this to enable the %s plugin for contact forms on this blog.'), $this->name ),
303
// uncheck and disable the comments options if comments are not allowed on this blog
306
if( $Blog->get( 'allowcomments' ) == 'never' )
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 );
313
// uncheck and disable the trackback options if trackbacks are not allowed on this blog
314
if( ! $Blog->get( 'allowtrackbacks' ) )
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 );
322
return $blog_settings;
535
572
$captcha_img .= '<script type="text/javascript">
537
574
document.write( \' <a href="#" onclick="document.getElementById(\\\''.$prefix.'_'.$this->public_key.'\\\').src = \\\''.$img_src.'&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>\' );
542
579
$captcha_img .= "<br />\n";
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 />' );
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' ) );
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' ) ) );
555
if( ! isset($params['form_use_fieldset']) || $params['form_use_fieldset'] )
592
if( ! isset( $params['form_use_fieldset'] ) || $params['form_use_fieldset'] )
557
594
$Form->end_fieldset();
780
816
global $current_User;
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>';
789
* @see Plugin::GetDefaultBlogSettings()
791
function GetDefaultBlogSettings( & $params )
795
$blog_settings = array(
796
'enable_comment' => array(
797
'label' => $this->T_('Comments'),
798
'type' => 'checkbox',
800
'note' => sprintf( $this->T_('Check this to enable the %s plugin for comments on this blog.'), $this->name ),
802
'enable_trackback' => array(
803
'label' => $this->T_('Trackbacks'),
804
'type' => 'checkbox',
806
'note' => sprintf( $this->T_('Check this to enable the %s plugin for trackbacks on this blog.'), $this->name ),
808
'enable_contact' => array(
809
'label' => $this->T_('Contact forms'),
810
'type' => 'checkbox',
812
'note' => sprintf( $this->T_('Check this to enable the %s plugin for contact forms on this blog.'), $this->name ),
816
// uncheck and disable the comments options if comments are not allowed on this blog
819
if( $Blog->get( 'allowcomments' ) == 'never' )
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 );
826
// uncheck and disable the trackback options if trackbacks are not allowed on this blog
827
if( ! $Blog->get( 'allowtrackbacks' ) )
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 );
835
return $blog_settings;
840
825
* Delete obsolete captcha data from DB table.
842
827
* Gets called as a shutdown function.
844
* @todo Optimize table from time to time
828
* @todo (0000) Optimize table from time to time
845
829
* @see PluginInit()
847
831
function purge_obsolete_db_data()
1075
1059
if( ! empty( $tmp_Blog ))
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,
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,
1243
1225
$this->debug_log( 'Fill background with noise' );
1245
1227
$validchars = $this->Settings->get( 'validchars' );
1246
$validchars_max_index = strlen($validchars)-1;
1228
$validchars_max_index = strlen( $validchars ) - 1;
1248
1230
for( $i = 0; $i < $nb_noise; $i++ )
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 );
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 ) )
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 );
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 ) )
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 );
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++ )
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 ) );
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 );
1304
1286
$this->post_process_image( $image_data );
1428
* dummy docblock makes error-free autodocs
1430
1412
function makeWebsafeColors(&$image)
1432
1414
//$a = array();
1433
for($r = 0; $r <= 255; $r += 51)
1415
for( $r = 0; $r <= 255; $r += 51 )
1435
for($g = 0; $g <= 255; $g += 51)
1417
for( $g = 0; $g <= 255; $g += 51 )
1437
for($b = 0; $b <= 255; $b += 51)
1419
for( $b = 0; $b <= 255; $b += 51 )
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);
1444
$this->debug_log( 'Allocate 216 websafe colors to image: ('.imagecolorstotal($image).')' );
1426
$this->debug_log( 'Allocate 216 websafe colors to image: ('.imagecolorstotal( $image ).')' );
1450
* dummy docblock makes error-free autodocs
1452
function random_color($min,$max)
1434
function random_color( $min, $max )
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 ) );
1461
* dummy docblock makes error-free autodocs
1463
1445
function change_TTF()
1465
$key = array_rand($this->TTF_RANGE);
1447
$key = array_rand( $this->TTF_RANGE );
1466
1448
$this->TTF_file = $this->TTF_RANGE[$key];
1468
1450
return $this->TTF_file;