I want to test a Magento block function. I don't know, how to call the function outside .phtml files. Does anybody know a function like getModel() for blocks?
I found
getBlockSingleton()
But, it is deprecated and I can't get it to work.
Let's say your Magento root is your web root. In your Magento root, create a test.php file. You'll be able to access it at http://base_url/test.php.
ini_set('display_errors',true); //PHP has such friendly errors, show them!
include 'app/Mage.php'; //include the helper class/bootstrap file
Mage::setIsDeveloperMode(true); //flag to render Magento's traces
Mage::app();
/**
Instantiate the app. Note that this is different from Mage::run()! This can
be skipped given the Mage::app() call below.
*/
//block "type"
$class = 'core/bar';
//block instance
$block = Mage::app()->getLayout()->createBlock($class);
if (is_object($block)) die("Okay! ".get_class($block));
/**
* If script execution reaches this point, there is one of
* two problems:
*
* 1) bad/missing config
* 2) bad path based on filename
*/
//the xpath which is used
$xpath = 'global/blocks/'.strstr($class,'/',true).'/class';
//a node from config XML (we hope)
$node = Mage::getConfig()->getNode($xpath);
//error condition 1:
if (!$node) die("Bad xpath, check configuration: ".$xpath);
//error condition 2:
$name = uc_words((string) $node . '_' . substr(strrchr($class, '/'), 1));
$file = str_replace('_', DIRECTORY_SEPARATOR, $name.'.php');
$issue = '<br /><br />';
if (!is_readable($file)) {
//no file matching classname
$issue .= "No file found for $file, tried:<pre> - ";
$issue .= str_replace(PATH_SEPARATOR,'/'.$file.'<br /> - ',get_include_path()).$xpath.'</pre>';
} else {
$issue .= "Wrong class name in $file";
}
echo sprintf('Xpath ok, looking for class <span style="font-family: Courier New">%s</span>%s',$name,$issue);
If you just need the block instance itself to test methods on, the following function may do:
/**
* Create block instance for given block classAlias.
*
* #param string $classAlias Magento class alias for this block, e.g. 'catalog/product_price'
*
* #return Mage_Core_Block_Abstract
*/
public static function getBlockInstance($classAlias)
{
$className = Mage::getConfig()->getBlockClassName($classAlias);
$result = new $className;
return $result;
}
Related
I extended tx_news to hold a number of courses. there are courses that treat the same subject matter for different arguments (which I select as sys_categories). This means that their title is identical, now I'm trying to make the list better for the editor by including the selected category in the list...
Imply a custom title in Configuration/TCA/Overrides/tx_news_domain_model_news.php:
$GLOBALS['TCA']['tx_news_domain_model_news']['ctrl']['label_userFunc'] = 'Vendor\\NewsExt\\Userfuncs\\Tca->customTitle';
The userfunction so far Classes/Userfuncs/Tca.php:
<?php
namespace Vendor\NewsExt\Userfuncs;
use GeorgRinger\News\Domain\Model\News;
/**
* Class Tca
*/
class Tca
{
/**
* Loads a custom title for the news list view
*
* #return void
*/
public function customTitle(
&$parameters,
$parentObject
){
$record = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord($parameters['table'], $parameters['row']['uid']);
$newTitle = $record['title'];
if($record['is_course']){
$newTitle .= ' (' . $record['categories'] . ')' ;
}
$parameters['title'] = $newTitle;
}
}
which obviously gives the number of selected categories ... I did not include any of my attempts because they lead to nothing ...
You can make an mm query to resolve the assigned category title:
<?php
namespace Vendor\NewsExt\Userfuncs;
use GeorgRinger\News\Domain\Model\News;
/**
* Class Tca
*/
class Tca
{
/**
* Loads a custom title for the news list view
*
* #return void
*/
public function customTitle(&$parameters, $parentObject)
{
# fetch all categories assigned to this news
$result = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
'sys_category.uid, sys_category.title',
'sys_category',
'sys_category_record_mm',
$parameters['table'],
'AND sys_category_record_mm.tablenames = "' . $parameters['table'] . '" ' .
'AND sys_category_record_mm.fieldname = "categories" ' .
'AND sys_category_record_mm.uid_foreign = ' . $parameters['row']['uid']
);
# walk the categories an get the title of them
$categoriesLabels = [];
foreach ($result->fetch_all(MYSQLI_ASSOC) as $category) {
$categoriesLabels[] = $category['title'];
}
# if at least one category put them into the title
if (!empty(array_filter($categoriesLabels))) {
$record = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord($parameters['table'], $parameters['row']['uid']);
$parameters['title'] = $record['title'] . ' ('. implode(', ', $categoriesLabels) .')';
}
}
}
Note: This code is was tested in TYPO3 8.7.12
Probably you've to make a custom database-query at best in an own repository where you request each applying category to get the title.
It's possible that you can use the Repository of tx_news for avoiding redundant code but surely you've to include some code / function that is instantiating the request - where ever the request is addressed to.
Anyone know of such a module?
Basically I want to dynamically load the users in certain usergroups inside an article with the loadmodule option.
Ended up building myself.
modfile:
<?php
defined('_JEXEC') or die;
// Include the latest functions only once
require_once __DIR__ . '/helper.php';
$shownumber = $params->get('shownumber', 10);
$groupnumber = $params->get('group', 4);
$names = ModUsersUsergroupHelper::getUsers($params);
$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8');
require JModuleHelper::getLayoutPath('mod_users_usergroup', $params->get('layout', 'default'));
helper:
<?php
defined('_JEXEC') or die;
/**
* Helper for mod_users_usergroup
*
* #package Joomla.Site
* #subpackage mod_users_usergroup
*
* #since 1.6
*/
class ModUsersUsergroupHelper
{
/**
* Get users in a certain usergroup
*
* #param \Joomla\Registry\Registry $params module parameters
*
* #return array The array of users
*
* #since 1.6
*/
public static function getUsers($params)
{
$db = JFactory::getDbo();
$groupId = $params->get('group', 2);
$query = $db->getQuery(true)
->select($db->quoteName(array('u.id', 'u.name', 'u.username', 'u.registerDate')))
->order($db->quoteName('u.registerDate') . ' DESC')
->from('#__users AS u')
->join('INNER', '#__user_usergroup_map AS ugm ON ugm.user_id = u.id')
->where('ugm.group_id =' . $db->quote($groupId));
$db->setQuery($query, 0, $params->get('shownumber'));
try
{
return (array) $db->loadObjectList();
}
catch (RuntimeException $e)
{
JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error');
return array();
}
}
}
I am not aware of such an extension but you could include some code in a Custom HTML module using Sourcerer or similar to achieve the desired result.
The Custom HTML module can then be displayed in an article using loadmodule.
For some example code see: https://stackoverflow.com/a/20743966
The code below works for products that have images, but for products that don't have images, the placeholder small image doesn't show.
echo Mage::getModel('catalog/product_media_config')->getMediaUrl( $_product->getSmallImage());
<?php
// get image full url
echo $imageUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . 'catalog/product' . $_product->getImage();
// get image using custom size with url
echo $imageCacheUrl = Mage::helper('catalog/image')->init($_product, 'image')->resize(135,135);
?>
The code that affects what you want to do is
//file: app/code/core/Mag/Catalog/Helper/Image.php
//class: Mage_Catalog_Helper_Image
/**
* Return Image URL
*
* #return string
*/
public function __toString()
{
try {
//...
} catch (Exception $e) {
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
return $url;
}
The interesting line is
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
So in your code you need to test the return value of $_product->getSmallImage() and if it is false or null use Mage::getDesign()->getSkinUrl($this->getPlaceholder()); instead.
You might want to inspect $_product->getSmallImage() to see what it returns when no value is set.
Oh, and I just checked: getPlaceholder() is a function not a magic getter. This is the function:
public function getPlaceholder()
{
if (!$this->_placeholder) {
$attr = $this->_getModel()->getDestinationSubdir();
$this->_placeholder = 'images/catalog/product/placeholder/'.$attr.'.jpg';
}
return $this->_placeholder;
}
So you will have to unravel some $this (hint $this->_getModel() is Mage::getModel('catalog/product_image') )
or to cut a long story short just fall back to the default:
echo ($this->helper('catalog/image')->init($_product, 'small_image'));
in your phtml file if $_product->getSmallImage() doesn't exist.
Update following your comment:
Specifcically in the .phtml file that you are using to generate the HTML that displays the small image you could write:
$testSmallImageExists = $_product->getSmallImage();
if($testSmallImageExists)
{
echo Mage::getModel('catalog/product_media_config')->getMediaUrl( $_product->getSmallImage());
}
else
{
echo ($this->helper('catalog/image')->init($_product, 'small_image'));
}
Or just simply use
echo ($this->helper('catalog/image')->init($_product, 'small_image'));
I'm sure that is the standard Magento way.
I have developed a code that contains a aquery which returns ratings of a product in json format. The code is as follows:
<?php header('content-type: application/json; charset=utf-8');
require_once('/opt/phpapps/magento/app/Mage.php');
umask(0);
Mage::app();
$cid=$_GET['catid'];
$read = Mage::getSingleton('core/resource')->getConnection('core_read');
$query = "SELECT round(t1.rating_summary / 20) AS rating, t2.product_id FROM review_entity_summary AS t1 INNER JOIN catalog_category_product AS t2 ON t1.entity_pk_value = t2.product_id WHERE category_id =" . $cid . " AND store_id = '1'";
$results = $read->fetchAll($query);
$json = json_encode($results);
print_r( $json );
?>
I am instructed to convert this into MVC pattern. I knew that MVC can be done by creating separate folders like blocks, controllers, models,sql,etc, helpers folders. But I am not sure what is the next stepa nd how to execute the developed to get the json data..
Help me in this...
The best way to is create a custom Extension/Model, there's a lot of tutorials out there to do this, however you could use something to generate an example for you to get started:
http://www.silksoftware.com/magento-module-creator/
However, for something this simple you could just create a custom block in the local namespace, for example:
app/code/local/Mage/Catalog/Block/Product/Ratingsjson.php
<?php
/**
* Ratingsjson.php
*/
class Mage_Catalog_Block_Product_Ratingsjson extends Mage_Catalog_Block_Product_Abstract
{
/**
* Get products with special offer attribute set
*
* #return type
*/
public function getRatings()
{
/**
* This will be injected from the tag / XML below
* you can pass what ever variables you want this way.
* getSomeAttribute() will get the value 'some_attribute' from the
* CMS tag or XML config.
*/
$categoryId = $this->getCategoryId();
if($categoryId == NULL) {
$categoryId = 1; // or some default;
}
$resource = Mage::getSingleton('core/resource');
$read = $resource->getConnection('catalog_read');
// Do your stuff here...
$query = "SELECT round(t1.rating_summary / 20) AS rating, t2.product_id FROM review_entity_summary AS t1 INNER JOIN catalog_category_product AS t2 ON t1.entity_pk_value = t2.product_id WHERE category_id =" . $cid . " AND store_id = '1'";
$results = $read->fetchAll($query);
return json_encode($results);
}
}
Create a template to do what you want:
template/mymodeule/mytemplate.phtml
<?php
echo $this->getRatings();
You can then use your new block inside CMS pages:
{{block type="catalog/ratignsjson" category_id="3" temaplte="mymodeule/mytemplate.phtml"}}
Or if you want to load it via XML config:
<block type="catalog/ratignsjson" category_id="3" name="ratignsjson" template="mymodeule/mytemplate.phtml"/>
To do this properly and output strict Json data you would want to set json content type headers etc but I think that's a little too much for this particular case.
hi i am new in joomla.I need the dynamic link in view file.
//no direct access
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
// include the helper file
require_once(dirname(FILE).DS.'helper.php');
// get a parameter from the module's configuration
$userCount = 5;
// get the items to display from the helper
$items = ModNewHelper::getItems($userCount);
//link of the component
// include the template for display
require(JModuleHelper::getLayoutPath('mod_new'));
this is main file
/**
* #author Raju Gautam
* #copyright 2011
*/
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
class ModNewHelper
{
/**
* Returns a list of post items
*/
public function getItems($userCount)
{
// get a reference to the database
$db = &JFactory::getDBO();
// get a list of $userCount randomly ordered users
$query = 'SELECT name,id FROM `#__hello` ORDER BY ordering LIMIT ' . $userCount . '';
$db->setQuery($query);
$items = ($items = $db->loadObjectList())?$items:array();
return $items;
} //end getItems
} //end ModHelloWorld2Helper
this is helper file
defined('JEXEC') or die('Restricted access'); // no direct access
echo JText::('Latest News');
//echo ""; print_r($items); exit;
foreach ($items as $item) {
echo JText::sprintf($item->name);
} this is view file
I need the link on echo JText::sprintf($item->name); this line. can i helped please?
change your this line from view file:
echo JText::sprintf($item->name);
to :
echo "<a href='".$item->link."'>". JText::sprintf($item->name)."</a>";
assuming, link is the field name of your link else change it according to the field name you've used for link. this may help, i guess .. good luck with it.
use
echo "<a href='".JRoute::_($item->link, false)."'>". JText::sprintf($item->name)."</a>";
JRoute will take care of routing also, if routing is enabled.