Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am in the process of writing my first plugin and my call to the plugin_basename(__FILE__) function results in a:

PHP Fatal error: Call to undefined function plugin_basename()

My plugin resides in a directory of its own under the standard wp-content/plugins/. I am also using wordpress 3.3.1 and have looked at the codex but cannot see anything wrong. The code block where it fails is shown below:

<?php
/*
Plugin Name: Send Invitation
Plugin URI: http://w3boutique.net
Description: Emails a the link of the current page to a friend
Author: Nandakumar Chandrasekhar
Version: 0.1wp-includes/plugin.php
Author URI: http://w3boutique.net/about-nanda.html
License: GPL2
*/

define( 'SEND_INVITATION_VERSION', '0.1' );

define( 'SEND_INVITATION_REQUIRED_WP_VERSION', '3.3.1' );

// Check if following are required

if ( ! defined( 'SEND_INVITATION_PLUGIN_BASENAME' ) ) {
    define( 'SEND_INVITATION_PLUGIN_BASENAME', plugin_basename(__FILE__) );
 }

if ( ! defined( 'SEND_INVITATION_PLUGIN_NAME' ) ) {
    define( 'SEND_INVITATION_PLUGIN_NAME', trim( dirname(     SEND_INVITATION_PLUGIN_BASENAME ), '/' ) );
}

if ( ! defined( 'SEND_INVITATION_PLUGIN_DIR' ) ) {
    define( 'SEND_INVITATION_PLUGIN_DIR', WP_PLUGIN_DIR . '/' . SEND_INVITATION_PLUGIN_NAME );
}

if ( ! defined( 'SEND_INVITATION_PLUGIN_URL' ) ) {
define( 'SEND_INVITATION_PLUGIN_URL', WP_PLUGIN_URL . '/' . SEND_INVITATION_PLUGIN_NAME );
}

// Version check
global $wp_version;

// Message to send if version is below the required version
$exit_msg = 'Send Invitation requires WordPress or newer' .   SEND_INVITATION_REQUIRED_WP_VERSION . ' <a href="http://codex.wordpress.org/Upgrading_WordPress">Please update!</a>';

if ( version_compare( $wp_version, SEND_INVITATION_REQUIRED_WP_VERSION, "<" ) ) {
    exit( $exit_msg );
}

function add_send_invitation_link() {
    wp_enqueue_script('jquery');
    wp_enqueue_script( 'show_form.js', SEND_INVITATION_PLUGIN_URL . '/js/show_form.js' );
    wp_enqueue_style( 'send-invitation.css', SEND_INVITATION_PLUGIN_URL . '/css/send-invitation.css' );

    # TODO Put this in another file and include it
    $invitation_form = '
    <h1><a href="#" onclick="show_form();">Send Invitation</a></h1>
    <form id="invitation-form" method="post" action="javascript:void(0);">
        <p>
            Your Email Address<br />
            <input type="text" name="email" />
        </p>
        <p>
            ' . "Friend's Email Address" . '<br />
            <input type="text" name="email" />
        </p>
        <p>
            Subject<br />
            <input type="text" name="subject" />
        </p>
        <p>
            Message<br/>
            <textarea rows="10" cols="20"></textarea>
        </p>
        <p><input type="submit" name="submit" value="Send" /></p>
     </form>
     <script type="text/javascript">
          jQuery("#invitation-form").submit(function(){
          alert("got here");
          var str = "this";
          jQuery.ajax("' . SEND_INVITATION_PLUGIN_URL . '/form-processor.php?action=send_email", str, function(result){
        alert(result);
        });
        alert("finished");
        return(false);
    });
   </script>';

   return $invitation_form;
}

function send_email() {
     error_log("Inside send email", 0);
     $subject = 'test';
     $message = 'this is a test from send invitation';
     $to = 'navanitachora@gmail.com';
     wp_mail($to, $subject, $message);
}

?>

I would appreciate any pointers you may have to what I might be doing wrong here.

Thanks in advance.

share|improve this question
    
are you calling that file directly? edit your question with the rest of the code . –  Bainternet Mar 1 '12 at 13:09
    
How do you mean. Do you mean that I should require_once the code for the plugin_basename function. –  navanitachora Mar 1 '12 at 13:30
    
Nope, (how you got that from my comment?) anyway update your question with the code form your plugin file. –  Bainternet Mar 1 '12 at 13:38
    
I have updated code segment with my complete code. Thanks. –  navanitachora Mar 2 '12 at 8:59
add comment

2 Answers

I've encountered this issue a few times before. It's a simple matter of adding this to the top of your plugin beneath the comments block. It appears that the way plugin_basename returns the value doesn't play nicely with much else.

$basename = plugin_basename(__FILE__);

Then replace this line:

define( 'SEND_INVITATION_PLUGIN_BASENAME', plugin_basename(__FILE__) );

With this instead:

define( 'SEND_INVITATION_PLUGIN_BASENAME', $basename );

Updated based on feedback.

So it appears you're not getting accessing to the function plugin_basename, for the sake of a temporary workaround in your plugin add this function.

function the_plugin_basename($file) {
    $file = str_replace('\\','/',$file); // sanitize for Win32 installs
    $file = preg_replace('|/+|','/', $file); // remove any duplicate slash
    $plugin_dir = str_replace('\\','/',WP_PLUGIN_DIR); // sanitize for Win32 installs
    $plugin_dir = preg_replace('|/+|','/', $plugin_dir); // remove any duplicate slash
    $mu_plugin_dir = str_replace('\\','/',WPMU_PLUGIN_DIR); // sanitize for Win32 installs
    $mu_plugin_dir = preg_replace('|/+|','/', $mu_plugin_dir); // remove any duplicate slash
    $file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . preg_quote($mu_plugin_dir, '#') . '/#','',$file); // get relative path from plugins dir
    $file = trim($file, '/');
    return $file;
}

Then in your plugin change any references to the function plugin_basename(), to the_plugin_basename() instead. This will get us past the error of not being able to call that function and with a little luck, we might see another error telling us what is going on.

share|improve this answer
    
Thank you for your reply. There seems to be no change in the error. PHP now complains about this line instead: $basename = plugin_basename(__FILE__);. –  navanitachora Mar 2 '12 at 13:19
    
Hmm, that's interesting. I wonder if there is an issue elsewhere because that function is in wp-includes/plugin.php. I've updated my answer with a temporary workaround. –  DigitalSea Mar 2 '12 at 21:30
    
I investigated further and have concluded that it is a timing issue where the plugin_basename function is not defined by wordpress. The first time the file is used the constant are set. If the file is used again the plugin_basename becomes undefined. The best way is to define the constants in one file keep all other functions elsewhere and use the require keyword. This link helped me understand this. I will have to try out this method but I think it will work. Thanks for everyones' replies. –  navanitachora Mar 3 '12 at 12:05
    
No worries Navanitachora. Please let us know if it works, I've never encountered this issue myself so I'll be just as amazed if it fixes it as you will. –  DigitalSea Mar 4 '12 at 1:31
add comment
up vote 0 down vote accepted

I know its been a while but the answer to the problem above is to create a main file for a plugin and require all related files as required inside that main file. This would avoid the problem because the main file will only be called once and the constants will be defined.

The problem occurs when the file is accessed a second time and the constants are made to initialise a second time which then makes the WP functions undefined. It is also good practice to put all functions related to plugin in a class and then create an object of the class by adding an action that will fire after the init event something like this

add_action('init', array( $this, 'my_plugin_init');

plugin_init will have the code new self; which will inturen call __construct which will initialise all variables. This way the object exists and all functions and constants also exist.

Hope that helps. :-)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.