title_max_length = absint( $args['title_max_length'] );
}
parent::__construct( $args );
// Add the font icons inline for thumb and product type columns.
self::$table_columns['thumb'] = '';
self::$table_columns['calc_type'] = '';
}
/**
* Generate the table navigation above or below the table
* Just the parent function but removing the nonce fields that are not required here
*
* @since 1.2.5
*
* @param string $which 'top' or 'bottom' table nav.
*/
protected function display_tablenav( $which ) {
// Table nav not needed in reports.
}
/**
* Extra controls to be displayed in table nav sections
*
* @since 1.2.5
*
* @param string $which 'top' or 'bottom' table nav.
*/
protected function extra_tablenav( $which ) {
// Extra table nav not needed in reports.
}
/**
* Generate row actions div
*
* @since 1.2.5
*
* @param array $actions The list of actions.
* @param bool $always_visible Whether the actions should be always visible.
*/
protected function row_actions( $actions, $always_visible = false ) {
// Row actions not needed in reports.
}
/**
* All columns are sortable by default except cb and thumbnail
*
* Optional. If you want one or more columns to be sortable (ASC/DESC toggle),
* you will need to register it here. This should return an array where the
* key is the column that needs to be sortable, and the value is db column to
* sort by. Often, the key and value will be the same, but this is not always
* the case (as the value is a column name from the database, not the list table).
*
* This method merely defines which columns should be sortable and makes them
* clickable - it does not handle the actual sorting. You still need to detect
* the ORDERBY and ORDER querystring variables within prepare_items() and sort
* your data accordingly (usually by modifying your query).
*
* @since 1.2.5
*
* @return array An associative array containing all the columns that should be sortable: 'slugs' => array('data_values', bool)
*/
protected function get_sortable_columns() {
return array();
}
/**
* Loads the current product
*
* @since 1.2.5
*
* @param \WP_Post $item The WooCommerce product post.
*/
public function single_row( $item ) {
$this->product = Helpers::get_atum_product( $item );
$type = $this->product->get_type();
$this->allow_calcs = Helpers::is_inheritable_type( $type ) ? FALSE : TRUE;
$row_style = '';
// mPDF has problems reading multiple classes so we have to add the row bg color inline.
if ( ! $this->allow_calcs ) {
$class_row = '';
if ( 'grouped' === $type ) {
$row_color = '#EFAF00';
}
elseif ( 'bundle' === $type ) {
$row_color = '#96588a';
$class_row = ' main-bundle';
}
else {
$row_color = '#00B8DB';
}
$row_style .= ' style="background-color:' . $row_color . ';" class="expanded' . $class_row . '"';
}
do_action( 'atum/list_table/before_single_row', $item, $this );
echo '
'; // WPCS: XSS ok.
$this->single_row_columns( $item );
echo '
';
do_action( 'atum/list_table/after_single_row', $item, $this );
// Add the children products of each Variable and Grouped product.
if ( ! $this->allow_calcs ) {
$product_class = '\WC_Product_' . ucwords( str_replace( '-', '_', $type ), '_' );
$parent_product = new $product_class( $this->product->get_id() );
if ( 'bundle' === $type ) {
$child_products = Helpers::get_bundle_items( array(
'return' => 'id=>product_id',
'bundle_id' => $this->product->get_id(),
) );
}else {
/* @noinspection PhpUndefinedMethodInspection */
$child_products = $parent_product->get_children();
}
if ( ! empty( $child_products ) ) {
$this->allow_calcs = TRUE;
foreach ( $child_products as $child_id ) {
// Exclude some children if there is a "Views Filter" active.
if ( ! empty( $_REQUEST['view'] ) ) {
$view = esc_attr( $_REQUEST['view'] );
if ( ! in_array( $child_id, $this->id_views[ $view ] ) ) {
continue;
}
}
$this->is_child = TRUE;
$this->product = Helpers::get_atum_product( $child_id );
if ( 'grouped' === $type ) {
$return_type = 'grouped';
}
elseif ( 'bundle' === $type ) {
$return_type = 'bundle-item';
}
else {
$return_type = 'variation';
}
$this->single_expandable_row( $this->product, ( $return_type ) );
}
}
}
// Reset the child value.
$this->is_child = FALSE;
}
/**
* Post title column
*
* @since 1.2.5
*
* @param \WP_Post $item The WooCommerce product post.
*
* @return string
*/
protected function column_title( $item ) {
$title = '';
if ( 'variation' === $this->product->get_type() ) {
$attributes = wc_get_product_variation_attributes( $this->get_current_product_id() );
if ( ! empty( $attributes ) ) {
$title = ucfirst( implode( ' ', $attributes ) );
}
}
else {
$title = $this->product->get_title();
// Limit the title length to 20 characters.
if ( $this->title_max_length && mb_strlen( $title ) > $this->title_max_length ) {
$title = trim( mb_substr( $title, 0, $this->title_max_length ) ) . '...';
}
}
return apply_filters( 'atum/data_export/html_report/column_title', $title, $item, $this->product );
}
/**
* Supplier column
*
* @since 1.3.3
*
* @param \WP_Post $item The WooCommerce product post.
*
* @return string
*/
protected function column__supplier( $item ) {
$supplier = self::EMPTY_COL;
if ( ! AtumCapabilities::current_user_can( 'read_supplier' ) ) {
return $supplier;
}
/* @noinspection PhpUndefinedMethodInspection */
$supplier_id = $this->product->get_supplier_id();
if ( $supplier_id ) {
$supplier_post = get_post( $supplier_id );
if ( $supplier_post ) {
$supplier = $supplier_post->post_title;
}
}
return apply_filters( 'atum/data_export/html_report/column_supplier', $supplier, $item, $this->product );
}
/**
* Column for product type
*
* @since 1.2.5
*
* @param \WP_Post $item The WooCommerce product post.
*
* @return string
*/
protected function column_calc_type( $item ) {
$type = $this->product->get_type();
$product_types = wc_get_product_types();
if ( isset( $product_types[ $type ] ) || $this->is_child ) {
/**
* ATUM icons
*/
$icon_char = 'e9c3';
switch ( $type ) {
case 'simple':
if ( $this->is_child ) {
$type = 'grouped-item';
$icon_char = 'e9c2';
}
elseif ( $this->product->is_downloadable() ) {
$type = 'downloadable';
$icon_char = 'e9c1';
}
elseif ( $this->product->is_virtual() ) {
$type = 'virtual';
$icon_char = 'e9c5';
}
break;
case 'variable':
case 'grouped':
case 'variable-subscription': // WC Subscriptions compatibility.
if ( $this->is_child ) {
$type = 'grouped-item';
$icon_char = 'e9c9';
}
elseif ( $this->product->has_child() ) {
$icon_char = 'grouped' === $type ? 'e9c2' : 'e9c4';
$type .= ' has-child';
}
break;
// WC Bookings compatibility.
case 'booking':
$icon_char = 'e926';
break;
// WC Bundle compatibility.
case 'bundle':
$icon_char = 'e9cf';
break;
}
return apply_filters( 'atum/data_export/html_report/column_type', '' . $icon_char . ';', $item, $this->product );
}
return '';
}
/**
* Column for stock indicators
*
* @since 1.2.5
*
* @param \WP_Post $item The WooCommerce product post to use in calculations.
* @param string $classes
* @param string $data
* @param string $primary
*/
protected function _column_calc_stock_indicator( $item, $classes, $data, $primary ) {
$product_id = $this->product->get_id();
$content = '';
$atum_icons_style = ' style="font-family: atum-icon-font; font-size: 20px;"';
// Add css class to the elements depending on the quantity in stock compared to the last days sales.
if ( ! $this->allow_calcs ) {
$content = self::EMPTY_COL;
}
// Stock not managed by WC.
elseif ( ! $this->product->managing_stock() || 'parent' === $this->product->managing_stock() ) {
$wc_stock_status = $this->product->get_stock_status();
$content = '';
switch ( $wc_stock_status ) {
case 'instock':
$classes .= ' cell-green';
break;
case 'outofstock':
$classes .= ' cell-red';
break;
case 'onbackorder':
$classes .= ' cell-blue';
break;
}
}
// Out of stock.
elseif ( in_array( $product_id, $this->id_views['out_stock'] ) ) {
if ( $this->product->backorders_allowed() ) {
$content = '';
}
else {
$classes .= ' cell-red';
$content = '';
}
}
// Low Stock.
elseif ( in_array( $product_id, $this->id_views['low_stock'] ) ) {
$classes .= ' cell-yellow';
$content = '';
}
// In Stock.
elseif ( in_array( $product_id, $this->id_views['in_stock'] ) ) {
$classes .= ' cell-green';
$content = '';
}
$classes = $classes ? ' class="' . $classes . '"' : '';
echo ' | ' . apply_filters( 'atum/data_export/html_report/column_stock_indicator', $content, $item, $this->product ) . ' | '; // WPCS: XSS ok.
}
/**
* Get an associative array ( id => link ) with the list of available views on this table.
*
* @since 1.2.5
*
* @return array
*/
protected function get_views() {
// Views not needed in reports.
return apply_filters( 'atum/data_export/html_report/views', array() );
}
/**
* Adds the data needed for ajax filtering, sorting and pagination and displays the table
*
* @since 1.2.5
*/
public function display() {
// Add the report template.
ob_start();
parent::display();
// The title column cannot be disabled, so we must add 1 to the count.
$columns = count( self::$table_columns ) + 1;
$max_columns = count( $this->_args['table_columns'] );
$count_views = $this->count_views;
if ( ! empty( $_REQUEST['product_type'] ) ) {
$type = esc_attr( $_REQUEST['product_type'] );
switch ( $type ) {
case 'grouped':
$product_type = __( 'Grouped', ATUM_TEXT_DOMAIN );
break;
case 'variable':
$product_type = __( 'Variable', ATUM_TEXT_DOMAIN );
break;
case 'variable-subscription':
$product_type = __( 'Variable Subscription', ATUM_TEXT_DOMAIN );
break;
case 'simple':
$product_type = __( 'Simple', ATUM_TEXT_DOMAIN );
break;
case 'downloadable':
$product_type = __( 'Downloadable', ATUM_TEXT_DOMAIN );
break;
case 'virtual':
$product_type = __( 'Virtual', ATUM_TEXT_DOMAIN );
break;
// Assuming that we'll have other types in future.
default:
$product_type = ucfirst( $type );
break;
}
}
if ( ! empty( $_REQUEST['product_cat'] ) ) {
$category = ucfirst( esc_attr( $_REQUEST['product_cat'] ) );
}
$report = ob_get_clean();
Helpers::load_view( 'exports/stock-central-html', compact( 'report', 'columns', 'max_columns', 'product_type', 'category', 'count_views' ) );
}
}