Contact Form 7 attaching a file based on a form field - file is empty - contact-form-7

I have a form field;
[hidden path default:shortcode_attr] which is successfully populated in the form to produce <input type="hidden" name="path" value="uploads/my-file.pdf" class="wpcf7-form-control wpcf7-hidden">
Then it's added to the mail by;
add_filter('wpcf7_mail_components', 'attach_files_based_on_field',10,3);
function attach_files_based_on_field($components, $form, $mail){
//get the form submited data
$submission = WPCF7_Submission::get_instance();
$data = $submission->get_posted_data('path');
$components['attachments'][] = $data;
return $components;
}
(thanks to #Aurovrata in this answer)
The issue is that although it appears the file is attached, it is empty (zero bytes).
It is also empty if the $data is replaced by the literal "uploads/my-file.pdf"
Needles to say this file is not empty. if it's entered in the Mail > Attachments field in CF7 as "uploads/my-file.pdf" it works (alongside the empty file)

Related

Modifying individual field form inputs (CSS, Placeholder, etc) Drupal 7 registration form preprocess

I'm attempting to preprocess CSS and placeholder etc to the form inputs for the Registration Form. I'm manually rendering each field input on the registration form.
The following code works fine for email or password, but not 'custom fields'.
$form['account']['mail']['#attributes']['placeholder'] = t('Email address');
$form['account']['mail']['#attributes']['class'][] = 'email-input';
$form['account']['mail']['#title_display'] = "invisible";
$form['account']['mail']['#description'] = t('');
When I apply the same to the custom fields, it won't apply.
I have looked through the user module and printed avialable varibles
$form['field_first_name']['#attributes']['placeholder'] = t('First Name');
$form['field_first_name']['#attributes']['class'][] = 'first-name-input';
$form['field_first_name']['#title_display'] = "invisible";
$form['field_first_name']['#description'] = t('');
I found multiple mentions of field_first_name in the variable print out, but I'm unable to modify the text inputs directly.

form validation with preg_match

I have created a form which gets user data about the city he leaves. The form stores data in a table called profile. I am using a function which inserts data into profile table. If there are already data, the function just updates the table. If the user does not insert data into city field and press submit, the table continues to keep the previous data, because nothing submitted.
In the form I would like to make a validation so that the user will inserts only a-z or space characters.
I have used the following code for validation:
if( empty($_POST) === false ){
if( empty($errors) === true ){
if( preg_match('/^[a-zA-Z ]+$/', $_POST['city']) ===0 ){
$errors[]='<font color="#963">City must only contains a-z and spaces</font>';
}
}
}
It works! But the problem now is that if the user leave the form empty and press submit the above code enforces him to place data( says: City must only contains a-z and spaces). How can I use the above code to validate the form only if the user enters data. And if not then to continue without any problem.
You can do this without even generating an error. Replace
if( preg_match('/^[a-zA-Z ]+$/', $_POST['city']) ===0 ){
With
$_POST['city'] = preg_replace("&[^a-zA-Z ]&","",$_POST['city']);
This will replace all non-lowercase letters and non-spaces with nothing before it's inserted into the database.
EDIT:
If you'd still like to generate an error, use
if( preg_match("&[^a-zA-Z ]&",$_POST['city']) ){
$errors[]='<font color="#963">City must only contains a-z and spaces</font>';
}
before the preg_replace.

Contactform 7 Placeholder Validation

I'm using Contactform 7 for Wordpress. I've edited the text.php and textarea.php to enable the use of placeholders. That works fine.
But, the validation isn't working for some input fields, 'cause the validation thinks the placeholder is the actual text being validated. And yes, ofcourse that validates true 'cause it's not empty.
My input fields with placeholders are as follows:
Your name
Your e-mailadress
Your telephone number
and so on.
In contactform 7's scripts.js I want the validation to check if the input isn't the same as the placeholder. So if the input value is the same as the placeholder value, do the CF7's error validation.
Any idea?
In scripts.js of the contactform 7 plugin folder
Change this:
var submit = form.find('input:submit');
if (! submit.length) return;
with this:
var submit = form.find('input:submit');
if (! submit.length || submit == this.find('[placeholder]').wpcf7Placeholder()) return;

In Yii, how best to POST both search results selection & previously entered form model back to form controller?

To complete a Yii form field, users often need to search for a referenced model record (like searching for a friend's profile in a social app). I'm sure other Yii apps are doing this elegantly. But in my dirty approach, in the search results page, I use a CHtml::submitButton to POST two models back to the form containing:
the "found" record (a user id associated with one of the profiles from the search results)
the previously entered form field contents (relationship characterization fields)
Alternatively, the autocomplete widget works well, but doesn't do the detailed search that I need (e.g. search based on a partial name and city or state or other user profile content).
Alternatively, you'd think that within the search results view I might be able to modify the form member to contain the found record (new friend's user id) and just POST/submit the modified model from the search results page . But for that to work each of the search results in the list needs a unique user id populated in that form field, and I can't figure out how to duplicate the form model before modifying that one member server-side for each of the search results' "submit" or "select" buttons, and it just doesn't seem right to create all those form models.
So what seems to work is to submit two separate models using subforms (within the search results view) , with the submitButton POSTing a model and the extra parameter (user id) separately.
Is there a better way? ...to link to and from a search results page and a form field, retaining already-entered data and populating the searched for field with a selected record from the search results.
Here's controllers/SiteController:
public function actionBefriend() {
$model=new BefriendForm;
if(isset($_POST['BefriendForm'])) {
$model->attributes=$_POST['BefriendForm'];
if ($model->validate()) {
$model->createFriendship();
$this->redirect('Index'); }
else
$er=$model->getErrors(); }
if(isset($_POST['idfriend'])) {
$model->idfriend=$_POST['idfriend']; }
if(isset($model->idfriend)) {
$model->friend_name=Bio::model()->findByPk($model->idfriend)->name; }
$this->render('newFrienship', array('model' =>$model)); // newFriendship is the form view }
Here's controllers/Bio.php (Profile)
public function actionIndex() {
$criteria = new CDbCriteria();
$model=new BefriendForm;
if(isset($_GET['q']))
$q = $_GET['q'];
elseif (isset($_POST['BefriendForm'])) {
$model->attributes=$_POST['BefriendForm'];
$q = $model['friend_name']; }
if(isset($q)) {
$criteria->compare('name', $q, true, 'OR');
$criteria->compare('city', $q, true, 'OR');
$criteria->compare('state', $q, true, 'OR');
$criteria->compare('bio_text', $q, true, 'OR'); }
else
$q = '';
$dataProvider=new CActiveDataProvider('Bio', array('criteria'=>$criteria));
$this->render('index',array('dataProvider'=>$dataProvider, 'q'=>$q, 'model'=>$model )); }
Here's the start of views/site/newFriendship (form view)
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'newFriendship-BefriendForm',
'enableAjaxValidation'=>true,)); ?>
Here's the core of views/bio/index.php (search results index page):
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'viewData'=>array('model'=>$model) )); ?>
Here's the search result row in views/bio/_view.php that links back to BefriendForm (SiteController) that sends the id of the user to populate the friend field in the form (which gets a name from the id):
<form method="POST">
<input type="hidden" name="idfriend" value="<?php echo $data->idfriend ?>" />
// Here's that submit button that I can't get to send both the model
//and the idfriend back to the form to repopulate it
// without manually writing HTML to submit all the fields individually
// or creating 2 subforms to submit together with a signle submitButton.
<?php echo CHtml::submitButton('Befriend', array('submit' => array('site/Befriend'),'model'=$model);
</form>
The best alternative I can see is to imbibe the searcher widget within the form.
Turns out you can just replace the form field containing the primary key with the appropriate value before POSTing back to the NewFriendship form when the user clicks the "Select" or "Befriend" button. So only one model is posted back to the original form from the search results page.
Replace the section from views/bio/_view.php in the question with...
<?php
foreach($model->attributeNames() as $name)
if($name != 'friend_id')
echo CHtml::activeHiddenField($model,$name);
else
echo CHtml::activeHiddenField($model,$name,array('value'=>$data->getPrimaryKey()));
echo CHtml::submitButton('Befriend', array('submit' => array('site/Befriend')));
?>

Zend Framework export Doctrine query results to XML file

I have a need to export certain queries to xml files. I have this working in that the file is created and the data are exported, however I'm receiving the following error on screen as the file is being exported and not displayed.
This page contains the following errors:
error on line 3 at column 1: Extra content at the end of the document
I'll admit that I'm new to this as most of you are aware but is there a way I can export and just display a confirmation message to the user that the report has been saved, or am I going about this the wrong way completely?
My code is below
My controller
public function init()
{
// allow certain reports to be exported to xml
// initialize context switch helper
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('newsletterexport', 'xml')
->initContext();
}
public function newsletterexportAction()
{
$q = Doctrine_Query::create()
->select('c.firstname,c.lastname,c.address1,c.address2,c.address3,t.county')
->from('PetManager_Model_Clients c')
->leftJoin('c.PetManager_Model_Counties t')
->where('c.consentToNews=1');
$result = $q->fetchArray();
if (count($result) >= 1) {
$this -> view -> records = $result;
}
}
EDIT
Ok I tried moving the code from the xml.phtml into my controller as suggested and tried to save the document with save, but now I get the start of the xml document as shown below but no records are saved to the document.
<?xml version="1.0" encoding="utf-8"?>
<petmanager:document xmlns:petmanager="http://petmanager"><petmanager:records/></petmanager:document>
My controller code as of this edit
public function newsletterexportAction()
{
$q = Doctrine_Query::create()
->select('c.firstname,c.lastname,c.address1,c.address2,c.address3,t.county')
->from('PetManager_Model_Clients c')
->leftJoin('c.PetManager_Model_Counties t')
->where('c.consentToNews=1');
$result = $q->fetchArray();
if (count($result) >= 1) {
//$this -> view -> records = $result;
$docpref="newsletterexport";
$docDate=date('y-m-d');
$ext=".xml";
$docname=$docpref.$docDate.$ext;
// create XML document
$dom = new DOMDocument('1.0', 'utf-8');
// create root element
$root = $dom->createElementNS('http://petmanager','petmanager:document');
$dom->appendChild($root);
// convert to SimpleXML
$xml = simplexml_import_dom($dom);
// add resultset elements
$records = $xml->addChild('records');
foreach($this->$result as $r){
$record = $records->addChild('record');
$record->addChild('firstName',$this->escape($r['firstName']));
$record->addChild('lastName',$this->escape($r['lastName']));
$record->addChild('address1',$this->escape($r['address1']));
$record->addChild('address2',$this->escape($r['address2']));
$record->addChild('address3',$this->escape($r['address3']));
$record->addChild('county',$this->escape($r['PetManager_Model_Counties']['county']));
}//end of foreach
// saave document
$xml->saveXML();
$dom->save('D:/reports/exports/'.$docname.'');
}
DomDocument::saveXML() doesnt take a file path - it returns the XML document as text. If you want to save it directly as a file like youre doing you use DomDocument::save().
All that logic in your phtml should be in your controller. You have also set the context to xml, so the view is going to output XML to the browser, not HTML... so id doesnt make sense to display a confirmation message unless its encoded in XML, otherwise you need to use the default context (HTML). So if you want to save the file to the webserver and display a confirmation you would do:
public function exportXmlAction(){
// remove the context switch from init
// do your doctrine stuff
// build the xml DOM as $xml
$xml->save('path/to/file');
$this->message = 'File was exported successfully!';
}
// in your phtml
<?php echo $this->message; ?>
If you want to display the xml on screen:
public function exportXmlAction(){
// do your doctrine stuff
// build the xml DOM as $xml
$this->xmlDom = $xml;
}
// in your phtml
<?php echo $this->xmlDom->saveXml(); ?>
The question i have though is whay would a user want ot export xml to the server. When you call DomDocument::save() youre saving that file to a path on the server, not the user's machine so what would be the point of exporting the xml to the server where the user has no access to it?