Access WordPress widget options on registered sidebars through AJAX - ajax

I am in need to get widget options available in sidebars of WordPress theme.

I have built following code for accessing widget options through ajax.
add_action('wp_ajax_get_sidebar_widget_info', 'get_sidebar_widget_info');
add_action('wp_ajax_nopriv_get_sidebar_widget_info', 'get_sidebar_widget_info');
function get_sidebar_widget_info(){
header('Content-Type: application/Json');
global $wp_registered_widgets;
$response = array();
$sidebars_widget_list = get_option('sidebars_widgets');
unset($sidebars_widget_list['array_version']);
foreach($sidebars_widget_list as $sidebar_id => $widget_list){
foreach($widget_list as $widget_id){
$widget_option_name = $wp_registered_widgets[$widget_id]['callback'][0]->option_name;
$widget_number = $wp_registered_widgets[$widget_id]['params'][0]['number'];
$widget_options = get_option($widget_option_name);
$response[$sidebar_id]['widgets'][$widget_id] = $widget_options[$widget_number];
}
}
echo json_encode($response);
wp_die();
}

Related

Woocommerce - Enable AJAX add to cart buttons only on specific page

On my Woocommerce shop settings I have checked the option:
[✓] Redirect to the cart page after successful addition.
And that's good behaviour for 99% of my shop.
On 1 single page (custom page with custom template) I need to enable Ajax functionality though.
Is there a way to accomplish this task in functions.php?
Ok insert this code into your functions.php. You have to replace the variable $your_ajax_page_slug with the name of your page that you want the redirect to cart functionality to be disabled. Ensure that you have 'Enable AJAX add to cart buttons on archives" checked in settings.
add_filter( 'woocommerce_get_script_data', 'modify_woocommerce_get_script_data', 20, 2 );
function modify_woocommerce_get_script_data ( $params, $handle ) {
global $wp;
$page_slug = '';
$your_ajax_page_slug = 'your-page-slug';
$current_url = home_url( $wp->request );
// Break the URL by the delimiter
$url_pieces = explode('/', $current_url);
// Get the page slug
if( is_array( $url_pieces ) )
$page_slug = end( $url_pieces );
if( $handle == 'wc-add-to-cart' && $page_slug == $your_ajax_page_slug ) {
$params['cart_redirect_after_add'] = false;
}
return $params;
}

cakephp ajax function issue

I have 2 functions in "events" (index, event_ajax)controller in my cakephp(2.5) web site. I'm trying to load HTML block to 'index.ctp' page by calling to 'event_ajax' function using ajax. When I call to this function it shows nothing. Look at 'net' tab in firebug it shows internal server error and 'net'->'Response' tab I can see whole layout is loaded.
I'm little confuse about in this scenario, can any one give a little explanation for following questions??? thanks in advance :)
Is it possible to call actions in same controller using ajax function ??
How 'Response' tab shows layout when '$this->layout' is set to NULL ??
when type url 'example.com/events/event_ajax', output data still '$this->autoRender=false'. how can this happen ??
this is my 'event_ajax' action.
public function event_ajax($x=1) {
$this->layout = NULL;
$this->autoRender = false ;
$contName = $this->Page->conName($x);
$latestContEvents = $this->Page->latestContEvent($x);
$internal = '';
if (!empty($latestContEvents)){
foreach ($latestContEvents AS $latestContEvent){
$internal .= '<li class="pull-left"> <div class="content-wrapper">'..... //do something
}
else {
$internal = '<p> No events found for this continent</p>';
}
$ContEvents = '<div class="carousel events-location-carousel">'.$internal.'</div> ';
return $ContEvents;
// return json_encode($ContEvents);
}
Try with
$this->layout = 'ajax';

How to render banners alongside featured items in home page

I'm making a custom template form joomla 2.5, and one of the goals for the development is to include a banner after each featured article iteration.
After a long research I can render a banner into /template_name/html/com_content/featured/default_item.php with the following code:
$document = JFactory::getDocument();
$renderer = $document->loadRenderer('modules');
$position = "nota";
$options = array('style' => 'raw');
echo $renderer->render($position, $options, null);
But the issue is that each iteration resets the banner list so I have the same banner repeated with each featured article.
I tried to include the banner module using the same code in /template_name/html/com_content/featured/default.php without success. Lately I'd try with <jdoc:include type="modules" name="nota" style="raw" /> and it didn't works too, so I will appreciate any help to solve this point.
Thanks in advance.
You can solve this in two ways.
The right way
Copy and rename the banner module (fx. to mybanners), change the getList() method in the helper file to retrieve different banners on each call. This could fx. be:
class modMybannersHelper
{
static function &getList(&$params)
{
static $index = 0;
JModelLegacy::addIncludePath(JPATH_ROOT.'/components/com_banners/models', 'BannersModel');
$document = JFactory::getDocument();
$app = JFactory::getApplication();
$keywords = explode(',', $document->getMetaData('keywords'));
$model = JModelLegacy::getInstance('Banners', 'BannersModel', array('ignore_request'=>true));
$model->setState('filter.client_id', (int) $params->get('cid'));
$model->setState('filter.category_id', $params->get('catid', array()));
$model->setState('list.limit', 1);
$model->setState('list.start', $index++);
$model->setState('filter.ordering', $params->get('ordering'));
$model->setState('filter.tag_search', $params->get('tag_search'));
$model->setState('filter.keywords', $keywords);
$model->setState('filter.language', $app->getLanguageFilter());
$banners = $model->getItems();
$model->impress();
return $banners;
}
}
This is just a sketch; you still need to handle the case of $index being greater than the number of records.
The hacky way
The retrieval code has only one port open to inject conditions - the documents's keywords.
So you could (in your template file) store the original keywords an replace them with a keyword to identify a banner. The banner must have the same keyword in that case.
$document = JFactory::getDocument();
$keywords = $document->getMetaData('keywords');
$renderer = $document->loadRenderer('modules');
$position = "nota";
$options = array('style' => 'raw');
$document->setMetaData('keywords', 'banner_key');
echo $renderer->render($position, $options, null);
$document->setMetaData('keywords', $keywords);
Either way, caching may prevent that from work, so you might have to turn it off (I didn't check that).

WordPress: snag first image from a gallery

On my homepage, I'm trying to output the first image of each post, and I'm able to successfully do that using this code in my functions.php:
function catch_that_image() {
global $post, $posts;
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
$first_img = $matches [1] [0];
if(empty($first_img)){ //Defines a default image
$first_img = "/images/default.jpg";
}
return $first_img;
}
and then I call it in my loop like this:
<img src=”<?php catch_that_image(); ?>” />
The problem with this method is that it won't work if I place a gallery in that same post. I'm confused because the output of the post still renders the img markup, and my assumption is that catch_that_image() should snag that markup? Is my thinking incorrect? Is there a better way to handle this?
The gallery is placed inside your post using a WordPress short-tag. The shorttag is transformed into HTML-image tags when the filter for transforming the shorttag is applied.
The following might work, but I am not sure:
function catch_that_image() {
global $post, $posts;
$first_img = '';
ob_start();
ob_end_clean();
$transformed_content = apply_filters('the_content',$post->post_content);
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $transformed_content, $matches);
$first_img = $matches [1] [0];
if(empty($first_img)){ //Defines a default image
$first_img = "/images/default.jpg";
}
return $first_img;
}
Please let me know if this was useful or if it was pointing you into the right direction!
Codex Links:
http://codex.wordpress.org/Gallery_Shortcode
http://codex.wordpress.org/Function_Reference/apply_filters
http://codex.wordpress.org/Function_Reference/do_shortcode

Magento custom add to cart process not working

REVISED QUESTION: We have tracked this down to a custom add to cart method. I have completely revised the question.
I am working on a site that is using Magento ver. 1.3.2.4 as its eCommerce platform. We have built a custom "Add To Cart" process which adds multiple items to the cart via an AJAX request. After this request, some postprocessing is done viw JavaScript in the browser before redirecting to the "View Cart" page. 99% of the time this process seems to function properly in Firefox and Safari but in IE8, the process fails. When adding an item to the cart, after being redirected to the "Your Cart" page, the shopping cart is empty.
Not all items on the site are added via this AJAX process. This issue only happens only when the cart is empty before adding the items via AJAX. That is to say, if an item that is added via the normal Magento process is added to the cat first, then the AJAX add to cart requests always succeed. Blu clearing cookies and then attempting to add via AJAX will fail consistently on IE8.
Server is an Apache/PHP server with PHP 5.2.9, eAccelerator and Suhosin. Please request any additional information and I'll be happy to provide it. We are storing sessions in a MySQL Database.
Here is the code for our custom add to cart method. This code is located in /app/code/core/Mage/Checkout/controllers/CartController.php:
public function ajaxaddAction()
{
$result = array('success' => true);
try
{
$session = $this->_getSession();
$cart = $this->_getCart();
$products = json_decode($_POST['products'],true);
if(!is_array($products))
{
throw new Exception("Products data not sent");
}
foreach ($products as $product_data)
{
$product = $this->_initProduct($product_data['id']);
if(!$product)
throw new Exception("Product id {$product_data['id']} not found");
$info = array('qty' => $product_data['qty']);
if($product_data['options'])
$info['options'] = $product_data['options'];
$cart->addProduct($product,$info);
}
$cart->save();
$this->_getSession()->setCartWasUpdated(true);
/**
* #todo remove wishlist observer processAddToCart
*/
Mage::dispatchEvent('checkout_cart_add_product_complete',
array('product' => $products[0], 'request' => $this->getRequest(), 'response' => $this->getResponse())
);
$cartItems = $cart->getQuote()->getAllItems();
$result['cart'] = array();
foreach($cartItems as $item)
$result['cart'][] = json_decode($item->toJson());
}
catch (Mage_Core_Exception $e)
{
if ($this->_getSession()->getUseNotice(true)) {
$this->_getSession()->addNotice($e->getMessage());
} else {
$messages = array_unique(explode("\n", $e->getMessage()));
foreach ($messages as $message) {
$this->_getSession()->addError($message);
}
}
$result['success'] = false;
$result['exception'] = $e->getMessage();
}
catch (Exception $e) {
$this->_getSession()->addException($e, $this->__('Can not add item to shopping cart'));
$result['success'] = false;
$result['exception'] = $e->getMessage();
}
header('Content-Type: application/json',true);
ob_end_clean();
echo json_encode($result);
exit();
}
Please don't answer with "Move the code to the /app/code/local/ directory". I understand that's a better place for it, and will move it there in the future, but unless your answer will solve the issue, please just post a comment. In order to get a faster response I'm starting a bounty and want good answers to this specific issue, not just tips on better ways to integrate this code.
If there's any information I can provide to assist please let me know. We're under a tight deadline...
I've spent over 10 hours on this. For the moment I believe I have a partial solution. But I'm not sure why this solution works...
It seems that Magento requires a redirect in order to complete the add to cart process. So instead of
header('Content-Type: application/json',true);
ob_end_clean();
echo json_encode($result);
exit();
I store my JSON in the session and redirect to a new cart action:
$this->_getSession()->setCartJsonResult(json_encode($result));
$this->_redirect('checkout/cart/postajaxadd');
That action then dumps the JSON data
public function postajaxaddAction()
{
$session = $this->_getSession();
header('Content-Type: application/json',true);
ob_end_clean();
echo $this->_getSession()->getCartJsonResult();
exit();
}
This still fails sometimes; however now my JavaScript code does not get the JSON data it was expecting and is able to repeat the request. The second request is successful more often than the first... However there are still cases when the AJAX requests fail no matter what.
Not sure if this is causing the problems you're running into, but a better way to do a JSON response would be to use the existing "Magento/Zend way" of doing it.
Instead of:
header('Content-Type: application/json',true);
ob_end_clean();
echo json_encode($result);
exit();
Use:
$this->getResponse()->setHeader('Content-Type', 'application/json', true)->setBody(json_encode($result));
We've experienced issues adding things to the cart when session storage runs out and new sessions can't be created. If you're storing sessions on disk or in memcache, check that you've allocated enough space.

Resources