We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 13784
    • 2 Posts
    Hello all,

    This is my first post in this forum so I hope it is a good one...

    I had been having very frustrating problems with the CAPTCHA setting in my MODx installation.
    Anytime I requested CAPTCHA on my forms (within the application or the manager), the background image would show but not the CAPTCHA word.

    After much digging into both my hosts configuration and the manager/includes/veriword.php file, I finally found the problem!

    There is an obscure ’bug’ in the PHP imagettfbbox() function - when your site is hosted on a Windows platform (which mine was unbeknownst to me embarrassed ) - the ’fontfile’ parameter MUST include the absolute path along with the filename! If you only supply a relative path, the function will find the font file but for some reason it will return an array filled with ZEROS!

    After changing the veriword.php file to account for this, I uploaded my new veriword.php file and...voila! CAPTCHA words!

    I hope this helps some of you as I know how frustrating the hunt for this solution was for me.

    Jeff.

    P.S. I have attached my revised veriword.php file.
      • 3749
      • 24,544 Posts
      See if you have any extra files in the font directory (other than .ttf files). I think the bug that hit you might be that veriword assumes that all files in that directory are font files.

      One fix is to delete the extraneous files.

      In the Revolution version I changed the font directory read section to this:

      while ($file = $dir->read()) {
      
          if(strstr($file,'.ttf') ) {  // include only .ttf files
             $fontstmp[] = $this->dir_font.'/'.$file;
          }
      }


      That way, you don’t have to hard-code the path into the snippet code.
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 13784
        • 2 Posts
        Thanks for the feedback BobRay.

        Good idea but I already checked just that. I only had the one file in that folder and it was the original ttf file that came with the MODx install.

        I actually created a one page test.php to confirm the issue with the imagettfbbox() and ran it on 2 configs - one Linux server and one Windows. The exact same code gave two different results.

        The changes I made to the vericode.php file do not require me to hard code the path in the snippet:

        // prefix font file name with absolute path
        $text_font = dirname($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']). '/ttf/' . $text_font;


        I had to make a few other changes (documented in the vericode.zip attached to the initial post) but this was the main problem.
          • 3749
          • 24,544 Posts
          Thanks for all the info jchown. I’m now suspecting that your problem is the IIS server rather than Windows. I’ve run the original vericode on Windows XP and Vista with XAMPP for some time without hitting that snag.

          If it’s really an IIS problem, I’ll probably have to deal with it for the Revolution version of CAPTCHA.
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 3749
            • 24,544 Posts
            PS: And speaking of Windows, the file you uploaded is coming up empty for me. Could you paste it into a message? I’d like to see the changes you made.
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting
              • 16610
              • 634 Posts
              Thank you so much jchown  smiley Your modified veriword file solved my problem too!

              You just solved my long lasting problem with one client.

              I have had this same veriword problem for months now on one shared server account. It’s LAMP configuration, so this veriword problem is not only about Windows or IIS.

              Below more info about this particular LAMP configuration, hopefully useful for others with this same problem:

              - Linux: distro unknown
              - Server: Apache 2.0
              - MySQL: 5.0.32 
              - PHP Version: 4.4.9
              - Configure Command:
              ’./configure’ ’--with-apxs2=/usr/local/apache/bin/apxs’ ’--prefix=/usr/local/apache/php’ ’--enable-memory-limit’ ’--enable-magic-quotes’ ’--disable-force-cgi-redirect’ ’--with-mysql=/usr’ ’--with-gd=/usr’ ’--enable-ftp’ ’--enable-calendar’ ’--with-jpeg-dir=/usr/lib’ ’--with-png-dir=/usr/local/lib’ ’--with-zlib-dir=/usr/local/lib’ ’--enable-xml’ ’--enable-inline-optimization’ ’--with-imap’ ’--disable-ipv6’ ’--enable-mcrypt’ ’--enable-discard-path’ ’--with-gettext’ ’--enable-path-info-check’ ’--enable-gd-native-ttf’ ’--with-freetype-dir=/usr/local/include/freetype2’ ’--with-mcrypt=/usr/local/lib’ ’--with-gmp’ ’--with-xsl=/usr/local/lib’ ’--enable-soap’ ’--with-kerberos’ ’--with-imap-ssl’ ’--enable-pdo’ ’--with-curl’ ’--with-openssl’ ’--enable-mbstring’ ’--enable-exif’ ’--with-iconv’
              - gd:
              GD Support enabled
              GD Version 2.0 or higher
              FreeType Support enabled
              FreeType Linkage with freetype
              GIF Read Support enabled
              GIF Create Support enabled
              JPG Support enabled
              PNG Support enabled
              WBMP Support enabled
                Mikko Lammi, Owner at Maagit
                • 3749
                • 24,544 Posts
                Could someone please paste the modified veriword code into a message here. The .zip file is empty for me no matter how I access it, and I have no clue what’s been done to veriword.php.
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 22303 MODX Staff
                  • 10,725 Posts
                  Quote from: BobRay at Sep 11, 2008, 04:16 PM

                  Could someone please paste the modified veriword code into a message here. The .zip file is empty for me no matter how I access it, and I have no clue what’s been done to veriword.php.
                  I had no problem with the zip; strange. Anyway, here is a patch of his changes, so as not to paste the whole thing:
                  Index: manager/includes/veriword.php
                  ===================================================================
                  --- manager/includes/veriword.php	(revision 4060)
                  +++ manager/includes/veriword.php	(working copy)
                  @@ -1,4 +1,12 @@
                   <?php
                  +// Date: Monday, September 1, 2008 @ 1:57pm EST
                  +// modified version: bug found if file hosted on Windows-based server
                  +// issue: imagettftext() requires absolute path to font file or it DOES NOT work
                  +// The only modified code is in member function draw_text() in this file.
                  +//
                  +// Author: Jeff Chown ([email protected])
                  +
                  +
                   include_once("config.inc.php");
                   
                   $vword = new VeriWord(148,60);
                  @@ -77,7 +85,7 @@
                   		// connect to the database
                   		if(@$dbConn = mysql_connect($database_server, $database_user, $database_password)) {
                   			mysql_select_db($dbase);
                  -            @mysql_query("{$database_connection_method} {$database_connection_charset}");
                  +            @mysql_query("SET CHARACTER SET {$database_connection_charset}");
                   			$sql = "SELECT * FROM $dbase.`".$table_prefix."system_settings` WHERE setting_name='captcha_words'";
                   			$rs = mysql_query($sql);
                   			$limit = mysql_num_rows($rs);
                  @@ -108,6 +116,7 @@
                   		/* pick one font type randomly from font directory */
                   		//$text_font 	= $this->dir_font."".rand(1,3).".ttf";
                   		// added by Alex - read ttf dir
                  +/*
                   		$dir = dir("./ttf");
                   		$fontstmp = array();
                   		while (false !== ($file = $dir->read())) {
                  @@ -117,6 +126,25 @@
                   		}
                   		$dir->close();
                   		$text_font = (string) $fontstmp[array_rand($fontstmp)];
                  +*/
                  +        
                  +        // added by Jeff Chown ([email protected]) - Sept. 1/08 to resolve issue with relative path
                  +        // on Windows servers - essentially a duplicate of Alex's above block with 
                  +        // adjustments for absolute path in font file name 
                  +		$dir = dir("./ttf");
                  +		$fontstmp = array();
                  +		while (false !== ($file = $dir->read())) {
                  +			if($file!="." && $file!=".." && file_exists('./ttf/'.$file) && !is_dir('./ttf/' . $file)) {
                  +				$fontstmp[] = $file; 	// just the file name, no path yet
                  +			}
                  +		}
                  +		$dir->close();
                  +        
                  +		$text_font = (string) $fontstmp[array_rand($fontstmp)];
                  +        // prefix font file name with absolute path
                  +        $text_font = dirname($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']). '/ttf/' . $text_font;
                  +        //
                  +		// end of modifications        
                   
                   		/* angle for text inclination */
                   		$text_angle = rand(-9,9);
                  


                  I’m proposing this however, to clean up unnecessary code and comment:
                  Index: manager/includes/veriword.php
                  ===================================================================
                  --- manager/includes/veriword.php	(revision 4064)
                  +++ manager/includes/veriword.php	(working copy)
                  @@ -40,7 +40,7 @@
                   class VeriWord {
                   
                   	/* path to font directory*/
                  -	var $dir_font 	= "fonts/";
                  +	var $dir_font 	= "ttf/";
                   	/* path to background image directory*/
                   	var $dir_noise 	= "noises/";
                   	var $word 		= ""; 
                  @@ -50,7 +50,8 @@
                   	function VeriWord($w=200, $h=80) {
                   		/* create session to set word for verification */
                   		startCMSSession();
                  -		$this->set_veriword();	
                  +		$this->set_veriword();
                  +		$this->dir_font = dirname(__FILE__) . '/' . $this->dir_font;
                   		$this->im_width 		= $w;
                   		$this->im_height 		= $h;
                   	}
                  @@ -105,14 +106,11 @@
                   		   } 
                   		} 		
                   		
                  -		/* pick one font type randomly from font directory */
                  -		//$text_font 	= $this->dir_font."".rand(1,3).".ttf";
                  -		// added by Alex - read ttf dir
                  -		$dir = dir("./ttf");
                  +		$dir = dir($this->dir_font);
                   		$fontstmp = array();
                   		while (false !== ($file = $dir->read())) {
                  -			if($file!="." && $file!=".." && file_exists('./ttf/'.$file) && !is_dir('./ttf/' . $file)) {
                  -				$fontstmp[] = './ttf/'.$file;
                  +			if($file!="." && $file!=".." && file_exists($this->dir_font.$file) && !is_dir($this->dir_font . $file)) {
                  +				$fontstmp[] = $this->dir_font.$file;
                   			}
                   		}
                   		$dir->close();
                  
                    • 3749
                    • 24,544 Posts
                    I think that will still put non-ttf files in the .ttf direectory into the fontstmp array.

                    I’d suggest this (which should also be faster):

                    while ($file = $dir->read()) {
                    
                              if(strstr($file,'.ttf') ) {  // include only .ttf files
                    	$fontstmp[] = $this->dir_font.'/'.$file;
                             }
                    }
                      Did I help you? Buy me a beer
                      Get my Book: MODX:The Official Guide
                      MODX info for everyone: http://bobsguides.com/modx.html
                      My MODX Extras
                      Bob's Guides is now hosted at A2 MODX Hosting
                      • 22303 MODX Staff
                      • 10,725 Posts
                      Fair enough BobRay; updated patch:

                      Index: manager/includes/veriword.php
                      ===================================================================
                      --- manager/includes/veriword.php	(revision 4064)
                      +++ manager/includes/veriword.php	(working copy)
                      @@ -40,7 +40,7 @@
                       class VeriWord {
                       
                       	/* path to font directory*/
                      -	var $dir_font 	= "fonts/";
                      +	var $dir_font 	= "ttf/";
                       	/* path to background image directory*/
                       	var $dir_noise 	= "noises/";
                       	var $word 		= ""; 
                      @@ -50,7 +50,8 @@
                       	function VeriWord($w=200, $h=80) {
                       		/* create session to set word for verification */
                       		startCMSSession();
                      -		$this->set_veriword();	
                      +		$this->set_veriword();
                      +		$this->dir_font = dirname(__FILE__) . '/' . $this->dir_font;
                       		$this->im_width 		= $w;
                       		$this->im_height 		= $h;
                       	}
                      @@ -105,14 +106,11 @@
                       		   } 
                       		} 		
                       		
                      -		/* pick one font type randomly from font directory */
                      -		//$text_font 	= $this->dir_font."".rand(1,3).".ttf";
                      -		// added by Alex - read ttf dir
                      -		$dir = dir("./ttf");
                      +		$dir = dir($this->dir_font);
                       		$fontstmp = array();
                       		while (false !== ($file = $dir->read())) {
                      -			if($file!="." && $file!=".." && file_exists('./ttf/'.$file) && !is_dir('./ttf/' . $file)) {
                      -				$fontstmp[] = './ttf/'.$file;
                      +			if(strstr($file, '.ttf')) {
                      +				$fontstmp[] = $this->dir_font.$file;
                       			}
                       		}
                       		$dir->close();