WordPress – Sorin Coza http://localhost/sorincoza.com/blog-wp Just another web blog. Tue, 30 Aug 2016 10:46:43 +0000 en-US hourly 1 https://wordpress.org/?v=4.4.4 PayPal setup with WooCommerce http://localhost/sorincoza.com/blog-wp/paypal-setup-with-woocommerce/ Tue, 30 Aug 2016 10:40:30 +0000 http://localhost/sorincoza.com/blog-wp/?p=100 I find PayPal to be very difficult to use in general. Even for everyday stuff. But this is especially true when you’re a developer and need to test things. Their developer website is sooo confusing…

So recently I needed to setup PayPal with WooCommerce on WordPress, and it was a nightmare, which is why I need to document the process here for you (the reader) and me (the frustrated developer).

First, let’s set up a sandbox account for testing.

Go to developer.paypal.com and create a test account. You’ll probably need to login with your “real” PayPal account the first time, but then you’ll only need to use the sandbox account and password (this is yet another confusing thing).

Then, let’s change the settings

Then you’ll need to set up some options for payments. You’ll never find the page that WooCommerce is reffering to, because PayPal is very confusing, so here is the direct link for both when you will set this up live and when in sandbox mode:

]]>
Improve Big Query Performance in WP http://localhost/sorincoza.com/blog-wp/improve-big-query-performance-in-wp/ Sat, 13 Feb 2016 09:53:09 +0000 http://localhost/sorincoza.com/blog-wp/?p=83 I was working on a site that had some custom posts and a lot of terms associated with that custom post type. After a while, we noticed that the search function is getting slower and slower, as the custom posts piled up. Sometimes, the time if took for the search to complete was more than a minute. Other times, it just gave back an error. So I knew I had do do something about this.

The thing is, when you have custom post types in WordPress, you’ll probably need at some point to make a custom query to the database. This can be quite easily done using the built-in class WP_Query, which can do just about anything you can think of. The problems start to appear when you have a relatively large database, and you do a big query on it.

What happens is that WP_Query returns an object that contains all the information about all the custom posts that you are querying. And trust me, every post contains a lot of information. So where is all this data stored after the query? In the RAM of course!

Our search function was doing just this: using WP_Query to get all the posts at once, then looping through them. When I did some tests to find out the memory usage of every search operation, I discovered that it uses quite a lot of RAM, and the amount increases with the search complexity and the number of results. The usage was often exceeding the allocated amount of 128 MB of memory per request.

The solution was to add an argument that limits the amount of data that is being stored in our query object, named fields.

// setup our args:
$args = array(
    'fields' => 'ids',
    // ... [other arguments that you need]
);

// get the query object that contains ids of posts:
$query = new WP_Query( $args );

// get only ids from object to loop them:
$ids = $query->posts;

// slightly rewrite the loop:
foreach( $ids as $id ){
    $post = get_post( $id );
    // ... [now do the other stuff with the $post]
}

The result

The result was amazing: memory usage improved 7 times, and execution time was 3 times faster for the usual searches, on average. The search function never crashed again, even though the posts kept multiplying, and continue to do so up until this day. And everyone lived happily ever after. The end.

]]>
How to add custom shortcodes in CF7 http://localhost/sorincoza.com/blog-wp/how-to-add-custom-shortcodes-in-cf7/ Wed, 16 Dec 2015 17:59:22 +0000 http://sorincoza.com/blog/?p=57 Sometimes, the types of fields that are available by default in Contact Form 7 are just not enough. And sometimes, you want to just be able to use a shortcode when you define the form . For such situation, we can use the wpcf7_add_shortcode() function, combined with the wpcf7_init hook.

Documentation

The wpcf7_add_shortcode() function takes 3 arguments:

  • $shortcode, which is our shortcode name, exactly as in WordPress;
  • $callback, which is a function that will be called when the shortcode is encountered, exactly as in WordPress;
  • $has_name_part, which is boolean and false by default, but if it is set to true, then the shortcode can be used with a name, for example: '[my_shortcode field-name]', just how you would use a usual CF7 field: '[text* your-name]'

Find all details on the Contact Form 7 site’s documentation page: Adding a custom form-tag.

Example

add_action( 'wpcf7_init', 'create_my_custom_cf7_shortcodes' );

function create_my_custom_cf7_shortcodes(){
    wpcf7_add_shortcode( 'lots_of_checkboxes', 'render_checkboxes' );
}

function render_checkboxes(){
    // Construct checkboxes HTML here...
    return $html;
}

Now we can use this when we are defining the form fields: [lots_of_checkboxes], which will output whatever the render_checkboxes() function decides.

]]>
Useful hooks in CF7 http://localhost/sorincoza.com/blog-wp/useful-hooks-in-cf7/ Wed, 16 Dec 2015 17:25:27 +0000 http://sorincoza.com/blog/?p=50 Contact form 7 has a few hooks that you can use to customize your forms. Here is a list of those hooks that I think are the most helpful.

wpcf7_init

This is great if you want to add custom shortcodes to be handled by Contact Form 7. The shortcodes can be used in your Dashboard when you define the form fields. More details here: How to add custom shortcodes in CF7.

wpcf7_before_send_mail

This is fired just before the mail is sent. By this time, all validations have passed.

wpcf7_mail_sent

This is fired after the mail was sent. By this time, the $_POST is empty. Check this post for details on how to manipulate posted data in this hook: How to correctly get posted data in CF7.

wpcf7_validate_{$field_type}

This is a filter that helps us to validate fields using our own custom rules. Read this post for more information on how to do that: How to validate a field in CF7.

]]>
How to correctly get posted data in CF7 http://localhost/sorincoza.com/blog-wp/how-to-correctly-get-posted-data-in-cf7/ Wed, 16 Dec 2015 17:08:44 +0000 http://sorincoza.com/blog/?p=46 In Contact Form 7, if you hook into wpcf7_mail_sent, then  the $_POST variable is empty, so you cannot use it to do stuff with it. You are too late. However, there is a way to get around this: you have to use Contact Form 7 built-in functions to get the posted data.

$submission = WPCF7_Submission::get_instance();
if ( $submission ) {
    $form_data = $submission->get_posted_data();

    // now $form_data contains the form values,
    // so you can do, for example $form_data['email'], instead of $_POST['email']

}else{
    // we got nothing; something went wrong
}

That’s it.

]]>
How to validate a field in CF7 http://localhost/sorincoza.com/blog-wp/how-to-validate-a-field-in-cf7/ Wed, 16 Dec 2015 16:46:56 +0000 http://sorincoza.com/blog/?p=36 What we need:

  • a filter 'wpcf7_validate_{$field_type}', which will filter the fields by type;
  • a function, which takes 2 arguments from Contact Form 7:
    • $result, which can be validated or invalidated before it is returned;
    • $tag, which helps us to identify the field by its name.

The {$field_type} is the exact field type that you have defined in your form, for example: text, text*, textarea, textarea*, email, etc.... The asterisk is used to indicate a required field, and yes, it has to be specified in the hook ( text is different from text* ).

Example

// hook our function:
add_filter( 'wpcf7_validate_text*', 'validate_phone', 20, 2 );

// define the function:
function validate_phone( $result, $tag ){

    // check if this is our phone field, and return the $result unchanged if it isn't:
    $tag = new WPCF7_Shortcode( $tag );
    if ( $tag->name !== 'phone' ){ return $result; }

    // if we got this far, then this is our phone input - we check to see if it is valid
    // assuming we have a function somewhere named "is_valid_phone"
    if( ! is_valid_phone('phone') ){
        $result->invalidate( $tag, 'This phone number is not valid! Please try again.' );
    }

    // finally, return the result:
    return $result;
}
]]>