Wordpress Plugin - Self-Hosted Update - wordpress

I'm developing a Wordpress plugin that requires updates, although the plugin version is being checked from my server. There are several plugins that I have developed which use the exact same server to check for new versions. The problem I'm experiencing is that when all the plugins require an update and I click View Details, one of the plugins will show details of the update (version, description, and etc), but the other plugins won't show any information. After some debugging I can see that the server is returning data for sure.
My question is, how can I apply the plugins_api filter multiple times without it conflicting with the other plugins?

Your observation is right. It is not obvious. Even the book of Brad and Ozh (Plugin development ed. Wrox) includes an error in the example on page 267 in the chapter "make your own API repository".
Like you, I spent (lost) time to find the issue with a two plugins in alternate API...
The solution:
Remember that that first parameter in the WP filter is the original value passed to the filter.
So to concatenate the filters (listed by plugins using alternate api)... the first line must be:
function xiliw_altapi_information( $false, $action, $args ) {
$plugin_slug = plugin_basename( __FILE__ );
// Check if this plugins API is about this plugin
if( $args->slug != $plugin_slug ) {
return $false; // var to conserve the value of previous filter of plugins list in alternate api. fixes book error not val false
}
// POST data to send to your API
$args = array(
'action' => 'plugin_information',
'plugin_name' => $plugin_slug,
'version' => $transient->checked[$plugin_slug],
'registration' => $this->registration
);//../..
By doing this test, each time the list of hooks is called, only one - the concerned plugin - gives the right answer to display the information for the splash window.
If I have time, I probably will publish soon a more complete article about a class to manage this alternate powerful API and how to add it to a -private- plugin.

Related

Getting notice is wordpress "WP_Scripts::localize was called incorrectly"

Complete message:
Notice: WP_Scripts::localize was called incorrectly. The $l10n parameter must be an array. To pass arbitrary data to scripts, use the wp_add_inline_script() function instead. Please see Debugging in WordPress for more information. (This message was added in version 5.7.0.) in /home3/dduconne/public_html/wp-includes/functions.php on line 5313
Appeared just after updating wordpress to 5.7.0
Ok since there quite a few views and the previous answer just throws it under the rug.
Yes it is a warning now, but who knows what will happen, it is a warning for a reason, disabling something is not resolving it, there is a reason devs set it as a warning for now.
While we wait for plugin developers to resolve it on their ends, you can find out the source of the problem by enabling php_xdebug in php. I recommend not leaving it after debugging, as I am not sure about the performance cost of it being enabled.
php_xdebug will return a stack of all files affected, from there you can trace it to the source of the problem. The fix once found the source is quite easy. Culprit most likely is wp_localize_script() which requires last parameter to be an array()!
So you would find something like this:
wp_localize_script( 'handle', 'object_name', 'l10n_culprit_string' );
Which should be turned into:
wp_localize_script( 'handle', 'object_name', array( 'l10n_culprit_string' ) );
Solution to problem came from here
This is a new warning appearing in Wordpress 5.7. If you don't want to see it, and still want to have WP_DEBUG set to true, it is possible to disable the message by adding the following for example in your theme's functions.php:
add_filter('doing_it_wrong_trigger_error', function () {return false;}, 10, 0);
It is now a notice if you are using wp5.7 and php7.4, but changing to php8 it may gets reported as error. For me, when i changed (in my own code) the passed value to array (yes, probably some changes also needed in the involved js), everything worked just fine.
This is because one of the PHP script in your wordpress installation uses wp_localize_script() to pass some PHP variables to a JS script through AJAX request, and it's not good practice anymore.
This can be inside a plugin or inside your custom theme or child-theme's functions.php.
If wp_localize_script() is not in a child-theme or custom theme's functions.php, try this :
backup your website
deactivate all plugins
reactivate them one by one until you get the notice again
when the notice shows up again, this means the plugin you just reactivated uses wp_localize_script() the wrong way
if it's not up-to-date, try updating it (if you want to) : maybe the notice is going to disappear
if it's already up-to-date, or you don't want to update it, search inside wp-content/plugins the corresponding plugin's folder
open it and try to find the file(s) where wp_localize_script() is called, you can also use CLI with your server's terminal to find string in files. For example, if your server runs on Linux : grep -H -r "wp_localize_script()" /root/pathtopluginfolder | cut -d: -f1
Then, replace the code as follow :
Old one should look almost like this :
wp_enqueue_script( 'wpdocs-my-script', 'https://url-to/my-script.js' );
wp_localize_script( 'wpdocs-my-script', 'MYSCRIPT', array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'otherParam' => 'some value',
) );
New one :
wp_enqueue_script( 'wpdocs-my-script', 'https://url-to/my-script.js' );
wp_add_inline_script( 'wpdocs-my-script', 'const MYSCRIPT = ' . json_encode( array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'otherParam' => 'some value',
) ), 'before' );
Note that you need to add 'before' as the third parameter to the wp_add_inline_script function.
Once it's done, the notice shouldn't show anymore. If so, contact the plugin dev to tell him about this so that it can be part of the next update.
For more informations, see Jules Colle's comment on this page : https://developer.wordpress.org/reference/functions/wp_add_inline_script/

WooCommerce - How To Update 'Net Sales' Only When Payment is Complete

I have a WooCommerce set up, whereby all orders are added manually.
When I add a (pending) order, the WooCommerce order status hook registers the sale (for reporting).
I wish the switch this process to the hook called only when the order is (again manually) set to 'complete'.
There are a couple plugins ( eg. https://docs.woocommerce.com/document/woocommerce-order-status-control/ / https://wordpress.org/plugins/advanced-reporting-for-woocommerce/ etc ), but these are either overkill or simply don't provide this functionality..
I've also found a couple related posts, essentially describing overriding the woocommerce hooks to this end ( Getting order data after successful checkout hook etc, but unfortunately whilst the solutions correspond ( ie adapting the correct hooks - the context differs ).
I'm reluctant to prevent functionality in these hooks when attempting to overwrite/reorder the actions so any pointers which hooks I can use to achieve this would be really helpful.
Many thanks!
maybe you can try to use the ... filter, something like (untested):
add_filter( 'woocommerce_reports_order_statuses', 'fc_order_status_reports', 20, 1 );
function fc_order_status_reports( $statuses ) {
$statuses = array('completed');
return $statuses;
}
The code snippet is to add to your active theme's functions.php file.
Let me know if it does the job ;)

submit to ninja form programmatically

I've been researching for days and all I want to be able to do is create entries in the ninja form admin listings. Either by submitting custom form (not ninja form generated) or just calling a hook and passing data (data will match actual form fields created in ninja form).
I want to be able to do this so that I can create any type of form layout and still be able to submit to ninja form entry. Or if anyone has any other information on a plugin that can allow me to do such a thing, please share.
In NinjaForms version 3, you probably want to look at this file:
ninja-forms/includes/Actions/Save.php
The process function contains the important bits that may help you:
$sub = Ninja_Forms()->form( $form_id )->sub()->get();
foreach($fields as $field_id => $field_value){
$sub->update_field_value( $field_id, $field_value );
}
$sub->save();
In NinjaForms version 2, it is a little different
$sub_id = Ninja_Forms()->subs()->create( $form_id );
foreach( $form_fields as $field_id => $value ) {
Ninja_Forms()->sub( $sub_id )->add_field( $field_id, $value );
}
Where the $form_fields array would look like:
$form_fields = array(
$fiel_id_1 => $value_1,
$fiel_id_2 => $value_2,
...
);
I know this is is quite a while after the last comment on this post, but it should be noted that if you submit the form this way you will not be able to trigger any notifications. I have spent hours upon hours trying to include different classes and functions and try to rewrite the notifications class locally in my webhook script that was processing my forms, but I can't get it to work. Maybe there is someone smarter than me that can figure it out or maybe one day Ninja Forms will properly build out this functionality in their API. But for right now, if you need notifications this is not a full solution.
I would recommend switching over to Gravity Forms if you are still early enough in your project. Their API does have a submit_form() function that also triggers notifications and action steps. I just wish they would spend some time on their absolutely atrocious interface. I hate everything about their admin UX, but for more complex development things like this, they really are the best option.
Documentation

WordPress constant scope using define method

I'm defining plugin path as a constant through constant define method as shown below.
define( 'MY_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
It is accessible within plugin all files and themes. But when I call this constant in another plugin this constant becomes undefined.
How I can get this plugin constant in another plugin? Any help will be appreciated.
Thanks,
Probably your problem is the order that wordpress is calling your plugins: the plugins that sets the constant is loaded after the one who calls it.
A better explanation of how to force your plugin be loaded first can be found here. I'm putting here a quote of the part that matters:
The order that plugins are loaded (as of WP 2.9.1 at least) is determined by the order of an array stored as "active_plugins" in the WP options table. Whenever a plugin is activated, it is added to this array, the array is sorted alphabetically by plugin name, and the array is saved to the DB.
Fortunately, there is a convenient action hook, "activated_plugins", that is called after the active plugins array is saved to the DB. This allows you to manipulate the order of the plugins stored in this array after the array is initially saved.
You'll have to the following PHP code in the plugin who defines the constant, then deactivate and reactivate it (copied from the link I providaded above).
function this_plugin_first() {
// ensure path to this file is via main wp plugin path
$wp_path_to_this_file = preg_replace('/(.*)plugins\/(.*)$/', WP_PLUGIN_DIR."/$2", __FILE__);
$this_plugin = plugin_basename(trim($wp_path_to_this_file));
$active_plugins = get_option('active_plugins');
$this_plugin_key = array_search($this_plugin, $active_plugins);
if ($this_plugin_key) { // if it's 0 it's the first plugin already, no need to continue
array_splice($active_plugins, $this_plugin_key, 1);
array_unshift($active_plugins, $this_plugin);
update_option('active_plugins', $active_plugins);
}
}
add_action("activated_plugin", "this_plugin_first");
Hope it helps!

reverse order of projects in wordpress

I have a list of latest projects displaying on the home page of my wordpress site. I can see the section that calls for the projects, but not sure where I can reverse the order.
I know this works for posts.
<?php query_posts($query_string . "&order=ASC"); ?>
but don't know where to add it. This is the code that calls the projects:
$wpGrade_Options->get('homepage_portfolio_limit') ? $projects_nr = $wpGrade_Options->get('homepage_portfolio_limit') : $projects_nr = 3;
wpgrade_display_portfolio( $projects_nr, true, true); ?>
You are probably using plugin or a theme.
You need to find this function in the plugin/theme files: wpgrade_display_portfolio
From command line you would simply do:
grep -ir "wpgrade_display_portfolio" wordpress/dir
Inside that function there is either a direct call to DB, or if writer of that script was wise built in wp get_posts, WP_POSTS, or query_posts functions.
IF you find any of these wordpress native functions than you can easily reverse order by adding:
'order' => 'DESC',
If there is a mysql query, then I will have to see it first to give you meaningful answer. I also need to see DB and how you actually would like to order things.

Resources