Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wordpress Plugin Dev : Fatal error: Call to undefined function add_action()

I'm new on plugin development.

I'm try to create a custom Printable form page in wp-admin to create Customer Postal Address.

very Similar This plugin

when administrator click on "print Address" link , pop-up template.php page with customer address and information for print address

enter image description here

The Problem is :

I get fatal Error when click on print order anchor tag and i can't run any wordpress action on template.php:

Fatal error: Call to undefined function add_action() in C:\xampp\htdocs\wp-content\plugins\address generator\template.php on line 4

 <?php
    /**
    * Plugin Name: Address Generator
    * Plugin URI: http://CGTV.ir
    * Description:Generate Postal Label for Parcel
    * Version: 1.0 or 
    * Author: Hamed Mayahian
    * Author URI: CGTV.ir
    * License: A "Slug" license name e.g. GPL12
    */
    // ADDING COLUMN TITLES (Here 2 columns)
    /*define( 'MY_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
    include( MY_PLUGIN_PATH . 'template.php');
    */      

      require_once(ADDRESS__PLUGIN_DIR .'template.php');




    add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column',11);
    function custom_shop_order_column($columns)
    {
       //add columns
        $columns['my-column1'] = __( 'چاپ آدرس','theme_slug');
       return $columns;

    }

    // adding the data for each orders by column (example)
    add_action( 'manage_shop_order_posts_custom_column' , 'cbsp_credit_details', 10, 2 );
    function cbsp_credit_details( $column )
    {
        global $post, $woocommerce, $the_order;
        $order_id = $the_order->id;

        switch ( $column )
        {
            case 'my-column1' :
                $myVarOne = wc_get_order_item_meta( $order_id, '_the_meta_key1', true );
                echo $myVarOne;
                echo "<a target='_blank' href='".plugins_url( 'template.php' , __FILE__ )."?order=$order_id'>Print Address</a>";
                break;


        }
    }

Template.php

<?php


add_action('init', 'my_init', 1);
function my_init(){

    global $post, $woocommerce, $the_order;

    $id = $_GET['order'];
    $order = new WC_Order($id);
    $address    = $order->get_billing_address();

    $customer_id = get_current_user_id();
if($_GET['order'] == "") {
  // no username entered
  echo "آدرس پیدا نشد";
} else {
  echo "Hello, " . $address;
}

}
?>
like image 892
Hamed mayahian Avatar asked Sep 01 '16 19:09

Hamed mayahian


2 Answers

Since I don't know what you are trying to accomplish, I can only suggest the following as an improvement in how you are launching your plugin and how you are displaying the custom column.

/**
 * Plugin Name: Custom Shop Column Link
 * Plugin URI: http://stackoverflow.com/a/39280792/383847
 * Description: Link for shop column to display billing address
 * Version: 1.0.0
 * Author: helgatheviking
 * Author URI: http://kathyisawesome.com/
 * Text Domain: your-plugin
 * Domain Path: /languages
 *
 * Copyright: © 2015 Kathy Darling and Manos Psychogyiopoulos
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 */


// add all your hooks only when woocommerce has fully loaded it's files
add_action( 'woocommerce_loaded', 'custom_address_generator_init' );
function custom_address_generator_init(){
    add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column',11);
    add_action( 'manage_shop_order_posts_custom_column', 'cbsp_credit_details',11);
}

// add your custom column
function custom_shop_order_column($columns)
{
   //add columns
    $columns['my-column1'] = __( 'چاپ آدرس', 'your-plugin');
   return $columns;

}

// adding the data for each orders by column (example)
function cbsp_credit_details( $column )
{
    global $the_order;
    $order_id = $the_order->id;

    switch ( $column )
    {
        case 'my-column1' :
            $myVarOne = get_post_meta( $order_id, '_the_meta_key1', true );
            echo $myVarOne;
            $url = add_query_arg( array( 'order_id' => $order_id, 'my-action' => 'do-something-cool', ), wp_nonce_url( admin_url(), 'my_order_nonce', 'my_nonce' ) );
            printf( '<a class="custom-class" href="%s" data-order_id="%s">%s</a>', $url, $order_id, __( 'Print Address', 'your-plugin' ) );
            break;
    }
}

EDIT 2 We're going to create a link to the front-end so we can load a custom template via template_include. It should have enough security on it to keep it limited to only the appropriate users.

// load a custom template when special link is clicked
add_action( 'template_include', 'my_template', 1 );
function my_template(){

    if( isset( $_GET['my-action'] ) && $_GET['my-action'] == 'do-something-cool' && isset( $_GET['order_id'] ) && current_user_can( 'edit_shop_order', $_GET['order_id'] ) && wp_verify_nonce( $_GET['my_nonce'], 'my_order_nonce' ) ){

        return untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/my-template.php';

    }
}

Then a /templates/my-plugin.php file in your plugin folder:

<?php

$order_id = intval( $_GET['order_id'] );
$order = wc_get_order($order_id);

if( is_a( $order, 'WC_Order' ) ){
    $address    = $order->get_formatted_billing_address ();
    if( $address ){
        printf( '%s, %s', __( 'Hello', 'your-plugin' ), $address );
    } else {
        _e( 'No billing address', 'your-plugin' );
    }
} else {
    _e( 'Not a valid order ID', 'your-plugin' );
}

I've dropped the my_init() function in favor of my_template() which will now load a custom template (/templates/my-template.php) via the template_include filter. This template is loaded by WordPress and has all the WordPress functions available for you to use.

like image 129
helgatheviking Avatar answered Sep 26 '22 23:09

helgatheviking


template.php file is out of Wordpress then we are not access Wordpress core functions. Include this file in main plugin is works properly but when we access by url directly this file then we can't access Wordpress core functions because we are not follow Wordpress stranded. Order list table have button called url generate like something is http://localhost/wp-content/plugins/address%20generator/template.php?order=5147. When we access this get following error "Fatal error: Call to undefined function add_action() in.."

First comment this line in your main plugin file.

 // require_once('template.php');

Changes in template.php file.

<?php

require('../../../wp-load.php');


    $id = $_GET['order'];
    $order = new WC_Order($id);
    $address    = $order->get_billing_address();

    $customer_id = get_current_user_id();
if($_GET['order'] == "") {
  // no username entered
  echo "آدرس پیدا نشد";
} else {
  echo "Hello, " . $address;
}

But this is not a Wordpress stranded solution. User @helgatheviking is provide best solution for this.

like image 45
user5200704 Avatar answered Sep 22 '22 23:09

user5200704