Magento - Enable HTML links in error/custom messages - php

I want to know if this is possible to enable HTML links in custom messages (ie: error messages).
Here is my example:
I've made an override for my needs of Mage_CatalogInventory_Model_Stock_Item/Item.php
Function checkQuoteItemQty :
if (!$this->checkQty($summaryQty) || !$this->checkQty($qty)) {
//$message = Mage::helper('cataloginventory')->__('The requested quantity for "%s" is not available.', $this->getProductName());
$message = Mage::helper('cataloginventory')->__('The requested quantity for "%s" is not available (max:%s).', $this->getProductName(), ($this->getQty() * 1));
$cat_id = $this->getProduct()->getCategoryIds();
if($cat_id){
$url = Mage::getModel('catalog/category')->load($cat_id[0])->getUrl();
$message .= Mage::helper('cataloginventory')->__('You might be interested in those products.', $url);
}
$result->setHasError(true)
->setMessage($message)
->setQuoteMessage($message)
->setQuoteMessageIndex('qty');
return $result;
}
But the HTML link I created in $message is not clickable and considered as text (because of the translation I guess...).
Is it possible to change this behavior?
Regards.

For those who would like to know, I had to override Mage_Core_Block_Messages, line 249 :
public function getGroupedHtml()
{
$types = array(
Mage_Core_Model_Message::ERROR,
Mage_Core_Model_Message::WARNING,
Mage_Core_Model_Message::NOTICE,
Mage_Core_Model_Message::SUCCESS
);
$html = '';
foreach ($types as $type) {
if ( $messages = $this->getMessages($type) ) {
if ( !$html ) {
$html .= '<' . $this->_messagesFirstLevelTagName . ' class="messages">';
}
$html .= '<' . $this->_messagesSecondLevelTagName . ' class="' . $type . '-msg">';
$html .= '<' . $this->_messagesFirstLevelTagName . '>';
foreach ( $messages as $message ) {
$html.= '<' . $this->_messagesSecondLevelTagName . '>';
$html.= '<' . $this->_messagesContentWrapperTagName . '>';
$html.= ($this->_escapeMessageFlag) ? $this->escapeHtml($message->getText()) : html_entity_decode($message->getText());
$html.= '</' . $this->_messagesContentWrapperTagName . '>';
$html.= '</' . $this->_messagesSecondLevelTagName . '>';
}
$html .= '</' . $this->_messagesFirstLevelTagName . '>';
$html .= '</' . $this->_messagesSecondLevelTagName . '>';
}
}
if ( $html) {
$html .= '</' . $this->_messagesFirstLevelTagName . '>';
}
return $html;
}
Adding a html_entity_decode at this line :
$html.= ($this->_escapeMessageFlag) ? $this->escapeHtml($message->getText()) : html_entity_decode($message->getText());
Just let me know if you find a better solution.

I'm not sure why, but in my case, by calling the obsolete method without "Message" solves the issue with the link.
Instead of using addNoticeMessage, I changed to addNotice, and the links appeared.
In my case:
$noticeMsg = __('You must be logged in or registered to purchase these products.',
$this->_storeManager->getStore()->getUrl('customer/account/login'),
$this->_storeManager->getStore()->getUrl('customer/account/create')
);
$this->_messageManager->addNotice($noticeMsg);

Related

Dynamic link with absolute URI gets changed to localhost

$refPointer = $site_to_be_extracted . $a->href;
echo $refPointer . '<br>';
generates in output (Chrome browser):
http://www.hackingwithphp.com/1/1/0/is-this-book-for-you
You would expect the following line to generate a correct <a> tag. That is a correct link
print '<a href=' . $refPointer . '>' . $a . '</a>';
Instead it generates in output:
localhost/1/1/0/is-this-book-for-you
So both the protocol (HTTP) and the $site_to_be_extracted (www.hackingwithphp.com) are lost. And replaced by "localhost"
Why? What could be the problem
This is the function where it's all happening. Now it works fine
include('simple_html_dom.php');
.
.
function createChapterContent ($site_to_be_extracted, $chapter_to_be_extracted) {
$html = file_get_html($chapter_to_be_extracted);
$refPointer;
foreach($html->find('ol') as $ol) {
foreach($ol->find('li') as $li) {
// echo '<br>' . $li->innertext ;
foreach($li->find('a') as $a) {
// Original. Causing the reported problem
// $refPointer = $site_to_be_extracted . $a->href;
// echo $refPointer . '<br>';
// changed to (see below). Now the output is correct
// Why?
$a->href = $site_to_be_extracted . $a->href;
$refPointer = $a->href;
print '<a href=' . $refPointer . '>' . $li->innertext . '</a>' . '<br>';
break;
};
}
}

Additional foreach loops cause PHP to crash with "Allowed memory size exhausted" fatal error

I'm trying to parse products in my company's store for indexing in our Google Base. I was given a .CSV with one column of products and another column of issue for that product. I shouldn't index the products that have particular issues with them.
What I did was create a function that takes .csv and outputs a "nonIndexedProducts" array.
If you're familiar with Google Base (in Opencart) they use a foreach loop to go through and display all the products. I added another foreach loop inside there that goes through each of the "nonIndexProducts" and if the product name matches the nonIndexProduct, I have a conditional statement that doesn't do anything. If the product name doesn't match then it is indexed and displayed.
Now after much tweaking and getting to that point, I'm running into this error:
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 20971484 bytes) in /home/xxxx/public_html/vqmod/vqcache/vq2-catalog_controller_feed_google_base.php on line 31
So I know there's too much going on and obviously I don't want to increase the memory size. I have a couple hundred products and only 160 products that don't need to be indexed. I understand that's still huge though, but what's the best way to go about this?
Here are my loops (but mind you everything else is what Google Base provided for me, I only added the lines where '// I added' is denoted):
public function index() {
if ($this->config->get('google_base_status')) {
$output = '<?xml version="1.0" encoding="UTF-8" ?>';
$output .= '<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">';
$output .= '<channel>';
$output .= '<title>' . $this->config->get('config_name') . '</title>';
$output .= '<description>' . $this->config->get('config_meta_description') . '</description>';
$output .= '<link>' . HTTP_SERVER . '</link>';
$this->load->model('catalog/category');
$this->load->model('catalog/product');
$this->load->model('tool/image');
$products = $this->model_catalog_product->getProducts();
// I added
$nonIndexArray = $this->getNonIndexedProducts("http://EXAMPLE.com/catalog/controller/feed/product_issues.csv");
foreach ($products as $product) {
// I added
foreach ($nonIndexedArray as $nonProduct) {
// I added
if ($product['name'] !== $nonProduct ) {
if ($product['description']) {
$output .= '<item>';
$output .= '<title>' . $product['name'] . '</title>';
$output .= '<link>' . $this->url->link('product/product', 'product_id=' . $product['product_id']) . '</link>';
$output .= '<description>' . $product['description'] . '</description>';
$output .= '<g:brand>' . html_entity_decode($product['manufacturer'], ENT_QUOTES, 'UTF-8') . '</g:brand>';
$output .= '<g:condition>new</g:condition>';
$output .= '<g:id>' . $product['product_id'] . '</g:id>';
if ($product['image']) {
$output .= '<g:image_link>' . $this->model_tool_image->resize($product['image'], 500, 500) . '</g:image_link>';
} else {
$output .= '<g:image_link>' . $this->model_tool_image->resize('no_image.jpg', 500, 500) . '</g:image_link>';
}
$output .= '<g:mpn>' . $product['model'] . '</g:mpn>';
$currencies = array(
'USD',
'EUR',
'GBP'
);
if (in_array($this->currency->getCode(), $currencies)) {
$currency_code = $this->currency->getCode();
$currency_value = $this->currency->getValue();
} else {
$currency_code = 'USD';
$currency_value = $this->currency->getValue('USD');
}
if ((float)$product['special']) {
$output .= '<g:price>' . $this->currency->format($product['special'], $currency_code, $currency_value, false) . '</g:price>';
} else {
$output .= '<g:price>' . $this->currency->format($product['price'], $currency_code, $currency_value, false) . '</g:price>';
}
$categories = $this->model_catalog_product->getCategories($product['product_id']);
foreach ($categories as $category) {
$path = $this->getPath($category['category_id']);
if ($path) {
$string = '';
foreach (explode('_', $path) as $path_id) {
$category_info = $this->model_catalog_category->getCategory($path_id);
if ($category_info) {
if (!$string) {
$string = $category_info['name'];
} else {
$string .= ' > ' . $category_info['name'];
}
}
}
$output .= '<g:product_type>' . $string . '</g:product_type>';
}
}
$output .= '<g:quantity>' . $product['quantity'] . '</g:quantity>';
$output .= '<g:upc>' . $product['upc'] . '</g:upc>';
$output .= '<g:weight>' . $this->weight->format($product['weight'], $product['weight_class_id']) . '</g:weight>';
$output .= '<g:availability>' . ($product['quantity'] ? 'in stock' : 'out of stock') . '</g:availability>';
$output .= '</item>';
}
} else {
}
}
}
$output .= '</channel>';
$output .= '</rss>';
$this->response->addHeader('Content-Type: application/rss+xml');
$this->response->setOutput($output);
}
}
Following up on my comment with an example. I'd start by reverting your code to the starting point, then removing the non index products prior to iterating over them:
// get the products, this is original code
$products = $this->model_catalog_product->getProducts();
// remove non-indexed products, this is your custom code to
// eliminate products you don't care about
$nonIndexArray = $this->getNonIndexedProducts("http://EXAMPLE.com/catalog/controller/feed/product_issues.csv");
foreach ($products as $i => $product) {
if (in_array($product['name'], $nonIndexArray)) {
unset($products[$i]);
}
}
// now resume the original code
foreach ($products as $product) {
if ($product['description']) {
This might allow the script to run within the memory constraint you have. Or it might not. Either way, it looks to be a cleaner approach owing to fewer inserted lines and fewer loops.
Edit I suspect your getNonIndexedProducts function is consuming most of your memory (like loading the entire CSV file into RAM). That function can probably be optimized, but you might just want a quick fix... which is bumping up your memory to the max:
ini_set('memory_limit', '-1');

Print specific array value via function argument

$menu = array(
0 =>'top',
1 =>'photography',
2 =>'about'
);
<?php
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
foreach( $menu as $key => $value)
{
$return .= '<a class="menu" href="index.php#' . $menu[$key] . '">' . $menu[$key] . '</a>' . PHP_EOL .'';
}
$return .= '</div>';
return $return;
}
?>
<?php echo main_menu($menu[1]); ?>
What i basically want to do is to pass a specific array value when i'm echoing out the menu.
I'm building a single page website with anchors and i want to pass value's so i can echo out the "top"-link.
I'm stuck at the point on how to pass the $key value trough the function.
**edit: I'm trying to print specific links. I want a function that is able to print out an link but i want to specify the link to print via the function argument.
for example:
<?php echo main_menu($key = '0'); ?>
result:
prints url: top
<?php echo main_menu($key = '2'); ?>
result:
prints url: photography
**
(A lack of jargon makes it a bit harder to explain and even harder to google.
I got my books in front of me but this is taking a lot more time than it should.)
You either need to pass the entire array and loop, or pass a single array item and not loop:
Single Item:
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
$return .= '<a class="menu" href="index.php#' . $menu . '">' . $menu . '</a>' . PHP_EOL .'';
$return .= '</div>';
return $return;
}
echo main_menu($menu[1]);
Entire Array:
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
foreach($menu as $value) {
$return .= '<a class="menu" href="index.php#' . $value . '">' . $value . '</a>' . PHP_EOL .'';
}
$return .= '</div>';
return $return;
}
echo main_menu($menu);
You don't need $menu[$key] just use the $value.
Should you not just be using $value inside your loop? And passing the entire array rather than one item of the $menu array?
$menu = array(
0 =>'top',
1 =>'photography',
2 =>'about'
);
<?php
function main_menu ($menu) {
$return = '<div class="menu_entry">' . PHP_EOL .'';
foreach( $menu as $key => $value)
{
$return .= '<a class="menu" href="index.php#' . $value . '">' . $value . '</a>' . PHP_EOL .'';
}
$return .= '</div>';
return $return;
}
?>
<?php echo main_menu($menu); ?>
Try:
echo main_menu($menu); // You will get your links printed
Instead of
echo main_menu($menu[1]); // In this case error is occured like : **Invalid argument supplied for foreach**
NOTE: You can use $value instead of $menu[$key]

Unidentified Index Error

I am using a plugin for WordPRess called Easy Bootstrap Shortcodes to use Booystrap CSS within wordpress posts. Tabs are one feature I use a lot and when I use the tabs short code, it throws the following error:
Notice: Undefined index: tabs in /home/onedirec/public_html/tester/wp-content/plugins/easy-bootstrap-shortcodes/shortcode/tabs/plugin_shortcode.php on line 38
What's weird is that the tabs and all the information following is rendered apart from an indent that shouldn;t be there. You can see this in action here: http://onedirectionconnection.com/tester/?projects=take-me-home-tour
If anyone could help me figure out what the issue is, it would be greatly appreciated. Here's the code that's causing the error:
<?php
/* * *********************************************************
* jQuery UI Tabs
* ********************************************************* */
$_oscitas_tabs = array();
function osc_theme_tabs($params, $content = null) {
global $_oscitas_tabs;
extract(shortcode_atts(array(
'id' => count($_oscitas_tabs),
'class' => ''
), $params));
$_oscitas_tabs[$id] = array();
do_shortcode($content);
$scontent = '<ul class="nav nav-tabs " id="oscitas-tabs-' . $id . '">' . implode('', $_oscitas_tabs[$id]['tabs']) . '</ul><div
class="tab-content">' . implode('', $_oscitas_tabs[$id]['panes']) . '</div>';
if (trim($scontent) != "") {
$output = '<div class="' . $class . '">' . $scontent;
$output .= '</div>';
return $output;
} else {
return "";
}
}
add_shortcode('tabs', 'osc_theme_tabs');
function osc_theme_tab($params, $content = null) {
global $_oscitas_tabs;
extract(shortcode_atts(array(
'title' => 'title',
'active' => '',
), $params));
$index = count($_oscitas_tabs) - 1;
$pane_id = 'pane-' . $index . '-' . count($_oscitas_tabs[$index]['tabs']);
$_oscitas_tabs[$index]['tabs'][] = '<li class="' . $active . '"><a href="#' . $pane_id . '" data-toggle="tab">' . $title
. '</a></li>';
$_oscitas_tabs[$index]['panes'][] = '<div class="tab-pane ' . $active . '" id="'
. $pane_id . '">'
. do_shortcode
(trim($content)) . '</div>';
}
add_shortcode('tab', 'osc_theme_tab');
And here is line 38 on its own:
$pane_id = 'pane-' . $index . '-' . count($_oscitas_tabs[$index]['tabs']);
I know very little about PHP so if anyone can help me spot the error here, it would be greatly appreciated.
Well I'll just post the answer here since it worked in the comments.
Add this line just before line 38:
$_oscitas_tabs[$index]['tabs'] = array();
Right above this line:
$pane_id = 'pane-' . $index . '-' . count($_oscitas_tabs[$index]['tabs']);
That should stop the PHP notice from appearing.
You could try adding a # right before count()
$pane_id = 'pane-' . $index . '-' . #count($_oscitas_tabs[$index]['tabs']);
It keeps PHP from complaining.

Need to add second line and third delimiter on php explode

This is tailing off my other question which was successfully answered: stackoverflow.com/questions/8597929/need-to-create-li-with-list-of-different-links-using-php-explode-method
so now I have this:
<?php
$separator1 = "\n";
$separator2 = ":";
$textarea = get_custom_field('my_custom_output');
$array = explode($separator1,$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
list($item_text, $item_links) = explode($separator2, trim($item));
$output .= '<li class="link-class"><a title="' . $item_text . '" href="http://mywebsite.com/' . $item_links . '">' . $item_text . '</a></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
and that, using the following in a textarea which is defined to "my_custom_output":
text1:text1-page-url
text2:new-text2-page
text3:different-page-text3
and the result is
text1
text2
text3
which are successfully linked and styled. (i didnt make them links because stackoverflow doesn't let me post more than two links because i only have 3 rep).
So my next and final desired task is to do this:
text1
description 1
text2
description 2
text3
description 3
where the text1 etc are linked like before but the descriptions are not linked.
So I will do my best, right here in stackoverflow, to try it. However, I expect I will need some help. Let's go:
<?php
$separator1 = "\n";
$separator2 = ":";
$separator3 = ";";
$textarea = get_custom_field('my_custom_output');
$array = explode($separator1,$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
list($item_text, $item_links) = explode($separator2, trim($item));
$output .= '<li class="link-class"><a title="' . $item_text . '" href="http://mywebsite.com/' . $item_links . '">' . $item_text . '</a><br /><span class="desc-class">' . $item_desc . '</span></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
and to use the following in the textarea which is is defined to "my_custom_output":
text1:text1-page-url;Text1 Description
text2:new-text2-page;Description For Text2
text3:different-page-text3;A Text3 Description
and I need the output to be:
text1
Text1 Description
text2
Description For Text2
..etc
I don't know if semicolon will work, but I can't use a space (\s) because there are spaces in the description. I am open to suggestions.
====================================================
MY NEWEST TRY:
<?php
$separator1 = "\n";
$separator2 = ":";
$separator3 = ";";
$textarea = get_custom_field('my_custom_output');
$array = explode($separator1,$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
$itemarray = explode($separator2, trim($item));
$item_text = $itemarray[0];
list($item_links, $item_desc) = explode($separator3,$itemarray[1]);
$output .= '<li class="link-class"><a title="' . $item_text . '" href="http://mywebsite.com/' . $item_links . '">' . $item_text . '</a><br /><span class="desc-class">' . $item_desc . '</span></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
IT WORKS!!! =D
Not sure if I understand this well enough (I'm not sure what get_custom_field() gets you - can't find that as a regular PHP function), but when you explode an item that has multiple instances of the delimiter, you'll get multiple arrays.
So:
$textarea = "text1:text1-page-url;Text1 Description";
$data = explode(':',$textarea);
// at this point $data[0] will contain "text1", while $data[1] contains text1-page-url;Text1 Description"
$descarray = explode(';',$data[1]);
// then $descarray[0] contains "text1-page-url" and $descarray[1] contains "Text1 Description" so you can echo this out however you like.
To work with your code..
Assume each $item is each row at this point, like this:
$item = "text1:text1-page-url;Text1 Description";
Then this will do the trick:
foreach ($array as $item) {
$itemarray = explode($separator2, trim($item));
$item_text = $itemarray[0];
list($item_links, $item_desc) = explode(';',$itemarray[1]);
$output .= '<li class="link-class"><a title="' . $item_text . '" href="http://mywebsite.com/' . $item_links . '">' . $item_text . '</a><br /><span class="desc-class">' . $item_desc . '</span></li>';
}
I'd slightly optimize the algorithm as there is no need for second explode(). Just separate substrings within one row with the same separators (and don't forget to escape that separator inside all your data):
<?php
$row_separator = "\n";
$line_separator = ":";
$textarea = get_custom_field('my_custom_output');
$array = explode($row_separator, $textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
list($item_text, $item_links, $item_desc) = explode($line_separator, trim($item));
$output .= '<li class="link-class"><a title="' . $item_text . '" href="http://mywebsite.com/' . $item_links . '">' . $item_text . '</a><br /><span class="desc-class">' . $item_desc . '</span></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
And here is the data format I suggest to use (separate all fields by :)
text1:text1-page-url:Text1 Description
text2:new-text2-page:Description For Text2
text3:different-page-text3:A Text3 Description

Categories