I am creating a captcha image (please do not suggest premade ones).
It gives you the ability to call
$captcha = new captcha();
$captcha->size(30)->getImage();
which sets the font size to 30 and then generates the captcha.
my issue is with sizing.
How can I work out how wide the image should be?
the captcha has 6 characters.
I thought I could just do ($size*6)+10 to make the image wide enough + give it a 5px padding on each side (text is centered), but apparently not.
Code
<?php
session_start();
class captcha {
private $font = 'monofont.ttf';
private $characters = '23456789bcdfghjkmnpqrstvwxyz';
private $size = 30;
private $count = 6;
private $colors = array(
'b' => array('r' => 0, 'g' => 0, 'b' => 0),
't' => array('r' => 200, 'g' => 200, 'b' => 200),
'n' => array('r' => 127, 'g' => 127, 'b' => 127)
);
function count($count) {
$this->count = $count;
return $this;
}
function size($size){
$this->size = $size;
return $this;
}
function characters($characters) {
$this->characters = $characters;
return $this;
}
function backgroundColor($red, $green, $blue){
$this->colors['b']['r'] = $red;
$this->colors['b']['g'] = $green;
$this->colors['b']['b'] = $blue;
return $this;
}
function noiseColor($red, $green, $blue){
$this->colors['n']['r'] = $red;
$this->colors['n']['g'] = $green;
$this->colors['n']['b'] = $blue;
return $this;
}
function textColor($red, $green, $blue){
$this->colors['t']['r'] = $red;
$this->colors['t']['g'] = $green;
$this->colors['t']['b'] = $blue;
return $this;
}
function generateCode() {
$code = '';
$i = 0;
while ($i < $this->count) {
$code .= strtoupper(substr($this->characters, mt_rand(0, strlen($this->characters) - 1), 1));
$i++;
}
return $code;
}
function getWidth() {
return ($this->count * $this->size);
}
function getHeight() {
return $this->size+10;
}
function getCaptcha() {
$code = $this->generateCode();
$this->width = $this->getWidth();
$this->height = $this->getHeight();
$image = #imagecreate($this->width, $this->height) or die('Cannot initialize new GD image stream');
//define colors
$tColor = imagecolorallocate($image, $this->colors['t']['r'], $this->colors['t']['g'], $this->colors['t']['b']);
$nColor = imagecolorallocate($image, $this->colors['n']['r'], $this->colors['n']['g'], $this->colors['n']['b']);
$bColor = imagecolorallocate($image, $this->colors['b']['r'], $this->colors['b']['g'], $this->colors['b']['b']);
//fill image
imagefill($image, 0, 0, $bColor);
/* generate random dots in background */
for ($i = 0; $i < ($this->width * $this->height) / 3; $i++) {
imagefilledellipse($image, mt_rand(0, $this->width), mt_rand(0, $this->height), 1, 1, $nColor);
}
/* generate random lines in background */
for ($i = 0; $i < ($this->width * $this->height) / 150; $i++) {
imageline($image, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $nColor);
}
/* create textbox and add text */
$textbox = imagettfbbox($this->size, 0, $this->font, $code) or die('Error in imagettfbbox function');
$x = ($this->width - $textbox[4]) / 2;
$y = ($this->height - $textbox[5]) / 2;
imagettftext($image, $this->size, 0, $x, $y, $tColor, $this->font, $code) or die('Error in imagettftext function');
//imagefilter($image, IMG_FILTER_NEGATE);
imagefilter($image, IMG_FILTER_SMOOTH, 1);
/* output captcha image to browser */
header('Content-Type: image/jpeg');
header('Cache-Control: no-cache, must-revalidate');
imagejpeg($image);
imagedestroy($image);
$_SESSION['security_code'] = $code;
}
}
$captcha = new captcha();
$captcha->size(30)->count(6)->getCaptcha();
?>
You can use imagegetttfbbox() to determine the bounding box which can contain your string. But since you're generating a captcha, which means the characters are highly distored, I don't think it'd particularly accurate. It's intended for regular un-altered text.
Related
I am trying to figure out how to resize an image on upload with symfony 5. Actually my fileupload is working perfectly, but it would be such a relief not to resize all my pics before I have to upload them.
Is there a way I can do this?
Here is my upload code:
if($form->isSubmitted() && $form->isValid()){
$imageFile = $form->get('file')->getData();
if($imageFile) {
#CAN'T RESIZE HERE BEFORE UPLOAD ???
$imageFileName = $fileUploader->upload($imageFile);
$image->setFilename($imageFileName);
}
#.....persist - flush etc.
}
First this is my controller with a method to upload an image from a form:
/**
* #Route("/admin/image/new", name="admin_image_new")
*/
public function newImage(Request $request, EntityManagerInterface $manager, FileUploader $fileUploader, ImageResizeService $imageResize)
{
$image = new Image();
$form = $this->createForm(ImageType::class, $image);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$imageFile = $form->get('file')->getData();
if($imageFile) {
$imageFileName = $fileUploader->upload($imageFile);
$image->setFilename($imageFileName);
}
$manager->persist($image);
$manager->flush();
$this->addFlash('success', 'Image added successfully !');
$imageName = $image->getFilename();
$fullSizeImgWebPath = $fileUploader->getTargetDirectory().'/'.$imageName;
[$width,$height] = getimagesize($fullSizeImgWebPath);
if($width > $height){
$width = 1500;
$height = 1000;
// $imageResize->writeThumbnail($fullSizeImgWebPath, 1500, 1000);
} else if($width == $height){
$width = 300;
$height = 300;
//$imageResize->writeThumbnail($fullSizeImgWebPath, 300, 300);
} else {
$width = 1500;
$height = 2254;
//$imageResize->writeThumbnail($fullSizeImgWebPath,1000,1600);
}
$imageResize->writeThumbnail($fullSizeImgWebPath, $width, $height);
return $this->redirectToRoute('admin_image');
}
return $this->render('admin/image/new_image.html.twig', [
'controller_name' => 'AdminImageController',
'form'=> $form->createView()
]);
}
I created a service to resize the uploaded image:
class ImageResizeService {
/**
* Write a thumbnail image using Imagine
*
* #param string $thumbAbsPath full absolute path to attachment directory e.g. /var/www/project1/images/thumbs/
*/
public function writeThumbnail($thumbAbsPath, $width, $height) {
$imagine = new Imagine;
$image = $imagine->open($thumbAbsPath);
$size = new Box($width, $height);
$image->thumbnail($size,ImageInterface::THUMBNAIL_OUTBOUND)
->save($thumbAbsPath);
}
}
The below code is being called from a simple script like this.
$test.line-validation();
method line-validation is rw {
my $file-data = slurp($!FileName, enc => "iso-8859-1");
my #lines = $file-data.lines;
my $start = now;
for #lines -> $line {
state $i = 1;
my #splitLine = split('|', $line);
if ($line.starts-with("H|") || $line.starts-with("T|")) {
next;
}
my $lnObject = LineValidation.new( line => $line, FileType => $.FileType );
$lnObject.ColumnIds = %.ColumnIds;
my #promises;
my #validationIds;
for %.ValidationRules.keys -> $validationId {
if (%.ValidationRules{$validationId}<ValidationType> eq 'COLUMN') {
push #promises, start {$lnObject.ColumnValidationFunction(%.ValidationRules{$validationId}<ValidationFunction>, %.ValidationRules{$validationId}<Arguments>, $.ValidationRules{$validationId}<Description>); 1};
push #validationIds, $validationId;
}
}
my #promise-output = await #promises;
for #validationIds -> $valId {
state $j = 0;
my $result = #promise-output[$j];
if ($result.Bool == True) {
if (%.ResultSet{$valId}<count> :!exists) {
%.ResultSet{$valId}<count> = 1;
} else {
%.ResultSet{$valId}<count> = %.ResultSet{$valId}<count> + 1;
}
my #prCol = (%.ValidationRules{$valId}<Arguments><column>, #.printColumns);
if (%.ResultSet{$valId}<count> <= 10) {
%.ResultSet{$valId}.push: (sample => join('|', #splitLine[#prCol[*;*]].map: { if ($_.Bool == False ) { $_ = ''} else {$_ = $_;} }));
}
%.ResultSet{$valId}<ColumnList> = #prCol[*;*];
}
$j++;
}
$i++;
}
say "Line validation completed in {now - $start } time for $.lineCount lines";
}
The code was working fine earlier but when run using larger files, it just arbitrarily throws the error Segmentation fault and exists. I cannot determine where it is failing either.
how to Validation IRAN Code Meli in Ajax ActiveForm Yii2
Correct:
2595722751
not Correct:
2595722752
Step1: in view
<?php $form = ActiveForm::begin(['enableAjaxValidation' => true]); ?>
Step2: function in model
public function checkCodeMeli()
{
$code_melli = $this->code_meli;
if (!preg_match('/^[0-9]{10}$/', $code_melli)) {
$this->addError('code_meli', 'کد ملی باید 10 رقم باشد');
}
for ($i = 0; $i < 10; $i++) {
if (preg_match('/^' . $i . '{10}$/', $code_melli)) {
$this->addError('code_meli', 'کد ملی صحیح وارد نشده است');
}
}
for ($i = 0, $sum = 0; $i < 9; $i++) {
$sum += ((10 - $i) * intval(substr($code_melli, $i, 1)));
}
$ret = $sum % 11;
$parity = intval(substr($code_melli, 9, 1));
if (($ret < 2 && $ret == $parity) || ($ret >= 2 && $ret == 11 - $parity)) {
return true;
}
else {
$this->addError('code_meli', 'کد ملی صحیح وارد نشده است');
}
}
Step3: rule in Model
['code_meli', 'checkCodeMeli'],
Step4: in controller
$model = new Model();
if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
I'm using TCPDF + FPDI. I want to embed all fonts fully. Font embedding works great when using addTTFfont() and SetFont() methods. But when I try to open existing pdf file using FPDI, I can't get list of used fonts and can't determine which of them are already embedded. Here is what I'm trying to do:
Get the font info(name, type, etc) of source pdf file;
Determine which fonts are not fully embedded;
Embed those fonts.
So far I tried to make TCPDF class protected member fonts public. So, I changed tcpdf.php file:
/**
* Array of used fonts.
* #protected
*/
public $fonts = array();
In main.php
$pdf = new FPDI();
$pdf->setSourceFile('Simple.pdf');
$pdf->AddPage();
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx, 10, 10, 200);
$pdf->setFontSubsetting(false);
var_dump($pdf->fonts);
Output:
array (size=2)
'helvetica' =>
array (size=17)
'fontkey' => string 'helvetica' (length=9)
'i' => int 1
'type' => string 'core' (length=4)
'name' => string 'Helvetica' (length=9)
'desc' =>
array (size=13)
'Flags' => int 32
'FontBBox' => string '[-166 -225 1000 931]' (length=20)
'ItalicAngle' => int 0
'Ascent' => int 931
'Descent' => int -225
'Leading' => int 0
'CapHeight' => int 718
'XHeight' => int 523
'StemV' => int 88
'StemH' => int 76
'AvgWidth' => int 513
'MaxWidth' => int 1015
'MissingWidth' => int 513
'up' => int -100
'ut' => int 50
'cw' =>
array (size=256)
0 => int 500
1 => int 500
2 => int 500
...
...
'cbbox' =>
array (size=0)
empty
'dw' => int 513
'enc' => string '' (length=0)
'cidinfo' =>
array (size=4)
'Registry' => string 'Adobe' (length=5)
'Ordering' => string 'Identity' (length=8)
'Supplement' => int 0
'uni2cid' =>
array (size=0)
empty
'file' => string '' (length=0)
'ctg' => string '' (length=0)
'subset' => boolean false
'subsetchars' =>
array (size=255)
0 => boolean true
1 => boolean true
2 => boolean true
3 => boolean true
...
...
'n' => int 3
'helveticaB' =>
array (size=17)
'fontkey' => string 'helveticaB' (length=10)
'i' => int 2
'type' => string 'core' (length=4)
'name' => string 'Helvetica-Bold' (length=14)
'desc' =>
array (size=13)
'Flags' => int 32
'FontBBox' => string '[-170 -228 1003 962]' (length=20)
'ItalicAngle' => int 0
'Ascent' => int 962
'Descent' => int -228
'Leading' => int 0
'CapHeight' => int 718
'XHeight' => int 532
'StemV' => int 140
'StemH' => int 118
'AvgWidth' => int 535
'MaxWidth' => int 1000
'MissingWidth' => int 535
'up' => int -100
'ut' => int 50
'cw' =>
array (size=256)
0 => int 278
1 => int 278
2 => int 278
3 => int 278
...
...
'cbbox' =>
array (size=0)
empty
'dw' => int 535
'enc' => string '' (length=0)
'cidinfo' =>
array (size=4)
'Registry' => string 'Adobe' (length=5)
'Ordering' => string 'Identity' (length=8)
'Supplement' => int 0
'uni2cid' =>
array (size=0)
empty
'file' => string '' (length=0)
'ctg' => string '' (length=0)
'subset' => boolean false
'subsetchars' =>
array (size=255)
0 => boolean true
1 => boolean true
2 => boolean true
3 => boolean true
...
...
'n' => int 5
There are info about 2 fonts: "helvetica"(which is the default font according to TCPDF documentacion) and "helveticaB". But source file contains other fonts too. They are not listed. How to list them?
Thanks in advance...
You will need to ensure that the imported document/pages have all fonts embedded in advance. It is impossible to ensure that fonts in imported pages are embedded through FPDI.
You also cannot access/list the fonts with FPDI.
After digging in .pdf file and reading some topics of pdf documentation, I managed to somehow solve the problem. The following code is only draft and needs a lot of improvements. I've tested several .pdf files and it worked, but there are a lot of things, that need a better approach.
While trying to solve the problem, I decided to leave TCPDF and FPDI libraries unchanged. I haven't used any method of those libraries, since I don't know the inner functionality of those libraries.
P.S: Unfortunately, I didn't have much time and my code is long (and not stable):
<?php
require_once('tcpdf.php');
require_once('fpdi.php');
class PDF extends FPDI
{
var $_tplIdx;
private $objects;
private $font_list;
private $raw_data;
private $raw_data_len;
private $font_read_offset;
private $embedded_font_addr;
private $is_descendant;
function __construct($filename)
{
$this->objects = array();
$this->font_list = array();
$this->raw_data = file_get_contents($filename);
$this->raw_data_len = strlen($this->raw_data);
$this->font_read_offset = 0;
$this->is_descendant = false;
parent::__construct();
}
private function EmbeddedFontRefs()
{
do
{
$f = $this->GetXObj('Subtype /CIDFontType2');
if($f == NULL)
return;
//var_dump($f);
$keys = array_keys($f);
$f = $f[$keys[0]];
$name = '';
$ref = '';
if(preg_match('/Subtype \/CIDFontType2/', $f))
{
$matches = array();
if(preg_match('/BaseFont \/\S+/', $f, $matches))
$name = substr($matches[0], 10);
if(preg_match('/FontDescriptor \d+ \d+ R+/', $f, $matches))
{
$ref = substr($matches[0], 15);
$ref = $this->GetObjFromRef($ref);
}
$this->embedded_font_addr[$name] = $ref;
}
}while($f !== NULL);
}
private function ParseObj($obj_search_string, $referrer_object_addr=NULL, $referrer_object_name=NULL)
{
$object_data = $this->GetObj($obj_search_string);
if($object_data == NULL)
return false;
$object_addr = array_keys($object_data);
$object_addr = $object_addr[0];
$object_raw_data = $object_data[$object_addr];
$embedded = false;
$subset = false;
if(!array_key_exists($object_addr, $this->objects))
{
$this->objects[$object_addr] = array();
$obj_content_items = preg_split('/\n\r?/', $object_raw_data);
for($i = 0; $i < count($obj_content_items); $i++)
{
$item = explode(' ', $obj_content_items[$i], 2);
if($item[0][0] == '/')
$item[0] = substr($item[0], 1);
if($item[1][0] == '/')
$item[1] = substr($item[1], 1);
if(($i + 1) < count($obj_content_items))
$item[1] = substr($item[1], 0, -1);
if(($item[0] == 'FontFile') || ($item[0] == 'FontFile2') || ($item[0] == 'FontFile3'))
$embedded = true;
else if(($item[0] == 'BaseFont') || ($item[0] == 'FontName'))
{
$item[1] = str_replace('#20', ' ', $item[1]);
if(preg_match('/[A-Z]{5}\+/', $item[1]))
$subset = true;
}
$this->objects[$object_addr][$item[0]] = $item[1]; // item_name => item_value
}
}
if($referrer_object_addr == NULL)
{
if(array_key_exists('Subtype', $this->objects[$object_addr]))
{
if($this->objects[$object_addr]['Subtype'] == 'Type0') //Composite Fonts
{
if(array_key_exists('DescendantFonts', $this->objects[$object_addr]))
{
$descendant_fonts_obj_addr = $this->GetObjFromRef($this->objects[$object_addr]['DescendantFonts']);
array_push($this->font_list, '');
$this->font_list[count($this->font_list)-1] = $this->objects[$object_addr];
$this->ParseObj($descendant_fonts_obj_addr, $object_addr, 'DescendantFonts');
}
}
}
if(array_key_exists('FontDescriptor', $this->objects[$object_addr]))
{
$font_desc_obj_addr = $this->GetObjFromRef($this->objects[$object_addr]['FontDescriptor']);
array_push($this->font_list, '');
$this->font_list[count($this->font_list)-1] = $this->objects[$object_addr];
$this->ParseObj($font_desc_obj_addr, $object_addr, 'FontDescriptor');
}
}
else
{
if(array_key_exists($referrer_object_addr, $this->objects))
{
if($referrer_object_name == 'DescendantFonts')
{
$this->font_list[count($this->font_list)-1]['DescendantFonts'] = array();
array_push($this->font_list[count($this->font_list)-1]['DescendantFonts'], $this->objects[$object_addr]);
$this->is_descendant = true;
if(array_key_exists('FontDescriptor', $this->objects[$object_addr]))
{
$font_desc_obj_addr = $this->GetObjFromRef($this->objects[$object_addr]['FontDescriptor']);
$this->ParseObj($font_desc_obj_addr, $object_addr, 'FontDescriptor');
}
}
else if($referrer_object_name == 'FontDescriptor')
{
if(array_key_exists('Type', $this->objects[$object_addr]))
unset($this->objects[$object_addr]['Type']);
//Embedded or not?
$keys = array_keys($this->objects[$object_addr]);
foreach($keys as $key)
{
if(($key == 'FontFile') || ($key == 'FontFile2') || ($key == 'FontFile3'))
{
$embedded = true;
break;
}
}
if(!$this->is_descendant)
{
$this->font_list[count($this->font_list)-1]['Embedded'] = $embedded;
$this->font_list[count($this->font_list)-1]['Subset'] = $subset;
$this->font_list[count($this->font_list)-1]['FontDescriptor'] = $this->objects[$object_addr];
}
else
{
$this->font_list[count($this->font_list)-1]['DescendantFonts'][0]['Embedded'] = $embedded;
$this->font_list[count($this->font_list)-1]['DescendantFonts'][0]['Subset'] = $subset;
$this->font_list[count($this->font_list)-1]['DescendantFonts'][0]['FontDescriptor'] = $this->objects[$object_addr];
$this->is_descendant = false;
}
}
}
}
return true;
}
private function GetObj($obj_search_string)
{
$obj_offset = strpos($this->raw_data, $obj_search_string, $this->font_read_offset);
if($obj_offset == false)
{
return NULL;
}
$obj_start = 0;
$obj_end = 0;
$object_content_start = 0;
$object_content_end = 0;
$obj_start = strrpos($this->raw_data, 'endobj', $obj_offset - $this->raw_data_len) + 8; // for 'endobj\n\r';
$obj_end = strpos($this->raw_data, 'endobj', $obj_start);
$this->font_read_offset = $obj_end;
$object_content_start = strpos($this->raw_data, '<<', $obj_start) + 2; //for '<<'
$object_content_end = strpos($this->raw_data, '>>', $object_content_start) - 2; //for /n/r;
$object_addr = substr($this->raw_data, $obj_start, $object_content_start - $obj_start - 4); // -2 for /n/r;
$object_raw_data = substr($this->raw_data, $object_content_start, $object_content_end - $object_content_start);
return array($object_addr => $object_raw_data);
}
private function GetXObj($obj_search_string)
{
$obj_offset = strpos($this->raw_data, $obj_search_string, $this->font_read_offset);
if($obj_offset == false)
return NULL;
$obj_start = 0;
$obj_end = 0;
$object_content_start = 0;
$object_content_end = 0;
$obj_start = strrpos($this->raw_data, 'endobj', $obj_offset - $this->raw_data_len) + 8; // for 'endobj\n\r';
$obj_end = strpos($this->raw_data, 'endobj', $obj_start);
$this->font_read_offset = $obj_end;
$object_content_start = strpos($this->raw_data, '<<', $obj_start) + 2; //for '<<'
$object_content_end = $obj_end - 1;
$object_addr = substr($this->raw_data, $obj_start, $object_content_start - $obj_start - 3); // -2 for /n/r;
$object_raw_data = substr($this->raw_data, $object_content_start, $object_content_end - $object_content_start);
return array($object_addr => $object_raw_data);
}
private function GetFontDescriptor($font_object_addr)
{
if(array_key_exists('FontDescriptor', $this->objects[$font_object_addr]))
$font_desc_ref = $this->objects[$font_object_addr]['FontDescriptor'];
$font_desc_obj_addr = $this->GetObjFromRef($font_desc_ref);
$this->ParseObj($font_desc_obj_addr, $font_object_addr);
}
}
private function GetObjFromRef($obj_ref)
{
$obj_ref_num = explode(' ', $obj_ref);
$obj = '';
if(end($obj_ref_num) == 'R')
{
foreach($obj_ref_num as $num)
{
if($num != 'R')
$obj .= (string)$num. ' ';
else
$obj .= 'obj';
}
}
else if(end($obj_ref_num) == 'obj')
$obj = $obj_ref;
return $obj;
}
public function EnsureFonts($filename)
{
$this->raw_data = file_get_contents($filename);
$this->raw_data_len = strlen($this->raw_data);
$this->font_read_offset = 0;
$this->EmbeddedFontRefs();
$this->font_read_offset = 0;
$font_objs = array();
do
{
$xobj = $this->GetXObj('/Type /XObject');
if($xobj !== NULL)
{
$xobj_addr = array_keys($xobj);
$xobj_addr = $xobj_addr[0];
$matches = array();
if(preg_match('/Resources \d+ \d+ R/', $xobj[$xobj_addr], $matches))
{
array_push($font_objs, $this->GetObjFromRef(substr($matches[0], 10))); //Resources+' '
}
}
}while($xobj !== NULL);
$fxobjs = array();
foreach($font_objs as $font_obj)
{
$fobj = $this->GetXObj($font_obj);
if($fobj !== NULL)
{
$xobj_addr = array_keys($fobj);
$xobj_addr = $xobj_addr[0];
$matches = array();
if(preg_match('/Font \d+ \d+ R/', $fobj[$xobj_addr], $matches))
{
array_push($fxobjs, $this->GetObjFromRef(substr($matches[0], 10))); //Resources+' '
}
}
}
$actual_font_objs = array();
foreach($fxobjs as $fxobj)
{
$f_obj = $this->GetXObj($fxobj);
if($f_obj !== NULL)
{
$xobj_addr = array_keys($f_obj);
$xobj_addr = $xobj_addr[0];
$matches = array();
if(preg_match('/F\d+/', $f_obj[$xobj_addr], $matches))
{
array_push($actual_font_objs, $this->GetObjFromRef(substr($matches[0], 10))); //Resources+' '
}
}
}
foreach($actual_font_objs as $fo)
{
$f = $this->GetXObj($fxobj);
if($f !== NULL)
{
$xobj_addr = array_keys($f);
$xobj_addr = $xobj_addr[0];
$matches = array();
$f_name = '';
if(preg_match('/BaseFont \/\S+/', $f[$xobj_addr], $matches))
{
$f_name = substr($matches[0], 10); // BaseFont+' '+'/'
}
if(preg_match('/FontDescriptor \d+ \d+ R/', $f[$xobj_addr], $matches))
{
$fd_replace_start_pos = strpos($this->raw_data, $matches[0]) + 15; //FontDescriptor+' ';
$fd_replace_end_pos = strpos($this->raw_data, 'R', $fd_replace_start_pos) + 1; //For 'R';
$s = substr($this->raw_data, 0, $fd_replace_start_pos);
$r = substr($this->embedded_font_addr[$f_name], 0, -3).'R'; //-4 for obj.
$e = substr($this->raw_data, $fd_replace_end_pos);
$this->raw_data = $s . $r . $e;
}
}
}
file_put_contents($filename, $this->raw_data);
}
public function GetFontInfo()
{
do
{
$this->ParseObj('/Type /Font');
}while($this->ParseObj('/Type /Font') == true);
return $this->GetNotEmbeddedFonts();
}
private function GetNotEmbeddedFonts()
{
$result = array();
foreach($this->font_list as $font)
{
if(array_key_exists('DescendantFonts', $font))
{
foreach($font['DescendantFonts'] as $desc_font)
{
if((array_key_exists('Embedded', $desc_font)) && (array_key_exists('BaseFont', $desc_font)))
if(!$desc_font['Embedded'])
array_push($result, $desc_font['BaseFont']);
}
}
else
{
if((array_key_exists('Embedded', $font)) && (array_key_exists('BaseFont', $font)))
if(!$font['Embedded'])
array_push($result, $font['BaseFont']);
}
}
for($i= 0; $i<count($result); $i++)
{
if(strpos($result[$i], ' ') || strpos($result[$i], ',')) //Adobe Acrobat system font name list. Needs improvment..
{
switch($r)
{
case 'Times New Roman':
$result[$i] = 'TimesNewRomanPSMT';
break;
case 'Times New Roman,Bold':
$result[$i] = 'TimesNewRomanPS-BoldMT';
break;
case 'Times New Roman,Italic':
$result[$i] = 'TimesNewRomanPS-ItalicMT';
break;
case 'Times New Roman,BoldItalic':
$result[$i] = 'TimesNewRomanPS-BoldItalicMT';
break;
case 'Aial':
$result[$i] = 'ArialMT';
break;
}
}
}
return $result;
}
}
$pdf = new PDF($filename);
$pdf->setSourceFile($filename);
$pdf->AddPage();
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx);
$pdf->SetMargins(PDF_MARGIN_LEFT, 40, PDF_MARGIN_RIGHT);
$pdf->SetAutoPageBreak(true, 40);
$pdf->setFontSubsetting(false);
$not_embedded_fonts = $pdf->GetFontInfo();
foreach($not_embedded_fonts as $f)
{
$font_name = strtolower($f);
$font_name = preg_replace('/[^a-z0-9_]/', '', $font_name);
$search = array('bold', 'oblique', 'italic', 'regular');
$replace = array('b', 'i', 'i', '');
$font_name = str_replace($search, $replace, $font_name);
if($pdf->AddFont($font_name) !== false)
$pdf->SetFont($font_name);
else
print('"' .$font_name. '" font not found!');
}
$pdf->Output();
?>
My Dear Buddies,
I need your help to make captcha case sensitive phpfox,
i want to make captcha not case sensitive in my phpfox site. please help me.
i can not find code for change case sensitivity in phpfox captcha module, and there is no any settings in phpfox backend for that so ple help me.
here is code of
captcha.class.php
<?php
/**
* [PHPFOX_HEADER]
*/
defined('PHPFOX') or exit('NO DICE!');
/**
*
*
* #copyright [PHPFOX_COPYRIGHT]
* #author Raymond Benc
* #package Module_Captcha
* #version $Id: captcha.class.php 6005 2013-06-06 14:12:12Z Raymond_Benc $
*/
class Captcha_Service_Captcha extends Phpfox_Service
{
private $_oSession;
/**
* Class constructor
*/
public function __construct()
{
$this->_oSession = Phpfox::getService('log.session');
}
public function checkHash($sCode = null)
{
if (Phpfox::getParam('captcha.recaptcha'))
{
require_once(PHPFOX_DIR_LIB . 'recaptcha' . PHPFOX_DS . 'recaptchalib.php');
if (isset($_POST["recaptcha_response_field"]))
{
$oResp = recaptcha_check_answer(Phpfox::getParam('captcha.recaptcha_private_key'), $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);
if ($oResp->is_valid){
return true;
}else{
return false;
}
}
return false;
}
if (Phpfox::getParam('core.store_only_users_in_session'))
{
$oSession = Phpfox::getLib('session');
$sSessionHash = $oSession->get('sessionhash');
$aRow = $this->database()->select('*')
->from(Phpfox::getT('log_session'))
->where('session_hash = \'' . $this->database()->escape($sSessionHash) . '\'')
->execute('getSlaveRow');
if (isset($aRow['session_hash']) && $this->_getHash(strtolower($sCode), $aRow['session_hash']) == $aRow['captcha_hash'])
{
return true;
}
}
else
{
if ($this->_getHash(strtolower($sCode), $this->_oSession->getSessionId()) == $this->_oSession->get('captcha_hash'))
{
return true;
}
}
return false;
}
public function setHash($sCode)
{
if (Phpfox::getParam('core.store_only_users_in_session'))
{
$oRequest = Phpfox_Request::instance();
$oSession = Phpfox::getLib('session');
$sSessionHash = $oSession->get('sessionhash');
$bCreate = true;
if (!empty($sSessionHash))
{
$bCreate = false;
$aRow = $this->database()->select('*')
->from(Phpfox::getT('log_session'))
->where('session_hash = \'' . $this->database()->escape($sSessionHash) . '\'')
->execute('getSlaveRow');
if (isset($aRow['session_hash']))
{
$this->database()->update(Phpfox::getT('log_session'), array('captcha_hash' => $this->_getHash($sCode, $sSessionHash)), "session_hash = '" . $sSessionHash . "'");
}
else
{
$bCreate = true;
}
}
if ($bCreate)
{
$sSessionHash = $oRequest->getSessionHash();
$this->database()->insert(Phpfox::getT('log_session'), array(
'session_hash' => $sSessionHash,
'id_hash' => $oRequest->getIdHash(),
'captcha_hash' => $this->_getHash($sCode, $sSessionHash),
'user_id' => Phpfox::getUserId(),
'last_activity' => PHPFOX_TIME,
'location' => '',
'is_forum' => '0',
'forum_id' => 0,
'im_hide' => 0,
'ip_address' => '',
'user_agent' => ''
)
);
$oSession->set('sessionhash', $sSessionHash);
}
}
else
{
$iId = $this->_oSession->getSessionId();
$this->database()->update(Phpfox::getT('log_session'), array('captcha_hash' => $this->_getHash($sCode, $iId)), "session_hash = '" . $iId . "'");
}
}
public function displayCaptcha($sText)
{
((Phpfox::getParam('captcha.captcha_use_font') && function_exists('imagettftext')) ? $this->_writeFromFont($sText) : $this->_writeFromString($sText));
ob_clean();
header("X-Content-Encoded-By: phpFox " . PhpFox::getVersion());
header("Pragma: no-cache");
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Content-Type: image/jpeg');
imagejpeg($this->_hImg);
imagedestroy($this->_hImg);
}
public function generateCode($sCharacters)
{
$sPossible = Phpfox::getParam('captcha.captcha_code');
$sCode = '';
$i = 0;
while ($i < $sCharacters)
{
$sCode .= substr($sPossible, mt_rand(0, strlen($sPossible)-1), 1);
$i++;
}
return strtolower($sCode);
}
/**
* If a call is made to an unknown method attempt to connect
* it to a specific plug-in with the same name thus allowing
* plug-in developers the ability to extend classes.
*
* #param string $sMethod is the name of the method
* #param array $aArguments is the array of arguments of being passed
*/
public function __call($sMethod, $aArguments)
{
/**
* Check if such a plug-in exists and if it does call it.
*/
if ($sPlugin = Phpfox_Plugin::get('captcha.service_captcha__call'))
{
return eval($sPlugin);
}
/**
* No method or plug-in found we must throw a error.
*/
Phpfox_Error::trigger('Call to undefined method ' . __CLASS__ . '::' . $sMethod . '()', E_USER_ERROR);
}
private function _getHash($sCode, $sSalt)
{
return md5(md5($sCode) . $sSalt);
}
private function _writeFromFont($sText)
{
$iString = strlen($sText);
$iWidth = (($iString + 5) * 10 * 2);
$iHeight = 45;
$iTextSize = 20;
$sFont = Phpfox::getParam('core.dir_static') . 'image/font/' . Phpfox::getParam('captcha.captcha_font');
if (!file_exists($sFont))
{
return $this->_writeFromString($sText);
}
$this->_imageCreate($iWidth, $iHeight);
$nBgColor = imageColorAllocate($this->_hImg, 255, 255, 255);
$nTxtColor = imageColorAllocate($this->_hImg, 0, 0, 0);
if (!($aBox = #imagettfbbox($iTextSize, 0, $sFont, $sText)))
{
return $this->_writeFromString($sText);
}
//Find out the width and height of the text box
$iTextW = $aBox[2] - $aBox[0];
$iTextH = $aBox[5] - $aBox[3];
if (function_exists('imagefilledellipse'))
{
$nNoiseColor = imagecolorallocate($this->_hImg, 207, 181, 181);
for ($i = 0; $i < ($iWidth*$iHeight) / 3; $i++)
{
imagefilledellipse($this->_hImg, mt_rand(0, $iWidth), mt_rand(0, $iHeight), 1, 1, $nNoiseColor);
}
}
$iImageLineColor = imagecolorallocate($this->_hImg, 207, 181, 181);
for ($i = 0; $i < ($iWidth*$iHeight) / 150; $i++)
{
imageline($this->_hImg, mt_rand(0, $iWidth), mt_rand(0, $iHeight), mt_rand(0, $iWidth), mt_rand(0, $iHeight), $iImageLineColor);
}
// Calculate the positions
$positionLeft = (($iWidth - $iTextW) / 2) - (20 + $iString);
$positionTop = (($iHeight - $iTextH) / 2);
for ($i = 0; $i < $iString; $i++)
{
if (!#imagettftext($this->_hImg, $iTextSize, 0, $positionLeft, 30, $nTxtColor, $sFont, $sText[$i]))
{
return $this->_writeFromString($sText);
}
$positionLeft += 20;
}
}
private function _writeFromString($sText)
{
$iString = strlen($sText);
$iWidth = (($iString + 5) * 6.4 * 2);
$iHeight = 40;
$this->_imageCreate($iWidth, $iHeight);
$nBgColor = imageColorAllocate($this->_hImg, 255, 255, 255);
$nTxtColor = imageColorAllocate($this->_hImg, 0, 0, 0);
$positionLeft = 20;
for ($i = 0; $i < $iString; $i++)
{
imagestring($this->_hImg, 5, $positionLeft, 12, $sText[$i], $nTxtColor);
$positionLeft += 15;
}
}
private function _imageCreate($iWidth, $iHeight)
{
$this->_hImg = imageCreate($iWidth, $iHeight);
}
}
?>
You need to remove all the code that use strtolower().
Here the fixed code:
<?php
/**
* [PHPFOX_HEADER]
*/
defined('PHPFOX') or exit('NO DICE!');
/**
*
*
* #copyright [PHPFOX_COPYRIGHT]
* #author Raymond Benc
* #package Module_Captcha
* #version $Id: captcha.class.php 6005 2013-06-06 14:12:12Z Raymond_Benc $
*/
class Captcha_Service_Captcha extends Phpfox_Service
{
private $_oSession;
/**
* Class constructor
*/
public function __construct()
{
$this->_oSession = Phpfox::getService('log.session');
}
public function checkHash($sCode = null)
{
if (Phpfox::getParam('captcha.recaptcha'))
{
require_once(PHPFOX_DIR_LIB . 'recaptcha' . PHPFOX_DS . 'recaptchalib.php');
if (isset($_POST["recaptcha_response_field"]))
{
$oResp = recaptcha_check_answer(Phpfox::getParam('captcha.recaptcha_private_key'), $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);
if ($oResp->is_valid){
return true;
}else{
return false;
}
}
return false;
}
if (Phpfox::getParam('core.store_only_users_in_session'))
{
$oSession = Phpfox::getLib('session');
$sSessionHash = $oSession->get('sessionhash');
$aRow = $this->database()->select('*')
->from(Phpfox::getT('log_session'))
->where('session_hash = \'' . $this->database()->escape($sSessionHash) . '\'')
->execute('getSlaveRow');
if (isset($aRow['session_hash']) && $this->_getHash($sCode, $aRow['session_hash']) == $aRow['captcha_hash'])
{
return true;
}
}
else
{
if ($this->_getHash($sCode, $this->_oSession->getSessionId()) == $this->_oSession->get('captcha_hash'))
{
return true;
}
}
return false;
}
public function setHash($sCode)
{
if (Phpfox::getParam('core.store_only_users_in_session'))
{
$oRequest = Phpfox_Request::instance();
$oSession = Phpfox::getLib('session');
$sSessionHash = $oSession->get('sessionhash');
$bCreate = true;
if (!empty($sSessionHash))
{
$bCreate = false;
$aRow = $this->database()->select('*')
->from(Phpfox::getT('log_session'))
->where('session_hash = \'' . $this->database()->escape($sSessionHash) . '\'')
->execute('getSlaveRow');
if (isset($aRow['session_hash']))
{
$this->database()->update(Phpfox::getT('log_session'), array('captcha_hash' => $this->_getHash($sCode, $sSessionHash)), "session_hash = '" . $sSessionHash . "'");
}
else
{
$bCreate = true;
}
}
if ($bCreate)
{
$sSessionHash = $oRequest->getSessionHash();
$this->database()->insert(Phpfox::getT('log_session'), array(
'session_hash' => $sSessionHash,
'id_hash' => $oRequest->getIdHash(),
'captcha_hash' => $this->_getHash($sCode, $sSessionHash),
'user_id' => Phpfox::getUserId(),
'last_activity' => PHPFOX_TIME,
'location' => '',
'is_forum' => '0',
'forum_id' => 0,
'im_hide' => 0,
'ip_address' => '',
'user_agent' => ''
)
);
$oSession->set('sessionhash', $sSessionHash);
}
}
else
{
$iId = $this->_oSession->getSessionId();
$this->database()->update(Phpfox::getT('log_session'), array('captcha_hash' => $this->_getHash($sCode, $iId)), "session_hash = '" . $iId . "'");
}
}
public function displayCaptcha($sText)
{
((Phpfox::getParam('captcha.captcha_use_font') && function_exists('imagettftext')) ? $this->_writeFromFont($sText) : $this->_writeFromString($sText));
ob_clean();
header("X-Content-Encoded-By: phpFox " . PhpFox::getVersion());
header("Pragma: no-cache");
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Content-Type: image/jpeg');
imagejpeg($this->_hImg);
imagedestroy($this->_hImg);
}
public function generateCode($sCharacters)
{
$sPossible = Phpfox::getParam('captcha.captcha_code');
$sCode = '';
$i = 0;
while ($i < $sCharacters)
{
$sCode .= substr($sPossible, mt_rand(0, strlen($sPossible)-1), 1);
$i++;
}
return $sCode;
}
/**
* If a call is made to an unknown method attempt to connect
* it to a specific plug-in with the same name thus allowing
* plug-in developers the ability to extend classes.
*
* #param string $sMethod is the name of the method
* #param array $aArguments is the array of arguments of being passed
*/
public function __call($sMethod, $aArguments)
{
/**
* Check if such a plug-in exists and if it does call it.
*/
if ($sPlugin = Phpfox_Plugin::get('captcha.service_captcha__call'))
{
return eval($sPlugin);
}
/**
* No method or plug-in found we must throw a error.
*/
Phpfox_Error::trigger('Call to undefined method ' . __CLASS__ . '::' . $sMethod . '()', E_USER_ERROR);
}
private function _getHash($sCode, $sSalt)
{
return md5(md5($sCode) . $sSalt);
}
private function _writeFromFont($sText)
{
$iString = strlen($sText);
$iWidth = (($iString + 5) * 10 * 2);
$iHeight = 45;
$iTextSize = 20;
$sFont = Phpfox::getParam('core.dir_static') . 'image/font/' . Phpfox::getParam('captcha.captcha_font');
if (!file_exists($sFont))
{
return $this->_writeFromString($sText);
}
$this->_imageCreate($iWidth, $iHeight);
$nBgColor = imageColorAllocate($this->_hImg, 255, 255, 255);
$nTxtColor = imageColorAllocate($this->_hImg, 0, 0, 0);
if (!($aBox = #imagettfbbox($iTextSize, 0, $sFont, $sText)))
{
return $this->_writeFromString($sText);
}
//Find out the width and height of the text box
$iTextW = $aBox[2] - $aBox[0];
$iTextH = $aBox[5] - $aBox[3];
if (function_exists('imagefilledellipse'))
{
$nNoiseColor = imagecolorallocate($this->_hImg, 207, 181, 181);
for ($i = 0; $i < ($iWidth*$iHeight) / 3; $i++)
{
imagefilledellipse($this->_hImg, mt_rand(0, $iWidth), mt_rand(0, $iHeight), 1, 1, $nNoiseColor);
}
}
$iImageLineColor = imagecolorallocate($this->_hImg, 207, 181, 181);
for ($i = 0; $i < ($iWidth*$iHeight) / 150; $i++)
{
imageline($this->_hImg, mt_rand(0, $iWidth), mt_rand(0, $iHeight), mt_rand(0, $iWidth), mt_rand(0, $iHeight), $iImageLineColor);
}
// Calculate the positions
$positionLeft = (($iWidth - $iTextW) / 2) - (20 + $iString);
$positionTop = (($iHeight - $iTextH) / 2);
for ($i = 0; $i < $iString; $i++)
{
if (!#imagettftext($this->_hImg, $iTextSize, 0, $positionLeft, 30, $nTxtColor, $sFont, $sText[$i]))
{
return $this->_writeFromString($sText);
}
$positionLeft += 20;
}
}
private function _writeFromString($sText)
{
$iString = strlen($sText);
$iWidth = (($iString + 5) * 6.4 * 2);
$iHeight = 40;
$this->_imageCreate($iWidth, $iHeight);
$nBgColor = imageColorAllocate($this->_hImg, 255, 255, 255);
$nTxtColor = imageColorAllocate($this->_hImg, 0, 0, 0);
$positionLeft = 20;
for ($i = 0; $i < $iString; $i++)
{
imagestring($this->_hImg, 5, $positionLeft, 12, $sText[$i], $nTxtColor);
$positionLeft += 15;
}
}
private function _imageCreate($iWidth, $iHeight)
{
$this->_hImg = imageCreate($iWidth, $iHeight);
}
}
?>
You may run into a problem or it could be your solution. Remember, the collation on your database also needs to be taken in consideration. If you are using utf8_general_ci then the ci means that it is case insensitive so no matter what you do on the code side, the database does not care if its upper or lower case. Test that on your search bar, look for some string, lets say a user, John Smith, and then search for the same string as john smith... If the search produces the same result, then your database doesn't care about case sensitive search. I don´t know where your captcha saves its answers, but if it does save them on the database, and its matching your questions in it, then it may not care if it is upper or lower case.
Just a reminder. You need to test that in your own enviroment.