Magento Mage::getUrl with suffix - magento

What is the correct way to handle generating urls in magento when urls have .html suffixes.
For example, to get the following product url:
category/product.html
You cannot simply do Mage::getUrl('mycategory/myproduct.html') or Mage::getUrl('mycategory/myproduct')
but instead
Mage::getUrl() . 'mycategory/myproduct.html'

You — dont?
The point of having a getUrl method is you provide the abstract, behind the scenes module/controller/action portions of the URL, and then the system handles generating actual HTML urls for you.

Best way to get the product url:
$productId = ***;
$productUrl = Mage::getBaseUrl().Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($productId, 'url_key', Mage::app()->getStore()).Mage::helper('catalog/product')->getProductUrlSuffix();

If you want to get a product url, you should use the following
$product = Mage::getModel('catalog/product')->load($productId);
echo $url = $product->getProductUrl();
If you just have created the product from the backend, you need to get this url just after the save process, you have to get it by using the event catalog_product_save_after, creating an observer class and there you can get the product object thanks to $product = $observer->getEvent()->getProduct();

Related

Prevent automatic URL rewrites created that include category URL key in product URL

Whenever I create a new product, Magento automatically creates unnecessary URL rewrites that include each category and subcategory combination, that use the categories' URL keys in the product path. For example, for a product product-name with the categories:
category
category > subcategory
category > subcategory > third
...Magento will automatically create URL rewrites with the following request paths:
/category/product-name
/category/subcategory/product-name
/category/subcategory/third/product-name
...as well as also creating the in-use URL rewrite with request path:
/product-name
My question is, even though I have the setting Use Categories Path for Product URLs set to No in:
System > Configuration > Catalog > Search Engine Optimizations
...how do I stop these additional URL rewrites from being created automatically?
Now, again, I realize that the site isn't linking to these additional paths anywhere on the site, but if for some reason a search engine picked up:
http://example.com/category/subcategory/third/product-name
...this would load! I'm nervous this will result in duplicate content being indexed by search engines. Since the Use Categories Path for Product URLs setting is set to No, and all links to the product on the site are pointing to:
http://example.com/product-name
...I want to stop Magento from creating these unnecessary URL rewrites automatically.
For reference, I tried truncating the core_url_rewrite table to zero (basically emptying it out) and reindexing the Catalog URL Rewrites in System > Index Management. This still results in Magento automatically creating these unnecessary URL rewrites.
Also, for reference, I am using Magento Community 1.9.1.
Please advise! Your help is much appreciated.
Its not only about canonical links the problem is mainly another: crawling budget. You dont want to waste your crawling budget so the unnecessary urls need to go.
You should modify every entry in core_url_rewrite by shell script which:
is_system = 1
product_id not null
category_id not null
there you set:
target_path = direct product url
options = RP
Now you created 301 redirects to the real page and only have one problem left:
If a product has no category-product-urls no other urls will be created if the feature is turned off via backend config settings, this is what we want.
But if a product yet has category-product-urls and you add this product to a category still a new category-product-url would be created. So you need to change one method by rewriting/extending Mage_Catalog_Model_Url :
/**
* Refresh product rewrite
*
* #param Varien_Object $product
* #param Varien_Object $category
* #return Mage_Catalog_Model_Url
*/
protected function _refreshProductRewrite(Varien_Object $product, Varien_Object $category)
{
//FIX: DONT ADD CATEGORY-PRODUCT-URL - MIGHT HAPPEN IF CATEGORY-PRODUCT-URL EXIST YET FOR THIS PRODUCT
if (Mage::getStoreConfigFlag('catalog/seo/product_use_categories')) {
if ($category->getId() && $product->getId()) {
return $this;
}
}
parent::_refreshProductRewrite($product, $category);
}
I suggest that rather than trying to disable this built-in functionality, instead turn on canonical links. If you have an older version of Magento without this option, there are other ways to implement it.
However, if one were still inclined to remove it, they could probably create an extension that extends Mage_Catalog_Model_Url to do something like this:
class My_Catalog_Model_Url extends Mage_Catalog_Model_Url
{
public function refreshProductRewrite($productId, $storeId = null)
{
if (is_null($storeId)) {
foreach ($this->getStores() as $store) {
$this->refreshProductRewrite($productId, $store->getId());
}
return $this;
}
$product = $this->getResource()->getProduct($productId, $storeId);
if ($product) {
$store = $this->getStores($storeId);
$storeRootCategoryId = $store->getRootCategoryId();
// List of categories the product is assigned to, filtered by being within the store's categories root
// CUSTOMIZATION: Ignore product categories if the 'catalog/seo/product_use_categories' config setting is false.
if (Mage::getStoreConfigFlag('catalog/seo/product_use_categories', $storeId)) {
$categories = $this->getResource()->getCategories($product->getCategoryIds(), $storeId);
} else {
$categories = array();
}
$this->_rewrites = $this->getResource()->prepareRewrites($storeId, '', $productId);
// Add rewrites for all needed categories
// If product is assigned to any of store's categories -
// we also should use store root category to create root product url rewrite
if (!isset($categories[$storeRootCategoryId])) {
$categories[$storeRootCategoryId] = $this->getResource()->getCategory($storeRootCategoryId, $storeId);
}
// Create product url rewrites
foreach ($categories as $category) {
$this->_refreshProductRewrite($product, $category);
}
// Remove all other product rewrites created earlier for this store - they're invalid now
$excludeCategoryIds = array_keys($categories);
$this->getResource()->clearProductRewrites($productId, $storeId, $excludeCategoryIds);
unset($categories);
unset($product);
} else {
// Product doesn't belong to this store - clear all its url rewrites including root one
$this->getResource()->clearProductRewrites($productId, $storeId, array());
}
return $this;
}
}

Laravel routing - shorten the urls upto only one URI segment.

It is said that shorter the URL, better the seo (atleast my client believes on it).
Now am creating website similar to watchtown.co.uk in laravel. I need to generate in such a way that the uri should not be more than one segment.
Requirement
I have following urls:
1.Need to change From:
localhost/laravelproj/public/brands/brandname/watches
to
localhost/laravelproj/public/brandname-watches.html
2.Need to change From:
localhost/laravelproj/public/brands/brandname/jewellery
to
localhost/laravelproj/public/brandname-jewellery.html
3.Need to change From:
localhost/laravelproj/public/categories/categoryname/watches
to
localhost/laravelproj/public/categoryname-watches.html
4.Need to change From:
localhost/laravelproj/public/categories/categoryname/jewellery
to
localhost/laravelproj/public/categoryname-jewellery.html
5.Need to change From:
localhost/laravelproj/public/products/productname
to
localhost/laravelproj/public/productname-watches.html
I hope you understood the pattern .
I can see watchtown.co.uk has done exactly the same (or is it any other way ?)
I created this function in controller for brands:
public function showProductListingByBrands($brandSlug) {
$brand = Brand::findBySlug($brandSlug)->first();
$products = "";
if($brand){
$products = $brand->products()->paginate(Misc::getSetting('paginate'));
}
$products = Product::findBySlug($brandSlug);
return View::make('store');
}
Now how do i manipulate it as my requirement? Im really new in laravel.
Thanks in advance.
Just to give you a brief idea.
On your route page
Route::get('/{product_name}/', array(
'as' => 'product_page',
'uses' => 'ProductPage#getProduct'
));
As you see when the user goes to the page like
Example: www.website.com/watch
it will go to the controller ProductPage with the method of getProduct, so the variable {product_name} will be passed on the controller.
Controller
public function getProduct($product_name = false) {
$product = Products::where('product_name', '=', $product_name);
// Do check product existing record
if ($product->count() == 0) {
return Redirect::route('some-page-error')
->with('failure', 'The hell are you doing?');
} else {
$product = $product->first();
return View::make('product_page')
->with('product_name', $product);
}
}
So on method getProduct, the parameter $product_name is watch
So, the method will check if the product exists or not, if not the user will be redirected to 404 page.
If not, it will be redirected to the template that you've made then pass all the product data and display it all there.
But it would be nice if you put the Route into /product/{product_name}, also it would be also good if it's product id instead of product name since product name can get redundant.
So yea.
edits
I don't know what you're trying to do and why it must be .html, but mmm.. Just wanna give you an idea. Well I don't know if my answer is a good way, someone might give better answer than me.

How can I get the Url of a product from its SKU in Magento

The question is simple.
If I know the sku of my product and nothing else, how can I retrieve the url to that item. This is commonly useful for third party integration where the unique id at the remote service wont match a product id. Or maybe you want to make a search box to search by sku only.
You can just do this:
$sku = 'ecco'; // SKU you want to load. 'ecco' is a sku in the Magento demo data
$url = Mage::getModel('catalog/product')->loadByAttribute('sku',$sku)->getProductUrl();
echo $url;
Also.... You could add this to a file named 'geturlbysku.php' in magento root dir. This code enables a small amount of json representing the product to be pulled easily, enabling small javascript integration. Product URL is part of the dataset
<?php
require_once '/app/Mage.php';
umask(0);
Mage::app('admin');
$actual_link = "http://$_SERVER[HTTP_HOST]";
$sku = $_GET['sku'];
$product = Mage::getModel('catalog/product')->loadByAttribute('sku',$sku);
$fullUrl = "/catalog/product/view/id/" . $product->getId();
header("Content-Type: application/json");
echo $_GET['callback'] . '('.json_encode($product->getData()).')';
?>
Use like this...
www.yoursite.com/geturlbysku.php?sku=theskuoftheproduct
Part of the data returned includes "url_path":"your-product-name.html" which corresponds to the real url.
You can use the load method. This is quicker and easier than all other solutions.
Mage::getModel('catalog/product')->load('sku', 'sku');
For more information on loading products Click Here
$product = Mage::helper('catalog/product')->getProduct($this->getData('sku'), Mage::app()->getStore()->getId(), 'sku');
$url = Mage::getUrl($product->getUrlPath());
You can access the full url of the product based on its sku by adding this to a method and then setting the sku attribute on the class to the sku that you wish to search by.

Codeigniter: Routing and URI Segments

I'm having an issue with routing in codeigniter.
Lets say I have a controller named Pages, with a method named product that does the following:
public function product() {
$this->load->model('pages_model');
$productid = $this->uri->segment(3);
$data['product'] = $this->pages_model->getProduct($productid);
// ...load view, etc.
}
To access a particular product, my url will be www.example.com/pages/product/ID.
I want to setup a custom route so I can access the product by going to www.example.com/name-of-product.
However, putting
$route['name-of-product'] = 'pages/product/ID';
does not work. It will load the product view, but the product data will not be loaded. If I say
$route['name-of-product/:any/ID'] = 'pages/product/ID';
it works as it should, but I would rather not have the two additional segments at the end of the url.
You don't need 2 additional segments. One should be sufficient.
$route['PRODUCT_NAME/PRODUCT_ID'] = 'pages/product/PRODUCT_ID';
However, if I were you I would make the URL to have the first segment to be the id of the product instead.
$route['PRODUCT_ID/PRODUCT_NAME'] = 'pages/product/PRODUCT_ID';
That way, if I only know the product id, I wouldn't have to type example.com//123 which might cause some problem. If I'm not mistaken, if you do that, CI will try to load a controller named 123.

Magento - redirect user group after login

How can I redirect different user groups to different pages in Magento ?
what I want to do is to assign a category to each customer group to redirect the user to it on login.
Thanks a lot.
I have not tried this. I think you need to do the following on the customer_login event:
$session = Mage::getSingleton('customer/session');
$category = // A category object based on $session->getCustomerGroupId()
$session->setBeforeAuthUrl($category->getUrl());
Go to /app/code/local/MagentoPycho/Customer/controllers/AccountController.php and replace this:
$session->setBeforeAuthUrl(Mage::helper('customer')->getAccountUrl());
with this:
$groupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
if($groupId == 5) {
$session->setBeforeAuthUrl('http://google.com');
} else {
// Set default URL to redirect customer to
$session->setBeforeAuthUrl(Mage::helper('customer')->getAccountUrl());
}
Be sure to put your Group ID instead of the "5" and your redirect URL instead of google.com.
I just tried it.
How about this for an approach:
Consider starting with an existing module such as:
http://www.magentocommerce.com/magento-connect/MagePsycho/extension/3763/custom_login_redirect
Then adding your own logic. For the group name of a customer you can try this:
$groupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
$group = Mage::getModel ('customer/group')->load($groupId)->getCode();
If you then have your categories named as per your groups you can do a redirect to http:// + base_url + $group therfore removing the need to explicitly work out what category page to load.
In order to redirect the customer as per customer group, there is a commercial extension:
http://www.magepsycho.com/custom-login-redirect-pro.html
really worths trying. FYI many merchants are using this module for their magento sites.
Happy e-commerce!!
Regards

Resources