WP PHP calling function in another file - php

In my WP plugin, I need to call some functions of it in a different file,
/wp-content/plugins/wolf-jplayer/includes/jplayer-show.php has public function head_script( $id, $playlist_id, $songs, $in_popup, $autoplay = false ) { which I need to call in /wp-content/themes/twentlytwelve/index.php and then remove the function from it's original place since it's going to be in Index.php then. Is that possible? I tried everything and nothing worked.
#Niels my usage: used in wp-content/themes/twentytwelve/header.php
<?php
$Wolf_Jplayer_Show = new Wolf_Jplayer_Shows;
$Wolf_Jplayer_Show->head_script( $id, $playlist_id, $songs, $in_popup, $autoplay = false );
?>
the function is located in wp-content/plugins/wolf-jplayer/includes/jplayer-show.php

The function is possibly part of a class. If you keep the plugin activated you can create an instance of the class by;
<?php
$the_class = new Classname;
$the_class->function_name();
?>

Related

PHP - Can't access properties declared in another method when calling methods using AJAX

I apologise if this question is a bit long winded, but it's quite a large chunk of code and I cannot get it to work for the life of me...
I am building a form inside a Wordpress plugin that should gather some data (either through form inputs, API, or a combination of both - such as calling different API endpoints depending on form values). I want to then use these variables (or properties, as they seem to be referred to within classes) in different methods.
Firstly, I have my class and then a method to register my plugin on the Wordpress menu bar:
class EnigmaDMU {
private $enigma_dmu_screen_name;
private static $instance;
static function GetInstance()
{
if (!isset(self::$instance))
{
self::$instance = new self();
}
return self::$instance;
}
// This loads the WP menu page and plugin page
public function PluginMenu() {
$this->enigma_dmu_screen_name = add_menu_page(
'Enigma DMU Post',
'Enigma DMU Post',
'manage_options',
__FILE__,
array($this, 'RenderPage'),
plugins_url('enigma-daily-update/assets/enigma-cube-white.svg',__DIR__)
);
}
I then have another method called 'RenderPage' which contains my form and the HTML elements for my plugin page inside the WP admin:
public function RenderPage(){
?>
<div class='wrap'>
<div class="header-bar">
<h1>Daily Market Update</h1>
....... continued here
At the very bottom of my code, I have a method to initiate the plugin which adds the AJAX handlers (my methods) for certain AJAX actions which are called in my AJAX requests:
public function InitPlugin() {
add_action('admin_menu', array($this, 'PluginMenu'));
add_action('admin_enqueue_scripts', array($this, 'dmu_load_scripts'));
add_action('admin_enqueue_styles', array($this, 'dmu_load_scripts'));
add_action('wp_ajax_btc_data', array($this, 'getBTCData'));
add_action('wp_ajax_test_func', array($this, 'testFunc'));
}
} //this is the closing tag for the Class.
Underneath this, I have some class-related definitions, which admittedly I am unsure what they do - this was part of a larger tutorial I followed to set up this plugin:
$EnigmaDMUpost = EnigmaDMU::GetInstance();
$EnigmaDMUpost->InitPlugin();
?>
Almost there... I also have my handlers (I have included a test handler to simplify this explanation):
public function getBTCData() {
require __DIR__."/vendor/autoload.php";
$client = new GuzzleHttp\Client();
$btc_curl = $client->get('https://api.alternative.me/v1/ticker/bitcoin/',);
$btc_curl_body = $btc_curl->getBody();
$btc_curl_body_json = json_decode($btc_curl_body);
foreach($btc_curl_body_json as $result){
$btc_price_ur = $result->price_usd;
$btc_change_ur = $result->percent_change_24h;
}
$btc_price = round($btc_price_ur, 2);
$btc_change = round($btc_change_ur, 2);
$this->row3b = $btc_change . '%';
echo 'inside: ' . $this->row3b;
die();
}
I am able to echo this value here (row3b) inside my plugin successfully - this works as expected.
However, when I try and call the property from my testFunc, I get nothing:
public function testFunc() {
$test_item = $this->row3b;
echo 'btc dominance = ' . $test_item . '%.';
}
Finally, the relevant areas of my AJAX script are as follows:
jQuery(document).ready(function($) {
$('#dmu_submit').click(function() {
$('#dmu-loader').show();
$('#dmu_submit').attr('disabled', true);
btc_data = {
action: 'btc_data',
dmu_nonce: dmu_vars.dmu_nonce
};
$.post(ajaxurl, btc_data, function(response) {
$('#dmu-results').html(response);
$('#dmu-loader').hide();
$('#dmu_submit').attr('disabled', false);
});
$('#dmu_test_func').click(function() {
$('#dmu-loader').show();
$('#dmu_submit').attr('disabled', true);
test_data = {
action: 'test_func',
dmu_nonce: dmu_vars.dmu_nonce
};
$.post(ajaxurl, test_data, function(response) {
$('#dmu-results-test').html(response);
$('#dmu-loader').hide();
$('#dmu_submit').attr('disabled', false);
});
return false;
});
Any help would be massively appreciated - I know it's a long post, but I feel as if the answer is actually really simple, I just cannot figure it out. It feels as if I'm doing everything right. Thank you!!
It's not completely clear from your code examples which class your testfunc() is in. But $this in php refers to the instance of the class that it resides within, and the ->row3b refers to a property called row3b (a property is a variable that belongs to the class which is usually defined at the top of the class code). If you're calling $this->row3b within the class itself it will work, but if you need to refer to it from outside the class you will need to instantiate a new instance of the class, and then refer to it with the variable name you assign. E.g.
$myInstance = new theclassname(); $myInstance->row3b;
If the row3b is a static property its slightly different again, you can refer to this outside of the class as theclassname::$row3b
Edit: also ensure that the testfunc resides in the same class that the add_actions are in. The $this in the add_action tells wordpress that it should look for your handler in 'this' class.
Edit2: I think you may also need the die() at the end of your testfunc. Wordpress ajax is funny about this.

PHP Update Global Variable Using Call From included file - Scoping Issue

I am trying to implement a simple add_hook function using PHP but am coming across some trouble with updating the global array I have to store available/set hooks. If I use add_hook from main.php it works fine and I can add as many hooks as needed, but if doing the same thing from an included file, the $hooks var only updates from within the function.
main.php
require dirname(__FILE__) . '/includes/functions.php';
$hooks = array();
function add_hook($hook_name, $function)
{
global $hooks;
$hooks[$hook_name] = $function;
}
add_hook("hook_name", "some_function");
function execute_hook($hook_name)
{
global $hooks;
foreach ($hooks[$hook_name] as $function) {
if (function_exists($function[0])) {
call_user_func($function[0]);
}
}
}
function execute_hooks($hook_name)
{
global $hooks;
print_r($hooks);
if (array_key_exists($hook_name, $hooks)) {
execute_hook($hook_name);
}
}
print_r($hooks);
// Array ( [hook_name] => some_function )
// missing the array added from functions.php
functions.php
add_hook("build_admin_menu", "hd_modify_menu");
If I print_r at the end of the add_hook function, it will print the added hook, but I think the problem is that the "global" $hooks does not seem to update with the add_hook call from functions.php.
Can anyone explain to me why this is happening and what I can do to fix? Much appreciated!
Please check you code
require dirname(__FILE__) . '/includes/functions.php';
// $hooks = array();
The $hook array is reassigned after including functions.php . you need to comment/remove it. as shown above.
Hope this will help you

Get instances to arbitrary plugins in php files

The name is quite bad, but I really don't know what else to call it.
I'm trying to make a extendable and modular plugin system for my website. I need to be able to access plugin php files that exist in a plugin directory and get access to their classes to call functions such as getting the html content that the plugin should show and more.
Below is a semi-pseudo code example of what I am trying to achieve, but how to actually arbitrarily load the plugins is where I am stuck (PluginLoader.php).
-Max
//BasePlugin.php
abstract class BasePlugin
{
public function displayContent()
{
print "<p>Base Plugin</p>";
}
};
//ExamplePlugin.php -> In specific plugin directory.
require('../BasePlugin.php');
class ExamplePlugin extends BasePlugin
{
public static function Instance()
{
static $inst = null;
if ($inst === null) {
$inst = new ExamplePlugin();
}
return $inst;
}
public function displayContent()
{
print "<p>Example Plugin</p>";
}
}
//PluginLoader.php
foreach($pluginFile : PluginFilesInDirectory) { // Iterate over plugin php files in plugin directory
$plugin = GetPlugin($pluginFile); // Somehow get instance of plugin.
echo plugin->displayContent();
}
I'm guessing here, but it seems to me that you need to:
get a list of the plugins in the desired directory.
include or require the plugin's class file.
create an instance of the class.
call the plugin's displayContent() method.
So, you probably want to do something like
$pluginDir = 'your/plugin/directory/' ;
$plugins = glob($pluginDir . '*.php') ;
foreach($plugins as $plugin) {
// include the plugin file
include_once($plugin) ;
// grab the class name from the plugin's file name
// this finds the last occurrence of a '/' and gets the file name without the .php
$className = substr($plugin,strrpos($plugin,'/') + 1, -4) ;
// create the instance and display your test
$aPlugin = $className::Instance() ;
$aPlugin->displayContent() ;
}
There's probably a cleaner way to do it, but that will ready your directory, get the plugins' code, and instantiate each one. How you manage/reference them afterwards depends on how your plugins register with your application.

Cannot load custom content type nodes with load_node_multiple or load_node

I have a custom content type called "program" that I am trying to load via a drupal module.
The .module file includes a class called Program that has a method called
getAllPrograms() using include_once(drupal_get_path('module', 'progs') . '/progs.php');
When i try and load nodes using either node_load() or node_load_multiple() i get one of two different errors randomly.
either:
Fatal error: Fatal error: Call to undefined function user_access() in /mypath/modules/filter/filter.module on line 1035
or
Error: Call to undefined function token_get_entity_mapping() in /mypath//sites/all/modules/contrib/token/token.tokens.inc, line 767
Note: 99% of times it is the first error, and occasionally i would recieve the token_get_entity error.
The strange thing is, while i have been trying different things to resolve the error I have been able to get both of these functions to work for a period but as soon as i clear the Drupal Cache i get the error again.
What I have tried
Disabling and enabling the user module via the database.
Checking the paths and status are correct for the main modules (system, user, block etc)
using db_select to get a list of node ids and then use node_load() (with a loop) and node_load_multiple() to load the nodes. This is one of the things that started working for a short time until i cleared the cache.
Tested to see if i can call user_access() from my .module file. This does not work and returns the same call to undefined function error.
Here is the code that I have (not progs an anonymized name)
progs.module
include_once(drupal_get_path('module', 'progs') . '/progs.php');
progs.php
if( !class_exists('progs') ):
class progs
{
//a bunch of properties
function __construct()
{
// load partial includes and objects
$this->load_partial_inclues();
//retrieve all programs that are open
$this->open_programs = Program::getAllOpenPrograms();
}
function load_partial_inclues()
{
//includes
include_once(drupal_get_path('module', 'progs') . '/core/objects/program.php');
}
}
function progs()
{
global $progs;
if( !isset($progs) )
{
$progs = new progs();
}
return $progs;
}
// initialize
progs();
endif;
Note: I load the $progs into the global space so i can call it elsewhere in my module.
program.php
if( !class_exists('Program') ):
class Program
{
//a bunch of properties
public static function getAllOpenPrograms()
{
// This is the line that causes all of the issues.
$result = node_load_multiple('',array('type' => 'program'));
dpm($result);
}
Thanks in advance!
Like Mike Vranckx mentioned, if you call progs() directly when you include it in progs.module, Drupal basically hasn't bootstrapped, i.e. hasn't started running fully yet. Suggest you put your progs() in progs_init() or similar so that Drupal will invoke it at the right time.
Here's a proposed way that follows your initial structure quite closely, and below you will see an alternative that better follows Drupal's conventions.
New progs.module
/**
* Implements hook_init().
*/
function progs_init(){
progs();
}
And modify your progs.php
// Why are you doing this check? Are you defining this class elsewhere in your project? If not you can safely ignore this
//if( !class_exists('progs') ):
// Convention is to name classes with Pascal case btw.
class progs
{
//a bunch of properties
function __construct()
{
// load partial includes and objects
$this->load_partial_inclues();
//retrieve all programs that are open
$this->open_programs = Program::getAllOpenPrograms();
}
function load_partial_inclues()
{
//includes
include_once(drupal_get_path('module', 'progs') . '/core/objects/program.php');
}
}
function progs()
{
global $progs;
if( !isset($progs) )
{
$progs = new progs();
}
return $progs;
}
A more Drupal way:
progs.module
/**
* Implements hook_init().
*/
function progs_init(){
global $progs;
// Consider using drupal_static to cache this
if( !isset($progs) )
{
module_load_include('inc', 'progs', 'progs');
$progs = new Progs();
}
}
progs.inc (convention is to use .inc)
class Progs
{
//a bunch of properties
function __construct()
{
// load partial includes and objects
$this->load_partial_inclues();
//retrieve all programs that are open
$this->open_programs = Program::getAllOpenPrograms();
}
function load_partial_inclues()
{
//includes
module_load_include('php', 'progs', 'core/objects/program');
}
}

WordPress Custom Filter - apply_filters multiple

I'm building a way to extend a WordPress plugin I'm developing using the following filter for grabbing the html content from a different plugin:
$content = apply_filters('satl_render_view', array($view, $slides));
With just one plugin this works perfectly, but once I activate a second plugin utilizing this same filter it stops working, $content is null for either plugin:
I'm adding the filters on the plugins in the __construct() method:
add_filter('satl_render_view', array('SatellitePortraitPlugin','addRender'));
and
add_filter('satl_render_view', array('SatelliteAwesomePlugin', 'addRender'));
Anyone run into this before?
In case it helps, this is the addRender method as it currently stands:
public static function addRender($params)
{
list($view, $slides) = $params;
$plugin = new SatelliteAwesomePlugin();
return $plugin->render($view, array('slides' => $slides, 'frompost' => 'false'), false);
}
For the record, I've tried remove_filter() if there is no content to return, but that didn't solve the problem.
Params get passed to callback function, in this case addRender() and contain all the HTML of what is wanted to display to the second plugin using that same filter. To utilize this bit of information one must change the method:
public static function addRender($params)
{
if (is_array($params)) {
list($view, $slides) = $params;
$plugin = new SatelliteAwesomePlugin();
return $plugin->render($view, array('slides' => $slides, 'frompost' => 'false'), false);
} else {
return $params;
}
}
You also need to make sure to update how the render() method passed the proper information back to the apply_filters method so the next plugin would have the proper array to run the addRender()
} else {
return array($file,$params['slides']);
}
Main Learning: WordPress apply_filters is much dumber than you'd think. You can't assume it merges everything for you, it just passes the information along and your code needs to make sense of it.

Categories