We currently use the {html_image file='pumpkin.jpg'} which calculates the width/height of a image.
What I would like to do is add an extra parameter to the function so you can pass in the container(parent) height.
The plugin would then calculate the margin-top by calculating: (container_height - image_height) / 2
At the moment we are doing this by JS and because the images are resized dynamically there is a slight delay. If we did this via Smarty the margin-top would be cached.
As an example if the image [foo.jpg] was 50px height and the container height was 100px:
{html_image file="images/foo.jpg" containerHeight=100}
<img src="images/foo.jpg" width="60" height="50" style="margin-top: 25px" alt="" />
http://www.smarty.net/docs/en/language.function.html.image.tpl
<?php
/**
* Smarty plugin
*
* #package Smarty
* #subpackage PluginsFunction
*/
/**
* Smarty {html_image} function plugin
*
* Type: function<br>
* Name: html_image<br>
* Date: Feb 24, 2003<br>
* Purpose: format HTML tags for the image<br>
* Examples: {html_image file="/images/masthead.gif"}
* Output: <img src="/images/masthead.gif" width=400 height=23>
*
* #link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
* (Smarty online manual)
* #author Monte Ohrt <monte at ohrt dot com>
* #author credits to Duda <duda#big.hu>
* #version 1.0
* #param array $params parameters
* Input:<br>
* - file = file (and path) of image (required)
* - height = image height (optional, default actual height)
* - width = image width (optional, default actual width)
* - basedir = base directory for absolute paths, default
* is environment variable DOCUMENT_ROOT
* - path_prefix = prefix for path output (optional, default empty)
* #param object $template template object
* #return string
* #uses smarty_function_escape_special_chars()
*/
function smarty_function_html_image($params, $template)
{
require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
$alt = '';
$file = '';
$height = '';
$width = '';
$extra = '';
$prefix = '';
$suffix = '';
$path_prefix = '';
$server_vars = $_SERVER;
$basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
foreach($params as $_key => $_val) {
switch ($_key) {
case 'file':
case 'height':
case 'width':
case 'dpi':
case 'path_prefix':
case 'basedir':
$$_key = $_val;
break;
case 'alt':
if (!is_array($_val)) {
$$_key = smarty_function_escape_special_chars($_val);
} else {
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
case 'link':
case 'href':
$prefix = '<a href="' . $_val . '">';
$suffix = '</a>';
break;
default:
if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
} else {
throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
}
}
if (empty($file)) {
trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
return;
}
if (substr($file, 0, 1) == '/') {
$_image_path = $basedir . $file;
} else {
$_image_path = $file;
}
if (!isset($params['width']) || !isset($params['height'])) {
if (!$_image_data = #getimagesize($_image_path)) {
if (!file_exists($_image_path)) {
trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
return;
} else if (!is_readable($_image_path)) {
trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
return;
} else {
trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
return;
}
}
if (isset($template->security_policy)) {
if (!$template->security_policy->isTrustedResourceDir($_image_path)) {
return;
}
}
if (!isset($params['width'])) {
$width = $_image_data[0];
}
if (!isset($params['height'])) {
$height = $_image_data[1];
}
}
if (isset($params['dpi'])) {
if (strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
$dpi_default = 72;
} else {
$dpi_default = 96;
}
$_resize = $dpi_default / $params['dpi'];
$width = round($width * $_resize);
$height = round($height * $_resize);
}
return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix;
}
?>
Try to add this before the plugin function return statement:
if (isset($params['containerHeight'])) {
$containerHeightAttr = ' style="margin-top: ' . intval(($params['containerHeight'] - $height) / 2) . 'px;"';
$extra .= $containerHeightAttr;
}
Here the full file:
http://pastebin.com/raw.php?i=V9eGsXVF
Try it and let me know if there are errors. I've not tested it, but i'm here to eventually fix problems.
Related
I have custom code that determines if a custom code value exists and if it does to select this option over the default sort order option in the product config.
What I am wanting to do is further add logic that if the product sku starts with "F" then it will show the default sort order value for that product.
The custom code is in this file..
app\code\local\Mage\Catalog\Block\Product\View\Options\Type\Select.php
Here is the code in question
// Set Default for the following cases:
// Ring Size for Men = T, Women = M
// Price for Custom Option is $0 and is the last, unless defaulted by Men or Women.
// if ($_value->getTitle() == 'M' && $isFemale) {
// $select->setValue($_value->getOptionTypeId());
// }
// else if ($_value->getTitle() == 'T' && $isMale) {
// $select->setValue($_value->getOptionTypeId());
// }
// else if ($_value->getPrice() == 0.0000 && $hasNoPrice && !$isFemale && !$isMale) {
// $select->setValue($_value->getOptionTypeId());
// }
if ($_value->getTitle() == 'M') {
$select->setValue($_value->getOptionTypeId());
}
else if ($_value->getTitle() == 'T') {
$select->setValue($_value->getOptionTypeId());
}
}
This code is ok as is.. but what I am wanting to add to the statements is that if the Stock code starts with 'F' then assign the default value.
something like
if ($sku_code == 'F') {
$select->setValue($configValue);
}
where this will show the default sort order value for the option..
I just cant seem to get this working.
Any help coding this and you get instant kudos and good Karma!
cheers
update Here is full code from Select.php
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license#magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* #category Mage
* #package Mage_Catalog
* #copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
* #license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Product options text type block
*
* #category Mage
* #package Mage_Catalog
* #author Magento Core Team <core#magentocommerce.com>
*/
class Mage_Catalog_Block_Product_View_Options_Type_Select
extends Mage_Catalog_Block_Product_View_Options_Abstract
{
/**
* Return html for control element
*
* #return string
*/
public function getValuesHtml()
{
$_option = $this->getOption();
$configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId());
$store = $this->getProduct()->getStore();
if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN
|| $_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) {
$require = ($_option->getIsRequire()) ? ' required-entry' : '';
$extraParams = '';
$select = $this->getLayout()->createBlock('core/html_select')
->setData(array(
'id' => 'select_'.$_option->getId(),
'class' => $require.' product-custom-option'
));
if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN) {
$select->setName('options['.$_option->getid().']');
// ->addOption('', $this->__('Please Select'));
} else {
$select->setName('options['.$_option->getid().'][]');
$select->setClass('multiselect'.$require.' product-custom-option');
}
// This is a very specific case for Ring Size
// $isMale = $isFemale = $hasNoPrice = false;
// foreach ($_option->getValues() as $_value) {
// if ($_value->getTitle() == 'I' && $_value->getPrice() == 0.0000) {
// $isFemale = true;
// }
// else if ($_value->getTitle() == 'M' && $_value->getPrice() == 0.0000) {
// $isMale = true;
// }
// if ($_value->getPrice() == 0.0000) {
// $hasNoPrice = true;
// }
// }
foreach ($_option->getValues() as $_value) {
$priceStr = $this->_formatPrice(array(
'is_percent' => ($_value->getPriceType() == 'percent'),
'pricing_value' => $_value->getPrice(($_value->getPriceType() == 'percent'))
), false);
$select->addOption(
$_value->getOptionTypeId(),
$_value->getTitle() . ' ' . $priceStr . '',
array('price' => $this->helper('core')->currencyByStore($_value->getPrice(true), $store, false))
);
// Set Default for the following cases:
// Ring Size for Men = T, Women = M
// Price for Custom Option is $0 and is the last, unless defaulted by Men or Women.
// if ($_value->getTitle() == 'M' && $isFemale) {
// $select->setValue($_value->getOptionTypeId());
// }
// else if ($_value->getTitle() == 'T' && $isMale) {
// $select->setValue($_value->getOptionTypeId());
// }
// else if ($_value->getPrice() == 0.0000 && $hasNoPrice && !$isFemale && !$isMale) {
// $select->setValue($_value->getOptionTypeId());
// }
//not sure about this line
if ($sku_code[0] == 'F') {
$select->setValue($configValue);
}
else if ($_value->getTitle() == 'M') {
$select->setValue($_value->getOptionTypeId());
}
else if ($_value->getTitle() == 'T') {
$select->setValue($_value->getOptionTypeId());
}
}
if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) {
$extraParams = ' multiple="multiple"';
}
if (!$this->getSkipJsReloadPrice()) {
$extraParams .= ' onchange="opConfig.reloadPrice()"';
}
$select->setExtraParams($extraParams);
if ($configValue) {
$select->setValue($configValue);
}
return $select->getHtml();
}
if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_RADIO
|| $_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_CHECKBOX
) {
$selectHtml = '<ul id="options-'.$_option->getId().'-list" class="options-list">';
$require = ($_option->getIsRequire()) ? ' validate-one-required-by-name' : '';
$arraySign = '';
switch ($_option->getType()) {
case Mage_Catalog_Model_Product_Option::OPTION_TYPE_RADIO:
$type = 'radio';
$class = 'radio';
if (!$_option->getIsRequire()) {
$selectHtml .= '<li><input type="radio" id="options_' . $_option->getId() . '" class="'
. $class . ' product-custom-option" name="options[' . $_option->getId() . ']"'
. ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"')
. ' value="" checked="checked" /><span class="label"><label for="options_'
. $_option->getId() . '">' . $this->__('None') . '</label></span></li>';
}
break;
case Mage_Catalog_Model_Product_Option::OPTION_TYPE_CHECKBOX:
$type = 'checkbox';
$class = 'checkbox';
$arraySign = '[]';
break;
}
$count = 1;
foreach ($_option->getValues() as $_value) {
$count++;
$priceStr = $this->_formatPrice(array(
'is_percent' => ($_value->getPriceType() == 'percent'),
'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent')
));
$htmlValue = $_value->getOptionTypeId();
if ($arraySign) {
$checked = (is_array($configValue) && in_array($htmlValue, $configValue)) ? 'checked' : '';
} else {
$checked = $configValue == $htmlValue ? 'checked' : '';
}
$selectHtml .= '<li>' . '<input type="' . $type . '" class="' . $class . ' ' . $require
. ' product-custom-option"'
. ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"')
. ' name="options[' . $_option->getId() . ']' . $arraySign . '" id="options_' . $_option->getId()
. '_' . $count . '" value="' . $htmlValue . '" ' . $checked . ' price="'
. $this->helper('core')->currencyByStore($_value->getPrice(true), $store, false) . '" />'
. '<span class="label"><label for="options_' . $_option->getId() . '_' . $count . '">'
. $_value->getTitle() . ' ' . $priceStr . '</label></span>';
if ($_option->getIsRequire()) {
$selectHtml .= '<script type="text/javascript">' . '$(\'options_' . $_option->getId() . '_'
. $count . '\').advaiceContainer = \'options-' . $_option->getId() . '-container\';'
. '$(\'options_' . $_option->getId() . '_' . $count
. '\').callbackFunction = \'validateOptionsCallback\';' . '</script>';
}
$selectHtml .= '</li>';
}
$selectHtml .= '</ul>';
return $selectHtml;
}
}
}
maybe I don't understand right but you want to see if the sku_code starts with "f"?
EDIT:
if ($sku_code == 'F') {
$select->setValue($configValue);
}
Try:
if (strpos($sku_code, 'F') === 0) {
$select->setValue($configValue);
}
Or perhaps:
if (substr($sku_code, 0, 1) === 'F') { $select->setValue($configValue); }
Hope it helps :)
On my codeigniter pagination links I am using bootstrap 3 +
When I am on the very first link it hides the << which goes back to start when I click on it.
1 2 >>
Question How can I make the codeigniter pagination all ways display << >> I have tried Always show Previous & Next links using CodeIgniter Pagination Class but is for CI2
$config['base_url'] = base_url('forum/?fid=' . $this->input->get('fid') . $url);
$config['total_rows'] = $this->thread_model->total_threads($this->input->get('fid'));
$config['per_page'] = $this->config->item('config_limit_admin');
$config['page_query_string'] = TRUE;
$config["full_tag_open"] = '<ul class="pagination">';
$config["full_tag_close"] = '</ul>';
$config["first_link"] = "«";
$config["first_tag_open"] = "<li>";
$config["first_tag_close"] = "</li>";
$config["last_link"] = "»";
$config["last_tag_open"] = "<li>";
$config["last_tag_close"] = "</li>";
$config['next_link'] = '»';
$config['next_tag_open'] = '<li>';
$config['next_tag_close'] = '<li>';
$config['prev_link'] = '«';
$config['prev_tag_open'] = '<li>';
$config['prev_tag_close'] = '<li>';
$config['cur_tag_open'] = '<li class="active"><a href="#">';
$config['cur_tag_close'] = '</a></li>';
$config['num_tag_open'] = '<li>';
$config['num_tag_close'] = '</li>';
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
I have just override the create_links() of core library in slightly different way to achieve this. So All you have to do is create a file name My_Pagination.php inapplication/libraries and put this code there (Code copied from create_link() method from core library Pagination.php)
My_Pagination.php file (Codeigniter 3.1.0)
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Pagination extends CI_Pagination {
public function create_links() {
if ($this->total_rows == 0 OR $this->per_page == 0) {
return '';
}
// Calculate the total number of pages
$num_pages = (int) ceil($this->total_rows / $this->per_page);
if ($num_pages === 1) {
return '';
}
// Check the user defined number of links.
$this->num_links = (int) $this->num_links;
if ($this->num_links < 0) {
show_error('Your number of links must be a non-negative number.');
}
// Keep any existing query string items.
// Note: Has nothing to do with any other query string option.
if ($this->reuse_query_string === TRUE) {
$get = $this->CI->input->get();
// Unset the controll, method, old-school routing options
unset($get['c'], $get['m'], $get[$this->query_string_segment]);
} else {
$get = array();
}
// Put together our base and first URLs.
// Note: DO NOT append to the properties as that would break successive calls
$base_url = trim($this->base_url);
$first_url = $this->first_url;
$query_string = '';
$query_string_sep = (strpos($base_url, '?') === FALSE) ? '?' : '&';
// Are we using query strings?
if ($this->page_query_string === TRUE) {
// If a custom first_url hasn't been specified, we'll create one from
// the base_url, but without the page item.
if ($first_url === '') {
$first_url = $base_url;
// If we saved any GET items earlier, make sure they're appended.
if (!empty($get)) {
$first_url .= $query_string_sep . http_build_query($get);
}
}
// Add the page segment to the end of the query string, where the
// page number will be appended.
$base_url .= $query_string_sep . http_build_query(array_merge($get, array($this->query_string_segment => '')));
} else {
// Standard segment mode.
// Generate our saved query string to append later after the page number.
if (!empty($get)) {
$query_string = $query_string_sep . http_build_query($get);
$this->suffix .= $query_string;
}
// Does the base_url have the query string in it?
// If we're supposed to save it, remove it so we can append it later.
if ($this->reuse_query_string === TRUE && ($base_query_pos = strpos($base_url, '?')) !== FALSE) {
$base_url = substr($base_url, 0, $base_query_pos);
}
if ($first_url === '') {
$first_url = $base_url . $query_string;
}
$base_url = rtrim($base_url, '/') . '/';
}
// Determine the current page number.
$base_page = ($this->use_page_numbers) ? 1 : 0;
// Are we using query strings?
if ($this->page_query_string === TRUE) {
$this->cur_page = $this->CI->input->get($this->query_string_segment);
} elseif (empty($this->cur_page)) {
// Default to the last segment number if one hasn't been defined.
if ($this->uri_segment === 0) {
$this->uri_segment = count($this->CI->uri->segment_array());
}
$this->cur_page = $this->CI->uri->segment($this->uri_segment);
// Remove any specified prefix/suffix from the segment.
if ($this->prefix !== '' OR $this->suffix !== '') {
$this->cur_page = str_replace(array($this->prefix, $this->suffix), '', $this->cur_page);
}
} else {
$this->cur_page = (string) $this->cur_page;
}
// If something isn't quite right, back to the default base page.
if (!ctype_digit($this->cur_page) OR ( $this->use_page_numbers && (int) $this->cur_page === 0)) {
$this->cur_page = $base_page;
} else {
// Make sure we're using integers for comparisons later.
$this->cur_page = (int) $this->cur_page;
}
// Is the page number beyond the result range?
// If so, we show the last page.
if ($this->use_page_numbers) {
if ($this->cur_page > $num_pages) {
$this->cur_page = $num_pages;
}
} elseif ($this->cur_page > $this->total_rows) {
$this->cur_page = ($num_pages - 1) * $this->per_page;
}
$uri_page_number = $this->cur_page;
// If we're using offset instead of page numbers, convert it
// to a page number, so we can generate the surrounding number links.
if (!$this->use_page_numbers) {
$this->cur_page = (int) floor(($this->cur_page / $this->per_page) + 1);
}
// Calculate the start and end numbers. These determine
// which number to start and end the digit links with.
$start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
$end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
// And here we go...
$output = '';
// Render the "First" link.
if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1 + !$this->num_links)) {
// Take the general parameters, and squeeze this pagination-page attr in for JS frameworks.
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, 1);
$output .= $this->first_tag_open . '<a href="' . $first_url . '"' . $attributes . $this->_attr_rel('start') . '>'
. $this->first_link . '</a>' . $this->first_tag_close;
}
// Render the "Previous" link.
//if ($this->prev_link !== FALSE && $this->cur_page !== 1)
if ($this->prev_link !== FALSE) {//REMOVED $this->cur_page !== 1
$i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, ($this->cur_page - 1));
if ($i === $base_page || $this->cur_page == 1) {//ADDED $this->cur_page == 1
// First page
$output .= $this->prev_tag_open . '<a href="' . $first_url . '"' . $attributes . $this->_attr_rel('prev') . '>'
. $this->prev_link . '</a>' . $this->prev_tag_close;
} else {
$append = $this->prefix . $i . $this->suffix;
$output .= $this->prev_tag_open . '<a href="' . $base_url . $append . '"' . $attributes . $this->_attr_rel('prev') . '>'
. $this->prev_link . '</a>' . $this->prev_tag_close;
}
}
// Render the pages
if ($this->display_pages !== FALSE) {
// Write the digit links
for ($loop = $start - 1; $loop <= $end; $loop++) {
$i = ($this->use_page_numbers) ? $loop : ($loop * $this->per_page) - $this->per_page;
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $loop);
if ($i >= $base_page) {
if ($this->cur_page === $loop) {
// Current page
$output .= $this->cur_tag_open . $loop . $this->cur_tag_close;
} elseif ($i === $base_page) {
// First page
$output .= $this->num_tag_open . '<a href="' . $first_url . '"' . $attributes . $this->_attr_rel('start') . '>'
. $loop . '</a>' . $this->num_tag_close;
} else {
$append = $this->prefix . $i . $this->suffix;
$output .= $this->num_tag_open . '<a href="' . $base_url . $append . '"' . $attributes . '>'
. $loop . '</a>' . $this->num_tag_close;
}
}
}
}
// Render the "next" link
//if ($this->next_link !== FALSE && $this->cur_page < $num_pages)
if ($this->next_link !== FALSE) {//REMOVED $this->cur_page < $num_pages
$i = ($this->use_page_numbers) ? $this->cur_page + 1 : $this->cur_page * $this->per_page;
if($this->cur_page == $num_pages){//WHEN LAST LINK
$i = $num_pages;
}
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $this->cur_page + 1);
$output .= $this->next_tag_open . '<a href="' . $base_url . $this->prefix . $i . $this->suffix . '"' . $attributes
. $this->_attr_rel('next') . '>' . $this->next_link . '</a>' . $this->next_tag_close;
}
// Render the "Last" link
if ($this->last_link !== FALSE && ($this->cur_page + $this->num_links + !$this->num_links) < $num_pages) {
$i = ($this->use_page_numbers) ? $num_pages : ($num_pages * $this->per_page) - $this->per_page;
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, $num_pages);
$output .= $this->last_tag_open . '<a href="' . $base_url . $this->prefix . $i . $this->suffix . '"' . $attributes . '>'
. $this->last_link . '</a>' . $this->last_tag_close;
}
$output = preg_replace('#([^:"])//+#', '\\1/', $output);
return $this->full_tag_open . $output . $this->full_tag_close;
}
}
Just removed 2 condition
$this->cur_page !== 1 (This is below // Render the "Previous" link COMMENT)
$this->cur_page < $num_pages (This is below // Render the "next" link COMMENT)
Added 2 condition
if ($i === $base_page){... changed this as if ($i === $base_page || $this->cur_page == 1) {...
Added this inside if ($this->next_link !== FALSE) {... condition
if($this->cur_page == $num_pages){
$i = $num_pages;
}
None you have to do except putting this file in libraries directory and now your << and >> links will show always even you may change it in config as normal configuration
Well, you'll have to modify the create_links of the Pagination class. What I'd do it's extending the system/libraries/Pagination.php class with a MY_Pagination.php, so you override the behaviour and you can modify it accordingly to your preferences.
By the way, checking the class, I think you should look into lines 563 on:
// Render the "First" link.
if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1 + ! $this->num_links))
{
// Take the general parameters, and squeeze this pagination-page attr in for JS frameworks.
$attributes = sprintf('%s %s="%d"', $this->_attributes, $this->data_page_attr, 1);
$output .= $this->first_tag_open.'<a href="'.$first_url.'"'.$attributes.$this->_attr_rel('start').'>'
.$this->first_link.'</a>'.$this->first_tag_close;
}
You'll have to take care of the if condition to always render the link.
I have the below code that creates a custom menu in Magento:
<?php
/**
* Catalog navigation
*/
class Infortis_Ultimo_Block_Navigation extends Mage_Core_Block_Template
{
//NEW:
protected $_isAccordion = FALSE;
protected $_categoryInstance = null;
/**
* Current category key
*
* #var string
*/
protected $_currentCategoryKey;
/**
* Array of level position counters
*
* #var array
*/
protected $_itemLevelPositions = array();
protected function _construct()
{
$this->addData(array(
'cache_lifetime' => false,
'cache_tags' => array(Mage_Catalog_Model_Category::CACHE_TAG, Mage_Core_Model_Store_Group::CACHE_TAG),
));
}
/**
* Get Key pieces for caching block content
*
* #return array
*/
public function getCacheKeyInfo()
{
$shortCacheId = array(
'CATALOG_NAVIGATION',
Mage::app()->getStore()->getId(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
Mage::getSingleton('customer/session')->getCustomerGroupId(),
'template' => $this->getTemplate(),
'name' => $this->getNameInLayout(),
$this->getCurrenCategoryKey()
);
$cacheId = $shortCacheId;
$shortCacheId = array_values($shortCacheId);
$shortCacheId = implode('|', $shortCacheId);
$shortCacheId = md5($shortCacheId);
$cacheId['category_path'] = $this->getCurrenCategoryKey();
$cacheId['short_cache_id'] = $shortCacheId;
return $cacheId;
}
/**
* Get current category key
*
* #return mixed
*/
public function getCurrenCategoryKey()
{
if (!$this->_currentCategoryKey) {
$category = Mage::registry('current_category');
if ($category) {
$this->_currentCategoryKey = $category->getPath();
} else {
$this->_currentCategoryKey = Mage::app()->getStore()->getRootCategoryId();
}
}
return $this->_currentCategoryKey;
}
/**
* Get catagories of current store
*
* #return Varien_Data_Tree_Node_Collection
*/
public function getStoreCategories()
{
$helper = Mage::helper('catalog/category');
return $helper->getStoreCategories();
}
/**
* Retrieve child categories of current category
*
* #return Varien_Data_Tree_Node_Collection
*/
public function getCurrentChildCategories()
{
$layer = Mage::getSingleton('catalog/layer');
$category = $layer->getCurrentCategory();
/* #var $category Mage_Catalog_Model_Category */
$categories = $category->getChildrenCategories();
$productCollection = Mage::getResourceModel('catalog/product_collection');
$layer->prepareProductCollection($productCollection);
$productCollection->addCountToCategories($categories);
return $categories;
}
/**
* Checkin activity of category
*
* #param Varien_Object $category
* #return bool
*/
public function isCategoryActive($category)
{
if ($this->getCurrentCategory()) {
return in_array($category->getId(), $this->getCurrentCategory()->getPathIds());
}
return false;
}
protected function _getCategoryInstance()
{
if (is_null($this->_categoryInstance)) {
$this->_categoryInstance = Mage::getModel('catalog/category');
}
return $this->_categoryInstance;
}
/**
* Get url for category data
*
* #param Mage_Catalog_Model_Category $category
* #return string
*/
public function getCategoryUrl($category)
{
if ($category instanceof Mage_Catalog_Model_Category) {
$url = $category->getUrl();
} else {
$url = $this->_getCategoryInstance()
->setData($category->getData())
->getUrl();
}
return $url;
}
/**
* Return item position representation in menu tree
*
* #param int $level
* #return string
*/
protected function _getItemPosition($level)
{
if ($level == 0) {
$zeroLevelPosition = isset($this->_itemLevelPositions[$level]) ? $this->_itemLevelPositions[$level] + 1 : 1;
$this->_itemLevelPositions = array();
$this->_itemLevelPositions[$level] = $zeroLevelPosition;
} elseif (isset($this->_itemLevelPositions[$level])) {
$this->_itemLevelPositions[$level]++;
} else {
$this->_itemLevelPositions[$level] = 1;
}
$position = array();
for($i = 0; $i <= $level; $i++) {
if (isset($this->_itemLevelPositions[$i])) {
$position[] = $this->_itemLevelPositions[$i];
}
}
return implode('-', $position);
}
/**
* Render category to html
*
* #param Mage_Catalog_Model_Category $category
* #param int Nesting level number
* #param boolean Whether ot not this item is last, affects list item class
* #param boolean Whether ot not this item is first, affects list item class
* #param boolean Whether ot not this item is outermost, affects list item class
* #param string Extra class of outermost list items
* #param string If specified wraps children list in div with this class
* #param boolean Whether ot not to add on* attributes to list item
* #return string
*/
protected function _renderCategoryMenuItemHtml($category, $level = 0, $isLast = false, $isFirst = false,
$isOutermost = false, $outermostItemClass = '', $childrenWrapClass = '', $noEventAttributes = false)
{
if (!$category->getIsActive()) {
return '';
}
$html = array();
// get all children
if (Mage::helper('catalog/category_flat')->isEnabled()) {
$children = (array)$category->getChildrenNodes();
$childrenCount = count($children);
} else {
$children = $category->getChildren();
$childrenCount = $children->count();
}
$hasChildren = ($children && $childrenCount);
// select active children
$activeChildren = array();
foreach ($children as $child) {
if ($child->getIsActive()) {
$activeChildren[] = $child;
}
}
$activeChildrenCount = count($activeChildren);
$hasActiveChildren = ($activeChildrenCount > 0);
// prepare list item html classes
$classes = array();
$classes[] = 'level' . $level;
$classes[] = 'nav-' . $this->_getItemPosition($level);
if ($this->isCategoryActive($category)) {
$classes[] = 'active';
}
$linkClass = '';
if ($isOutermost && $outermostItemClass) {
$classes[] = $outermostItemClass;
$linkClass = ' class="'.$outermostItemClass.'"';
}
if ($isFirst) {
$classes[] = 'first';
}
if ($isLast) {
$classes[] = 'last';
}
if ($hasActiveChildren) {
$classes[] = 'parent';
}
//NEW: add special class if level == 1 and menu is not an accordion.
if ($this->_isAccordion == FALSE && $level == 1) {
$classes[] = 'item';
}
// prepare list item attributes
$attributes = array();
if (count($classes) > 0) {
$attributes['class'] = implode(' ', $classes);
}
if ($hasActiveChildren && !$noEventAttributes) {
$attributes['onmouseover'] = 'toggleMenu(this,1)';
$attributes['onmouseout'] = 'toggleMenu(this,0)';
}
// assemble list item with attributes
$htmlLi = '<li';
foreach ($attributes as $attrName => $attrValue) {
$htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
}
$htmlLi .= '>';
$html[] = $htmlLi;
if ($level == 0 && $hasChildren) {
$html[] = '<a href="javascript:void(0)"'.$linkClass.'>';
$html[] = '<span>' . $this->escapeHtml($category->getName()) . '</span>';
$html[] = '</a>';
}
else {
$html[] = '<a href="'.$this->getCategoryUrl($category).'"'.$linkClass.'>';
$html[] = '<span>' . $this->escapeHtml($category->getName()) . '</span>';
$html[] = '</a>';
}
// render children
$htmlChildren = '';
$j = 0;
foreach ($activeChildren as $child) {
$htmlChildren .= $this->_renderCategoryMenuItemHtml(
$child,
($level + 1),
($j == $activeChildrenCount - 1),
($j == 0),
false,
$outermostItemClass,
$childrenWrapClass,
$noEventAttributes
);
$j++;
}
if (!empty($htmlChildren)) {
//NEW: add opener if menu is used as accordion.
if ($this->_isAccordion == TRUE)
$html[] = '<span class="opener"> </span>';
if ($childrenWrapClass) {
$html[] = '<div class="' . $childrenWrapClass . '">';
}
$html[] = '<ul class="level' . $level . '">';
$html[] = $htmlChildren;
$html[] = '</ul>';
if ($childrenWrapClass) {
$html[] = '</div>';
}
}
$html[] = '</li>';
$html = implode("\n", $html);
return $html;
}
/**
* Render category to html
*
* #deprecated deprecated after 1.4
* #param Mage_Catalog_Model_Category $category
* #param int Nesting level number
* #param boolean Whether ot not this item is last, affects list item class
* #return string
*/
public function drawItem($category, $level = 0, $last = false)
{
return $this->_renderCategoryMenuItemHtml($category, $level, $last);
}
/**
* Enter description here...
*
* #return Mage_Catalog_Model_Category
*/
public function getCurrentCategory()
{
if (Mage::getSingleton('catalog/layer')) {
return Mage::getSingleton('catalog/layer')->getCurrentCategory();
}
return false;
}
/**
* Enter description here...
*
* #return string
*/
public function getCurrentCategoryPath()
{
if ($this->getCurrentCategory()) {
return explode(',', $this->getCurrentCategory()->getPathInStore());
}
return array();
}
/**
* Enter description here...
*
* #param Mage_Catalog_Model_Category $category
* #return string
*/
public function drawOpenCategoryItem($category) {
$html = '';
if (!$category->getIsActive()) {
return $html;
}
$html.= '<li';
if ($this->isCategoryActive($category)) {
$html.= ' class="active"';
}
$html.= '>'."\n";
$html.= '<span>'.$this->htmlEscape($category->getName()).'</span>'."\n";
if (in_array($category->getId(), $this->getCurrentCategoryPath())){
$children = $category->getChildren();
$hasChildren = $children && $children->count();
if ($hasChildren) {
$htmlChildren = '';
foreach ($children as $child) {
$htmlChildren.= $this->drawOpenCategoryItem($child);
}
if (!empty($htmlChildren)) {
$html.= '<ul>'."\n"
.$htmlChildren
.'</ul>';
}
}
}
$html.= '</li>'."\n";
return $html;
}
/**
* Render categories menu in HTML
*
* #param bool Add opener if menu is used as accordion.
* #param int Level number for list item class to start from
* #param string Extra class of outermost list items
* #param string If specified wraps children list in div with this class
* #return string
*/
public function renderCategoriesMenuHtml($isAccordion = FALSE, $level = 0, $outermostItemClass = '', $childrenWrapClass = '')
{
//NEW: save additional attribute
$this->_isAccordion = $isAccordion;
$activeCategories = array();
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive()) {
$activeCategories[] = $child;
}
}
$activeCategoriesCount = count($activeCategories);
$hasActiveCategoriesCount = ($activeCategoriesCount > 0);
if (!$hasActiveCategoriesCount) {
return '';
}
$html = '';
$j = 0;
foreach ($activeCategories as $category) {
$html .= $this->_renderCategoryMenuItemHtml(
$category,
$level,
($j == $activeCategoriesCount - 1),
($j == 0),
true,
$outermostItemClass,
$childrenWrapClass,
true
);
$j++;
}
return $html;
}
}
I would like to add a custom category attribute (menu_label) to the menu items. I have created the custom category attribute using this tutorial http://www.atwix.com/magento/add-category-attribute/
The attribute shows up fine in admin and I can get it to print out on my normal template files but can't get it to show in this menu.
I thought $this->escapeHtml($category->getMenuLabel()) would have done it but this doesn't output anything.
Any ideas?
You have to consider the fact that Magento is not acting the same with flat categories enable or disable.
I suppose you may be with flat category enabled, in your case, because it should work otherwise.
(Please check in System > Configuration > Catalog > Catalog > Frontend the field Use Flat Catalog Category. If it is set to Yes, then that is where your problem is.)
To solve it add this to your config.xml in the frontend node:
<events>
<catalog_category_flat_loadnodes_before>
<observers>
<somemodule>
<type>singleton</type>
<class>somemodule/observer</class>
<method>addMenuAttributes</method>
</somemodule>
</observers>
</catalog_category_flat_loadnodes_before>
</events>
Then create an Observer.php in the Model folder of your module (the model folder should be declared in your config.xml too, of course).
Here is the observer code:
<?php
class Somecompany_Somemodule_Model_Observer {
public function addMenuAttributes(Varien_Event_Observer $observer) {
$observer->getSelect()->columns(
array('menu_label')
);
}
}
You assumtion is incorrect:
$this->escapeHtml($category->getMenuLabel())
This assumes $category is indeed a Category Model (Mage_Catalog_Model_category) when infact it's not, it's a Node object.
if you look here:
Mage_Catalog_Model_Observer::_addCategoriesToMenu()
You will notice where the actual catalog model is used to create an array which is passed to the Navigation routine as a Varien_Data_Tree_Node.
You can add in your custom attribute here, and then access it inside the block.
$categoryData = array(
'name' => $category->getName(),
'id' => $nodeId,
'url' => Mage::helper('catalog/category')->getCategoryUrl($category),
'is_active' => $this->_isActiveMenuCategory($category),
'my_attribute' => $category->getData('my_attribute')
);
You will then be able to access the attribute inside your custom menu block:
$child->getData('my_attribute');
//$this->escapeHtml($category->getData('my_attribute'))
While i run a component i am getting 500 - An error has occurred error reading db in joomla.
My configuration file is perfect.
I don't know what else to change..
Any guidance will be helpful
Thanks in advance...
//No direct acesss
defined('_JEXEC') or die();
jimport('joomla.application.component.model');
class DealsModelDeals extends JModel {
function getDeals(){
$db = $this->getDBO();
$db->setQuery('SELECT * from #__todaysdeal');
$deals = $db->loadObjectList();
if ($deals === null)
JError::raiseError(500, 'Error reading db');
return $deals;
}
function getDeal($id){
$query = ' SELECT * FROM #__todaysdeal '. ' WHERE id = '.$id;
$db = $this->getDBO();
$db->setQuery($query);
$deal = $db->loadObject();
if ($deal === null)
JError::raiseError(500, 'Deal with ID: '.$id.' not found.');
else
return $deal;
}
/**
* Method that returns an empty greeting with id 0
*
* #access public
*/
function getNewDeal(){
$dealTableRow =& $this->getTable('deals');
$dealTableRow->id=0;
$dealTableRow->clientName='';
return $dealTableRow;
}
/**
* Method to store a greeting in the DB
*
* #access public
*/
function saveDeal($deal)
{
//Parameter not necessary because our model is named DealsModelDeals (used to ilustrate that you can specify an alternative name to the JTable extending class)
$dealTableRow =& $this->getTable('deals');
//print_r($dealTableRow);
//print_r($_FILES); exit;
// Bind the form fields to the todaysdeal table
if (!$dealTableRow->bind($deal)) {
JError::raiseError(500, 'Error binding data');
}
// Make sure the deal record is valid
if (!$dealTableRow->check()) {
JError::raiseError(500, 'Invalid data');
}
// Insert/update this record in the db
if (!$dealTableRow->store()) {
$errorMessage = $dealTableRow->getError();
JError::raiseError(500, 'Error binding data: '.$errorMessage);
}
$id = $dealTableRow->id;
if(!empty($_FILES['dealImage']))
{
$file = $_FILES['dealImage'];
$id = $dealTableRow->id;
if ((($_FILES["dealImage"]["type"] == "image/gif") || ($_FILES["dealImage"]["type"] == "image/jpeg") || ($_FILES["dealImage"]["type"] == "image/pjpeg")) && ($_FILES["dealImage"]["size"] < 150000))
{
if ($_FILES["dealImage"]["error"] > 0)
{
echo "Return Code: " . $_FILES["dealImage"]["error"] . "<br />";
}
else
{
if (file_exists("components/com_deals/dealImages/" . $_FILES["dealImage"]["name"])) {
$_FILES["dealImage"]["name"] . " already exists. ";
} else {
move_uploaded_file($_FILES["dealImage"]["tmp_name"], "components/com_deals/dealImages/" .$id."_".$_FILES["dealImage"]["name"]);
echo "Stored in: " . "dealImages/" . $_FILES["dealImage"]["name"];
}
}
}
else
{
}
}
$dealImage = $_FILES['dealImage']['name'];
$dealImage .= (!empty($_FILES['dealImage']['name'])) ? ' ' . $_FILES['dealImage']['name'] : '';
$query = "UPDATE #__todaysdeal SET dealImage='".$id."_".$_FILES['dealImage']['name']."' WHERE id='".$id."'";
$db = $this->getDBO();
$db->setQuery($query);
$db->query();
//If we get here and with no raiseErrors, then everythign went well
}
function deleteDeals($arrayIDs)
{
$query = "DELETE FROM #__todaysdeal WHERE id IN (".implode(',', $arrayIDs).")";
$db = $this->getDBO();
$db->setQuery($query);
if (!$db->query()){
$errorMessage = $this->getDBO()->getErrorMsg();
JError::raiseError(500, 'Error deleting Deals: '.$errorMessage);
}
}
function dealsUploadPhoto($file, $id)
{
//UPLOAD FILE
$config = & JComponentHelper::getParams('com_deals');
$allowed = array('image/pjpeg', 'image/jpeg', 'image/jpg', 'image/png', 'image/x-png', 'image/gif', 'image/ico', 'image/x-icon');
$pwidth = $config->get('pwidth');
$pheight = $config->get('pheight');
$maxsize = $config->get('maxsize');
if($file['size'] > 0 && ($file['size'] / 1024 < $maxsize)){
if(!file_exists(JPATH_SITE . DS. 'images' . DS . 'deals'))
{
if(mkdir(JPATH_SITE . DS . 'images' . DS . 'deals')) {
JPath::setPermissions(JPATH_SITE . DS . 'images' . DS . 'deals', '0777');
if(file_exists(JPATH_SITE . DS . 'images' . DS . 'index.html')) {
copy(JPATH_SITE . DS . 'images' . DS . 'index.html', JPATH_SITE . DS . 'images' . DS . 'deals/index.html');
}
}
}
if($file['error'] != 0){
tpJobsMsgAlert('Upload file photo error.');
exit ();
}
if($file['size'] == 0){
$file = null;
}
if(!in_array($file['type'], $allowed)) {
$file = null;
}
if ($file != null){
$dest = JPATH_SITE.DS.'images'.DS.'deals'.DS.$id.'.jpg';
if(file_exists($dest))
{
$del = unlink($dest);
}
$soure = $file['tmp_name'];
jimport('joomla.filesystem.file');
$uploaded = JFile::upload($soure,$dest);
$fileAtr = getimagesize($dest);
$widthOri = $fileAtr[0];
$heightOri = $fileAtr[1];
$type = $fileAtr['mime'];
$img = false;
switch ($type)
{
case 'image/jpeg':
case 'image/jpg':
case 'image/pjpeg':
$img = imagecreatefromjpeg($dest);
break;
case 'image/ico':
$img = imagecreatefromico($dest);
break;
case 'image/x-png':
case 'image/png':
$img = imagecreatefrompng($dest);
break;
case 'image/gif':
$img = imagecreatefromgif($dest);
break;
}
if(!$img)
{
return false;
}
$curr = #getimagesize($dest);
$perc_w = $pwidth / $widthOri;
$perc_h = $pheight / $heightOri;
if(($widthOri<$pwidth) && ($heightOri<$height))
{
return;
}
if($perc_h > $perc_w)
{
$pwidth = $pwidth;
$pheight = round($heightOri * $perc_w);
}
else
{
$pheight = $pheight;
$pwidth = round($widthOri * $perc_h);
}
$nwimg = imagecreatetruecolor($pwidth, $pheight);
imagecopyresampled($nwimg, $img, 0, 0, 0, 0, $pwidth, $pheight, $widthOri, $heightOri);
imagejpeg($nwimg, $dest, 100);
imagedestroy($nwimg);
imagedestroy($img);
}
}else{
if($file['size'] / 1024 > $maxsize){
dealsMsgAlert('Size of file photo is too big. Maximum size".$maxsize." KB');
exit ();
}
}
}
function dealsMsgAlert($msg)
{
if (!headers_sent())
{
while(#ob_end_clean());
ob_start();
echo "<script> alert('".$msg."'); window.history.go(-1); </script>\n";
$out = ob_get_contents();
ob_end_clean();
echo $out;
exit();
}
echo "<script> alert('".$msg."'); window.history.go(-1); </script>\n";
exit();
}
}
?>
The problem that causes the red screen with 500 Error is happening because you are raising an exception if the requested quote is does not exist. You should not use JError::raiseError().
Use one of the following instead:
// This will set error to the model. You can get the errors from
// the model by your controller $model->getErrors() and output them to the screen.
$this->setError('ERROR MESSAGE GOES HERE');
OR
// This will output errors to the screen right the way
JFactory::getApplication()->enqueueMessage('ERROR MESSAGE GOES HERE', 'message');
Model already has _db property, you do not need to get db into variable. You can access it like this $this->_db. You can read about Joomla Model class here.
Also within your model you are using
$db = $this->getDBO();
$db->setQuery('SELECT * from #__todaysdeal');
$deals = $db->loadObjectList();
Model has simplified method to load list of object, like so
$deals =& $this->_getList('SELECT * from #__todaysdeal');
i want ot change new product images prospective to original images.
when i am upload image for product , images are squazed so any help?
We modified the tep_image function to accept -1 which means it will only output a "height" or a "width" constraint but not both. You can modify this to your liking but you want to look at includes/functions/html_output.php for tep_image()
// The HTML image wrapper function
function tep_image($src, $alt = '', $width = '', $height = '', $parameters = '') {
if ( (empty($enter code heresrc) || ($src == DIR_WS_IMAGES)) && (IMAGE_REQUIRED == 'false') ) {
return false;
}
if($src=='images/')
$src='images/noimage.jpg';
// alt is added to the img tag even if it is null to prevent browsers from outputting
// the image filename as default
$image = '<img src="' . tep_output_string($src) . '" border="0" alt="' . tep_output_string($alt) . '"';
if (tep_not_null($alt)) {
$image .= ' title=" ' . tep_output_string($alt) . ' "';
}
if(((int)$height==-1) && ((int)$width)==-1){
$image .= '';
}elseif((!empty($width) && ((int)$height)==-1)){
$image .= ' width="' . tep_output_string($width) . '" ';
}elseif((!empty($height) && ((int)$width)==-1)){
$image .= ' height="' . tep_output_string($height) . '" ';
}else{
if ( (CONFIG_CALCULATE_IMAGE_SIZE == 'true') && (empty($width) || empty($height)) ) {
if ($image_size = #getimagesize($src)) {
if (empty($width) && tep_not_null($height)) {
$ratio = $height / $image_size[1];
$width = intval($image_size[0] * $ratio);
} elseif (tep_not_null($width) && empty($height)) {
$ratio = $width / $image_size[0];
$height = intval($image_size[1] * $ratio);
} elseif (empty($width) && empty($height)) {
$width = $image_size[0];
$height = $image_size[1];
}
} elseif (IMAGE_REQUIRED == 'false') {
return false;
}
}
if (tep_not_null($width) && tep_not_null($height)) {
$image .= ' wddidth="' . tep_output_string($width) . '" height="' . tep_output_string($height) . '"';
}
}
if (tep_not_null($parameters)) $image .= ' ' . $parameters;
$image .= '>';
return $image;
}