WordPress AJAX is_admin is true, causing issues. - php

i'm trying to make a plugin for WordPress, which is has got an admin section for some basic settings, and also registers some shortcode to display some HTML, which is basically a form.
Here is my main plugin file, plugins/my-plugin/my-plugin.php:
/**
* Plugin Name: Pathway
* Plugin URI: http://www.martynleeball.com/
* Description: Pathway integration.
* Version: 1.0
* Author: Martyn Lee Ball
* Author URI: https://www.martynleeball.com/
**/
define('PATHWAY_VERSION', '0.0.8');
define('PATHWAY_AUTHOR', 'Martyn Lee Ball');
define('PATHWAY__MINIMUM_WP_VERSION', '4.*');
define('PATHWAY_CONTACT', 'martynleeball#gmail.com');
add_action(
'plugins_loaded',
array ( Pathway::get_instance(), 'plugin_setup' )
);
class Pathway
{
protected static $instance = NULL;
public $plugin_url = '';
private $cpt = 'post'; # Adjust the CPT
public function __construct() {}
public static function get_instance()
{
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
public function plugin_setup()
{
$this->plugin_url = '';
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );
// if (is_admin()) {
//
// require_once( $this->plugin_url . 'admin/index.php' );
//
// register_activation_hook( __FILE__, 'install' );
//
// return;
// }
add_shortcode( 'pathway', array($this, 'shortcode'));
add_action( 'wp_ajax_ajax_login', array( $this, 'ajax_login' ) );
add_action( 'wp_ajax_nopriv_ajax_login', array( $this, 'ajax_login' ) );
add_action( 'wp_ajax_ajax_register', array( $this, 'ajax_register' ) );
add_action( 'wp_ajax_nopriv_ajax_register', array( $this, 'ajax_register' ) );
}
public function enqueue()
{
wp_enqueue_script( 'vuejs', 'https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js' );
wp_enqueue_script(
'ajax-handle-form',
"{$this->plugin_url}/wp-content/plugins/pathway/frontend/js/scripts.js"
);
wp_localize_script(
'ajax-handle-form',
'wp_ajax',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajaxnonce' => wp_create_nonce( 'ajax_post_validation' )
)
);
}
public function ajax_login()
{
echo 'login';exit;
}
public function ajax_register()
{
echo 'register';exit;
}
public function shortcode()
{
if (!isset($_SESSION['pathway_login'])) {
self::view('forms/login');
}
}
public static function view( $name, array $args = array() ) {
foreach ( $args AS $key => $val ) {
$$key = $val;
}
// $file = $this->plugin_url . 'views/'. $name . '.php';
$file = 'views/'. $name . '.php';
include( $file );
}
}
Please correct me if i'm going wrong somewhere, there's so many mixed guides online showing different ways. Within this file i'm basically:
Adding my scripts and assigning the PHP values.
I would be then starting the admin section however has to comment this out for the AJAX call, this is my issue.
Registering my shortcode.
Adding the actions for the AJAX form submit.
Obviously my issue is that when I hit the is_admin from the AJAX call it is returning true, when it should be false as an public visitor can submit this form. The wp_ajax_nopriv action doesn't appear to work which would solve the issue, this is probably due to me being logged into WordPress.
I have tried logging out of WordPress but the is_admin still returns true!
Can someone advise?

is_admin will return true on all ajax calls.
It is not actually a useful function to check the user as it checks the uri rather than the user details, i.e. if on a admin page = true, if not false.
Now I was a little confused about your question here, it appears you want the is_admin to return false if its actually an ajax call?
if ( is_admin() && ! wp_doing_ajax() ) {}
It will return false on ajax calls.
If you are checking there is an "admin" logged in, as in can edit posts, see the other capabilities here
if ( current_user_can( 'edit_post' ) ) {}
The no_priv hook will not work when logged in, its not called.

Related

remove_action From PHP Class in WooCommerce Memberships

I have previously used a solution described here: remove_action From PHP Class for removing an action in the WooCommerce membership plugin.
However, the solution no longer works, as WooComemerce have changed the code behind the membership plugin.
So this is the new code.
Main woocommerce-memberships.php
public function includes() {
// load post types
require_once( $this->get_plugin_path() . '/includes/class-wc-memberships-post-types.php' );
// load user messages helper
require_once( $this->get_plugin_path() . '/includes/class-wc-memberships-user-messages.php' );
// load helper functions
require_once( $this->get_plugin_path() . '/includes/functions/wc-memberships-functions.php' );
// init general classes
$this->rules = $this->load_class( '/includes/class-wc-memberships-rules.php', 'WC_Memberships_Rules' );
$this->plans = $this->load_class( '/includes/class-wc-memberships-membership-plans.php', 'WC_Memberships_Membership_Plans' );
$this->emails = $this->load_class( '/includes/class-wc-memberships-emails.php', 'WC_Memberships_Emails' );
$this->user_memberships = $this->load_class( '/includes/class-wc-memberships-user-memberships.php', 'WC_Memberships_User_Memberships' );
$this->capabilities = $this->load_class( '/includes/class-wc-memberships-capabilities.php', 'WC_Memberships_Capabilities' );
$this->member_discounts = $this->load_class( '/includes/class-wc-memberships-member-discounts.php', 'WC_Memberships_Member_Discounts' );
$this->restrictions = $this->load_class( '/includes/class-wc-memberships-restrictions.php', 'WC_Memberships_Restrictions' );
Main instance
function wc_memberships() {
return WC_Memberships::instance();
}
From included class-wc-memberships-restrictions.php file
/**
* Returns the general content restrictions handler.
*
* #since 1.9.0
*
* #return null|\WC_Memberships_Posts_Restrictions
*/
public function get_posts_restrictions_instance() {
if ( ! $this->posts_restrictions instanceof WC_Memberships_Posts_Restrictions ) {
$this->posts_restrictions = wc_memberships()->load_class( '/includes/frontend/class-wc-memberships-posts-restrictions.php', 'WC_Memberships_Posts_Restrictions' );
}
return $this->posts_restrictions;
}
Then in class-wc-memberships-posts-restrictions.php
public function __construct() {
// decide whether attempting to access restricted content has to be redirected
add_action( 'wp', array( $this, 'handle_restriction_modes' ) );
// restrict the post by filtering the post object and replacing the content with a message and maybe excerpt
add_action( 'the_post', array( $this, 'restrict_post' ), 0 );
How do i remove the 'the_post' action?
So far i have the following in functions.php theme file:
function weteach_remove_actions(){
if(is_singular( 'post' )) {
if( function_exists( 'wc_memberships' ) ){
remove_action( 'the_post', array( wc_memberships()->restrictions, 'restrict_post' ));
}
}
return;
}
add_action( 'the_post', 'weteach_remove_actions', 1 );
Which gives me a "blank-page"-error.
Could you tell us what the error message was? My guess is that restrictions and post_restrictions aren't the same property and so you aren't finding the restrict_post method in the right class.
Edited now that I have looked at Memberships, this seems to work for me:
function so_41431558_remove_membership_post_restrictions(){
if( function_exists( 'wc_memberships' ) && version_compare( WC_Memberships::VERSION, '1.9.0', '>=' ) && is_singular( 'post' ) ){
remove_action( 'the_post', array( wc_memberships()->get_restrictions_instance()->get_posts_restrictions_instance(), 'restrict_post' ), 0 );
}
}
add_action( 'wp_head', 'so_41431558_remove_membership_post_restrictions', 1 );
Your add_action attempt is happening on priority 1, which is after the function has already run the Memberships method on priority 0, so even if the rest of your code was correct it would be too late.
So 1. I think we need to go to an earlier hook.
And 2. I think we need to use the new method for accessing the post restrictions class instance.
edited to add
and 3. I've switched to a direct version compare condition
and 4. I misread where the get_posts_restrictions_instance() method was... it is accessed via wc_memberships()->get_restrictions_instance()->get_posts_restrictions_instance()

Page template option not showing after update to 4.7

I've used this plugin for adding specific templates for page.
class PageTemplater {
protected $plugin_slug;
private static $instance;
protected $templates;
public static function get_instance() {
if( null == self::$instance ) {
self::$instance = new PageTemplater();
}
return self::$instance;
}
private function __construct() {
$this->templates = array();
add_filter('page_attributes_dropdown_pages_args', array($this, 'register_project_templates'));
// add_filter('wp_insert_post_data', array($this, 'register_project_templates'));
add_filter('template_include', array($this, 'view_project_template'));
$this->templates = array(
'page-json.php' => 'JSON list',
);
}
public function register_project_templates( $atts ) {
// Create the key used for the themes cache
$cache_key = 'page_templates-' . md5( get_theme_root_uri() . '/' . get_stylesheet() );
// Retrieve the cache list.
// If it doesn't exist, or it's empty prepare an array
$templates = wp_get_theme()->get_page_templates();
if ( empty( $templates ) ) {
$templates = array();
}
// New cache, therefore remove the old one
wp_cache_delete( $cache_key , 'themes');
// Now add our template to the list of templates by merging our templates
// with the existing templates array from the cache.
$templates = array_merge( $templates, $this->templates );
// Add the modified cache to allow WordPress to pick it up for listing
// available templates
wp_cache_add( $cache_key, $templates, 'themes', 1800 );
return $atts;
}
/**
* Checks if the template is assigned to the page
*/
public function view_project_template( $template ) {
global $post;
if (!isset($this->templates[get_post_meta( $post->ID, '_wp_page_template', true)])) {
}
$file = plugin_dir_path(__FILE__) . get_post_meta($post->ID, '_wp_page_template', true);
// Just to be safe, we check if the file exists first
if (file_exists($file)) {
return $file;
} else {
echo $file;
}
return $template;
}
}
add_action( 'plugins_loaded', array( 'PageTemplater', 'get_instance' ) );
But when I've have updated a WordPress to 4.7 page template options had stopped to show. Maybe I use some deprecated functions?
Please help.
Fixed code:
// Add a filter to the attributes metabox to inject template into the cache.
if ( version_compare( floatval( get_bloginfo( 'version' ) ), '4.7', '<' ) ) {
// 4.6 and older
add_filter(
'page_attributes_dropdown_pages_args',
array( $this, 'register_project_templates' )
);
} else {
// Add a filter to the wp 4.7 version attributes metabox
add_filter(
'theme_page_templates', array( $this, 'add_new_template' )
);
}
/**
* Adds our template to the page dropdown for v4.7+
*
*/
public function add_new_template( $posts_templates ) {
$posts_templates = array_merge( $posts_templates, $this->templates );
return $posts_templates;
}
source: http://www.wpexplorer.com/wordpress-page-templates-plugin/

wp_enqueue_script not working when dependent on query string value in custom template.

So for some reason wp_enqueue_script does not execute when dependent on query string value. If I change function check to simply return true, it works. Why is this? Looking at the WordPress initiation order, wp_enqueue_script fires after parse_query which means it must be available. My goal is to only load the scripts if template foo is requested.
class Car {
public function __construct() {
if ( $this->check() ) {
add_action('template_include', array( $this, 'get_template') );
// Does not work
add_action( 'wp_enqueue_scripts', array( $this, 'get_scripts') );
add_action( 'wp_enqueue_scripts', array( $this, 'get_styles') );
}
// Works
add_action( 'wp_enqueue_scripts', array( $this, 'get_scripts') );
add_action( 'wp_enqueue_scripts', array( $this, 'get_styles') );
}
public function check() {
return ( isset( $_GET['foo'] ) && $_GET['foo'] == true );
}
public function get_template() {
return locate_template( array( 'foo.php' ) );
}
}
$car = new Car();
I suspect that it's ignoring your 'foo' parameter because to use custom query vars, they need to be registered with WordPress, using the 'query_vars' filter.
Like this:
function themeslug_query_vars( $qvars ) {
$qvars[] = 'foo';
return $qvars;
}
add_filter( 'query_vars', 'themeslug_query_vars' , 10, 1 );

PHP/Wordpress: Why is this echo always loading in the same spot no matter what?

I am extending someone else's plugin. He has an action hook in the function he uses to initialize the plugin. It doesn't matter if I put echo nl2br("this is located OVER the do action anspress loaded. \n"); BELOW or ABOVE the line do_action('anspress_loaded'); - the line always get's echo'd out ABOVE another line I have being echo'd inside the other code loaded on that hook. Why is this? It's probably not TREMENDOUSLY important but I'm just curious....(noob here). Any idea?
this initializes the plugin
/**
* Initializes the plugin by setting localization, hooks, filters, and administrative functions.
*
* #return instance
*/
public static function instance() {
if ( ! isset( self::$instance ) && ! (self::$instance instanceof self) ) {
self::$instance = new self();
self::$instance->setup_constants();
self::$instance->actions = array();
self::$instance->filters = array();
add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
add_action( 'bp_loaded', array( self::$instance, 'bp_include' ) );
global $ap_classes;
$ap_classes = array();
self::$instance->includes();
self::$instance->ajax_hooks();
self::$instance->site_include();
self::$instance->anspress_forms = new AnsPress_Process_Form();
self::$instance->anspress_query_filter = new AnsPress_Query_Filter();
self::$instance->anspress_cpt = new AnsPress_PostTypes();
self::$instance->anspress_reputation = new AP_Reputation();
/*
* ACTION: anspress_loaded
* Hooks for extension to load their codes after AnsPress is leaded
*/
echo nl2br("this is located OVER the do action anspress loaded. \n");
do_action('anspress_loaded');
self::$instance->setup_hooks();
}
return self::$instance;
}
this might be important:
/**
* Register the filters and actions with WordPress.
*/
private function setup_hooks() {
foreach ( $this->filters as $hook ) {
add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
}
foreach ( $this->actions as $hook ) {
add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
}
}

plugin activation hook not working in wordpress

I'm trying to develop my first Wordpress plugin and I got staled in the very first stage. I'm trying to setup some options and database tables when the plugin is activated, but no luck. No matter what I do, the plugin activates, but the database is untouched and the options are not stored in DB. I tried echoing inside the constructor, but it seems that it never reaches it. I have debug activated in WP, but no error is being reported. The function is not being hooked. Does someone can spot what's wrong with my code?
Thanks for any help in advance.
class Myplugin {
private static $instance;
public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
register_activation_hook( __FILE__, array( &$this, 'plugin_activate' ) );
}
public function plugin_activate() {
if ( version_compare( get_bloginfo( 'version' ), '3.8.2', ' < ' ) ) {
deactivate_plugins( basename( __FILE__ ) );
} else {
$rlm_rsvplus_options = array(
'db_version' => '1.0',
'event_name' => '',
'end_date' => '',
);
update_option( 'rlm_myplugin_options', $rlm_myplugin_options );
require_once( "includes/rlm_myplugin_db_setup.php" );//It never reaches this file.
}
}
}
$myplugin = Myplugin::get_instance();
Back to the WordPress documentation.
<?php register_activation_hook( $file, $function ); ?>
Parameters
$file
(string) (required) Path to the main plugin file inside the wp-content/plugins directory. A full path will work.
Default: None
$function
(callback) (required) The function to be run when the plugin is activated. Any of PHP's callback pseudo-types will work.
Default: None
Possible issue
If calling a function from a file that is outside of main plugin file, then the hook will not work as it is not pointing to the right file. FILE will point to the file where the code is written. So if you happen to include this part of code from elsewhere (another file - not the main plugin file) it's not supposed to work unless you point the right path.
Solution
A solution could be declaring a constant in the main plugin file.
your_main_plugin_file.php
define(PLUGIN_FILE_URL, __FILE__);
and then use it in your included file like so.
includes/some_file.php
<?php register_activation_hook( PLUGIN_FILE_URL, ['your_class_name_here', 'your_class_method_name_here']); ?>
or if you use functions instead of classes then do
<?php register_activation_hook( PLUGIN_FILE_URL, 'your_function_name_here'); ?>
The register_activation_hook call needs to be outside of the class itself.
Something like:
class Myplugin {
private static $instance;
public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
// do other stuff here
}
public function plugin_activate() {
if ( version_compare( get_bloginfo( 'version' ), '3.8.2', ' < ' ) ) {
deactivate_plugins( basename( __FILE__ ) );
} else {
$rlm_rsvplus_options = array(
'db_version' => '1.0',
'event_name' => '',
'end_date' => '',
);
update_option( 'rlm_myplugin_options', $rlm_myplugin_options );
require_once( "includes/rlm_myplugin_db_setup.php" );
}
}
register_activation_hook( __FILE__, array( 'Myplugin', 'plugin_activate' ) );
You can read more on the following tutorial by Francis Yaconiello about How to write WordPress plugin.
In order to work register_activation_hook OR register_deactivation_hook the functions should be in index file OR we need to specify the full path to the file argument.
Replace this:
register_activation_hook( FILE, array( &$this, 'plugin_activate' ) );
With:
register_activation_hook( FILE . 'plugin-main-file.php', array( &$this, 'plugin_activate' ) );
Here the point is register_activation_hook( $file, $function );
Here $file means Path to the main plugin file
Reference: https://codex.wordpress.org/Function_Reference/register_activation_hook
Thanks,
- Adi

Categories