Magento, grid, add column with link to a website - magento

I'm banging my head to add a plain, simple link to a website on a custom column of a grid. I used the Inchoo blog to add a custom renderer for the column and it works. I though that just modifying the render and adding a tag will be enough. But my hopes were dashed, is not working.
How can be this done? Should be simple, but no way I can find how. I found lot of question/answers here in SO but about adding links to products, categories, etc, no reference to external websites, maybe I'm just using the wrong keywords in the search.
Here is the _prepareColumns() from my Grid.php
protected function _prepareColumns() {
$blog = Mage::getModel('blogtest/blog');
$this->addColumn('api_blog_url', array(
'header' => $this->__('URL'),
'align' => 'center',
'index' => 'api_blog_url',
'width' => 50,
'type' => 'text',
'renderer' => 'Dts_Blogtest_Block_Adminhtml_Blog_Renderer_MyRender'
));
....
And here is my render override for that column:
<?php
class Dts_Blogtest_Block_Adminhtml_Blog_Renderer_MyRender extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
$value = $row->getData($this->getColumn()->getIndex());
// return '<a href="http://'.$value.'>'.$value.'</a>';
return '<span style="color:red;">'.$value.'</span>';
}
}
?>

You mean the style with color red it working properly but if you uncomment the line with the <a href..> it is not?
I think you just missed a quote in the href attribute.
return ''.$value.'';

Btw, i think, that you can write more good looking code, if will be use next approach: In render function you create a block and send link-data. After, you create block and template for this block. In template you get link-data and display it as you wish.
<?php
class Something
extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
$column_data = $row->getData(
$this->getColumn()->getIndex()
);
return $this->getLayout()
->createBlock('something/adminhtml_renderer_link')
->setLink($column_data )
->_toHtml();
}
}
?>
<?php
class Something
extends Mage_Core_Block_Template
{
protected function _construct()
{
parent::_construct();
$this->setTemplate('something/link.phtml');
}
}
?>
<?php
$link = $this->getLink();
?>
<?php if ($link): ?>
<?php echo $this->__('Click to view!'); ?>
<?php else: ?>
<?php echo $this->__('No link'); ?>
<?php endif; ?>

Related

How Do I Output Multiselect Attribute Values In Magento 2.3.x?

In a Magento 2.3.3 store I am trying to ouput the values of a multiselect custom attribute on a category page, but not having any luck.
I have set the attribute to be used in product listing and tried to output it on catalog/product/listing.phtml template page in my custom theme.
I am using the using the following code:
<?php /* #escapeNotVerified */ echo $_product->getResource()->getAttribute('custom_attribute')->getFrontend()->getValue($_product); ?>
This is working for dropdown attributes but not multi select attributes.
Kind of stuck on this...
You can use the below code to get MultiSelect Attribute value
create block in "catalog_product_view.xml"
<referenceBlock name="product.info.main">
<block class="Magento\Catalog\Block\Product\View" name="attribue.name" template="Magento_Catalog::product/view/attribute_name.phtml" after="-" />
</referenceBlock>
create "phtml" file under "Magento_Catalog::product/view/attribute_name.phtml"
<?php $product = $block->getProduct(); ?>
<div>
<?php
$data = explode(',',$product->getData('attribute_code'));
foreach($data as $value):
?>
<?php
$attr = $product->getResource()->getAttribute('attribute_code');
if ($attr->usesSource()):
?>
<?php
$option_value = $attr->getSource()->getOptionText($value);
?>
<p><?php echo $option_value; ?></p>
<?php endif;?>
<?php endforeach;?>
</div>
Here is an example of a code that returns "Multiselect Attribute Values". The attribute belongs to product entity. As it isn't a good idea to get ProductResource model from ProductModel and taking into account that probably you need to get it inside some template, just create a ViewModel and use this example there.
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
...
public function __construct(
...
ProductResource $productResource
)
{
...
$this->productResource = $productResource;
}
public function prepareProductAttributeOptions($product, $attributeCode)
{
$result = [];
$data = $product->getData($attributeCode);
$optionsIds = [];
if ($data) {
$optionsIds = explode(',', $data);
}
foreach ($optionsIds as $optionId) {
$attr = $this->productResource->getAttribute($attributeCode);
if ($attr->usesSource()) {
$option_value = $attr->getSource()->getOptionText($optionId);
$result[] = $option_value;
}
}
return implode(',', $result);
}

Fetching and updating data from a database

I want to fetch and update data from database using codeigniter. I am facing some problem. This is my code:
This is my Model by the name of Update_site_model.
<?php
class update_site_model extends CI_Model{
function show_invoice_id($data) {
$this->db->select('*');
$this->db->from('invoices');
$this->where('invoiceId', $data);
$query = $this->db->get();
$result = $query->result();
return $result;
//Update Query For Selected Invoice.
function update($id,$data) {
$this->db->where('invoiceId',$id);
$this->db->update('invoices',$data);
}
}
?>
This is my Controller by the name of update site.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Update_site extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->view('includes/header');
$this->load->view('site/update');
$this->load->view('includes/footer');
//load the model
$this->load->model('update_site_model');
}
function show_invoices() {
$id = $this->uri->segment(3);
$data['single_invoice'] = $this->update_site_model->show_invoice_id($id);
$this->load->view('site/update', $data);
}
function update() {
$id = $this->input->post('invoiceId');
$data = array(
'Date' => $this->input->post('invoiceDate'),
'Client' => $this->input->post('invoiceClient'),
'Amount' => $this->input->post('invoiceAmount'),
'Status' => $this->input->post('invoivceStatus')
);
$this->update_site_model->update($id, $data);
}
}
This is my view by the name of update. it is inside a folder by the name of site.
<div id="content">
<ol>
<?php foreach ($invoices as $invoice): ?>
<li><?php echo $invoice->invoiceId; ?></li>
</ol>
<?php endforeach; ?>
</div>
and this is the problem.
Severity: Notice
Message: Undefined variable: invoices
Filename: site/update.php
Line Number: 11
Severity: Warning
Message: Invalid argument supplied for foreach()
Filename: site/update.php
Line Number: 11
Please help me to solve the problem.
Look at this in your controller:
$data['single_invoice'] = $this->update_site_model->show_invoice_id($id);
and now look at this in your view:
<?php foreach ($invoices as $invoice): ?>
did you got your mistake..?
no..?
let me tell you , since you are storing the database result in $data['single_invoice'] you should access this by $single_invoice in the view.
so correct usage in your view is :
<?php foreach ($single_invoice as $invoice): ?>
and next time when you ask any question give appropriate title to it.

Flash messanger in zf2

How can i use flash messenger in zend freamwork 2? Session documentation is not yet. Anyone know it? But session libraries are there.
Update :
Zend Framework new release added FlashMessenger View Helper , found in path /library/Zend/View/Helper/FlashMessenger.php
FlashMessenger.php
Old answer :
I have written a custom view helper, for printing flash messages
In /module/Application/Module.php
public function getViewHelperConfig()
{
return array(
'factories' => array(
'flashMessage' => function($sm) {
$flashmessenger = $sm->getServiceLocator()
->get('ControllerPluginManager')
->get('flashmessenger');
$message = new \My\View\Helper\FlashMessages( ) ;
$message->setFlashMessenger( $flashmessenger );
return $message ;
}
),
);
}
Create a custom view helper in /library/My/View/Helper/FlashMessages.php
namespace My\View\Helper;
use Zend\View\Helper\AbstractHelper;
class FlashMessages extends AbstractHelper
{
protected $flashMessenger;
public function setFlashMessenger( $flashMessenger )
{
$this->flashMessenger = $flashMessenger ;
}
public function __invoke( )
{
$namespaces = array(
'error' ,'success',
'info','warning'
);
// messages as string
$messageString = '';
foreach ( $namespaces as $ns ) {
$this->flashMessenger->setNamespace( $ns );
$messages = array_merge(
$this->flashMessenger->getMessages(),
$this->flashMessenger->getCurrentMessages()
);
if ( ! $messages ) continue;
$messageString .= "<div class='$ns'>"
. implode( '<br />', $messages )
.'</div>';
}
return $messageString ;
}
}
then simple call from layout.phtml , or your view.phtml
echo $this->flashMessage();
Let me show example of controller action
public function testFlashAction()
{
//set flash message
$this->flashMessenger()->setNamespace('warning')
->addMessage('Mail sending failed!');
//set flash message
$this->flashMessenger()->setNamespace('success')
->addMessage('Data added successfully');
// redirect to home page
return $this->redirect()->toUrl('/');
}
In home page, it prints
<div class="success">Data added successfully</div>
<div class="warning">Mail sending failed!</div>
Hope this will helps !
i have written a post about this some time ago. You can find it right here
Basically you use it just the same like earlier.
<?php
public function commentAction()
{
// ... display Form
// ... validate the Form
if ($form->isValid()) {
// try-catch passing data to database
$this->flashMessenger()->addMessage('Thank you for your comment!');
return $this->redirect()->toRoute('blog-details'); //id, blabla
}
}
public function detailsAction()
{
// Grab the Blog with given ID
// Grab all Comments for this blog
// Assign the view Variables
return array(
'blog' => $blog,
'comments' => $comments,
'flashMessages' => $this->flashMessenger()->getMessages()
);
}
Then in your .phtml file you do it like this:
// details.phtml
<?php if(count($flashMessages)) : ?>
<ul>
<?php foreach ($flashMessages as $msg) : ?>
<li><?php echo $msg; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
Obviously this isn't all too handy, as you have to do this for every single .phtml file. Therefore doing it within the layout you have to do it at best like the following:
<?php
// layout.phtml
// First get the viewmodel and all its children (ie the actions viewmodel)
$children = $this->viewModel()
->getCurrent()
->getChildren();
$ourView = $children[0];
if (isset($ourView->flashMessages) && count($ourView->flashMessages)) : ?>
<ul class="flashMessages">
<?php foreach ($ourView->flashMessages as $fMessage) : ?>
<li><?php echo $fMessage; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
If you need further description, please see my blog, but i guess the code itself is pretty clear (apart frmo the layout.phtml example). Alternatively you're always free to write your own view helper to have it look a little cleaner inside your view-templates.
How to grab Flashmessenger’s messages in a View Helper – sharing code as requested by Sam.
The View helper should implement the ServiceManagerAwareInterface interface and related methods. The plugin will now have access to a Service Manager which we can use to get the Service Locator and ultimately access to the Flash Messenger.
I’ve not touched this code since I initially wrote it – so there may be a more elegant way of doing this.
protected function getMessages()
{
$serviceLocator = $this->getServiceManager()->getServiceLocator();
$plugin = $serviceLocator->get('ControllerPluginManager');
$flashMessenger = $plugin->get('flashmessenger');
$messages = $flashMessenger->getMessages();
// Check for any recently added messages
if ($flashMessenger->hasCurrentMessages())
{
$messages += $flashMessenger->getCurrentMessages();
$flashMessenger->clearCurrentMessages();
}
return $messages;
}
And calling getMessages() from within the plugin should return an array of messages that can be passed to a partial and rendered.
Add code below to the view to render error messages:
<?php echo $this->flashmessenger()
->setMessageOpenFormat('<div class="alert alert-danger"><ul%s><li>')
->setMessageCloseString('</li></ul></div>')
->render('error')
; ?>
In previous request, make sure you created an error message by running code below in your controller:
$this->flashmessenger()->addErrorMessage('Whops, something went wrong...');

Magento - how to retrieve bundled option images

I've been working on my first magento deploy. Got a pretty customized theme built up... tackling some of the non-standard customizations now:
One of my primary product types is an office chair which I have set up as a bundled product. There are many options available for this product type (about 100 fabric options, arm style, lumbar, headrest etc) and I need to be able to show an image for each of these on the catalog/product/view page.
Being a bundled product (and I'll refrain from any discussion about whether this was the right product type - we went around in circles debating between a configurable and a bundled) - each product is assembled from a number of simple products (as options). These simple products can have images uploaded to them, and I've done so. I now want to retrieve the urls to those from the media folder...
After some hunting - these seem to be the essential elements:
theme/../template/catalog/product/view/options.phtml
<?php $_options = Mage::helper('core')->decorateArray($this->getOptions()) ?>
<dl>
<?php foreach($_options as $_option): ?>
<?php echo $this->getOptionHtml($_option) ?>
<?php endforeach; ?>
</dl>
theme/../template/bundle/catalog/product/view/type/bundle/option/select.phtml
<?php /* #var $this Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Select */ ?>
<?php $_option = $this->getOption(); ?>
<?php $_selections = $_option->getSelections(); ?>
I found finally found getSelections() in:
class Mage_Bundle_Model_Resource_Price_Index extends Mage_Core_Model_Resource_Db_Abstract
{ ...
/**
* Retrieve bundle options with selections and prices by product
*
* #param int $productId
* #return array
*/
public function getSelections($productId)
{
$options = array();
$read = $this->_getReadAdapter();
$select = $read->select()
->from(
array('option_table' => $this->getTable('bundle/option')),
array('option_id', 'required', 'type')
)
->join(
array('selection_table' => $this->getTable('bundle/selection')),
'selection_table.option_id=option_table.option_id',
array('selection_id', 'product_id', 'selection_price_type',
'selection_price_value', 'selection_qty', 'selection_can_change_qty')
)
->join(
array('e' => $this->getTable('catalog/product')),
'e.entity_id=selection_table.product_id AND e.required_options=0',
array()
)
->where('option_table.parent_id=:product_id');
$query = $read->query($select, array('product_id' => $productId));
while ($row = $query->fetch()) {
if (!isset($options[$row['option_id']])) {
$options[$row['option_id']] = array(
'option_id' => $row['option_id'],
'required' => $row['required'],
'type' => $row['type'],
'selections' => array()
);
}
$options[$row['option_id']]['selections'][$row['selection_id']] = array(
'selection_id' => $row['selection_id'],
'product_id' => $row['product_id'],
'price_type' => $row['selection_price_type'],
'price_value' => $row['selection_price_value'],
'qty' => $row['selection_qty'],
'can_change_qty' => $row['selection_can_change_qty']
);
}
return $options;
}
so we get back an array with selection_id, product_id, price_type etc... but nothing referring to the image url for that selection...
Given that:
class Mage_Catalog_Helper_Product extends Mage_Core_Helper_Url
{ ...
public function getImageUrl($product)
{
$url = false;
if (!$product->getImage()) {
$url = Mage::getDesign()->getSkinUrl('images/no_image.jpg');
}
elseif ($attribute = $product->getResource()->getAttribute('image')) {
$url = $attribute->getFrontend()->getUrl($product);
}
return $url;
}
I'm trying to build a js object with refs to each selection's image url kind of like so in theme/../template/bundle/catalog/product/view/type/bundle/option/select.phtml
var option_set_<?php echo $_option->getId() ?> = {};
<?php foreach ($_selections as $_selection): ?>
option_set_<?php echo $_option->getId() ?>._<?php echo $_selection->getSelectionId() ?> = '<?php echo $_selection->getImageUrl(); ?>';
<?php endforeach; ?>
But $_selection obviously isn't typed correctly because it just bounces me to the placeholder graphic.
Assuming these options can be typed as a Product (or somehow obtain the simple product from the selection_id, it seems like something like that can work. I'm not sure if that's exactly how I want to manage this feature, but if I can just get a stack of urls - then I'll be in business
Weirdly, the interwebs is basically silent on this subject. Apparently nobody needs to show images for their product options (or, rather, the only solutions are paid extensions - which will be a last resort).
How I can go about figuring this out?
Jesus tapdancing christ. Could Mage be any more complicated?
Update
Got this to work as such:
<?php echo $this->helper('catalog/image')->init($_selection, 'small_image')->resize(40,40); ?>
The answer I selected will also work fine, if anybody needs this fix.
The product_id in the $_selections represents the id of the selected simple product.
So all to do is:
take the product_id of the $_selections,
load the product by this product_id
give the resulting product object to Mage_Catalog_Helper_Product::getImageUrl.

How to pass multiple variable data from model to view

Could you please tell me how my model,controller and view should look like if I want to pass the following variable data($amount1, $amount2, $amount3) to my view file via controller from my model.
case 1: $amount1=100;
case 2: $amount2=500;
case 3: $amount3=1000;
I want to have the variables in a way that I don't have to echo them in any { } example:
foreach ($records as $row){ $i++; ?>
// I don't want to echo those inside in this.
// I want to echo it like this way- <? echo $amount1;?>
}
Thanks in Advance :)
If you pass an array of data from your controller to your view you can access each element as a variable in the view. Here is an example of what I mean:
model:
class Model extends CI_Model
{
public function get_data()
{
$data = array(
'amount1' => 100,
'amount2' => 500,
'amount3' => 1000,
);
return $data;
}
}
controller:
class Controller extends CI_Controller
{
public function index()
{
// get data from model
$data = $this->model->get_data();
// load view
$this->load->view('view', $data);
}
}
view:
<h1><?php echo $amount1; ?></h2>
<p><?php echo $amount2; ?></p>
<!-- etc... -->
I have found a solution myself. I just wanted to share so that it can help others. So here it is..
Your model should look like following :
function net_income(){
$data['amount1']=50;
$data['amount2']=100;
return json_encode($data);
}
Your controller:
function add(){
$this->load->model('mod_net_income');
$json = $this->mod_net_income->net_income();
$obj = json_decode($json);
$data['amount1']= $obj->{'amount1'};
$this->load->view('your_viewfile_name',$data);
}
And then in your view file: just
<? echo "$amount" ; ?>
Thanks :)

Resources