I’d like to update what users insert into 3 specific xprofile fields and store it to the database using sanitize_key (force letters lowercase, remove special characters besides "-" and "_"). The values change the way I want to temporarily when I echo them out, but don't store in the database.
Would really appreciate your help! Here's what I have so far
In my functions.php:
function expertise_tag_functions_before_save() {
global $bp;
foreach ($_REQUEST as $field => $value) {
if ($field == ‘field_24’ || $field == ‘field_26’ || $field == ‘field_27’) {
$value = sanitize_key( $value );
$field_label = str_replace(‘field_’, ”, $field);
xprofile_set_field_data($field_label, $user_id, $value);
}
}
};
add_action( ‘xprofile_data_before_save’, ‘expertise_tag_functions_before_save’, 10);
I've tried switching out ‘xprofile_data_before_save for ‘xprofile_data_after_save’ but it still doesn't work.
Your changes are probably being overwritten after the filter hook runs.
You are directly updating the field. You should be changing the submitted profile data.
This is the filter hook which includes access to that data:
do_action_ref_array( 'xprofile_data_before_save', array( $this ) );
So try:
function expertise_tag_functions_before_save( $data ) {
// make your changes to field values in $data
}
Related
I am using the following code to validate integer input fields in my form:
if (isset($_POST['MaxiVegXP']) && ctype_digit($_POST['MaxiVegXP']))
{
$MaxiVegXP = $_POST['MaxiVegXP'];
} else {
$MaxiVegXP = FALSE;
}
I have another 20 or so similar form input fields. Is there a quicker way of doing this with a PHP loop? I'd rather not do the above for another 20 input fields :-)
I would do something like #Simply Dread, but with a slight improvement, so I could explicitly indicate which fields needed to be fixed:
$validFields = array('field1' => true, 'field2' => true, 'field3' => true, ..., 'fieldN' => true);
foreach ($validFields as $field => $valid) {
if (!isset($_POST[$field]) && !ctype_digit($_POST[$field])) {
$validFields[$field] = false;
}
}
With this information, I can now show errors on the appropriate fields instead of only saying that there is a problem.
You could iterate over all fields for example:
foreach ($_POST as $key=>$value){
if (isset($_POST[$key]) && ctype_digit($_POST[$key])) {
$$key = $value;
} else {
$$key = FALSE;
}
}
But I would instead put the code in a function and call the fuction excplicitly for every post variable:
function isDigit($value) {
if (isset($value) && ctype_digit($value)) {
return true;
}
return false;
}
$MaxiVegXP = isDigit($_POST["MaxiVegXP"]) ? $_POST["MaxiVegXP"] : false;
An option would be to create an array of the field names and loop over it. Doing it this way will ensure all fields have to be set and are digits. Check the validate variable afterwards and you'll know if it was successful. :-)
$fieldArray = array('fieldOne', 'fieldTwo', 'fieldThree');
$validate = true;
foreach ($fieldArray as $field) {
if (!isset($_POST[$field]) && !ctype_digit($_POST[$field])) {
$validate = false;
}
}
Is there a quicker way of doing this with a PHP loop?
there's a quicker to do this without a PHP loop:
I would use filter_input_array. This code will assign null to the value if it does not pass the filter. It's quite practical, you just have to add the name of the variable and it's desired filter in the array.
$vars = filter_input_array(INPUT_POST,array (
'MaxiVegXP'=>FILTER_VALIDATE_INT,
'myVar'=>FILTER_DEFAULT,
// or FILTER_VALIDATE_INT. you can also define validator callbacks if need be
));
here you define the keys you wish to get from the input ($_POST in this example, but you can use INPUT_GET to get variables from the $_GET superglobal). You can also define more advanced options in the array to define a min or max range for your inputs, for instance
$vars = filter_input_array(INPUT_POST,array (
'MaxiVegXP'=>array(
'filter'=>FILTER_VALIDATE_INT,
'options'=>array('min_range'=>1, 'max_range'=>10),
),
));
the usefulness is that you don't have to verify manually for each key if they exist and what type they're of, filter_input_array takes care of that once you've defined your array of accepted value
I need to validate just one field (called 'Instance') to accept lowercase ASCII letters and numbers only, the first character also has to be a letter not a number. It will accept uppercase characters but we will need it to lowercase them on input. So if someone uses the instance name McDonalds it will be lowercased to mcdonalds (not just with CSS). Spaces are not allowed either.
Is this possible with CF7? If so please explain how.
I've already tried this custom validation method but even with the preset custom validation in the file it was just displaying the field shortcode rather than the field itself.
Thanks
From contactform7.com on Custom Validation → Validation as a Filter:
In Contact Form 7, a user-input validation is implemented as a filter
function. The filter hook used for the validation varies depending on
the type of form-tag and is determined as: wpcf7_validate_ + {type of
the form-tag}. So, for text form-tags, the filter hook
wpcf7_validate_text is used. Likewise, wpcf7_validate_email* is used
for email* form-tags.
Let’s say you have the following email fields in a form:
Email: [email* your-email]
Confirm email: [email* your-email-confirm]
The following listing shows code that verifies whether the two fields
have identical values.
add_filter('wpcf7_validate_email*', 'custom_email_confirmation_validation_filter', 20, 2);
function custom_email_confirmation_validation_filter($result, $tag) {
$tag = new WPCF7_FormTag($tag);
if ('your-email-confirm' == $tag->name) {
$your_email = isset($_POST['your-email']) ? trim($_POST['your-email']) : '';
$your_email_confirm = isset($_POST['your-email-confirm']) ? trim($_POST['your-email-confirm']) : '';
if ($your_email != $your_email_confirm) {
$result->invalidate($tag, "Are you sure this is the correct address?");
}
}
return $result;
}
Two parameters will be passed to the filter function: $result and
$tag. $result is an instance of WPCF7_Validation class that manages a
sequence of validation processes. $tag is an associative array
composed of given form-tag components; as you saw in the previous
recipe, you can use WPCF7_FormTag class to handle this type of data.
Look through the inside of the filter function. First, check the name
of the form-tag to ensure the validation is applied only to the
specific field (your-email-confirm).
The two email field values are then compared, and if they don’t match,
$result->invalidate() will be called. You need to pass two parameters
to the invalidate() method: the first parameter should be the $tag
variable, and the second parameter is the validation error message
that you want the field to display.
Lastly, don’t forget to return the $result.
// Add custom validation for CF7 form fields
function is_company_email($email){ // Check against list of common public email providers & return true if the email provided *doesn't* match one of them
if(
preg_match('/#gmail.com/i', $email) ||
preg_match('/#hotmail.com/i', $email) ||
preg_match('/#live.com/i', $email) ||
preg_match('/#msn.com/i', $email) ||
preg_match('/#aol.com/i', $email) ||
preg_match('/#yahoo.com/i', $email) ||
preg_match('/#inbox.com/i', $email) ||
preg_match('/#gmx.com/i', $email) ||
preg_match('/#me.com/i', $email)
){
return false; // It's a publicly available email address
}else{
return true; // It's probably a company email address
}
}
function your_validation_filter_func($result,$tag){
$type = $tag['type'];
$name = $tag['name'];
if('yourid' == $value){ // Only apply to fields with the form field name of "company-email"
$the_value = $_POST[$name];
if(!is_company_email($the_value)){ // Isn't a company email address (it matched the list of free email providers)
$result['valid'] = false;
$result->invalidate( $tag, wpcf7_get_message( 'invalid_email' ));
}
}
return $result;
}
add_filter( 'wpcf7_validate_email', 'your_validation_filter_func', 10, 2 );
// Email field or contact number field
add_filter( 'wpcf7_validate_email*', 'your_validation_filter_func', 10, 2 ); // Req. Email field or contact number
I had a similar issue for validating name fields, I added the following code in my functions.php, you could customize it by changing the regex
function my_wpcf7_validate_text( $result, $tag ) {
$type = $tag['type'];
$name = $tag['name'];
$value = $_POST[$name] ;
if ( strpos( $name , 'name' ) !== false ){
$regex = '/^[a-zA-Z]+$/';
$Valid = preg_match($regex, $value, $matches );
if ( $Valid > 0 ) {
} else {
$result->invalidate( $tag, wpcf7_get_message( 'invalid_name' ) );
}
}
return $result;
}
add_filter( 'wpcf7_validate_text*', 'my_wpcf7_validate_text' , 10, 2 );
add_filter( 'wpcf7_messages', 'mywpcf7_text_messages' );
function mywpcf7_text_messages( $messages ) {
return array_merge( $messages, array(
'invalid_name' => array(
'description' => __( "Name is invalid", 'contact-form-7' ),
'default' => __( 'Name seems invalid.', 'contact-form-7' )
)
));
}
Please use this wordpress plugin
Jquery Validation For Contact Form 7
https://wordpress.org/plugins/jquery-validation-for-contact-form-7/
You can add your own custom validation for a form field input by using the add_filter function.
For adding a custom validation for a textarea field you can add the following inside functions.php file in the root directory of your theme.
add_filter( 'wpcf7_validate_textarea*', 'custom_textarea_validation_filter', 1, 2 );
function custom_textarea_validation_filter( $result, $tag ) {
$tag = new WPCF7_Shortcode($tag);
$result = (object)$result;
$name = 'project-synopsis';
if ( $name == $tag->name ) {
$project_synopsis = isset( $_POST[$name] ) ? trim( wp_unslash( (string) $_POST[$name] ) ) : '';
if ( empty( $project_synopsis ) ) {
$result->invalidate( $tag, "Please write a quick project synopsis." );
}
}
return $result;
}
For me the trick was to cast the $result parameter to an object, because the invalidate method that is used to add the error message didn't work before casting.
Try this plugin. It's allow to set custom validation message for each field in free version.
URL : https://wordpress.org/plugins/cf7-custom-validation-message/
I want to apply addslashes() to all the post elements got through
$this->input->post('my_var');
How can I do that ? Is there any feature like filters under wordpress for this ?
I think you want something global. My idea is to edit the global post function in the codeigniter to use addslashes on everything. You can find that function in:
/yourfolder/system/core/Input.php
You can escape it by setting it global.
function post($index = NULL, $xss_clean = FALSE)
{
// Check if a field has been provided
if ($index === NULL AND ! empty($_POST))
{
$post = array();
// Loop through the full _POST array and return it
foreach (array_keys($_POST) as $key)
{
$post[$key] = addslashes($this->_fetch_from_array($_POST, $key, $xss_clean));
}
return $post;
}
return addslashes($this->_fetch_from_array($_POST, $index, $xss_clean));
}
Although I don't really find it as good solution to modify the global functions this should do the trick in your case.
Edit: I see that input->post already does that and you would not need to add that function additionally.
I'm pretty new to Silex and Symfony and I'm trying to create a form with the symfony Form component. That's working fine, but whet it comes to validation/sanitization I'm not sure how to do it.
Of course I know the $app->escape($data) method, but it doesn't seem to fit my needs.
I'd like to escape html tags from the submitted data before I call the $form->isValid() method. I don't want to invalidate texts with html tags, only escape/remove them from the text then validate the gained values.
So basically I want to give the escaped values to the form instead of the originals or use.
My problem is that I'd like to show the error messages only if the submitted text is empty after removing the html tags.
I thought about to write a custom constraint - as I didn't find anything about html validation in the package - but in that case I had to filter/escape two times, first in the validation then before saving the data.
I'd like to achieve something like this:
if ($request->getMethod() == 'POST') {
$comment = $request->get('comment');
if($comment) {
foreach($comment as &$value) {
$value = $app->escape($value);
}
$cleared = new Request(array(), array('comment' => $comment));
$form->bindRequest($cleared);
if ($form->isValid()) {
var_dump($form->getData());
}
}
}
Thanks.
$app->escape() is just a shortcut for htmlspecialchars(), you have to use strip_tags() function to remove html tags.
My problem is that I'd like to show the error messages only if the
submitted text is empty after removing the html tags.
$form->get('FILED_NAME')->addError(new Form\FormError('ERROR'));
for example :
if ($request->getMethod() == 'POST') {
$comment = $request->get('comment');
if($comment) {
$emptyCM = false;
foreach($comment as &$value) {
$value = strip_tags($value);
if (empty($value)) $emptyCM = true;
}
if ($emptyCM)
$form->get('comment')->addError(new Form\FormError('my custom error message'));
$cleared = new Request(array(), array('comment' => $comment));
$form->bindRequest($cleared);
if ($form->isValid()) {
var_dump($form->getData());
}
}
}
If you want to pre-sanitize your all your data before it goes into the form, you can use a before filter, either for all routes or for specific routes.
The following example strips all tags from string parameters from GET and POST. If your parameters are arrays (like in your initial example), you'd need to add another if branch. If your parameters are deeply nested, you need a recursive function for filtering.
$app->before( function( Request $request ) {
foreach ( [ $request->request, $request->query ] as $parameterBag ) {
foreach ( $parameterBag->keys() as $key ) {
if ( is_string( $parameterBag->get( $key ) ) ) {
$parameterBag->set( $key, strip_tags( $parameterBag->get( $key ) ) );
}
}
}
}, Application::EARLY_EVENT );
I'm trying to save a long form in Codeigniter's Datamapper. I'm able to save the form if I pass the value like this
$t->brandName = $this->input->post('brandName');
$t->specialNotes = $this->input->post('specialNotes');
$t->name = $this->input->post('name');
Now if I call save method it works
$t->save();
Since the form is big I tried to add object values in foreach
$a = get_object_vars($t);
foreach ($a['stored'] as $k => $val){
$t->$k = $this->input->post("$k");
}
however if I call the $t->save() it doesn't work.
I'm not sure what $a['stored'] represents, but it's nothing that's default in Datamapper.
Why don't you do it the opposite way, looping through the post keys?
foreach ($_POST as $key => $val)
{
$t->$key = $this->input->post($key);
}
$t->save();
Note: Any columns that don't exist will just be ignored by Datamapper.
I actually wrote a Datamapper extension for this:
class DM_Data {
function assign_postdata($object, $fields = NULL)
{
// You can pass a different field array if you want
if ( ! $fields)
{
$fields = $object->validation;
}
foreach ($fields as $k => $data)
{
$rules = isset($data['rules']) ? $data['rules'] : array();
if ( ! isset($_POST[$k])) continue;
// Cast value to INT, usually for an empty string.
if (in_array('integer', $rules))
{
$object->$k = (integer) $_POST[$k];
}
// Do other manipulation here if desired
else
{
$object->$k = $_POST[$k];
}
}
return $object;
}
}
You can use $t->assign_postdata()->save(), and optionally pass an array of fields to update to the function (in the datamapper validation format). However, I forget why I use that... but I removed some of the custom stuff. This should be useful for you if you are doing this a lot. It definitely saves me time.