How to use pluggables functions on plugins - wordpress

I need to use functions such as wp_insert_user and wp_update_user in a plugin, but theses functions call others functions who are not yet loaded (such as get_user_by or get_userdata).
If I require the pluggable.php file where I use theses functions it works, but messing with WordPress load orders seems a pretty bad idea to me.
How would you use theses functions in a plugin ?

After looking at how ACF plugin do it, I've found a solution, instead of calling the function at the plugin load, I just add it to the action init.
require 'myClass.php';
$myClass = new myClass();
add_action('init', [$myClass, 'myFunction']);
I would even suggest to use a main class for your plugins and in the __construct hook your logic to init and/or plugins_loaded.
class MyPlugin {
public function __construct() {
add_action( 'plugins_loaded', [$this, 'plugins_loaded'] );
add_action( 'init', [$this, 'init'] );
}
public function plugins_loaded() {
// pluggables functions are available here
}
public function init() {
// pluggables functions are available here
}
}
new MyPlugin();

Related

Using Woocommerce Hooks in a Wordpress Plugin

I created a sample plugin for using woocommerce hooks. Basically my requirement was to add some javascript to the footer of the wordpress page based on some woocommerce hooks. However, those hooks don't seem to get fired at all. I have woocommerce installed. If I put the same code in theme's function file, the javsacript gets added, but not from the plugin.
In the plugin, there are three actions. The first action is a plain wp_footer action which works and js is added. the remaining two are woocommerce actions and are not getting fired. Can anyone please help? I am sure I am calling the hooks the wrong way but I can't figure out.
<?php
/*
* Plugin Name: Demo Woo Plugin
* Plugin URI:
* Description:
* Version: 1.0
* Author:
* Author URI:
* License: GPLv2
*/
/*
*/
if(!class_exists('Demowoo')) {
class Demowoo {
var $plugin_url;
var $plugin_dir;
public function __construct() {
global $woocommerce;
$this->plugin_url = trailingslashit( WP_PLUGIN_URL . '/' . dirname(plugin_basename(__FILE__)) );
$this->plugin_dir = trailingslashit( plugin_dir_path(__FILE__) );
add_action( 'wp_footer', array($this, 'demowoo_content') );
// initiate woocommerce hooks and activities
add_action('woocommerce_init', array($this, 'on_woocommerce_init'));
add_action('woocommerce_after_cart_contents', 'cart_page_visited');
}
public function install() {
}
public function deactivate() {
}
/**
* Append the required javascript.
*/
public function demowoo_content() {
echo '<script type="text/javascript">console.log("Demo Plugin Content");</script>';
}
public function on_woocommerce_init() {
add_action('wp_footer', 'woocommerce_initialized');
}
public function woocommerce_initialized() {
echo '<script type="text/javascript">console.log("JS through woo commerce init.");</script>';
}
public function cart_page_visited() {
add_action('wp_footer', 'demo_woo_add_to_cart');
}
public function demo_woo_add_to_cart() {
echo '<script type="text/javascript">console.log("JS for added_to_cart on the cart page");</script>';
}
} // End class
$Demowoo = new Demowoo();
if($Demowoo) {
register_activation_hook( __FILE__, array(&$Demowoo, 'install'));
}
}
All your calls of add_action should use the form array($this, 'method_name') in their second parameter, like the first hook on wp_footer. This is because you are hooking methods of an object, not functions.
If you just write the name of the method WP will look for a global function with that name, not a class method. Since there are no global functions with those names, nothing happens.
The array syntax allows WP to know not only the method name but which object it should be invoked from. PHP cannot just invoke an object method without having an instance of the object, so you need to provide one to the hooking system. With the style to define plugins that you're using here the object instance is usually always $this.

decluttering UI, order Extension gets applied

A few years ago I made a SilverStripe website and added too many fields to Page.php. I'm reworking some of this at the moment but cannot afford do reinvent the Project - now on SilverStripe 3.1.10.
I thought to declutter the UI for Page Sub-Classes, that do not need all the inherited fields, with a few Extensions.
An example how this extension could look
class NoClutter extends Extension {
public function updateCMSFields(FieldList $fields) {
$fields->removeFieldFromTab("Root.Main", "MenuTitle");
$fields->removeFieldFromTab("Root.Main", "Workflow");
}
}
config.yml
RedirectorPage:
extensions:
- NoClutter
This works on all classes for fields added in SiteTree (such as the MenuTitle field), but not for fields added in Page (such as the Workflow field). If the Extension is on UserDefinedForm, Workflow is also removed. But it does not work if the extension is on RedirectorPage. MenuTitle on the other hand is removed in both classes. My guess it's about order. My project is After: 'framework/','cms/' and hope I can make an extension like NoClutter work within the project.
How can I achieve this or how else could I work around the problem?
You need to add $this->extend('updateCMSFields', $fields) at the end of your Page getCMSFields() function.
class Page extends SiteTree {
// ...
public function getCMSFields() {
// call updateCMSFields after adding your fields
SiteTree::disableCMSFieldsExtensions();
$fields = parent::getCMSFields();
SiteTree::enableCMSFieldsExtensions();
// ...
$this->extend('updateCMSFields', $fields);
return $fields;
}
}
$this->extend('updateCMSFields', $fields) declares where your code updateCMSFields() function will get called.
The problem you are having is updateCMSFields() is getting called before you add your custom fields in the Page getCMSFields() function. So you are trying to remove the Workflow field before it is added. This is because the updateCMSFields extension hook is declared in the parent SiteTree getCMSFields() function.
UserDefinedForm solves this by calling $this->extend('updateCMSFields', $fields) at the bottom of its getCMSFields(). SiteTree::disableCMSFieldsExtensions() is required before parent::getCMSFields() is called for the extension hook to work.

Gravity Forms gform_after_submission not working from a plugin?

I have a plugin that I've written that is trying to call the gforms_after_submission hook. For some reason it isn't calling the function. I see in Gravity Forms documentation that it says I have to call gform_after_submission from the functions file - is there any reason I can't call it from the plugin? I've tested with the mail function, and the function admin_init is triggering.
<?php
class Infusionsoft_GformsPDF {
public function __construct() {
add_action( 'admin_init', array( $this, 'admin_init' ) );
}
/**
* Should call my function, but doesn't
*/
public function admin_init() {
add_action('gform_after_submission', 'handle_file', 10, 2);
}
/**
* Get the file URL and post it to Infusionsoft
*/
public function handle_file($entry, $form){
mail('myemail#email.com', 'Handle File was triggered', 'yippee');
}
}
the problem here is that you've added the function call to the admin_init hook. The admin_init hook is only triggered when the user accesses the admin area, but you're submitting a form here, an action taking place on the front-end of your site outside of the admin area.
It's a simple fix :-) Just use the front-end initialization hook instead — init
Also check out this reference for the actions that are typically run when a page is loaded, on the front of your site and the admin area:
http://codex.wordpress.org/Plugin_API/Action_Reference

Unregister WordPress plugin widget from theme

Question about WordPress theme - plugins interaction.
Can i unregister widget that was added by plugin using theme functions.php file?
Tried to unregister it using sample code, but it didn't work for me:
function remove_some_widget() {
unregister_widget('some_plugin_widget');
}
add_action( 'widgets_init', 'remove_some_widget' );
The parameter to pass in unregister_widget function is the name of a class that extends, so, pass the appropriate class name. Here is an example of unregister_widget to Unregister all widgets
function unregister_default_widgets() {
unregister_widget('WP_Widget_Pages');
unregister_widget('WP_Widget_Calendar');
unregister_widget('WP_Widget_Archives');
unregister_widget('WP_Widget_Links');
unregister_widget('WP_Widget_Meta');
unregister_widget('WP_Widget_Search');
unregister_widget('WP_Widget_Text');
unregister_widget('WP_Widget_Categories');
unregister_widget('WP_Widget_Recent_Posts');
unregister_widget('WP_Widget_Recent_Comments');
unregister_widget('WP_Widget_RSS');
unregister_widget('WP_Widget_Tag_Cloud');
unregister_widget('WP_Nav_Menu_Widget');
unregister_widget('Twenty_Eleven_Ephemera_Widget');
}
add_action('widgets_init', 'unregister_default_widgets', 11);

Wordpress plugins - divide in (OOP) Classes

So, i am developing a Plugin, and I am using a main Class so it can be more easily managed:
class MyPlugin{
function __construct(){
//my add_actions here
add_action('template_redirect', array($this, 'template_redirect'));
}
//my_class_methods here
function template_redirect(){}
}
Up until now, this is all working just fine. But as the plot thickens, I need to add more and more complexity in the plugin so I would like to do something like:
create a new Class Comment
in MyPlugin's __construct instantiate $comment = new Comment()
delegate, in my template_redirect(), an action to a method in $comment like:
add_action('wp_insert_comment', array($this->comment,'wp_insert_comment'));
or:
create a new Class Comment
in MyPlugin's __construct instantiate $comment = new Comment()
in my Class Comment's __construct add the action to it's method comment_method:
add_action('wp_insert_comment', array($this, 'comment_method'));
Is this even possible? in either way, my behaviour isn't being called.
Thanks for your help
Yes, it's possible, but you should probably add most actions and filters with the plugins_loaded hook rather than using the template_redirect hook, which probably is not called at all when a comment is posted (the form goes to wp-comments-post.php, wordpress deals with request, then redirects the user back to the page where the comment form was before the template is needed.)
class MyPlugin{
function __construct(){
add_action("plugins_loaded", array($this,"_action_plugins_loaded"));
}
function _action_plugins_loaded(){
//add actions & filters here...
}
}

Resources