Zend_Form_Element_Captcha Not Working - php

Apparently this is a common problem but I have not been able to figure out how to get a Zend Captcha Image to show up, it will create the image and it will create the hidden element but the image tag never shows up, does anyone have a solution??
Here is the code that doesn't work:
<?php
class Application_Form_Contact extends Zend_Form
{
public function init()
{
/* Form Elements & Other Definitions Here ... */
$this->setAction('/contact/')->setMethod('post');
$element = new Zend_Form_Element_Text('name');
$element->setLabel('Name:')
->setRequired(true)
->addFilter('HtmlEntities');
$this->addElement($element);
$element = new Zend_Form_Element_Text('phone');
$element->setLabel('Phone:')
->setRequired(true)
->addFilter('HtmlEntities');
$this->addElement($element);
$element = new Zend_Form_Element_Text('email');
$element->setLabel('Email:')
->setRequired(true)
->addValidator('EmailAddress', true)
->addFilter('StripTags')
->addFilter('HtmlEntities')
->addFilter('StringToLower')
->addFilter('StringTrim');
$this->addElement($element);
$comments = $this->createElement('textarea', 'comments')
->setLabel('Comments:')
->setRequired(true)
->setOptions(array('style'=>'width:95%;'))
->addFilter('StripTags')
->addFilter('HtmlEntities')
->addFilter('StringTrim');
$this->addElement($comments);
$captcha= new Zend_Form_Element_Captcha('captcha', array(
'id'=>'captchas',
'title'=>'Security Check.',
'captcha' => array(
'captcha' => 'Image',
'required' => true,
'font'=> PUBLIC_PATH . '/verdana.ttf',
'wordlen'=>'4',
'width'=>'80',
'height'=>'50',
'ImgAlign'=>'left',
'imgdir'=> PUBLIC_PATH . '/images/captcha/',
'DotNoiseLevel'=>'0',
'LineNoiseLevel'=>'0',
'Expiration'=>'1000',
'fontsize'=>'16'
)));
$this->addElement($captcha);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Send');
$this->addElement($submit);
}
}

I've only got two ideas that might help:
Check to make sure your GD extension is enabled in php.
It requires the GD extension compiled with TrueType or Freetype support. Currently, the Zend_Captcha_Image adapter can only generate PNG images.
you may want to specify the imgUrl =>
setImgUrl($imgUrl) and getImgUrl() allow you to specify the relative path to a CAPTCHA image to use for HTML markup. The default is "/images/captcha/".
also just for information you don't need to set the element as required as the captcha is always required.
As noted, the captcha adapter itself acts as a validator for the element. Additionally, the NotEmpty validator is not used, and the element is marked as required. In most cases, you should need to do nothing else to have a captcha present in your form.
Try to edit your captcha down to bare bones
$captcha = new Zend_Form_Element_Captcha('Captcha', array(
'captcha' => array(
'captcha' => 'Image',
'wordLen' => 6,
'timeout' => 300,
'width' => 300,
'height' => 100,
'imgUrl' => '/captcha',
'imgDir' => APPLICATION_PATH . '/../public/captcha',
'font' => APPLICATION_PATH . '/../public/fonts/LiberationSansRegular.ttf')));
just get anything to work then add back what you need 'till you find the problem. I suspect you have a problem with one of your paths.
Start with the APPLICATION_PATH constant then change to PUBLIC_PATH if you feel it's better.

check your file permissions; I had to give group write access before the image would write.

Related

Drupal 9: add node programmatically (PHP)

Some years ago I made a Drupal 7 site. I want to remake the site with Drupal 9.
In Drupal 7 I added nodes programmatically with this PHP code:
<?php
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$data = $_GET['d'];
AddNewNode($data);
function AddNewNode($data)
{
list($installlanguage, $playerid) = explode('|', $data);
$node = new stdClass();
$node->type = 'new_install';
node_object_prepare($node);
$node->language = LANGUAGE_NONE;
$node->field_hm_new_installlanguage[$node->language][0]['value'] = $installlanguage;
$node->field_hm_new_install_playerid[$node->language][0]['value'] = $playerid;
node_save($node);
}
?>
This code isn't working with Drupal 9.
I tried to search Google for "drupal 9 add content programmatically", but I don't seem to get any useful results. Most links are about Drupal 8.
Can someone point me in the right direction?
Thank you!
You can still do this if you really want. However, there are much better ways of managing content creation now (look at the examples for "migrate" module with e.g. JSON or CSV files).
The equivalent of what you have previously would be something like this;
<?php
use Drupal\Core\Database\Database;
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
$autoloader = require_once 'autoload.php';
$request = Request::createFromGlobals();
$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$kernel->boot();
defined('DRUPAL_ROOT') or define('DRUPAL_ROOT', getcwd());
$node = \Drupal::entityTypeManager()->getStorage('node')->create([
'type' => 'article',
'title' => 'something something',
'langcode' => 'en',
'field_something' => ... // Check the structure as it differs between fields.
]);
// You don't have to do it all in one array.
$node->set('field_something_2', 'something');
$node->save();
Take a look here for more information https://drupalbook.org/drupal/9111-working-entity-fields-programmatically.
According to this blog post,
the code is simpler (compared to #Pobtastic's answer) when you use it within a Drupal PHP page:
use Drupal\node\Entity\Node;
$node = Node::create([
'type' => 'article',
'langcode' => 'en',
'title' => 'My test!',
'body' => [
'summary' => '',
'value' => '<p>The body of my node.</p>',
'format' => 'full_html',
],
]);
$node->save();
\\ Add URL alias :
\Drupal::service('path.alias_storage')->save("/node/" . $node->id(), "/my/path", "en");
Source:

Blueimp jQuery fileupload Plugin and Symfony : how to dynamically change file repository name based on an id?

I use the plugin 'blueimp jquery fileupload' to upload files in Javascript (that part I got it right) and then I have to handle the uploads on the server side using an uploadhandler affiliated to the plugin (UploadHandler.php).
Working in Symfony, I managed to create a service based on this php script and it works in my controller (the files are uploaded in the default repository, yet on my page I get the error message 'upload failed' and I don't know why but it's not a big problem I guess), but the thing is :
I would like to custom the repository path to upload the files based on the user id, and since I call the uploadhandler file as a service, I don't know how to override the options using the construct function, as I would be able to with a basic call in php.
Here's my code :
public function uploadFiles(Request $request)
{
$uploadhandler = $this->container->get('extranetcontratbundle.uploadhandler');
$response = $uploadhandler->response;
$files = $response['files'];
return new JsonResponse($files);
}
In the options of UploadHandler.php there is :
$this->options = array(
'script_url' => $this->get_full_url().'/'.$this->basename($this->get_server_var('SCRIPT_NAME')),
'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/',
'upload_url' => $this->get_full_url().'/files/',
'input_stream' => 'php://input',
'user_dirs' => false,
'mkdir_mode' => 0755,
'param_name' => 'files',
...blabla
And I would like to override the options in a similar way as I would in 'normal' php :
$tmpImagesDir = JPATH_ROOT . 'tmp' . $userId .;
$tmpUrl = 'tmp/' . $userId . '/' . '/';
$uploadOptions = array('upload_dir' => $tmpImagesDir, 'upload_url' => $tmpUrl);
$uploadHandler = new UploadHandler($uploadOptions);
But to do that I would have to write "require_once(blabla)" and I would have created the service for nothing. If I understood it right, that's not the way to do it in Symfony. Is there a way ?
Thank you for reading, please help.

drupal 6: file upload in form not working

I'm trying to have a simple form with a file upload, but it isn;t working. when I check form_state both in the validate and in the submit callbacks, the file value is missing. also check $_FILES and there's nothing.
here is the code I'm using in _form:
$form['file'] = array(
'#type' => 'file',
'#title' => 'Photo',
);
this is what i'm doing in submit:
$validators = array();
$file = file_save_upload('file', $validators, '/sites/default/files');
file_set_status($file, FILE_STATUS_PERMANENT);
krumo ($file);
You need specify $form['#attributes'] = array('enctype' => 'multipart/form-data'); apart from your other fields to make it working. See here for details.

Zend File Transfer: Problem when uploading a single image

I cannot understand how ->isuploaded() works. I am suppose to upload six images to display on my index page. Now the problem is, in my update function, if I upload only one or two image $upload->isUploaded() returns a false value, but if I decide to update all six of them it returns a true value. How do I deal with this problem? Am i missing out something here?
Here is my zend file transfer upload
$upload = new Zend_File_Transfer();
$upload->addValidator('Count', false, array('min' =>1, 'max' => 6))
->addValidator('Size', false, array('max' => '1Mb'))
->addValidator('ImageSize', false, array('minwidth' => 50,
'maxwidth' => 1000,
'minheight' => 50,
'maxheight' => 1000));
if ($upload->isUploaded()) $hasImage = true;
By default Zend guess all uploaded files are invalid even if just one of submitted form file fields was empty.
Zend docs are suggest to override this behavior by calling isValid() method before receive().
So I'm not sure if suggest best solution, but it works for me:
$upload = new Zend_File_Transfer();
$upload->setDestination( 'some your destination' );
if( $adapter->isValid( 'your form file field name' ) ){
$adapter->receive( 'your form file field name' );
}
And so on with every file field name. Wrap in foreach if needed.
Use isValid() instead.
if ($upload->isValid()) {
// success!
} else {
// failure!
}
Once you know your upload passed the validators, then start processing the images.

Uploaded docx files turning into zip

I am currently using symfony 1.4 and would like to allow users to upload Microsoft Word docx files. Using the sfWidgetFormInputFile widget and sfValidatorFile below users are able to select and successfully upload their docx files using a simple web form.
$this->widgetSchema['file_name'] = new sfWidgetFormInputFile(array('label' => 'File'));
$this->validatorSchema['file_name'] = new sfValidatorFile(array(
'required' => true,
'path' => sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR,
'mime_types' => array('application/msword',
'application/vnd.ms-word',
'application/msword',
'application/msword; charset=binary')
), array(
'invalid' => 'Invalid file.',
'required' => 'Select a file to upload.',
'mime_types' => 'The file must be a supported type.'
));
The problem is that after the file is uploaded, the extension is changed to .zip and the file contains a file tree of xml files. My understanding is that this is because Office 2007 are now using Open xml file formats. Is there any way to prevent this from happening using symfony or PHP?
The problem is Content-Sniffing. The new Office formats ARE .zip files, and if on upload, the content is sniffed, the browser will identify this as a ZIP file and set the Content-Type header as such. Similarly, on download unless your server sets the proper Content-Type HTTP response header, the browser will assume that this is a ZIP file.
Symfony 1.3+ has an option mime_type_guessers for sfValidatorFile which allows you to define your own mime type guesser PHP callable or use a build in guesser. Calling any of the 3 built-in mime type guessers finds the correct file type for docx and keeps the the docx file extension.
Here is the updated code using guessFromFileinfo:
$this->validatorSchema['file_name'] = new sfValidatorFile(array(
'required' => true,
'path' => sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR,
'mime_type_guessers' => array('guessFromFileinfo'),
'mime_types' => array('application/msword',
'application/vnd.ms-word',
'application/msword',
'application/msword; charset=binary')
), array(
'invalid' => 'Invalid file.',
'required' => 'Select a file to upload.',
'mime_types' => 'The file must be a supported type.'
));
It seems to be a bug in Symfony's file type detection. A workaround is described.
The suggested use of mime_type_guessers uses a non-existing function.
If you want to use the sfValidatorFile method, you should write array(array('sfValidatorFile', 'guessFromFileinfo')).
The suggested solution uses no mime-type detection at all and results in problems with the classic excel format on my system.
I fixed the problem by extending the sfValidatorFile class and changing the getMimeType method.
Create a new msValidatorFile.class.php file in your lib folder :
<?php
class msValidatorFile extends sfValidatorFile
{
protected function getMimeType($file, $fallback)
{
$arrayZips = array( "application/zip",
"application/x-zip",
"application/x-zip-compressed");
$officeTypes = array(
"application/vnd.ms-word.document.macroEnabled.12",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"application/vnd.ms-powerpoint.template.macroEnabled.12",
"application/vnd.openxmlformats-officedocument.presentationml.template",
"application/vnd.ms-powerpoint.addin.macroEnabled.12",
"application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
"application/vnd.ms-powerpoint.presentation.macroEnabled.12",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/vnd.ms-excel.addin.macroEnabled.12",
"application/vnd.ms-excel.sheet.binary.macroEnabled.12",
"application/vnd.ms-excel.sheet.macroEnabled.12",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-excel.template.macroEnabled.12",
"application/vnd.openxmlformats-officedocument.spreadsheetml.template");
foreach ($this->getOption('mime_type_guessers') as $method)
{
$type = call_user_func($method, $file);
if (null !== $type && $type !== false)
{
if (in_array($type, $arrayZips) && in_array($fallback, $officeTypes))
{
return $fallback;
}
return strtolower($type);
}
}
return strtolower($fallback);
}
}
Use this new validator in your form code :
$this->validatorSchema['file'] =
new msValidatorFile(array('required' => false,
'path' => sfConfig::get('sf_upload_dir')
));

Categories