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' );
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-]+)/';
I am working with multi file upload with gravity form. So after uploading I want to show the uploaded file in single post page (single.php). How to show the uploaded files in the post page. I have been using this.
(http://pastebin.com/r9w2beDW)
class GW_Multi_File_Merge_Tag {
private static $instance = null;
private $_merge_tag_args = array();
private $_settings = array();
private function __construct() {
add_filter( 'gform_pre_replace_merge_tags', array( $this, 'replace_merge_tag' ), 10, 7 );
}
public static function get_instance() {
if( null == self::$instance )
self::$instance = new self;
return self::$instance;
}
public function get_default_args() {
return array(
'form_id' => false,
'exclude_forms' => array(),
'default_markup' => '{filename}.{ext}',
'markup' => array(
array(
'file_types' => array( 'jpg', 'png', 'gif' ),
'markup' => ''
),
array(
'file_types' => array( 'mp4', 'ogg', 'webm' ),
'markup' => '
Your browser does not support the video tag.
'
),
array(
'file_types' => array( 'ogv' ),
'markup' => '
Your browser does not support the video tag.
'
)
)
);
}
public function register_settings( $args = array() ) {
$args = wp_parse_args( $args, $this->get_default_args() );
if( ! $args['form_id'] ) {
$this->_settings['global'] = $args;
} else {
$this->_settings[$args['form_id']] = $args;
}
}
public function replace_merge_tag( $text, $form, $entry, $url_encode, $esc_html, $nl2br, $format ) {
preg_match_all( '/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $text, $matches, PREG_SET_ORDER );
foreach( $matches as $match ) {
$input_id = $match[1];
$field = GFFormsModel::get_field( $form, $input_id );
if( ! $this->is_applicable_field( $field ) )
continue;
if( $format != 'html' ) {
$value = $this->_merge_tag_args['value'];
} else {
if( $entry['id'] == null && is_callable( array( 'GWPreviewConfirmation', 'preview_image_value' ) ) ) {
$files = GWPreviewConfirmation::preview_image_value( 'input_' . $field->id, $field, $form, $entry );
} else {
$value = GFFormsModel::get_lead_field_value( $entry, $field );
$files = empty( $value ) ? array() : json_decode( $value, true );
}
$value = '';
foreach( $files as &$file ){
$value .= $this->get_file_markup( $file, $form['id'] );
}
}
$text = str_replace( $match[0], $value, $text );
}
return $text;
}
public function get_file_markup( $file, $form_id ) {
$value = str_replace( " ", "%20", $file );
$file_info = pathinfo( $value );
extract( $file_info ); // gives us $dirname, $basename, $extension, $filename
if( ! $extension )
return $value;
$markup_settings = $this->get_markup_settings( $form_id );
if( empty( $markup_settings ) )
return $value;
$markup_found = false;
foreach( $markup_settings as $file_type_markup ) {
$file_types = array_map( 'strtolower', $file_type_markup['file_types'] );
if( ! in_array( strtolower( $extension ), $file_types ) )
continue;
$markup_found = true;
$markup = $file_type_markup['markup'];
$tags = array(
'{url}' => $file,
'{filename}' => $filename,
'{basename}' => $basename,
'{ext}' => $extension
);
foreach( $tags as $tag => $tag_value ) {
$markup = str_replace( $tag, $tag_value, $markup );
}
$value = $markup;
break;
}
if( ! $markup_found && $default_markup = $this->get_default_markup( $form_id ) ) {
$tags = array(
'{url}' => $file,
'{filename}' => $filename,
'{basename}' => $basename,
'{ext}' => $extension
);
foreach( $tags as $tag => $tag_value ) {
$default_markup = str_replace( $tag, $tag_value, $default_markup );
}
$value = $default_markup;
}
return $value;
}
public function get_markup_settings( $form_id ) {
$form_markup_settings = rgars( $this->_settings, "$form_id/markup" ) ? rgars( $this->_settings, "$form_id/markup" ) : array();
$global_markup_settings = rgars( $this->_settings, 'global/markup' ) ? rgars( $this->_settings, 'global/markup' ) : array();
return array_merge( $form_markup_settings, $global_markup_settings );
}
public function get_default_markup( $form_id ) {
$default_markup = rgars( $this->_settings, "$form_id/default_markup" );
if( ! $default_markup )
$default_markup = rgars( $this->_settings, 'global/default_markup' );
return $default_markup;
}
public function is_excluded_form( $form_id ) {
$has_global_settings = isset( $this->_settings['global'] );
$excluded_forms = (array) rgars( $this->_settings, 'global/exclude_forms' );
$explicity_excluded = $has_global_settings && in_array( $form_id, $excluded_forms );
$passively_excluded = ! $has_global_settings && ! isset( $this->_settings[$form_id] );
return $explicity_excluded || $passively_excluded;
}
public function is_applicable_field( $field ) {
$is_valid_form = ! $this->is_excluded_form( $field['formId'] );
$is_file_upload_filed = GFFormsModel::get_input_type( $field ) == 'fileupload';
$is_multi = rgar( $field, 'multipleFiles' );
return $is_valid_form && $is_file_upload_filed && $is_multi;
}
}
function gw_multi_file_merge_tag() {
return GW_Multi_File_Merge_Tag::get_instance();
}
gw_multi_file_merge_tag()->register_settings( array(
'form_id' => 1,
'markup' => array(
array(
'file_types' => array( 'jpg', 'jpeg', 'png', 'gif' ),
'markup' => '{filename}'
),
array(
'file_types' => array( 'pdf', 'txt' ),
'markup' => '{filename}{filenam}'
),
array(
'file_types' => array( 'mp4', 'ogg', 'webm' ),
'markup' => 'Your browser does not support the video tag.{filename}'
),
array(
'file_types' => array( 'ogv' ),
'markup' => 'Your browser does not support the video tag.{filename}'
)
)
) );
But cannot show the file or file link in post page. Can anyone help me?
Below is my code for uploading images, creating posts and to fanpage. Auto posting works fine apart from one thing - when images are posted to album, nothing shows up on the fan page timeline. Could you help me resolve the problem or point to some documentation. I have tried to google it, but none of the results from stackoverflow or facebook developer helped me.
$function ips_fanpage_post( $id, $row = false, $force_type = 'post' )
{
require_once( ABS_PATH . '/connect/facebook/facebook.php');
if( !is_array( $row ) )
{
$row = PD::getInstance()->simpleSelect( IPS__FILES, "`id` = '$id'", 1);
if( empty($row) )
{
ips_log( "ips_fanpage_post($id)" );
return;
}
global ${IPS_LNG};
$row['type'] = 'post';
$row['caption'] = ${IPS_LNG}['meta_site_title'];
$row['description'] = 'เยี่ยมไหม แย่ไหม ชอบไหม';
$row['image'] = IMG_LINK . '/' . $row['img_url'];
$row['link'] = seoLink($row['id'], $row['title']);
$row['message'] = 'เยี่ยมไหม แย่ไหม ชอบไหม';
}
$image = null;
if( !empty( $_FILES["file"]["tmp_name"] ) )
{
$image = realpath($_FILES["file"]["tmp_name"]);
}
else
{
if( file_exists( IMG_PATH . '/' . basename( $row['image'] ) ) )
{
$image = IMG_PATH . '/' . basename( $row['image'] );
}
elseif( file_exists( ABS_PATH . '/upload/img_obrazki/' . basename( $row['image'] ) ) )
{
$image = ABS_PATH . '/upload/img_obrazki/' . basename( $row['image'] );
}
elseif( file_exists( ABS_PATH . '/upload/import/' . basename( $row['image'] ) ) )
{
$image = ABS_PATH . '/upload/import/' . basename( $row['image'] );
}
}
if( empty( $image ) )
{
return array('Nie można odnależć określonego obrazka.');
}
$fanpage_id = Config::GET('apps_facebook_fanpageid');
$facebook = new Facebook(array(
'appId' => Config::GET('apps_facebook_appid'),
'secret' => Config::GET('apps_facebook_appsecret'),
'cookie' => true,
'fileUpload' => true
));
if( $row['type'] == 'upload' || $force_type == 'upload' )
{
$params = array(
'access_token' => Config::GET('apps_facebook_token')
);
$accounts = $facebook->api('/me/accounts', 'GET', $params);
foreach($accounts['data'] as $account)
{
if( $account['id'] == $fanpage_id || (isset($account['name']) && $account['name'] == $fanpage_id) )
{
$fanpage_token = $account['access_token'];
}
}
$image = str_replace( '_middle', '', $image );
if( !isset( $fanpage_token ) )
{
ips_log( 'Pusty $fanpage_token, prawdopodobnie nie jest adminem.' );
return false;
}
$params = array(
'message' => 'เยี่ยมไหม แย่ไหม ชอบไหม',
'image' => '#' . $image,
'no_story' => 1,
'aid' => $row['album_id'],
'access_token' => $fanpage_token
);
try
{
$rest = $facebook->api( '$row['album_id']' . '/photos', 'post', $params );
if( $rest )
{
$data = array(
'id' => 'NULL',
'file_id' => $row['album_id'],
'post_id' => $rest['id'],
'title' => $row['title'],
'data' => date("Y-m-d H:i:s"),
'link_post' => 'https://www.facebook.com/photo.php?fbid=' . $rest['id'],
'type' => 'upload'
);
PD::getInstance()->insert("fanpage_post", $data);
return true;
}
ips_log( $rest );
return false;
} catch (FacebookApiException $e) {
ips_log($e);
return $e->getMessage();
}
}
else
{
$image = str_replace( ABS_PATH, substr( ABS_URL, 0 , -1 ), $image );
if( substr( $image, 0 , 4 ) != 'http' )
{
$image = substr( ABS_URL, 0 , -1 ) . $image;
}
$attachment = '{
"name":"คลิกที่นี่ ตอนนี้",
"href":"'. $row['link'] .'",
"caption":"'. $row['caption'] .'",
"description":"'. $row['description'] .'",
"properties":null,
"media":[{
"type":"image",
"src":"' . $image . '",
"href":"' . $row['link'] . '",
}],
"auto_publish":true
}';
try {
$rest = $facebook->api(array(
"uid" => $fanpage_id,
"method" => "stream.publish",
"access_token" => Config::GET('apps_facebook_token'),
"message" => $row['message'],
"attachment" => $attachment,
"caption" => $row['caption']
));
if( $rest )
{
$data = array(
'id' => 'NULL',
'file_id' => $id,
'post_id' => $rest,
'title' => $row['title'],
'data' => date("Y-m-d H:i:s"),
'link_post' => 'https://www.facebook.com/'. str_replace('_', '/posts/', $rest),
'type' => 'post'
);
PD::getInstance()->insert("fanpage_post", $data);
return true;
}
ips_log( $rest );
return false;
} catch (FacebookApiException $e) {
/**
* Błąd zapisany do pliku log
*/
ips_log($e);
return false;
}
}
}
https://developers.facebook.com/docs/reference/api/page/#photos:
no_story: If set to 1, optionally suppresses the feed story that is automatically generated on the page when you upload a photo.