I'm currently building a website with a number of components in Timber, however I have one specific component that breaks the page entirely on mobile and I'm unsure why.
I can only assume it's something to do with either the WP loop or the ajax call. I've never had this issue in the past when running WP loops, however I'm fairly new to Timber itself so I'm wondering whether there is something specific that I'm missing that's Timber-related.
//functions.php
<?php
namespace Flynt\Components\Portfolio;
use Timber\Timber;
const POST_TYPE = 'portfolio';
add_filter('Flynt/addComponentData?name=Portfolio', function ($data) {
$postType = POST_TYPE;
$data['path'] = get_stylesheet_directory_uri() . '/Components/Portfolio';
$data['items'] = Timber::get_posts([
'post_status' => 'publish',
'post_type' => $postType,
'posts_per_page' => -1,
'ignore_sticky_posts' => 1,
'post__not_in' => array(get_the_ID())
]);
$data['go_to_market_options'] = Timber::get_terms([
'taxonomy' => 'Go To Market',
'hide_empty' => true,
'orderby' => 'name',
'order' => 'asc'
]);
$data['funding_stage_options'] = Timber::get_terms([
'taxonomy' => 'Funding Stage',
'hide_empty' => true,
'orderby' => 'name',
'order' => 'asc'
]);
$data['industry_options'] = Timber::get_terms([
'taxonomy' => 'Industry',
'hide_empty' => true,
'orderby' => 'name',
'order' => 'asc'
]);
return $data;
});
function filter_portfolio() {
$context = Timber::get_context();
$context['orderby'] = $_POST['orderby'];
$args = array(
'suppress_filters' => true,
'post_type' => 'portfolio',
'post_status' => 'publish',
'orderby' => $context['orderby'],
'posts_per_page' => -1,
'fields' => 'ids',
'cache_results' => false,
);
if($context['orderby'] == 'name'):
$args['order'] = 'ASC';
endif;
$context['items'] = Timber::get_posts($args);
Timber::render( 'Partials/portfolio-loop.twig', $context );
die();
}
add_action('wp_ajax_filter_portfolio', 'Flynt\Components\Portfolio\filter_portfolio');
add_action('wp_ajax_nopriv_filter_portfolio', 'Flynt\Components\Portfolio\filter_portfolio');
//scripts.js
...
const getPortfolioResults = () => {
$.ajax({
type: "POST",
url: "/wp-admin/admin-ajax.php",
dataType: "html",
data: {
action: "filter_portfolio",
orderby: orderby,
},
success: function (data) {
$loadingIcon.hide();
if (data.length) {
$(data).insertAfter($(".portfolio-grid div#insert"));
}
},
error: function () {
$loadingIcon.hide();
$(".no-results").fadeIn();
},
});
};
...
// portfolio-loop.twig
{% for item in items %}
{% include "Partials/portfolio-item.twig" %}
{% endfor %}
Please accept my apology in advance if my question is long.
I am using a payment gateway of woocommerce.
When click on checkout it goes to an external link. Then there We have button to click and Then It goes to another link which make it enable to pay via cards.
Now What I want to do is that.
I want to minimize some step.
1- If possible I want to bypass detail page which appears after click on Checkout button.
2- Is this possible to hide amount on detail page. As my website currecny is different and this payment gateway the show in different.
3- If above 1,2 not possible. Can simply put external pages in a iframe.
So if user click on check out. It should show a ifram on new page current page with redirected link.
Below code is from gateway plugin.
<?php
add_action( 'plugins_loaded', 'init_pp_woo_gateway');
function mib_ppbycp_settings( $links ) {
$settings_link = 'Setup';
array_push( $links, $settings_link );
return $links;
}
$plugin = plugin_basename( __FILE__ );
add_filter( "plugin_action_links_$plugin", 'mib_ppbycp_settings' );
function init_pp_woo_gateway(){
if ( ! class_exists( 'WC_Payment_Gateway' ) ) return;
class WC_Gateway_MIB_PayPro extends WC_Payment_Gateway {
// Logging
public static $log_enabled = false;
public static $log = false;
var $merchant_id;
var $merchant_password;
var $test_mode;
var $plugin_url;
var $timeout;
var $checkout_url;
var $api_url;
var $timeout_in_days;
public function __construct(){
global $woocommerce;
$this -> plugin_url = WP_PLUGIN_URL . DIRECTORY_SEPARATOR . 'woocommerce-paypro-payment';
$this->id = 'mibwoo_pp';
$this->has_fields = false;
$this->checkout_url = 'https://marketplace.paypro.com.pk/';
$this->icon = 'https://thebalmainworld.com/wp-content/uploads/2020/10/Credit-Card-Icons-copy-1.png';
$this->method_title = 'Paypro';
$this->method_description = 'Pay via Debit/Credit card.';
$this->title = "Paypro";
$this->description = "Pay via Debit/Credit card.";
$this->merchant_id = $this->get_option( 'merchant_id' );
$this->merchant_password = trim($this->get_option( 'merchant_password' ));
$this->merchant_secret = $this->get_option( 'merchant_secret' );
$this->test_mode = $this->get_option('test_mode');
$this->timeout_in_days = $this->get_option('timeout_in_days');
$this->debug = $this->get_option('debug');
$this->pay_method = "Paypro";
if($this->timeout_in_days==='yes'){
$this->timeout = trim($this->get_option( 'merchant_timeout_days' ));
}
else{
$this->timeout = trim($this->get_option( 'merchant_timeout_minutes' ));
}
if($this->test_mode==='yes'){
$this->api_url = 'https://demoapi.paypro.com.pk';
}
else{
$this->api_url = 'https://api.paypro.com.pk';
}
$this->init_form_fields();
$this->init_settings();
self::$log_enabled = $this->debug;
// Save options
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
// Payment listener/API hook
add_action( 'woocommerce_api_wc_gateway_mib_paypro', array( $this, 'paypro_response' ) );
}
function init_form_fields(){
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Yes', 'woocommerce' ),
'default' => 'yes'
),
'merchant_id' => array(
'title' => __( 'Merchant Username', 'woocommerce' ),
'type' => 'text',
'description' => __( 'This Merchant Username Provided by PayPro', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
),
'test_mode' => array(
'title' => __( 'Enable Test Mode', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Yes', 'woocommerce' ),
'default' => 'yes'
),
'merchant_password' => array(
'title' => __( 'Merchant Password', 'woocommerce' ),
'type' => 'password',
'description' => __( 'Merchant Password Provided by PayPro', 'woocommerce' ),
'default' => __( '', 'woocommerce' ),
'desc_tip' => true,
),
'merchant_secret' => array(
'title' => __( 'Secret Key', 'woocommerce' ),
'type' => 'password',
'description' => __( 'Any Secret Key Or Word with No Spaces', 'woocommerce' ),
'default' => __( rand(), 'woocommerce' ),
'desc_tip' => true,
),
'merchant_timeout_minutes' => array(
'title' => __( 'Timeout (In Minutes)', 'woocommerce' ),
'type' => 'number',
'description' => __( 'Timeout Before order expires it can be between 5 to 30 minutes', 'woocommerce' ),
'default' => __( 5, 'woocommerce' ),
'desc_tip' => true,
'custom_attributes' => array(
'min' => 5,
'max' => 30
)
),
'timeout_in_days' => array(
'title' => __( 'Enable Timeout in days', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Yes', 'woocommerce' ),
'default' => 'no'
),
'merchant_timeout_days' => array(
'title' => __( 'Timeout (In Days)', 'woocommerce' ),
'type' => 'number',
'description' => __( 'Minimum 1 day Max 3 Days. Remember, It works as due date you\'ve selected 1 day the expiration date of the PayPro id will be set as the day after today.', 'woocommerce' ),
'default' => __( 1, 'woocommerce' ),
'desc_tip' => true,
'custom_attributes' => array(
'min' => 1,
'max' => 3
)
),
'debug' => array(
'title' => __( 'Debug Log', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable logging', 'woocommerce' ),
'default' => 'no',
'description' => sprintf( __( 'Debug Information <em>%s</em>', 'woocommerce' ), wc_get_log_file_path( 'paypro' ) )
),
);
}
/**
* Logging method
* #param string $message
*/
public static function log( $message ) {
if ( self::$log_enabled ) {
if ( empty( self::$log ) ) {
self::$log = new WC_Logger();
}
$message = is_array($message) ? json_encode($message) : $message;
self::$log->add( 'paypro', $message );
}
}
/**
* Process the payment and return the result
*
* #access public
* #param int $order_id
* #return array
*/
function process_payment( $order_id ) {
$order = new WC_Order( $order_id );
$paypro_args = $this->get_paypro_args( $order );
$paypro_args = http_build_query( $paypro_args, '', '&' );
$this->log("========== Payment Processing Started: args =========");
$this->log($paypro_args);
//if demo is enabled
$checkout_url = $this->checkout_url;;
return array(
'result' => 'success',
// 'redirect' => 'http://localhost:8000/secureform?'.$paypro_args
'redirect' => 'https://marketplace.paypro.com.pk/secureform?'.$paypro_args
);
}
/**
* Get PayPro Args for passing to PP
*
* #access public
* #param mixed $order
* #return array
*/
function get_paypro_args( $order ) {
global $woocommerce;
$order_id = $order->get_id();
//Encrypting the username and password
$token1 = $this->merchant_id;
$token2 = $this->merchant_password;
$cipher_method = 'aes-128-ctr';
$secret_word = md5($this->merchant_secret);
$enc_key = openssl_digest($secret_word.date('d/m/y'), 'SHA256', TRUE);
$enc_iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher_method));
$crypted_token1 = openssl_encrypt($token1, $cipher_method, $enc_key, 0, $enc_iv) . "::" . bin2hex($enc_iv);
$crypted_token2 = openssl_encrypt($token2, $cipher_method, $enc_key, 0, $enc_iv) . "::" . bin2hex($enc_iv);
unset($token, $cipher_method, $enc_key, $enc_iv);
// PayPro Args
$paypro_args = array(
'mid' => $crypted_token1,
'mpw' => $crypted_token2,
'secret_public' => base64_encode($this->merchant_secret),
'is_encrypted' => 1,
'mode' => $this->test_mode,
'timeout_in_days' => $this->timeout_in_days,
'merchant_order_id' => $order_id,
'merchant_name' => get_bloginfo( 'name' ),
'request_is_valid' => 'true',
'request_from' => 'woocommerce',
// Billing Address info
'first_name' => $order->get_billing_first_name(),
'last_name' => $order->get_billing_last_name(),
'street_address' => $order->get_billing_address_1(),
'street_address2' => $order->get_billing_address_2(),
'city' => $order->get_billing_city(),
'state' => $order->get_billing_state(),
'zip' => $order->get_billing_postcode(),
'country' => $order->get_billing_country(),
'email' => $order->get_billing_email(),
'phone' => $order->get_billing_phone(),
);
if (!function_exists('is_plugin_active')) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
if(is_plugin_active( 'custom-order-numbers-for-woocommerce/custom-order-numbers-for-woocommerce.php' )){
$paypro_args['paypro_order_id'] = time().'-'.get_option( 'alg_wc_custom_order_numbers_counter', 1 );
}
else{
$paypro_args['paypro_order_id'] = time().'-'.$order_id;
}
// Shipping
if ($order->needs_shipping_address()) {
$paypro_args['ship_name'] = $order->get_shipping_first_name().' '.$order->get_shipping_last_name();
$paypro_args['company'] = $order->get_shipping_company();
$paypro_args['ship_street_address'] = $order->get_shipping_address_1();
$paypro_args['ship_street_address2'] = $order->get_shipping_address_2();
$paypro_args['ship_city'] = $order->get_shipping_city();
$paypro_args['ship_state'] = $order->get_shipping_state();
$paypro_args['ship_zip'] = $order->get_shipping_postcode();
$paypro_args['ship_country'] = $order->get_shipping_country();
}
$paypro_args['x_receipt_link_url'] = $this->get_return_url( $order );
$paypro_args['request_site_url'] = get_site_url();
$paypro_args['request_site_checkout_url'] = wc_get_checkout_url();
$paypro_args['return_url'] = $order->get_cancel_order_url();
$paypro_args['issueDate'] = date('d/m/Y');
$paypro_args['cartTotal'] = $order->get_total();
$paypro_args['store_currency'] = get_woocommerce_currency();
$paypro_args['store_currency_symbol'] = get_woocommerce_currency_symbol();
//Getting Cart Items
$billDetails= array();
$flag = 0;
foreach ($order->get_items() as $item => $values){
// Get the product name
$product_name = $values['name'];
// Get the item quantity
$item_quantity = $order->get_item_meta($item, '_qty', true);
// Get the item line total
$item_total = $order->get_item_meta($item, '_line_total', true);
$price = $item_total/$item_quantity;
$billDetails[$flag]['LineItem'] = esc_html($product_name);
$billDetails[$flag]['Quantity'] = $item_quantity;
$billDetails[$flag]['UnitPrice'] = $price;
$billDetails[$flag++]['SubTotal'] = $item_total;
}
$paypro_args['cartItemList'] = urlencode(json_encode($billDetails));
////
//setting payment method
if ($this->pay_method)
$paypro_args['pay_method'] = $this->pay_method;
//if test_mode is enabled
if ($this -> test_mode == 'yes'){
$paypro_args['test_mode'] = 'Y';
}
//if timeout_in_days is enabled
if ($this -> timeout_in_days == 'yes'){
$paypro_args['timeout'] = $this->timeout;
}
else{
$paypro_args['timeout'] = $this->timeout*60;
}
$paypro_args = apply_filters( 'woocommerce_paypro_args', $paypro_args );
return $paypro_args;
}
/**
* this function is return product object for two
* different version of WC
*/
function get_product_object(){
return $product;
}
/**
* Check for PayPro IPN Response
*
* #access public
* #return void
*/
function paypro_response() {
global $woocommerce;
// woocommerce_log($_REQUEST);
$this->log(__("== INS Response Received == ", "PayPro") );
$this->log( $_REQUEST );
$wc_order_id = '';
if( !isset($_REQUEST['merchant_order_id']) ) {
if( !isset($_REQUEST['vendor_order_id']) ) {
$this->log( '===== NO ORDER NUMBER FOUND =====' );
exit;
} else {
$wc_order_id = $_REQUEST['vendor_order_id'];
}
} else {
$wc_order_id = $_REQUEST['merchant_order_id'];
}
$this->log(" ==== ORDER -> {$wc_order_id} ====");
// echo $wc_order_id;
$wc_order_id = apply_filters('woocommerce_order_no_received', $wc_order_id, $_REQUEST);
$this->log( "Order Received ==> {$wc_order_id}" );
// exit;
$wc_order = new WC_Order( absint( $wc_order_id ) );
$this->log("Order ID {$wc_order_id}");
$this->log("WC API ==> ".$_GET['wc-api']);
// If redirect after payment
if( isset($_GET['key']) && (isset($_GET['wc-api']) && strtolower($_GET['wc-api']) == 'wc_gateway_mib_paypro') ) {
$this->verify_order_by_hash($wc_order_id);
exit;
}
$message_type = isset($_REQUEST['message_type']) ? $_REQUEST['message_type'] : '';
$sale_id = isset($_REQUEST['sale_id']) ? $_REQUEST['sale_id'] : '';
$invoice_id = isset($_REQUEST['invoice_id']) ? $_REQUEST['invoice_id'] : '';
$fraud_status = isset($_REQUEST['fraud_status']) ? $_REQUEST['fraud_status'] : '';
$this->log( "Message Type/Fraud Status: {$message_type}/{$fraud_status}" );
switch( $message_type ) {
case 'ORDER_CREATED':
$wc_order->add_order_note( sprintf(__('ORDER_CREATED with Sale ID: %d', 'woocommerce'), $sale_id) );
$this->log(sprintf(__('ORDER_CREATED with Sale ID: %d', 'woocommerce'), $sale_id));
break;
case 'FRAUD_STATUS_CHANGED':
if( $fraud_status == 'pass' ) {
// Mark order complete
$wc_order->payment_complete();
$wc_order->add_order_note( sprintf(__('Payment Status Clear with Invoice ID: %d', 'woocommerce'), $invoice_id) );
$this->log(sprintf(__('Payment Status Clear with Invoice ID: %d', 'woocommerce'), $invoice_id));
add_action('woocommerce_order_completed', $order, $sale_id, $invoice_id);
} elseif( $fraud_status == 'fail' ) {
$wc_order->update_status('failed');
$wc_order->add_order_note( __("Payment Declined", 'woocommerce') );
$this->log( __("Payment Declined", 'woocommerce') );
}
break;
}
exit;
}
function verify_order_by_hash($wc_order_id) {
global $woocommerce;
#ob_clean();
$paypro_id = $_REQUEST['paypro_id'];
$tpaycode = $_REQUEST['tpaycode'];
$order_id = $_REQUEST['merchant_order_id'];
$wc_order = wc_get_order( $wc_order_id );
// $order_total = isset($_REQUEST['total']) ? $_REQUEST['total'] : '';
$order_total = $wc_order->get_total();
$compare_string = $this->merchant_id . $paypro_id . $order_total;
$compare_hash1 = strtoupper(md5($compare_string));
$this->log("Compare String ===>" .$compare_string);
$compare_hash2 = $_REQUEST['key'];
if ($compare_hash1 != $compare_hash2) {
$this->log("Hash_1 ==> {$compare_hash1}");
$this->log("Hash_2 ==> {$compare_hash2}");
wp_die( "PayPro Hash Mismatch... check your secret word." );
} else {
//Curl Request
$url = $this->api_url.'/cpay/gos?userName=' . $this->merchant_id . '&password=' . $this->merchant_password . '&cpayId=' . $tpaycode;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
// Submit the GET request
$result = curl_exec($ch);
if (curl_errno($ch)) //catch if curl error exists and show it
echo 'Curl error: ' . curl_error($ch);
else {
//Check if the order ID passed is the same or fake
$res = json_decode($result, true);
$returnedOrderID = explode('-',$res[1]['OrderNumber']);
if ($returnedOrderID[1]===$order_id) {
if (strtoupper($res[1]['OrderStatus']) == "PAID") {
$wc_order->add_order_note( sprintf(__('Payment completed via PayPro Order Number %d', 'paypro'), $tpaycode) );
// Mark order complete
$wc_order->payment_complete();
// Empty cart and clear session
$woocommerce->cart->empty_cart();
$order_redirect = add_query_arg('paypro','processed', $this->get_return_url( $wc_order ));
// Close cURL session handle
curl_close($ch);
wp_redirect( $order_redirect );
exit;
} elseif (strtoupper($res[1]['OrderStatus']) == "BLOCKED") {
$wc_order->add_order_note( sprintf(__('Error processing the payment of Order Number %d', 'paypro'), $tpaycode) );
$order_redirect = add_query_arg('paypro','canceled', $wc_order->get_cancel_order_url());
// Close cURL session handle
curl_close($ch);
wp_redirect( $order_redirect );
exit;
}
elseif (strtoupper($res[1]['OrderStatus']) == "UNPAID") {
$wc_order->add_order_note( sprintf(__('Error processing the payment of Order Number %d', 'paypro'), $tpaycode) );
$order_redirect = add_query_arg('paypro','pending', $wc_order->get_cancel_order_url());
// Close cURL session handle
curl_close($ch);
wp_redirect( $order_redirect );
exit;
}
}
}
}
}
function get_price($price){
$price = wc_format_decimal($price, 2);
return apply_filters('mib_get_price', $price);
}
}
}
function add_mib_payment_gateway( $methods ) {
$methods[] = 'WC_Gateway_MIB_PayPro';
return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'add_mib_payment_gateway' );
function payproco_log( $log ) {
if ( true === WP_DEBUG ) {
if ( is_array( $log ) || is_object( $log ) ) {
$resp = error_log( print_r( $log, true ), 3, plugin_dir_path(__FILE__).'payproco.log' );
} else {
$resp = error_log( $log, 3, plugin_dir_path(__FILE__).'payproco.log' );
}
var_dump($resp);
}
}
I'm using the master card checkout.js method version 57.
There are two types of payments ways.
I want to use only showLightbox() but unfortunately completeCallback() function is not working.
I have tried to find solution but everyone is suggesting to send Interaction.returnUrl parameter in session request but I don't want redirection.
Here is my code,
<script src="https://dohabank.gateway.mastercard.com/checkout/version/57/checkout.js"
data-error="errorCallback"
data-cancel="cancelCallback"
data-beforeRedirect="beforeRedirect"
data-afterRedirect="afterRedirect"
data-complete="completeCallback"
></script>
function completeCallback(resultIndicator, sessionVersion) {
alert(resultIndicator);
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dohabank.gateway.mastercard.com/api/rest/version/57/merchant/TESTDB95810/session",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\r\n \"apiOperation\": \"CREATE_CHECKOUT_SESSION\",\r\n \"interaction\": {\r\n \"operation\": \"PURCHASE\"\r\n },\r\n \"order\" : {\r\n \"amount\" : \"5.10\",\r\n \"currency\" : \"QAR\",\r\n \"description\": \"Ordered goods\",\r\n \"id\": \"5\"\r\n }\r\n}",
CURLOPT_HTTPHEADER => array(
"authorization: Basic Auth Token",
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
// if ($err) {
// echo "cURL Error #:" . $err;
// } else {
// echo $response;
// }
// echo $response;
$object = json_decode($response);
$sessionId = $object->{'session'}->id;
//$sessionSuccess = $object->{'successIndicator'};
//echo $sessionId;
echo $sessionId;
I Found the solution. MerchantId was missing in **Checkout.configure()** method.
I created a custom post type and also a custom taxonomy for that post type. Everything seems to be working... except when I go to create a new post, if I click on "+ Add New Category" it changes the URL, but nothing happens. All the other JS buttons work and it works just fine on regular posts.. not sure why it is doing this. Below is the codes i am using the the functions.php file.
Register Custom Post Type
/* Custom Post Type Galleries */
function bhgallery_register_post_type() {
$singular = 'Gallery';
$plural = 'Galleries';
$labels = array (
'name' => $plural,
'singular' => $singular,
'add_name' => 'Create New',
'add_new_item' => 'Create New ' . $singular,
'edit' => 'Edit',
'edit_item' => 'Edit ' . $singular,
'new_item' => 'New' . $singular,
'view' => 'View' . $singular,
'view_item' => 'View' . $singular,
'search_term' => 'Search ' . $plural,
'parent' => 'Parent ' . $singular,
'not_found' => 'No ' . $plural . ' Found',
'not_found_in_trash' => 'No ' . $plural . ' in Trash'
);
$args = array (
'labels' => $labels,
'public' => true,
'public_queryable' => true,
'exclude_from_search' => false,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 10,
'menu_icon' => 'dashicons-camera',
'can_export' => true,
'delete_with_user' => false,
'hierarchical' => false,
'has_archive' => true,
'query_var' => true,
'capability_type' => 'post',
'map_meta_cap' => true,
// 'capabilities' => array();
'rewrite' => array(
'slug' => 'gallery',
'with_front' => true,
'pages' => true,
'feeds' => false,
),
'supports' => array(
'title',
'thumbnail',
'editor'
)
);
register_post_type( 'bh_gallery', $args );
}
add_action ( 'init', 'bhgallery_register_post_type');
CUSTOM TAXONOMY
/** Custom Categories for Gallery **/
function bhgallery_register_taxonomy() {
$plural = 'Categories';
$singular = 'Category';
$labels = array (
'name' => $plural,
'singular_name' => $singular,
'search_items' => 'Search ' . $plural,
'popular_items' => 'Popular ' . $plural,
'all_items' => 'All ' . $plural,
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => 'Edit ' . $singular,
'update_item' => 'Update ' . $singular,
'add_new_item' => 'Add New ' . $singular,
'new_item_name' => 'New ' . $singular . ' Name',
'separate_items_with_comas' => 'Seperate ' . $singular . ' with commas',
'add_or_remove_items' => 'Add or remove ' . $plural,
'choose_from_most_used' => 'Choose from the most used ' . $plural,
'not_found' => 'No ' . $plural . 'fount',
'menu_name' => $plural,
);
$args = array (
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'update_count_callback' => '_update_post_term_count',
'query_var' => true,
'rewrite' => array( 'slug' => 'categories'),
);
register_taxonomy( 'gallery category', 'bh_gallery', $args );
}
add_action ( 'init', 'bhgallery_register_taxonomy');
If there is anything else you need to know, let me know.
Your second to last line of code above has
register_taxonomy( 'gallery category', 'bh_gallery', $args );
From the codex, register taxonomy, the first argument should not have any spaces. In fact, there are very few places that spaces are ever allowed and they are mainly limited to strings meant for display.
$taxonomy (string) (required) The name of the taxonomy. Name should
only contain lowercase letters and the underscore character, and not
be more than 32 characters long (database structure restriction).
I have a FB app that enable the user to draw shapes and type text on a canvas. The app should have a feature to share what is on canvas on FB as custom story. I was able to do that using PHP SDK.
My question is can I do the same using only JavaScript SDK without any server side code?
Thanks,
Haider
My PHP code is below:
$imgDataBase64 = $_REQUEST["imgBase64"];
$img = str_replace('data:image/png;base64,', '', $imgDataBase64);
$img = str_replace(' ', '+', $img);
$imgData = base64_decode($img);
$pictName = tempnam(sys_get_temp_dir(),"hs").".png";
$ret = file_put_contents($pictName, $imgData);
if ($fbuser) {
try {
$access_token = $facebook->getAccessToken();
$imageURI = $facebook->api(
'me/staging_resources',
'POST',
array(
'file' => "#".$pictName.";type=image/png",
'access_token' => $access_token
)
);
$object = $facebook->api(
'me/objects/testapp:photo',
'POST',
array(
'access_token' => $access_token,
'object' => array(
'app_id' => xxxxxxxxxxxxxxx,
'type' => "testapp:photo",
'title' => "test",
'image' => array (
'url' => $imageURI['uri'],
'user_generated' => true
)
)
)
);
$action = $facebook->api(
'me/testapp:share',
'POST',
array(
'photo' => $object['id'],
'access_token' => $access_token
)
);