0

be gentle, I'm pretty new (just over from Joomla).

This is part of an array...

echo '<tr><th>' . esc_html( $item_1_title ) . '</th><td>' . esc_url( wp_get_attachment_url($row['item_code1']) ) . '</td></tr>';

It works fine, but at the front end, the output is plain text. I can't seem to figure out how to render an encoded URL (clickable link).

Should I be using get_attachment_link or 'image source'?

Any help would be gratefully received.

Thanks

Mark

.........

Complete php (pertinent lines; 203, 403, 463)

<?php

if ( ! defined( 'ABSPATH' ) ) { exit; }

/** * Class WC_LD_Code_Assignment * * assign codes when user pruchase a product */ class WC_LD_Code_Assignment {

public function setup() {

    // assign codes on processing or complete order status
    $delivery_order_status = get_option( 'wc_ld_delivery_order_status' );
    $order_status          = ( empty( $delivery_order_status ) ? 'completed' : $delivery_order_status );

    add_action( 'woocommerce_order_status_' . $order_status, array( $this, 'assign_license_codes_to_order' ), 10, 1 );
    add_action( 'woocommerce_order_item_meta_start', array( $this, 'display_license_codes_in_user_account' ), 10, 3 );
    add_action( 'woocommerce_email_after_order_table', array( $this, 'email_after_order_table' ), 100, 4 );
    add_filter( "woocommerce_can_reduce_order_stock", array( $this, 'dont_reduce_order_stock' ), 10, 2 );
    add_action( 'woocommerce_order_status_changed', array( $this, 'manage_stock_for_simple_products' ), 100, 3 );

}

/**
 *
 * As we disabled auto stock reduction for all product
 * here, we reduce order manually for simple products
 *
 * @param $order_id
 * @param $old_status
 * @param $new_status
 *
 * @return bool
 */
public function manage_stock_for_simple_products( $order_id, $old_status, $new_status ) {
    if ( is_object( $order_id ) ) {
        $order_id = $order_id->id;
    }
    // if order stock already reduced
    if ( get_post_meta( $order_id, '_order_stock_reduced', true ) ) {
        return false;
    }


    if ( $new_status == 'processing' || $new_status == 'completed' ) {
        // get the order details
        $order = new WC_Order( $order_id );

        $order_items = $order->get_items();
        $reduced     = false;

        foreach ( $order_items as $item ) {

            $qty = $item['qty'];

            if ( $item['product_id'] > 0 ) {

                $is_license_code = get_post_meta( $item['product_id'], '_wc_ld_license_code', true );


                if ( empty( $is_license_code ) || $is_license_code == 'no' ) {


                    $_product = $order->get_product_from_item( $item );


                    if ( $_product && $_product->exists() && $_product->managing_stock() ) {

                            if(version_compare( WC_VERSION, '3.0.0', '>' )){
                                $new_stock = wc_update_product_stock($item['product_id'], $qty, 'decrease' );
                            }
                            else{
                            $new_stock = $_product->reduce_stock( $qty );
                            }

                        $item_name = $_product->get_sku() ? $_product->get_sku() : $item['product_id'];

                            if ( isset( $item['variation_id'] ) && $item['variation_id'] ) {
                                $order->add_order_note( sprintf( __( 'Item %s variation #%s stock reduced from %s to %s.', 'highthemes' ), $item_name, $item['variation_id'], $new_stock + $qty, $new_stock ) );
                            } else {
                                $order->add_order_note( sprintf( __( 'Item %s stock reduced from %s to %s.', 'highthemes' ), $item_name, $new_stock + $qty, $new_stock ) );
                            }


                        if(version_compare( WC_VERSION, '3.0.0', '>' )){

                        }
                        else{
                        $order->send_stock_notifications( $_product, $new_stock, $item['qty'] );
                        }
                        $reduced = true;

                    }

                }


            }
        }

        if ( $reduced ) {
            add_post_meta( $order_id, '_order_stock_reduced', '1', true );
        }
    }


}

/**
 * @return bool
 *
 * prevent payment proccessing addons to reduce stock. It is done with this plugin
 */
public function dont_reduce_order_stock( $current_value, $order ) {
    return false;
}


/**
 * @param $order
 * @param $sent_to_admin
 * @param $plain_text
 * @param $email
 *
 * included the license codes in the order email sent to the user
 */
public function email_after_order_table( $order, $sent_to_admin, $plain_text, $email ) {
    if ( is_object( $order ) ) {
        $delivery_order_status = get_option( 'wc_ld_delivery_order_status' );
        $order_id = $order->get_id();
        $order_status          = ( empty( $delivery_order_status ) ? 'completed' : $delivery_order_status );
        if ( $order->get_status() ==  $order_status ) {
            echo $this->get_assigned_codes( $order_id );

        }
    }

}

/**
 * @param $order_id
 *
 * get the assigned codes to an order
 *
 * @return string|void
 */
public function get_assigned_codes( $order_id ) {
    if ( is_object( $order_id ) ) {
        $order_id = $order_id->id;
    }

    // get the order details
    $order = new WC_Order( $order_id );

    // check order items to get quantity and product id
    $order_items = $order->get_items();
    $codes_table = '';

    foreach ( $order_items as $key => $value ) {
        if ( ! isset( $value['license_code_ids'] ) ) {
            continue;
        }
        $license_code_ids = is_array($value['license_code_ids']) ?  $value['license_code_ids']: unserialize( $value['license_code_ids'] );

        if ( empty( $license_code_ids ) ) {
            return;
        }

        $product_id = (isset($value['variation_id']) && !empty($value['variation_id'])) ? $value['variation_id'] : $value['product_id'];
        $rows         = WC_LD_Model::get_codes_by_id( implode( ",", $license_code_ids ) );
        $code_1_title = WC_LD_Model::get_code_title( 1, $product_id );
        $code_2_title = WC_LD_Model::get_code_title( 2, $product_id );
        $code_3_title = WC_LD_Model::get_code_title( 3, $product_id );
        $code_4_title = WC_LD_Model::get_code_title( 4, $product_id );
        $code_5_title = WC_LD_Model::get_code_title( 5, $product_id );

        $description = get_post_meta( $value['product_id'], '_wc_ld_product_code_description', true );
        $codes_table .= '<h3>' . $value['name'] . '</h3>';
        $codes_table .= '<div style="padding-bottom:20px;">' . $description . '</div>';

        foreach ( $rows as $row ) {
            $codes_table .= '<table class="td" cellspacing="0" cellpadding="6" style="margin-bottom:20px;width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;" border="1">';
            $codes_table .= ' <tbody>';
            if ( ! empty( $row['license_code1'] ) ) {
                $codes_table .= '<tr><th class="td" scope="col" style="text-align:left;width:40%; background-color:#eeeeee;">' . esc_html( $code_1_title ) . '</th><td class="td" scope="col" style="text-align:left;">' . esc_html( $row['license_code1'] ) . '</td></tr>';
            }

            if ( ! empty( $row['license_code2'] ) ) {
                $codes_table .= '<tr><th class="td" scope="col" style="text-align:left;">' . esc_html( $code_2_title ) . '</th><td class="td" scope="col" style="text-align:left;">' . esc_html( $row['license_code2'] ) . '</td></tr>';
            }

            if ( ! empty( $row['license_code3'] ) ) {
                $codes_table .= '<tr><th class="td" scope="col" style="text-align:left;">' . esc_html( $code_3_title ) . '</th><td class="td" scope="col" style="text-align:left;">' . esc_html( $row['license_code3'] ) . '</td></tr>';
            }

            if ( ! empty( $row['license_code4'] ) ) {
                $codes_table .= '<tr><th class="td" scope="col" style="text-align:left;">' . esc_html( $code_4_title ) . '</th><td class="td" scope="col" style="text-align:left;">' . esc_html( $row['license_code4'] ) . '</td></tr>';
            }
            if ( ! empty( $row['license_code5'] ) ) {
                $codes_table .= '<tr><th class="td" scope="col" style="text-align:left;">' . esc_url( wp_get_attachment_url($code_5_title) ) . '</th><td class="td" scope="col" style="text-align:left;">' . esc_html( $row['license_code5'] ) . '</td></tr>';
            }
            $codes_table .= '</tbody></table>';


        }


    }

    return $codes_table;

}

/**
 * @param $order_id
 *
 * do the license code assignment to order
 */
public function assign_license_codes_to_order( $order_id ) {

    global $wpdb;

    if ( is_object( $order_id ) ) {
        $order_id = $order_id->id;
    }

    // get the order details
    $order = new WC_Order( $order_id );

    // check order items to get quantity and product id
    $order_items = $order->get_items();


    // assign license codes to order items
    foreach ( $order_items as $item_id => $item ) {

        // if there is no code assigned to this order item
        if ( empty( $item['license_code_ids'] ) ) {

            // if product has marked as license code product
            $is_license_code = get_post_meta( $item['product_id'], '_wc_ld_license_code', true );
            if ( empty( $is_license_code ) || $is_license_code == 'no' ) {
                continue;
            }
            $this->assign_license_to_item( $item_id, $item, $order, $order_id );

        }


    }


}

/**
 * @param $item_id
 * @param $item
 * @param $order
 * @param $order_id
 *
 * does the license assignment for each order item
 */
public function assign_license_to_item( $item_id, $item, $order, $order_id ) {
    global $wpdb;

    $product_id = (isset($item['variation_id']) && !empty($item['variation_id'])) ? $item['variation_id'] : $item['product_id'];
    $qty        = $item['qty'];

    // get license codes from databse based on requested qty
    $rows = $wpdb->get_results( "SELECT * FROM {$wpdb->wc_ld_license_codes}
                WHERE product_id = $product_id
                AND license_code1 <> ''
                AND license_status = '0'
                LIMIT $qty" );

    // build an array of license code ids
    foreach ( $rows as $query ) {
        $license_code_ids[] = $query->id;
    }
    // only assign license codes if we have the requested quantity of the item
    if ( count( $license_code_ids ) == $qty ) {

        // save the order id in license codes table
        $this->assign_order_id_to_license_codes( $order_id, $license_code_ids );

        // save the assigned license codes in order item meta
        wc_add_order_item_meta( $item_id, '_license_code_ids', $license_code_ids );

        // change sold license codes status to sold
        WC_LD_Model::change_license_codes_status( implode( $license_code_ids, ',' ), '1' );


        // reduce stock

        $_product = $order->get_product_from_item( $item );

        if ( $_product && $_product->exists() && $_product->managing_stock() ) {

                if(version_compare( WC_VERSION, '3.0.0', '>' ) ){
                    $new_stock = wc_update_product_stock($product_id , $qty, 'decrease' );
                    update_post_meta( $order_id, '_order_stock_reduced', '1', true );
                }
                else{
                    $new_stock = $_product->reduce_stock( $qty );
                    update_post_meta( $order_id, '_order_stock_reduced', '1', true );
                }

            $item_name = $_product->get_sku() ? $_product->get_sku() : $item['product_id'];

            if ( isset( $item['variation_id'] ) && $item['variation_id'] ) {
                $order->add_order_note( sprintf( __( 'Item %s variation #%s stock reduced from %s to %s.',
                    'highthemes' ), $item_name, $item['variation_id'], $new_stock + $qty, $new_stock ) );
            } else {
                $order->add_order_note( sprintf( __( 'Item %s stock reduced from %s to %s.',
                    'highthemes' ),
                    $item_name, $new_stock + $qty, $new_stock ) );
            }

            if(version_compare( WC_VERSION, '3.0.0', '>' )){
            }
            else{
                $order->send_stock_notifications( $_product, $new_stock, $item['qty'] );
            }
        }


    } else {
        $order->add_order_note( sprintf( __( 'Not enough license code available for product <strong>%s</strong>.',
            'highthemes' ),
            $item['name'] ), 1, false );
    }


}

/**
 * @param $order_id
 * @param $license_code_ids
 *
 * saves order id into license codes table for later usages
 */
public function assign_order_id_to_license_codes( $order_id, $license_code_ids ) {
    global $wpdb;
    $wpdb->query( "UPDATE {$wpdb->wc_ld_license_codes} SET order_id=$order_id
                            WHERE id IN (" . implode( $license_code_ids, ',' ) . ")" );

}

/**
 * @param $item_id
 * @param $item
 * @param $order
 *
 * displays the purchased license codes in my account page
 *
 * @return bool
 */
public function display_license_codes_in_user_account( $item_id, $item, $order ) {

    if ( ! is_account_page() && !is_wc_endpoint_url( 'order-received' ) ) {
        return false;
    }

    if ( empty( $item['license_code_ids'] ) ) {
        return false;
    }


    $license_code_ids = is_array( $item['license_code_ids']) ?  $item['license_code_ids']:unserialize( $item['license_code_ids'] );
    $rows             = WC_LD_Model::get_codes_by_id( implode( ",", $license_code_ids ) );
    $product_id = (isset($item['variation_id']) && !empty($item['variation_id'])) ? $item['variation_id'] : $item['product_id'];
    $code_1_title = WC_LD_Model::get_code_title( 1, $product_id );
    $code_2_title = WC_LD_Model::get_code_title( 2, $product_id );
    $code_3_title = WC_LD_Model::get_code_title( 3, $product_id );
    $code_4_title = WC_LD_Model::get_code_title( 4, $product_id );
    $code_5_title = WC_LD_Model::get_code_title( 5, $product_id );


    // checking the user capability
    echo '<table class="license-codes-table" style="width:100%;">';
    echo ' <tbody>';
    foreach ( $rows as $row ) {
        echo '';
        if ( ! empty( $row['license_code1'] ) ) {
            echo '<tr><th>' . esc_html( $code_1_title ) . '</th><td>' . esc_html( $row['license_code1'] ) . '</td></tr>';
        }

        if ( ! empty( $row['license_code2'] ) ) {
            echo '<tr><th>' . esc_html( $code_2_title ) . '</th><td>' . esc_html( $row['license_code2'] ) . '</td></tr>';
        }

        if ( ! empty( $row['license_code3'] ) ) {
            echo '<tr><th>' . esc_html( $code_3_title ) . '</th><td>' . esc_html( $row['license_code3'] ) . '</td></tr>';
        }

        if ( ! empty( $row['license_code4'] ) ) {
            echo '<tr><th>' . esc_html( $code_4_title ) . '</th><td>' . esc_html( $row['license_code4'] ) . '</td></tr>';
        }
        if ( ! empty( $row['license_code5'] ) ) {
            echo '<tr><th>' . esc_html( $code_5_title ) . '</th><td>' . esc_url( wp_get_attachment_url($row['license_code5']) ) . '</td></tr>';
        }
        echo '<tr class="order-gap"><td colspan="2">&nbsp;</td></tr>';

    }


    echo '</tbody></table>';
}

/**
 * @param $item_id
 * @param $item
 * @param $order
 *
 * displays the purchased license codes in my account page
 *
 * @return bool
 */
public function display_license_codes( $item ) {
    //echo $this->get_assigned_codes(15);
    $license_ids=wc_get_order_item_meta( $item->get_id(), '_license_code_ids' );    
    if ( empty( $license_ids ) ) {
        return false;
    }
    //$license_code_ids=$license_ids;
    $license_code_ids = is_array( $license_ids)
        ? $license_ids
        : unserialize( $license_ids );

    $rows = WC_LD_Model::get_codes_by_id( implode( ",", $license_code_ids ) );
    $product_id = (isset($item['variation_id']) && !empty($item['variation_id']))  ? $item['variation_id'] : $item['product_id'];
    $code_1_title = WC_LD_Model::get_code_title( 1, $product_id);
    $code_2_title = WC_LD_Model::get_code_title( 2, $product_id );
    $code_3_title = WC_LD_Model::get_code_title( 3, $product_id );
    $code_4_title = WC_LD_Model::get_code_title( 4, $product_id );
    $code_5_title = WC_LD_Model::get_code_title( 5, $product_id );


    // checking the user capability
    echo '<table class="license-codes-table" style="width:100%;">';
    echo ' <tbody>';
    foreach ( $rows as $row ) {
        echo '';
        if ( ! empty( $row['license_code1'] ) ) {
            echo '<tr><th>' . esc_html( $code_1_title ) . '</th><td>' . esc_html( $row['license_code1'] ) . '</td></tr>';
        }

        if ( ! empty( $row['license_code2'] ) ) {
            echo '<tr><th>' . esc_html( $code_2_title ) . '</th><td>' . esc_html( $row['license_code2'] ) . '</td></tr>';
        }

        if ( ! empty( $row['license_code3'] ) ) {
            echo '<tr><th>' . esc_html( $code_3_title ) . '</th><td>' . esc_html( $row['license_code3'] ) . '</td></tr>';
        }

        if ( ! empty( $row['license_code4'] ) ) {
            echo '<tr><th>' . esc_html( $code_4_title ) . '</th><td>' . esc_html( $row['license_code4'] ) . '</td></tr>';
        }
        if ( ! empty( $row['license_code5'] ) ) {
            echo '<tr><th>' . esc_html( $code_5_title ) . '</th><td>' . esc_url( wp_get_attachment_url($row['license_code5']) ) . '</td></tr>';
        }
        echo '<tr class="order-gap"><td colspan="2">&nbsp;</td></tr>';

    }


    echo '</tbody></table>';
}


/**
 * @param $code
 *
 * this function used to mask license codes
 *
 * @return string
 */
public function mask_license_code( $code ) {


    if ( is_admin() && ! current_user_can( 'manage_woocommerce' ) ) {
        if ( strlen( $code ) <= 4 ) {
            $padsize = 2;
            $n       = - 2;
        } else {
            $padsize = strlen( $code ) - 4;
            $n       = - 4;
        }

        return str_repeat( '*', $padsize ) . substr( $code, $n );
    } else {
        return $code;

    }


}

}

1

You're onto the answer...

The function, wp_get_attachment_url() (see Codex) just gives you the URL. You could wrap it in a link:

echo '<tr><td><a href="' . esc_attr(wp_get_attachment_url($row['item_code1'])) . '">' . esc_html($item_1_title) . '</a></td></tr>';

Alternately, you can use wp_get_attachment_link() (see Codex) as you mentioned:

echo wp_get_attachment_link($row['item_code1'], 'medium', false, false, esc_html($item_1_title));

Neither is specifically better all the time, it'll depend on what you're doing.

Keep in mind that if you use the first bit of code above, your <a> tag should have an alt attribute. I believe this is for accessibility. You could use the link text, wrapped in esc_attr() for this.

Updated (after added code module)

I've looked at your code.

I must be missing something because I don't see anywhere it's rendering <a> tags. Going with what you're saying, that they're rendered in the front-end HTML, I'd have to guess that someone somewhere has some filter that's modifying what esc_url() does.

Looking at the core code (line 4171), there's one filter, clean_url, that's applied to the output of esc_url() before it returns. It's messy and poor according to WP best practices, but I've seen worse than someone editing that to do something like this. You'd probably have to do a text search on the code base (probably wp-content/plugins, although that could be a lot of code) to find if there's an instance of this filter being hooked. My spidey sense tells me that this isn't the place to start though.

Not to be snarky, and I mean this in the most straightforward way, but I'm not completely sure I understand what you're saying is going wrong. I think you mean that the browser is rendering something like this:

<td>
    <a href="http://domain.com/path-to-something">http://domain.com/path-to-something</a>
</td>

That would seem like the right output to me, but you're asking this question because the output isn't right to you. This leads me to believe that I don't fully understand the question, reinforced by the fact that I don't understand the thing about pasting a URL into a text box.

Could you maybe edit with a snippet of HTML as rendered, and a snippet of HTML as you want it rendered? Given the code you posted, I could try to reconcile the two and see what's going on.

Updated (let's try this)

For starters, welcome to WordPress. Also welcome to WP SE.

(Your code doesn't show in your post with line numbers so please bear with me.)

In the function, get_assigned_codes, try changing this line:

$codes_table .= '<tr><th class="td" scope="col" style="text-align:left;">' . esc_url( wp_get_attachment_url($code_5_title) ) . '</th><td class="td" scope="col" style="text-align:left;">' . esc_html( $row['license_code5'] ) . '</td></tr>';

(it's the third-to-last line in the function that isn't whitespace or curlies) with this:

$codes_table .= '<tr><th class="td" scope="col" style="text-align:left;"><a href="' . esc_attr(esc_url(wp_get_attachment_url($code_5_title))) . '">' . esc_url(wp_get_attachment_url($code_5_title)) . '</a></th><td class="td" scope="col" style="text-align:left;">' . esc_html( $row['license_code5'] ) . '</td></tr>';

To see if that works, you'll have to go to the right place that uses that function and compare the output.

There appear to be a few other places where it's doing about the same thing (hence why you referenced several code lines) but let's try one to see what it does.

If you try that, do you get more of what you want?

Updating (a bit more info but we're onto something)

Try this:

$codes_table .= '<tr><th class="td" scope="col" style="text-align:left;">' . esc_url( wp_get_attachment_url($code_5_title) ) . '</th><td class="td" scope="col" style="text-align:left;"><a href="' . esc_attr( $row['license_code5'] ) . '">' . esc_html($row['license_code5']) . '</a>&nbsp;<a href="' . esc_attr(wp_get_attachment_url($row['license_code5'])) . '">' . esc_html($row['license_code5']) . '</a></td></tr>';

My apologies, the previous suggestion was incorrect. I put the change in the wrong place.

This should print 2 items in the URL field. If either of them is correct, remove the incorrect one and the extra stuff around it. Also, you probably don't need wp_get_attachment_url() in the left-hand field.

17
  • Hi Stephen, thanks very much for the support... The solution worked (kind of) as expected, but on the front end, it's just pulling in the full href, it still won't generate a clickable link... Might it have something to do with charset, or the formatting of the SQL column? - I'm just guessing here. - FYI, the URL in question is just an image uploaded through a pretty typical CMS-type event (adding a product to an inventory), it just seems weird that it's behaviour is so restricted at the front end. - Thanks again – Mark Rogers May 9 '19 at 19:10
  • What's it doing on the front end? Can you take a look at the source HTML and see if it's outputting an <a> tag at all? If it's an encoding issue, you can take care of a lot of that with esc_attr(), or you may need to use some of the mb_ functions. – Stephan Samuel May 9 '19 at 19:16
  • To spare you a life story, it's a WooCommerce order 'details' page... It's a site that sells license codes. - At the front end the HTML is rendering the full HREF (including <a> tags) - I've tried various methods, but it's like trying to paste a link into a plain text field, it just doesn't render. - I've attached the whole module php on my original post... I don't for one minute expect you to go through it in detail, I'm just hoping it might provide a frame of reference (apologies for the impromptu 'break', I think it's because the comment-out is a bit weird) . Thanks so much for your time – Mark Rogers May 9 '19 at 19:32
  • Updated, the code looks like it's doing something different than what you say the output looks like. I'm clearly missing something, hopefully we can get to what that is. – Stephan Samuel May 9 '19 at 20:50
  • Many apologies if I'm not explaining myself properly... Here's an image of the front end domsdailydeals.com/screenshot.png - You'll notice the URL for the image file is called in the 3rd custom field (generated by the plug in). I'm just looking to make this clickable, but maybe there's a filter issue with wp_get_link or something. It's a bit of a mystery, considering, in principle anyway, it should be a pretty basic hack. – Mark Rogers May 9 '19 at 20:53
0

My previous answer wasn't helping. Let me approach this a different way that may be of some use to someone in the future.

You're coming from Joomla. It's been forever since I used it but Google tells me it's based on PHP. WP is somewhat object-oriented but I've seen more non-object-oriented plugins than I've seen object-oriented ones.

So you've got a basis in PHP.

A filter is a thing that lets you modify things at runtime. Filter names are ephemeral but core uses a whole bunch of them. You hook using add_filter() with a priority and a number of arguments. The return value of a filter is always supposed to be of the same type as the first argument, thereby making the remaining arguments modifiers for how the filter is supposed to work. Also, if you call a filter (using apply_filters()) and there are no filters defined, it'll just give you back your argument. add_action() does the same thing without returning a value (PHP void).

The wp_posts table contains stuff. Some CMS systems do it differently but many just use a big flat table like this. The post_type column tells you what kind of post it is, with post (re-use of the name) being a blog and page being a front-end page. You can define custom post types. Additional metadata about a post is stored in wp_postmeta, using the post ID.

(Tables are prefixed and your prefix may not be wp_. The suffix is the same.)

wp_get_attachment_url() takes a post ID and returns the URL of a post of post_type attachment that's associated with that post. (Therefore, attachment is another core post type.) It returns just the URL, not a link. If you want a link, you have to either use wp_get_attachment_link() or draw the link yourself. That's something like this:

?>
    <a href="<?php echo wp_get_attachment_link($id); ?>">link text</a>
<?php

I'm not sure which of your variables contains the post ID and which contains the text to display. This is based on how WooCommerce is set up. In WC (it appears as if you're in Europe so please excuse the abbreviation), products are stored as posts. I forgot the exact post_type and I don't have a WC setup handy. Therefore, you're probably looking for the post ID for a product.

You can use direct database access to get things using the wpdb class but the way you're, "supposed to," do it is with the WP_Query class. Instantiate one with an array like so:

$query = new WP_Query(array('post_type' => 'product', 'nopaging' => true));

Then use $query->posts to get an array of the matched records.

The helper functions esc_html() and esc_attr() escape text for output for element content and attributes, respectively. esc_url() is similar. As with any other CMS, never trust anything that comes from the user (even an admin) or the database. These functions help you wrap it.

You can debug using printf(). print_r() works for arrays and objects. I prefer var_export($object, true) because it always pretty-prints everything. If you can set up your PHP log, error_log() works well (that's what I use). I've never found an IDE that really helps me debug well enough.

That having been said, you're dumping data into an HTML table. Find out (using some debugging method) what your post ID is and what text you want to display. Then use wp_get_attachment_url() with your post ID to get the URL of the image you want to display. If $id has the post ID and $linktext has the link text, do this:

echo '<a href="' . esc_attr(wp_get_attachment_url($id)) . '">' . $linktext . '</a>';

Stick that somewhere into a <th> or <td> and you'll get a clickable link. If you want to display the image, do this:

echo '<img src="' . esc_attr(wp_get_attachment_url($id)) . '" />';

Hopefully, somewhere in there is all you need to get this to work.

1
  • You're nothing short of a superstar, thank you. – Mark Rogers May 9 '19 at 22:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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