I am trying to create a shortcode to connect to an API but there is a problem with the shortcode. I know that it is because a function is inside a functinon but I can't figure out how to fix. I tried something that didn't work.
// Add Shortcode
function api_test() {
function execute_request( $args ) {
global $base_url;
$target_url = add_query_arg( $args, $base_url );
$data = wp_remote_get( $target_url );
echo '<pre><code>';
print_r( $data['body'] );
echo '<code></pre>';
}
if ( ! current_user_can( 'manage_options' ) ) die();
// API variables, please override
$base_url = 'https://website.com';
$email = 'email#gmail.com';
$product_id = '1146';
$license_key = '0g96b29x5v27fmfnmbr4hxaflky';
$instance = '';
$request = ( isset( $_GET['request'] ) ) ? $_GET['request'] : '';
$links = array(
'check' => 'Check request',
'activation' => 'Activation request',
'deactivation' => 'Deactivation',
'version_check' => 'Version Check',
);
foreach ( $links as $key => $value ) {
echo '' . $value . ' | ';
}
// Valid check request
if ( $request == 'check' ) {
$args = array(
'wc-api' => 'serial-numbers-api',
'request' => 'check',
'email' => $email,
'serial_key' => $license_key,
'product_id' => $product_id
);
echo '<br>';
echo '<br>';
echo '<b>Valid check request:</b><br />';
//execute_request( $args );
$this->execute_request($args);
}
}
add_shortcode( 'api-test', 'api_test' );
Just create execute_request() outside of shortcode.
function execute_request( $args ) {
global $base_url;
$target_url = add_query_arg( $args, $base_url );
$data = wp_remote_get( $target_url );
echo '<pre><code>';
print_r( $data['body'] );
echo '<code></pre>';
}
function api_test() {
if ( ! current_user_can( 'manage_options' ) ) die();
// API variables, please override
$base_url = 'https://website.com';
$email = 'email#gmail.com';
$product_id = '1146';
$license_key = '0g96b29x5v27fmfnmbr4hxaflky';
$instance = '';
$request = ( isset( $_GET['request'] ) ) ? $_GET['request'] : '';
$links = array(
'check' => 'Check request',
'activation' => 'Activation request',
'deactivation' => 'Deactivation',
'version_check' => 'Version Check',
);
foreach ( $links as $key => $value ) {
echo '' . $value . ' | ';
}
// Valid check request
if ( $request == 'check' ) {
$args = array(
'wc-api' => 'serial-numbers-api',
'request' => 'check',
'email' => $email,
'serial_key' => $license_key,
'product_id' => $product_id
);
echo '<br>';
echo '<br>';
echo '<b>Valid check request:</b><br />';
//execute_request( $args );
execute_request($args);
}
}
add_shortcode( 'api-test', 'api_test' );
Missing WP_List_Table Entries Screenshot Here
I'm trying to populate a list table in WordPress using WP_List_Table with country and state codes from WooCommerce, but it seems that either :display(), :prepare-items() or :column_default is failing me. Been staring myself blind for hours and I can't track down what's happening.
The class setup looks as follows:
<?php
if ( ! class_exists( 'WP_List_Table' ) ) {
require_once ABSPATH . 'wp-admin/includes/screen.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
class My_List_Table extends WP_List_Table {
public function __construct() {
parent::__construct(
array(
'singular' => __( 'state', 'my-text-domain' ),
'plural' => __( 'states', 'my-text-domain' ),
'ajax' => false,
)
);
}
public function get_columns() {
$columns = array(
'cb' => '<input type="checkbox" />',
'col_state_name' => __( 'Region Name', 'my-text-domain' ),
'col_state_id' => __( 'Region Code', 'my-text-domain' ),
);
return $columns;
}
public function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'col_state_id':
case 'col_state_name':
return $item[ $column_name ];
default:
return $item;
}
}
public function my_load_states() {
if ( get_option( 'my_countries' ) && get_option( 'my_current_country' ) && get_option( 'my_states_' . get_option( 'my_current_country' ) ) ) {
$states = get_option( 'my_states_' . get_option( 'my_current_country' ) );
update_option( 'myplugin', true );
return $states;
} else {
$states = WC()->countries->get_states( get_option( 'my_current_country' ) );
if ( is_array( $states ) ) {
return $states;
} else {
update_option( 'myplugin', true );
return '';
}
}
}
public function get_states() {
$data = array();
if ( get_option( 'my_states_' . get_option( 'my_current_country' ) ) && ! empty( get_option( 'my_states_' . get_option( 'my_current_country' ) ) ) && get_option( 'my_country' ) && in_array( get_option( 'my_current_country' ), get_option( 'my_countries' ), true ) ) {
$states = get_option( 'my_states_' . get_option( 'my_current_country' ) );
update_option( 'myplugin', true );
} else {
$states = $this->my_load_states();
}
if ( ! empty( $states ) ) {
foreach ( $states as $code => $name ) {
$temp = array(
'col_state_name' => $name,
'col_state_id' => $code,
);
array_push( $data, $temp );
}
return $data;
} else {
return '';
}
}
public function prepare_items() {
$this->_column_headers = $this->get_column_info();
$this->process_bulk_action();
$data = $this->get_states();
if ( ! empty( $data ) && is_array( $data ) ) {
usort( $data, array( &$this, 'usort_reorder' ) );
$per_page = count( $data );
$total_items = count( $data );
}
$current_page = $this->get_pagenum();
if ( is_array( $data ) && count( $data ) > 1 ) {
$found_data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );
} else {
$found_data = $data;
$total_items = 0;
}
$this->set_pagination_args(
array(
'total_items' => $total_items,
'per_page' => $per_page,
)
);
$this->items = $found_data;
}
public function no_items() {
esc_html_e( 'No states avaliable.', 'my-text-domain' );
}
}
I'm initiating things through this:
<?php
class My_Admin {
...
public function my_add_menu_item() {
add_submenu_page(
'woocommerce',
'Locations',
'Locations',
'manage_options',
'my_states',
array( $this, 'my_settings_page' ),
);
}
public function my_settings_page() {
$slp_obj = new My_List_Table();
$slp_obj->prepare_items();
$slp_obj->display();
}
}
?>
I'm developing an extension in Opencart when I try updating existing products with a relationship to some categories, the products get uncategorized and leave their categories although I disabled all kinds of categorizing in product importing or updating.
Here a snippet of product import & update function:
public function format_product( $product, $update = false, $force_update = false ){
if( empty( $product ) ){
return $product;
}
if( !$update || $force_update ){
$temp = array(
'product_description' => array(),
'model' => isset( $product->sku ) ? $product->sku : '',
'sku' => isset( $product->sku ) ? $product->sku : '',
'upc' => '',
'ean' => '',
'jan' => '',
'isbn' => '',
'mpn' => '',
'location' => '',
'price' => '0',
'points' => '',
'tax_class_id' => '0',
'quantity' => '0',
'minimum' => '1',
'subtract' => '1',
'stock_status_id' => '5',
'shipping' => '1',
'date_available' => date( 'Y-m-d', strtotime( '-1 day') ),
'length' => '',
'width' => '',
'height' => '',
'length_class_id' => '1',
'weight' => '',
'weight_class_id' => '1',
'status' => '1',
'sort_order' => '0',
'manufacturer' => '',
'manufacturer_id' => '0',
'product_store' => array(0),
// 'product_category' => array(),
'product_option' => array(),
'image' => '' // This is Pending.
);
// Add to selected stores.
if ( !empty( $this->all_stores ) ) {
$temp['product_store'] = $this->all_stores;
}
$languageCodes = array();
foreach ( $this->languages as $key => $lng ) {
// Check for name in current language.
$lng_code = explode( '-', $lng['code'] );
$lng_code = $lng_code[0];
$name = $product->name;
$description = $product->description;
/*$product_name = array_key_exists( $lng_code, $name ) ? $name[$lng_code] : $name['en'];
$product_desc = array_key_exists( $lng_code, $description ) ? $description[$lng_code] : $description['en'];*/
$product_name = isset( $name->$lng_code ) ? $name->$lng_code : '';
if( empty( $product_name )){
$product_name = isset( $name->en ) ? $name->en : '';
}
/*set url*/
if(version_compare(VERSION, '3.0.0','<') ) {
if(isset($name->en)){
$urlData = $name->en;
}elseif (isset($name->$lng_code)) {
$urlData = $name->en;
}
if(!empty($urlData)){
$url = strtolower($urlData);
$urlKey = str_replace(' ', '-', $url);
$temp['keyword'] = $urlKey;
}
}
/*set url*/
$product_desc = isset( $description->$lng_code ) ? $description->$lng_code : '';
if( empty( $product_desc )){
$product_desc = isset( $description->en ) ? $description->en : '';
}
$temp['product_description'][$lng['language_id']] = array(
'name' => $product_name,
'description' => $product_desc,
'meta_title' => $product_name,
'meta_description' => '',
'meta_keyword' => '',
'tag' => '',
);
$languageCodes[] = $lng_code;
$languageIds[$lng_code] = $lng['language_id'];
}
/*attribute group code*/
if(!empty($languageCodes)){
$language_code = $languageCodes[0];
$attributeGrouplanguageId = $languageIds[$language_code];
}
/*load model*/
if( $this->is_admin ){
$this->load->model('catalog/attribute_group');
}else{
$admin_dir = str_replace( 'system/', 'admin/', DIR_SYSTEM );
require_once $admin_dir . "model/catalog/attribute_group.php";
$this->model_catalog_attribute_group = new ModelCatalogAttributeGroup( $this->registry );
}
/*load model*/
$attribute_group_id = $this->model_extension_module_knawat_dropshipping->getAttributeGroup('knawat');
if(!$attribute_group_id){
/*add attribute set*/
$attributeGroupArray = array();
$attributeGroupArray['sort_order'] = 2;
$attributeGroupArray['attribute_group_description'][$attributeGrouplanguageId] = array(
'name' => 'Knawat'
);
$attribute_group_id = $this->model_catalog_attribute_group->addAttributeGroup($attributeGroupArray);
}
/*add attribute set*/
/*attribute group code*/
/*load model*/
if( $this->is_admin ){
$this->load->model('catalog/attribute');
}else{
$admin_dir = str_replace( 'system/', 'admin/', DIR_SYSTEM );
require_once $admin_dir . "model/catalog/attribute.php";
$this->model_catalog_attribute = new ModelCatalogAttribute( $this->registry );
}
/*load model*/
/*variation array*/
if (isset($product->variations[0]->attributes) && !empty($product->variations[0]->attributes)) {
$attribute = $product->variations[0]->attributes;
if($attribute[0]){
if (isset($attribute[0]->name) || !empty($attribute[0]->name) ) {
$variationdata = (array)$attribute[0]->name;
}
}
}
/*variation array*/
/*attribute code*/
if (isset($product->attributes) && !empty($product->attributes)) {
$subArray = array();
foreach ($product->attributes as $key => $attribute) {
$attributeNames = (array)$attribute->name;
foreach ($attributeNames as $key => $value) {
if(!empty($variationdata[$key]) && !in_array($variationdata[$key], $attributeNames)){
if(in_array($key, $languageCodes)){
$attributeId = $this->model_extension_module_knawat_dropshipping->getAttributeData($value);
if(!$attributeId){
$languageId = $languageIds[$key];
$newArray[$languageId] = array(
'language_id' => $languageId,
'name' => $value
);
}
}
}
}
if(!empty($newArray)){
$subArray['attribute_group_id'] = $attribute_group_id;
$subArray['sort_order'] = 2;
$subArray['attribute_description'] = $newArray;
$this->model_catalog_attribute->addAttribute($subArray);
}
}
}
/*attribute code*/
/*product code*/
if(!empty($product->attributes)){
foreach ($product->attributes as $key => $attribute) {
$attributeNames = (array)$attribute->name;
if($variationdata != $attributeNames){
$productAttributes = array();
foreach ($attributeNames as $key => $value) {
if(in_array($key, $languageCodes)){
$languageId = $languageIds[$key];
if(isset($attribute->options[0]->$key)){
$options = $attribute->options[0]->$key;
}else{
if(isset($attribute->options[0]->en)){
$options = $attribute->options[0]->en;
}else if (isset($attribute->options[0]->ar)) {
$options = $attribute->options[0]->ar;
}else if (isset($attribute->options[0]->tr)){
$options = $attribute->options[0]->tr;
}
}
$attributeId = $this->model_extension_module_knawat_dropshipping->getAttributeData($value);
$productAttributes[$languageId] = array(
'text' => $options
);
$attributeId = (int) $attributeId;
$temp['product_attribute'][] = array(
'attribute_id' => $attributeId,
'product_attribute_description' => $productAttributes
);
}
}
}
}
}
/*product code end*/
/**
* Setup Product Category.
*/
//make products get uncategorized in both import and update.
// if( isset( $product->categories ) && !empty( $product->categories ) ) {
// $new_cats = array();
// foreach ( $product->categories as $category ) {
// if( isset( $category->name ) && !empty( $category->name ) ){
// $new_cats[] = (array)$category->name;
// }
// }
// $temp['product_category'] = $this->model_extension_module_knawat_dropshipping->parse_categories( $new_cats );
// }
/**
* Setup Product Images.
*/
if( isset( $product->images ) && !empty( $product->images ) ) {
$images = (array)$product->images;
$product_sku = isset( $product->sku ) ? $product->sku : '';
$product_images = $this->parse_product_images( $images, $product_sku );
if( !empty( $product_images ) ){
$temp['image'] = $product_images[0];
unset( $product_images[0] );
if( count( $product_images ) > 0 ){
foreach ($product_images as $pimage ) {
$temp_image['image'] = $pimage;
$temp_image['sort_order'] = '0';
$temp['product_image'][] = $temp_image;
}
}
}
}
}else{
$temp = array();
}
if( isset( $product->variations ) && !empty( $product->variations ) ){
$quantity = 0;
$price = $product->variations[0]->sale_price;
if( isset( $product->variations[0]->market_price ) ){
$market_price = $product->variations[0]->market_price;
}
if( empty( $market_price ) ){
$market_price = $price;
}
foreach ( $product->variations as $vvalue ) {
$quantity += $vvalue->quantity;
}
if(isset($product->variations[0]->weight)){
$weight = $product->variations[0]->weight;
$temp['weight'] = $weight;
}
$temp['price'] = $market_price;
$temp['quantity'] = $quantity;
if( $quantity > 0 ){
$temp['stock_status_id'] = '7';
}else{
$temp['stock_status_id'] = '5';
}
if(!empty($price)){
if($price < $market_price){
$temp['product_special'][] = array(
'customer_group_id' => 1,
'price' => $price,
'priority' => 1,
'date_start' => 0000-00-00,
'date_end' => 0000-00-00
);
}
}
$temp['product_option'] = $this->model_extension_module_knawat_dropshipping->parse_product_options( $product->variations, $price,$update );
}
if(!empty($temp['product_option'])){
foreach ($temp['product_option'] as $key) {
$i = 0;
if(isset($key['product_option_value'])){
$j = count($key['product_option_value']);
}else{
$j = 0;
}
foreach ($key['product_option_value'] as $value) {
if($value['quantity'] == 0){
$i++;
}
}
}
if($i == $j){
$temp['stock_status_id'] = '5';
}
}
if(empty($temp['product_option']) && !$update){
$this->log->write("Product Failed , It's variations not available or available with zero quantity, Sku : ".$temp['sku']);
return false;
}
///////////////////////////////////
/////// #TODO Custom Fields ///////
///////////////////////////////////
error_log("Orginal Product: " . json_encode($product));
error_log("temp Product: " . json_encode($temp));
return $temp;
}
If anyone can help me with this problem. Thank you
So the answer to this question is as follows:
editProduct function in CatalogModel class in Opencart removes all relation_id_to_category before beginning to modify an existing product, so in order to not make the attached categories in a product be removed you should comment out this line of code and everything as it should but it may affect other modules working in Opencart so do it at your own risk.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 months ago.
Improve this question
My WordPress website has a Warning on a grid article saying:
preg_match(): Compilation failed: invalid range in character class at offset 12 in wp-content/plugins/js_composer/include/classes/shortcodes/vc-basic-grid.php on line 177
<?php
if ( ! defined( 'ABSPATH' ) ) {
die( '-1' );
}
require_once vc_path_dir( 'SHORTCODES_DIR', 'paginator/class-vc-pageable.php' );
require_once vc_path_dir( 'SHORTCODES_DIR', 'vc-btn.php' );
class WPBakeryShortCode_VC_Basic_Grid extends WPBakeryShortCode_Vc_Pageable {
public $pagable_type = 'grid';
public $items = array();
public static $excluded_ids = array();
protected $element_template = '';
protected static $default_max_items = 1000;
public $post_id = false;
protected $filter_terms;
public $attributes_defaults = array(
'initial_loading_animation' => 'zoomIn',
'full_width' => '',
'layout' => '',
'element_width' => '4',
'items_per_page' => '5',
'gap' => '',
'style' => 'all',
'show_filter' => '',
'filter_default_title' => 'all',
'exclude_filter' => '',
'filter_style' => '',
'filter_size' => 'md',
'filter_align' => '',
'filter_color' => '',
'arrows_design' => '',
'arrows_position' => '',
'arrows_color' => '',
'paging_design' => '',
'paging_color' => '',
'paging_animation_in' => '',
'paging_animation_out' => '',
'loop' => '',
'autoplay' => '',
'post_type' => 'post',
'filter_source' => 'category',
'orderby' => '',
'order' => 'DESC',
'meta_key' => '',
'max_items' => '10',
'offset' => '0',
'taxonomies' => '',
'custom_query' => '',
'data_type' => 'query',
'include' => '',
'exclude' => '',
'item' => 'none',
'grid_id' => '',
// disabled, needed for-BC:
'button_style' => '',
'button_color' => '',
'button_size' => '',
// New button3:
'btn_title' => '',
'btn_style' => 'modern',
'btn_el_id' => '',
'btn_custom_background' => '#ededed',
'btn_custom_text' => '#666',
'btn_outline_custom_color' => '#666',
'btn_outline_custom_hover_background' => '#666',
'btn_outline_custom_hover_text' => '#fff',
'btn_shape' => 'rounded',
'btn_color' => 'blue',
'btn_size' => 'md',
'btn_align' => 'inline',
'btn_button_block' => '',
'btn_add_icon' => '',
'btn_i_align' => 'left',
'btn_i_type' => 'fontawesome',
'btn_i_icon_fontawesome' => 'fa fa-adjust',
'btn_i_icon_openiconic' => 'vc-oi vc-oi-dial',
'btn_i_icon_typicons' => 'typcn typcn-adjust-brightness',
'btn_i_icon_entypo' => 'entypo-icon entypo-icon-note',
'btn_i_icon_linecons' => 'vc_li vc_li-heart',
'btn_i_icon_pixelicons' => 'vc_pixel_icon vc_pixel_icon-alert',
'btn_custom_onclick' => '',
'btn_custom_onclick_code' => '',
// fix template
'page_id' => '',
);
protected $grid_settings = array();
protected $grid_id_unique_name = 'vc_gid'; // if you change this also change in hook-vc-grid.php
function __construct( $settings ) {
parent::__construct( $settings );
$this->attributes_defaults['btn_title'] = __( 'Load more', 'js_composer' );
$this->shortcodeScripts();
}
public function shortcodeScripts() {
parent::shortcodeScripts();
wp_register_script( 'vc_grid-js-imagesloaded', vc_asset_url( 'lib/bower/imagesloaded/imagesloaded.pkgd.min.js' ) );
wp_register_script( 'vc_grid', vc_asset_url( 'js/dist/vc_grid.min.js' ), array(
'jquery',
'underscore',
'vc_pageable_owl-carousel',
'waypoints',
//'isotope',
'vc_grid-js-imagesloaded',
), WPB_VC_VERSION, true );
}
public function enqueueScripts() {
parent::enqueueScripts();
wp_enqueue_script( 'vc_grid-js-imagesloaded' );
wp_enqueue_script( 'vc_grid' );
}
public static function addExcludedId( $id ) {
self::$excluded_ids[] = $id;
}
public static function excludedIds() {
return self::$excluded_ids;
}
/**
* Get shortcode hash by it content and attributes
*
* #param $atts
* #param $content
*
* #deprecated 4.4.3
* #return string
*/
public function getHash( $atts, $content ) {
if ( vc_is_page_editable() || is_preview() ) {
_deprecated_function( 'WPBakeryShortCode_VC_Basic_Grid::getHash', '4.4.3 (will be removed in 4.10)', 'getId resave your grid' );
/* We are in Frontend editor
* We need to send RAW shortcode data, so hash is just json_encode of atts and content
*/
return urlencode( json_encode( array(
'tag' => $this->shortcode,
'atts' => $atts,
'content' => $content,
) ) );
}
/** Else
* We are in preview mode (viewing page).
* So hash is shortcode atts and content hash
*/
return sha1( serialize( array(
'tag' => $this->shortcode,
'atts' => $atts,
'content' => $content,
) ) );
}
public function getId( $atts, $content ) {
if ( vc_is_page_editable() || is_preview() ) {
/* We are in Frontend editor
* We need to send RAW shortcode data, so hash is just json_encode of atts and content
*/
return urlencode( json_encode( array(
'tag' => $this->shortcode,
'atts' => $atts,
'content' => $content,
) ) );
}
$id_pattern = '/' . $this->grid_id_unique_name . '\:([\w\_-]+)/';
$id_value = isset( $atts['grid_id'] ) ? $atts['grid_id'] : '';
preg_match( $id_pattern, $id_value, $id_matches );
$id_to_save = json_encode( array( 'failed_to_get_id' => esc_attr( $id_value ) ) );
if ( ! empty( $id_matches ) ) {
$id_to_save = $id_matches[1];
}
return $id_to_save;
}
/**
* Search in post meta vc_post_settings value
* For shortcode data by hash
*
* #param $page_id
* #param $hash
*
* #deprecated 4.4.3
* #return bool|array
*/
public function findPostShortcodeByHash( $page_id, $hash ) {
_deprecated_function( 'WPBakeryShortCode_VC_Basic_Grid::findPostShortcodeByHash', '4.4.3 (will be removed in 5.3)', 'findPostShortcodeById resave your grid to renew' );
if ( $hash ) {
if ( $this->currentUserCanManage( $page_id ) && preg_match( '/\"tag\"\:/', urldecode( $hash ) ) ) {
return json_decode( urldecode( $hash ), true ); // if frontend, no hash exists - just RAW data
}
$post_meta = get_post_meta( (int) $page_id, '_vc_post_settings' );
if ( is_array( $post_meta ) ) {
foreach ( $post_meta as $meta ) {
if ( isset( $meta['vc_grid'] ) && ! empty( $meta['vc_grid']['shortcodes'] ) && isset( $meta['vc_grid']['shortcodes'][ $hash ] ) ) {
return $meta['vc_grid']['shortcodes'][ $hash ];
}
}
}
}
return false;
}
public function findPostShortcodeById( $page_id, $grid_id ) {
if ( $this->currentUserCanManage( $page_id ) && preg_match( '/\"tag\"\:/', urldecode( $grid_id ) ) ) {
return json_decode( urldecode( $grid_id ), true ); // if frontend, no hash exists - just RAW data
}
$post_meta = get_post_meta( (int) $page_id, '_vc_post_settings' );
if ( is_array( $post_meta ) ) {
foreach ( $post_meta as $meta ) {
if ( isset( $meta['vc_grid_id'] ) && ! empty( $meta['vc_grid_id']['shortcodes'] ) && isset( $meta['vc_grid_id']['shortcodes'][ $grid_id ] ) ) {
return $meta['vc_grid_id']['shortcodes'][ $grid_id ];
}
}
}
return false;
}
private function renderItems() {
$output = $items = '';
$this->buildGridSettings();
$atts = $this->atts;
$settings = $this->grid_settings;
$filter_terms = $this->filter_terms;
$is_end = isset( $this->is_end ) && $this->is_end;
$css_classes = 'vc_grid vc_row' . esc_attr( $atts['gap'] > 0 ? ' vc_grid-gutter-' . (int) $atts['gap'] . 'px' : '' );
if ( is_array( $this->items ) && ! empty( $this->items ) ) {
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-vc-grid-item.php' );
$grid_item = new Vc_Grid_Item();
$grid_item->setGridAttributes( $atts );
$grid_item->setIsEnd( $is_end );
$grid_item->setTemplateById( $atts['item'] );
$output .= $grid_item->addShortcodesCustomCss();
ob_start();
wp_print_styles();
$output .= ob_get_clean();
$attributes = array(
'filter_terms' => $filter_terms,
'atts' => $atts,
'grid_item',
$grid_item,
);
$output .= apply_filters( 'vc_basic_grid_template_filter', vc_get_template( 'shortcodes/vc_basic_grid_filter.php', $attributes ), $attributes );
while ( have_posts() ) {
the_post();
$items .= $grid_item->renderItem( get_post() );
}
wp_reset_postdata();
}
$items = apply_filters( $this->shortcode . '_items_list', $items );
$output .= $this->renderPagination( $atts['style'], $settings, $items, $css_classes );
return $output;
}
public function setContentLimits() {
$atts = $this->atts;
if ( 'ids' === $this->atts['post_type'] ) {
$this->atts['max_items'] = 0;
$this->atts['offset'] = 0;
$this->atts['items_per_page'] = apply_filters( 'vc_basic_grid_max_items', self::$default_max_items );
} else {
$this->atts['offset'] = $offset = isset( $atts['offset'] ) ? (int) $atts['offset'] : $this->attributes_defaults['offset'];
$this->atts['max_items'] = isset( $atts['max_items'] ) ? (int) $atts['max_items'] : (int) $this->attributes_defaults['max_items'];
$this->atts['items_per_page'] = ! isset( $atts['items_per_page'] ) ? (int) $this->attributes_defaults['items_per_page'] : (int) $atts['items_per_page'];
if ( $this->atts['max_items'] < 1 ) {
$this->atts['max_items'] = apply_filters( 'vc_basic_grid_max_items', self::$default_max_items );
}
}
$this->setPagingAll( $this->atts['max_items'] );
}
protected function setPagingAll( $max_items ) {
$atts = $this->atts;
$this->atts['items_per_page'] = $this->atts['query_items_per_page'] = $max_items > 0 ? $max_items : apply_filters( 'vc_basic_grid_items_per_page_all_max_items', self::$default_max_items );
$this->atts['query_offset'] = isset( $atts['offset'] ) ? (int) $atts['offset'] : $this->attributes_defaults['offset'];
}
public function renderAjax( $vc_request_param ) {
$this->items = array(); // clear this items array (if used more than once);
$id = isset( $vc_request_param['shortcode_id'] ) ? $vc_request_param['shortcode_id'] : false;
if ( ! isset( $vc_request_param['page_id'] ) ) {
return json_encode( array( 'status' => 'Nothing found' ) );
}
if ( $id ) {
$shortcode = $this->findPostShortcodeById( $vc_request_param['page_id'], $id );
} else {
/**
* #deprecated since 4.4.3 due to invalid logic in hash algorithm
*/
$hash = isset( $vc_request_param['shortcode_hash'] ) ? $vc_request_param['shortcode_hash'] : false;
$shortcode = $this->findPostShortcodeByHash( $vc_request_param['page_id'], $hash );
}
if ( ! is_array( $shortcode ) ) {
return json_encode( array( 'status' => 'Nothing found' ) );
}
visual_composer()->registerAdminCss();
visual_composer()->registerAdminJavascript();
// Set post id
$this->post_id = (int) $vc_request_param['page_id'];
$shortcode_atts = $shortcode['atts'];
$this->shortcode_content = $shortcode['content'];
$this->buildAtts( $shortcode_atts, $shortcode['content'] );
$this->buildItems();
return $this->renderItems();
}
public function postID() {
if ( false == $this->post_id ) {
$this->post_id = get_the_ID();
}
return $this->post_id;
}
public function buildAtts( $atts, $content ) {
$arr_keys = array_keys( $atts );
for ( $i = 0; $i < count( $atts ); $i ++ ) {
$atts[ $arr_keys[ $i ] ] = html_entity_decode( $atts[ $arr_keys[ $i ] ], ENT_QUOTES, 'utf-8' );
}
if ( isset( $atts['grid_id'] ) && ! empty( $atts['grid_id'] ) ) {
$id_to_save = $this->getId( $atts, $content );
} else {
$hash = $this->getHash( $atts, $content );
}
$atts = $this->convertButton2ToButton3( $atts );
$atts = shortcode_atts( $this->attributes_defaults, vc_map_get_attributes( $this->getShortcode(), $atts ) );
$this->atts = $atts;
if ( isset( $id_to_save ) ) {
$this->atts['shortcode_id'] = $id_to_save;
} else if ( isset( $hash ) ) {
$this->atts['shortcode_hash'] = $hash;
}
$this->atts['page_id'] = $this->postID();
$this->element_template = $content;
// #since 4.4.3
if ( 'custom' === $this->attr( 'post_type' ) ) {
$this->atts['style'] = 'all';
}
}
/**
* Getter attribute.
*
* #param $key
*
* #return mixed|null
*/
public function attr( $key ) {
return isset( $this->atts[ $key ] ) ? $this->atts[ $key ] : null;
}
public function buildGridSettings() {
$this->grid_settings = array(
'page_id' => $this->atts['page_id'],
// used in basic grid for initialization
'style' => $this->atts['style'],
'action' => 'vc_get_vc_grid_data',
);
// used in ajax request for items
if ( isset( $this->atts['shortcode_id'] ) && ! empty( $this->atts['shortcode_id'] ) ) {
$this->grid_settings['shortcode_id'] = $this->atts['shortcode_id'];
} elseif ( isset( $this->atts['shortcode_hash'] ) && ! empty( $this->atts['shortcode_hash'] ) ) {
// #deprecated since 4.4.3
$this->grid_settings['shortcode_hash'] = $this->atts['shortcode_hash'];
}
if ( 'load-more' === $this->atts['style'] ) {
$this->grid_settings = array_merge( $this->grid_settings, array(
// used in dispaly style load more button, lazy, pagination
'items_per_page' => $this->atts['items_per_page'],
'btn_data' => vc_map_integrate_parse_atts( $this->shortcode, 'vc_btn', $this->atts, 'btn' . '_' ),
) );
} elseif ( 'lazy' === $this->atts['style'] ) {
$this->grid_settings = array_merge( $this->grid_settings, array(
'items_per_page' => $this->atts['items_per_page'],
) );
} elseif ( 'pagination' === $this->atts['style'] ) {
$this->grid_settings = array_merge( $this->grid_settings, array(
'items_per_page' => $this->atts['items_per_page'],
// used in pagination style
'auto_play' => $this->atts['autoplay'] > 0 ? true : false,
'gap' => (int) $this->atts['gap'],
// not used yet, but can be used in isotope..
'speed' => (int) $this->atts['autoplay'] * 1000,
'loop' => $this->atts['loop'],
'animation_in' => $this->atts['paging_animation_in'],
'animation_out' => $this->atts['paging_animation_out'],
'arrows_design' => $this->atts['arrows_design'],
'arrows_color' => $this->atts['arrows_color'],
'arrows_position' => $this->atts['arrows_position'],
'paging_design' => $this->atts['paging_design'],
'paging_color' => $this->atts['paging_color'],
) );
}
$this->grid_settings['tag'] = $this->shortcode;
}
// TODO: setter & getter to attributes
public function buildQuery( $atts ) {
// Set include & exclude
if ( 'ids' !== $atts['post_type'] && ! empty( $atts['exclude'] ) ) {
$atts['exclude'] .= ',' . implode( ',', $this->excludedIds() );
} else {
$atts['exclude'] = implode( ',', $this->excludedIds() );
}
if ( 'ids' !== $atts['post_type'] ) {
$settings = array(
'posts_per_page' => $atts['query_items_per_page'],
'offset' => $atts['query_offset'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_key' => in_array( $atts['orderby'], array(
'meta_value',
'meta_value_num',
) ) ? $atts['meta_key'] : '',
'post_type' => $atts['post_type'],
'exclude' => $atts['exclude'],
);
if ( ! empty( $atts['taxonomies'] ) ) {
$vc_taxonomies_types = get_taxonomies( array( 'public' => true ) );
$terms = get_terms( array_keys( $vc_taxonomies_types ), array(
'hide_empty' => false,
'include' => $atts['taxonomies'],
) );
$settings['tax_query'] = array();
$tax_queries = array(); // List of taxnonimes
foreach ( $terms as $t ) {
if ( ! isset( $tax_queries[ $t->taxonomy ] ) ) {
$tax_queries[ $t->taxonomy ] = array(
'taxonomy' => $t->taxonomy,
'field' => 'id',
'terms' => array( $t->term_id ),
'relation' => 'IN',
);
} else {
$tax_queries[ $t->taxonomy ]['terms'][] = $t->term_id;
}
}
$settings['tax_query'] = array_values( $tax_queries );
$settings['tax_query']['relation'] = 'OR';
}
} else {
if ( empty( $atts['include'] ) ) {
$atts['include'] = - 1;
} elseif ( ! empty( $atts['exclude'] ) ) {
$include = array_map( 'trim', explode( ',', $atts['include'] ) );
$exclude = array_map( 'trim', explode( ',', $atts['exclude'] ) );
$diff = array_diff( $include, $exclude );
$atts['include'] = implode( ', ', $diff );
}
$settings = array(
'include' => $atts['include'],
'posts_per_page' => $atts['query_items_per_page'],
'offset' => $atts['query_offset'],
'post_type' => 'any',
'orderby' => 'post__in',
);
$this->atts['items_per_page'] = - 1;
}
return $settings;
}
public function buildItems() {
$this->filter_terms = $this->items = array();
$this->setContentLimits();
$this->addExcludedId( $this->postID() );
if ( 'custom' === $this->atts['post_type'] && ! empty( $this->atts['custom_query'] ) ) {
$query = html_entity_decode( vc_value_from_safe( $this->atts['custom_query'] ), ENT_QUOTES, 'utf-8' );
$post_data = query_posts( $query );
$this->atts['items_per_page'] = - 1;
} elseif ( false !== $this->atts['query_items_per_page'] ) {
$settings = $this->filterQuerySettings( $this->buildQuery( $this->atts ) );
$post_data = query_posts( $settings );
} else {
return;
}
if ( $this->atts['items_per_page'] > 0 && count( $post_data ) > $this->atts['items_per_page'] ) {
$post_data = array_slice( $post_data, 0, $this->atts['items_per_page'] );
}
foreach ( $post_data as $post ) {
$post->filter_terms = wp_get_object_terms( $post->ID, $this->atts['filter_source'], array( 'fields' => 'ids' ) );
$this->filter_terms = wp_parse_args( $this->filter_terms, $post->filter_terms );
$this->items[] = $post;
}
}
public function filterQuerySettings( $args ) {
$defaults = array(
'numberposts' => 5,
'offset' => 0,
'category' => 0,
'orderby' => 'date',
'order' => 'DESC',
'include' => array(),
'exclude' => array(),
'meta_key' => '',
'meta_value' => '',
'post_type' => 'post',
'suppress_filters' => apply_filters( 'vc_basic_grid_filter_query_suppress_filters', true ),
'public' => true,
);
$r = wp_parse_args( $args, $defaults );
if ( empty( $r['post_status'] ) ) {
$r['post_status'] = ( 'attachment' === $r['post_type'] ) ? 'inherit' : 'publish';
}
if ( ! empty( $r['numberposts'] ) && empty( $r['posts_per_page'] ) ) {
$r['posts_per_page'] = $r['numberposts'];
}
if ( ! empty( $r['category'] ) ) {
$r['cat'] = $r['category'];
}
if ( ! empty( $r['include'] ) ) {
$incposts = wp_parse_id_list( $r['include'] );
$r['posts_per_page'] = count( $incposts ); // only the number of posts included
$r['post__in'] = $incposts;
} elseif ( ! empty( $r['exclude'] ) ) {
$r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
}
$r['ignore_sticky_posts'] = true;
$r['no_found_rows'] = true;
return $r;
}
public static function convertButton2ToButton3( $atts ) {
if ( isset( $atts['button_style'] ) || isset( $atts['button_size'] ) || isset( $atts['button_color'] ) ) {
// we use old button 2 attributes:
$style = isset( $atts['button_style'] ) ? $atts['button_style'] : 'rounded';
$size = isset( $atts['button_size'] ) ? $atts['button_size'] : 'md';
$color = isset( $atts['button_color'] ) ? $atts['button_color'] : 'blue';
$oldData = array(
'style' => $style,
'size' => $size,
'color' => str_replace( '_', '-', $color ),
);
// remove attributes on save
$atts['button_style'] = '';
$atts['button_size'] = '';
$atts['button_color'] = '';
$newData = WPBakeryShortCode_VC_Btn::convertAttributesToButton3( $oldData );
foreach ( $newData as $key => $value ) {
$atts[ 'btn_' . $key ] = $value;
}
}
return $atts;
}
}
By removing hyphen the warning disappears but the article grid not display
just place this code ([\w-]+) instead of ([\w_-]+)
it will work.
$id_pattern = '/' . $this->grid_id_unique_name . '\:([\w\_-]+)/';
preg_match( $id_pattern, $id_value, $id_matches );
Apart from the issue you mentioned (or maybe the cause of the issue you mentioned), there is an issue in the way you generate $id_pattern.
It is used as the first argument of preg_match that expects it to be a string containing a valid regular . But, because its value is generated and $this->grid_id_unique_name may contain anything, including characters that have special meaning in regex, $id_pattern may end up containing a string that is not a valid regex.
When you build a regex using dynamic values (user input, values from persistence etc) you need to use preg_quote() to encode the special regex characters properly.
The code should be:
$id_pattern = '/' . preg_quote($this->grid_id_unique_name, '/') . '\:([\w\_-]+)/';
There are other small issues (that does not cause errors) in the fixed part of the regex.
The underscore (_) is not a special character, there is no need to escape it. Even more the underscore is already included in \w (the class word characters - it contains the digits, the letters and the underscore). This renders _ (escaped or not) completely useless.
Other than that, : is a special character in regex only in subpatterns. It does not have any special meaning in this combination. You can safely leave it unescaped.
In the end, the correct generation of $id_pattern is:
$id_pattern = '/' . preg_quote($this->grid_id_unique_name, '/') . ':([\w-]+)/';
So here is shortcode that i can use to output names based on attributes.
For example, [my_site dfd_name="boy"] will output all boys name.
However if I put "girl" in the name attribute, it does not recognize it. ([my_site dfd_name="boy,girl"]).
Here is the full php:
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
function sp_shortcode_listings($atts, $content = null, $code = "") {
global $wp_query;
global $title;
global $active_tab;
global $showposts;
global $sp_taxonomy;
$defaults = array(
'type' => 'grid',
'before' => '',
'after' => '',
'wrap' => 'div',
'title' => '',
'showposts' => '12',
'type'=> 'grid',
);
extract( shortcode_atts( $defaults, $atts ) );
if ($showposts == 12) {
$showposts = isset($_GET['showposts']) ? $_GET['showposts'] : '12';
}
$shorcode = "sc";
if(!empty($atts))
{
foreach ( $atts as $key => $val)
{
if(strstr($key, 'dfd'))
{
$metaquery[] = array(
'key' => $key,
'value' => $val,
'compare' => 'LIKE',
'terms' => explode(',',$val)
);
}
}
}
if(empty($metaquery))
{
$shorcode = "";
}
global $active_tab;
$active_tab = isset( $_GET[ 'type' ] ) ? $_GET[ 'type' ] : $type;
include(my_site_dir . '/archive-filter.php');
global $post;
ob_start();
if ( have_posts() )
{
my_template_property_archive_content_main_shortcode();
}
else
{
echo apply_filters( 'my_site_no_match', 'Sorry, no name matched your criteria' ) ;
}
$output_string = ob_get_contents();
ob_end_clean();
$output = sprintf( '<%4$s class="sp">%1$s%3$s%2$s</%4$s>', $before, $after, $output_string, $wrap );
wp_reset_query();
return $output;
}
add_shortcode("my-listings", "sp_shortcode_listings");
?>
How can I change it so that I can add multiple values in the "dfd" attributes?
Thanks