Creating a link in top menu in Magento - magento

Hi I hope you can help me with this. I'm new in Magento and I'm trying to implement the same functionality discussed in this thread
Magento hide navigation menu item from guest.
The only thing I haven't figured out yet is how to create a navigation block in the first place or create custom links in the top menu.
I have been trying to follow the method described in the link below but I'm not sure which config.xml and observer file I should modify in order to get this work
http://inchoo.net/ecommerce/adding-links-to-the-top-menu-in-magento/comment-page-1/#comment-71252
Could somebody please provides me with some guidance?

Your question is not clear. I assumes that, you want to add new menu in header and you want to show it only when user is logged in. Based on that assumption, let us start to create a custom module. (Tutorial that you point out is referencing your own module and not to any other existing module). Let us create a module with name Mysite_Addmenu
First you need to configure your module. For that create a file in
Location : app/code/core/local/Mysite/Addmenu/etc/config.xml
<config>
<modules>
<Mysite_Addmenu>
<version>0.1.0</version>
</Mysite_Addmenu>
</modules>
<frontend>
<events>
<page_block_html_topmenu_gethtml_before>
<observers>
<add_top_menu>
<type>singleton</type>
<class>addmenu/observer</class>
<method>addToTopmenu</method>
</add_top_menu>
</observers>
</page_block_html_topmenu_gethtml_before>
</events>
</frontend>
<global>
<models>
<addmenu>
<class>Mysite_Addmenu_Model</class>
</addmenu>
</models>
</global>
</config>
As you can see it has two section. One section defines the observer part and other section defines its model part. In model, you are going to define your observer.
Now let us make magento knows about our module.For this you need to add this file in the given location
Location:app/etc/modules/Mysite_Addmenu.xml
<config>
<modules>
<Mysite_Addmenu>
<active>true</active>
<codePool>local</codePool>
</Mysite_Addmenu>
</modules>
</config>
Now its time to define our observer.Let us do that
Location : app/code/local/Mysite/Addmenu/Model/Observer.php
<?php
class Mysite_Addmenu_Model_Observer
{
public function addToTopmenu(Varien_Event_Observer $observer)
{
if(Mage::getSingleton('customer/session')->isLoggedIn())
{
$menu = $observer->getMenu();
$tree = $menu->getTree();
$node = new Varien_Data_Tree_Node(array(
'name' => 'Newmenu',
'id' => 'newmenu',
'url' => Mage::getUrl().'newmenu', // point somewhere
), 'id', $tree, $menu);
$menu->addChild($node);
// Children menu items
$collection = Mage::getResourceModel('catalog/category_collection')
->setStore(Mage::app()->getStore())
->addIsActiveFilter()
->addNameToResult()
->setPageSize(3);
foreach ($collection as $category) {
$tree = $node->getTree();
$data = array(
'name' => $category->getName(),
'id' => 'category-node-'.$category->getId(),
'url' => $category->getUrl(),
);
$subNode = new Varien_Data_Tree_Node($data, 'id', $tree, $node);
$node->addChild($subNode);
}
}
}
}
What observer does : Observer checks whether a user is exist or not. If not, it will not create a menu. If a user is already logged in, then the menu will appear.
I have used same code in referenced tutorial. You can make your own changes to submenu part. Display it as you desire. Hope it will help you.

This is what I understand by your question here Magento hide navigation menu item from guest.
so you need to follow the steps
step 1: Need to create observer by using event page_block_html_topmenu_gethtml_before
you will find lots of article to create an observer as you added
http://inchoo.net/ecommerce/adding-links-to-the-top-menu-in-magento/comment-page-1/
and update the code with below
$subNode = new Varien_Data_Tree_Node($data, 'id', $tree, $node);
// here added the condition to check the customer is logged in or not then only show the menu
if(Mage::getSingleton('customer/session')->isLoggedIn())
{
$node->addChild($subNode);
}

Related

Magento - Add custom block to existing tab in catalog product edit view

I need to add some content to the top of the images tab in the catalog product edit view. I do not want to add a new tab, i want to include some content (custom block) to the existing one.
I have seen a lot of tutorials on how to add a whole new tab, but nothing on how to edit an existing one.
I have managed to create an observer on the event "core_block_abstract_prepare_layout_after":
<core_block_abstract_prepare_layout_after>
<observers>
<edit_images_tab>
<type>singleton</type>
<class>custom_module/observer</class>
<method>editImagesTab</method>
</edit_images_tab>
</observers>
</core_block_abstract_prepare_layout_after>
and remove and recreate the tab in the same position:
public function editImagesTab(Varien_Event_Observer $observer) {
$block = $observer->getEvent()->getBlock();
if ($block instanceof Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs) {
$block->removeTab('group_10');
$block->addTabAfter(
'group_10',
array(
'label' => 'Upload Product Files',
'content' => $block->getLayout()->createBlock('adminhtml/catalog_product_helper_form_gallery_content')->toHtml() . 'custom content'
),
'group_9'
);
}
}
Anyway, it seems that $block->getLayout()->createBlock('adminhtml/catalog_product_helper_form_gallery_content')->toHtml() is not enough to recreate the images tab.
Not sure if i'm going in the right direction.
Any hint would be greatly appreciated.
I've found another way to achieve my goal, here is what I did.
I have overridden the method toHtml() of the class "Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Gallery" in that way:
class Custom_Module_Block_Adminhtml_Catalog_Product_Helper_Form_Gallery
extends Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Gallery {
public function toHtml() {
$myBlock = Mage::getSingleton('core/layout')->createBlock('custom_module/custom_block')->toHtml();
return $myBlock . parent::toHtml();
}
}
and added this in the config.xml file:
<global>
<blocks>
<adminhtml>
<rewrite>
<catalog_product_helper_form_gallery>Custom_Module_Block_Adminhtml_Catalog_Product_Helper_Form_Gallery</catalog_product_helper_form_gallery>
</rewrite>
</adminhtml>
</blocks>
</global>
not sure if this is the best approach but it works.

How to Protect user,for visit product page in magento

I am working in a Magento site, Requirement is when user comes to the site user should be redirect to login page,
Without visit any product page.
After register he will be able to view the products,
I have already tried but not getting any solution yet.
Anyone can help me on this?
You can simply use free available extension on magento connect. I used this extension for my store http://www.magentocommerce.com/magento-connect/login-check.html
It is free and doing job nice.
You can try the following approach as described here. Since posting single link answers is not recommended, here is what you need to do.
You need to create an observer for the event controller_action_predispatch for frontend. You can do that in a custom module. Let's call that module Easylife_Restrict.
You will need the following files:
app/etc/modules/Easylife_Restrict.xml - the declaration file.
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Restrict>
<codePool>local</codePool>
<active>true</active>
<depends>
<Mage_Customer />
</depends>
</Easylife_Restrict>
</modules>
</config>
app/code/local/Easylife/Restrict/etc/config.xml - the configuration file
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Restrict>
<version>1.0.0</version>
</Easylife_Restrict>
</modules>
<global>
<models>
<easylife_restrict>
<class>Easylife_Restrict_Model</class>
</easylife_restrict>
</models>
</global>
<frontend>
<events>
<controller_action_predispatch>
<observers>
<easylife_restrict>
<class>easylife_restrict/observer</class>
<method>redirectNotLogged</method>
</easylife_restrict>
</observers>
</controller_action_predispatch>
</events>
</frontend>
</config>
app/code/local/Easylife/Restrict/Model/Observer.php - the module observer - this is where the magic happens:
<?php
class Easylife_Restrict_Model_Observer{
public function redirectNotLogged(Varien_Event_Observer $observer)
{
//get the current request action
$action = strtolower(Mage::app()->getRequest()->getActionName());
//get the current request controller
$controller = strtolower(Mage::app()->getRequest()->getControllerName());
//a list of allowed actions for the not logged in user
$openActions = array(
'create',
'createpost',
'login',
'loginpost',
'logoutsuccess',
'forgotpassword',
'forgotpasswordpost',
'resetpassword',
'resetpasswordpost',
'confirm',
'confirmation'
);
//if the controller is the customer account controller and the action is allowed for everyone just do nothing.
if ($controller == 'account' && in_array($action, $openActions)) {
return $this; //if in allowed actions do nothing.
}
//if the user is not logged in redirect to the login page
if(! Mage::helper('customer')->isLoggedIn()){
Mage::app()->getFrontController()->getResponse()->setRedirect(Mage::getUrl('customer/account/login'));
}
}
}
Clear the cache and give it a try.
Please use this
Step 1: Go to Admin => System => Configuration => Customer Configuration => Login Options => "Redirect Customer to Account Dashboard after Logging in" set it "No".
Step 2: If you're using a module page then you've the controller Action method like:
public function indexAction()
{
// use here to restrict the page //
if(!Mage::helper('customer')->isLoggedIn()){
Mage::getSingleton('customer/session')->setBeforeAuthUrl('Restricted Page Url');
$this->_redirect('customer/account/login');
}
// End your addition //
$this->loadLayout();
$this->renderLayout();
}
you can use one of this code to redirect:
Mage::getSingleton('customer/session')->setBeforeAuthUrl('Restricted Page Url');
$this->_redirect('customer/account/login');
OR
$this->_redirect('customer/account/login/referer/'.Mage::helper('core')->urlEncode('Restricted Page Url'));
Step 3: (optional) If you're using a cms page then follow this step:
In your admin CMS section include a phtml page and write the below code at the top of the page:
if(!Mage::helper('customer')->isLoggedIn()){
Mage::getSingleton('customer/session')->setBeforeAuthUrl('Restricted Page Url');
$this->_redirect('customer/account/login');
}
>> Now if you want to use the login url inside a page with referer url follow this:
<?php $referer = Mage::helper('core')->urlEncode(Mage::helper('core/url')->getCurrentUrl()); ?>
Login
I think it will solve your problem

magento link to cms page in product attribute not working

I'm trying to add an 'a href' / link in an Attribute Field for a product.
However, the methods that I'm using are not working - although they work in CMS page content. When I view the product, the attribute with the link is displayed, but the actual URL does not seem to be generated correctly (404 error)
I've tried the following:
1. Test link 1
2. Test link 2
3. Test link 3
What am I doing wrong?
Your help is appreciated in advance
Thank you!
Magento EAV attributes values will not be parsed by PHP on their own. For display to the user, they are rendered through a frontend model. See eav_attribute table for examples.
Based on the "we do not want to display the entire url, just a text link" comment, you need an attribute with a custom frontend model. I'm guessing that it was added via the Admin Panel, which won't allow to add custom frontend models. Whereas adding the frontend model requires a script, I'd recommend adding the attribute via script in the first place.
To install this attribute properly , Magento needs to execute a setup script, which is a Magento term for (usually) PHP code which is executed exactly once with the ability to manipulate the database. Running these presupposes a module exists:
app/etc/modules/Your_Module.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Your_Module>
<active>true</active>
<codePool>local</codePool>
</Your_Module>
</modules>
</config>
app/code/local/Your/Module/etc/config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Your_Module>
<version>1.0.0.0</version>
</Your_Module>
</modules>
<global>
<models>
<your_module>
<class>Your_Module_Model</class>
</your_module>
</models>
<resources>
<your_module_setup>
<setup>
<module>Your_Module</module>
</setup>
</your_module_setup>
</resources>
</global>
</config>
app/code/local/Your/Module/sql/your_module_setup/install-1.0.0.0.php:
<?php
$installer = Mage::getResourceModel('catalog/setup','catalog_setup');
/* #var $installer Mage_Catalog_Model_Resource_Setup */
$installer->startSteup();
$installer->addAttribute(
'catalog_product',
'unique_attr_code',
array(
'label' => 'Link to Product',
'required' => 'false', //or true if appropriate
'group' => 'General', //Adds to all sets
'frontend' => 'your_module/frontend_url'
)
);
$installer->endSetup();
app/code/local/Your/Module/Model/Frontend/Url.php:
class Your_Module_Model_Frontend_Url
extends Mage_Eav_Model_Entity_Attribute_Frontend_Abstract
{
public function getUrl($object)
{
$url = false;
if ($path = $object->getData($this->getAttribute()->getAttributeCode())) {
$url = Mage::getUrl('path');
}
return $url;
}
}

Magento - Convert a module using <rewrite> to use Events for the Sales > Order Grid

I've made a simple module that adds extra fields to the Sales > Order Grid. It works great but the problem is that another module we're using <rewrites> the order grid to add their field to the grid. I wanted to try to change it to use Events instead (besides, it's a better method)...
The issue is that I've been trying and trying and I just can't make it happen. (Maybe I just can't grasp the event/observer concept yet...)
Here is my current module structure:
app/code/local/Artizara/OrderGridAdditions/
app/code/local/Artizara/OrderGridAdditions/Block/Sales/Order/Grid.php
app/code/local/Artizara/OrderGridAdditions/etc/config.xml
app/code/local/Artizara/OrderGridAdditions/controllers [empty]
app/code/local/Artizara/OrderGridAdditions/Helper [empty]
app/code/local/Artizara/OrderGridAdditions/Model [empty]
Inside my Grid.php file, I have copied the main Grid.php file contents into my Grid.php file and edited the _getCollectionClass(), _prepareCollection() and _prepareColumns() functions.
I've changed the _getCollectionClass() to this:
//return 'sales/order_grid_collection';
return 'sales/order_collection';
I've changed the _prepareCollection() to this:
$collection = Mage::getResourceModel($this->_getCollectionClass());
$collection->getSelect()->joinLeft(array('sfog' => 'sales_flat_order_grid'),'main_table.entity_id = sfog.entity_id',array('sfog.shipping_name','sfog.billing_name'));
$collection->getSelect()->joinLeft(array('sfo'=>'sales_flat_order'),'sfo.entity_id=main_table.entity_id',array('sfo.customer_email','sfo.weight','sfo.discount_description','sfo.increment_id','sfo.store_id','sfo.created_at','sfo.status','sfo.base_grand_total','sfo.grand_total','shipping_description','sfo.total_item_count'));
$collection->getSelect()->joinLeft(array('sfoa'=>'sales_flat_order_address'),'main_table.entity_id = sfoa.parent_id AND sfoa.address_type="shipping"',array('sfoa.street','sfoa.city','sfoa.region','sfoa.postcode','sfoa.telephone'));
//$collection->getSelect()->joinLeft(array('sfop' => 'sales_flat_order_payment'),'main_table.entity_id = sfop.entity_id',array('sfop.method'));
$this->setCollection($collection);
return parent::_prepareCollection();
I've added columns to the _prepareColumns() like this (only added one here as example):
$this->addColumn('total_item_count', array(
'header' => Mage::helper('sales')->__('Total Items'),
'index' => 'total_item_count',
'filter_index' => 'sfo.total_item_count',
'width' => '50px',
));
In my config.xml file I have a simple <rewrite>:
<modules>
<Artizara_OrderGridAdditions>
<version>0.1.0</version>
</Artizara_OrderGridAdditions>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<sales_order_grid>Artizara_OrderGridAdditions_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
<ordergridadditions>
<class>Artizara_OrderGridAdditions_Block</class>
</ordergridadditions>
</blocks>
</global>
Changing it over to Events/Observers
I've been trying a lot to change this up to a module that uses an Event but am hitting a wall with it. I've been trying to follow some other answers on here (the ones that are not rewrites, but they use a different method to add custom tables to the grid from the database). I'm looking to use the same setup I already have.
I've added /Helper/Data.php container that contains this:
class Artizara_OrderGridAdditions_Helper_Data extends Mage_Core_Helper_Abstract{ }
In /etc/config.xml I've tried many things. Here's my latest attempt:
<modules>
<Artizara_OrderGridAdditions>
<version>0.1.0</version>
</Artizara_OrderGridAdditions>
</modules>
<adminhtml>
<events>
<adminhtml_block_html_before>
<observers>
<Artizara_OrderGridAdditions_Observer>
<class>Artizara_OrderGridAdditions_Model_Observer</class>
<method>addAdditionsToGrid</method>
</Artizara_OrderGridAdditions_Observer>
</observers>
</adminhtml_block_html_before>
</events>
</adminhtml>
<global>
<models>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Model</class>
</Artizara_OrderGridAdditions>
</models>
<blocks>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Block</class>
</Artizara_OrderGridAdditions>
</blocks>
<helper>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Helper</class>
</Artizara_OrderGridAdditions>
</helper>
</global>
Then in /Model/Observer.php I have:
class Artizara_OrderGridAdditions_Model_Observer {
public function addAdditionsToGrid(Varien_Event_Observer $observer) {
// code here
}
}
Inside addAdditionsToGrid(), I've tried many different things including copying the entire Grid.php file but nothing seems to work (errors) :(
Please help guide me in remaking this simple module using Events please!
There is no (good) way to add a column to Sales Order Grid with Observers, because there is no event call. Take a look yourself for Mage::dispatchEvent inside Mage_Adminhtml_Block_Sales_Order_Grid and all superclasses.
I think the best practice is extend the grid class like this:
class Artizara_OrderGridAdditions_Block_Sales_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid {
protected function _prepareColumns() {
$this->addColumn(/* your definition here */);
}
}
If you really need do this by observers, you can watch the adminhtml_block_html_before event and dig a way out, but a lot of blocks will call this event either.

How to send category based order emails in magento?

I have two root categories in my magento site. One is "Home Products" and the other is "Office products".
These two root categories have some sub categories also.
I want to send "Home Products" related orders to this email address "email_home#example.com",
And to send "Office Products" related orders to this email address "email_office#example.com".
How will I do this?
I suggest you to write own Observer to order.
sales_order_place_after
event suits best for your purpose.
If buyer can add to shopping cart items only from 1 cateogry.
Your module should:
Get order via observer.
Get order first item and get it's category
Choose email based on category
Send email
public function sendOrder(){
$order = $observer->getEvent()->getOrder();
...
//Implement logic here
...
$emailTemplate = Mage::getModel('core/email_template')
->loadDefault('your_template');
$emailTemplateVariables = array();
$emailTemplateVariables['order'] = $order;
$emailTemplate->setSenderName('Your shops name');
$emailTemplate->setSenderEmail('addres#from.com');
$emailTemplate->setTemplateSubject(Subject');
$emailTemplate->send('to#addres.com','Name', $emailTemplateVariables);
}
Update 1
First of all I insist that you see the link I provide in the comments area.
Then:
To create module:
Create in app/etc/modules/ Company_Module.xml file. With the content similiar to this one:
true
local
This eill tell magento, that in app/code/local/Company/Module there is something interesting to watch.
Create proper folder and file structure.
For you module I think it would be enough:
Company
-Module
--etc
---config.xml
--Model
---Observer.php
--Helper
---Data.php
Magento should know everything about your module. Moreover you should define observer for event.
Important note: we will catch Magento's event. Not ours.
config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Company_Module>
<version>0.1.0</version>
</Company_Module>
</modules>
<global>
<models>
<company_module>
<class>Company_Module_Model</class>
</company_module>
</models>
<helpers>
<cmod>
<class>Company_Module_Helper</class>
</cmod>
</helpers>
<events>
<sales_order_place_after>
<observers>
<sales_order_place_after_observer>
<class>company_module/observer</class>
<method>handleOrder</method>
</sales_order_place_after_observer>
</observers>
</sales_order_place_after>
</events>
</global>
</config>
Data.php - It is empty but it should be.
class Company_Module_Helper_Data extends Mage_Core_Helper_Abstract{
}
Observer.php
class Company_Module_Model_Observer{
public function handleOrder($observer){
$order = $observer->getEvent()->getOrder();
...
//Implement logic here
...
$emailTemplate = Mage::getModel('core/email_template')
->loadDefault('your_template');
$emailTemplateVariables = array();
$emailTemplateVariables['order'] = $order;
$emailTemplate->setSenderName('Your shops name');
$emailTemplate->setSenderEmail('addres#from.com');
$emailTemplate->setTemplateSubject(Subject');
$emailTemplate->send('to#addres.com','Name', $emailTemplateVariables);
}
}
#Jevgeni (and anyone else needing the link), the Link for Magento has moved
http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method

Resources