Unable to call custom methods within extended Magento model - magento

I'm attempting to customize the way pricing / tiered pricing is displayed in Magento CE 1.6.0.0.
I've followed the instructions in the second post of the link below to override Mage_Catalog_Model_Product_Type_Price
http://www.magentocommerce.com/boards/viewthread/16829/
Following is my custom model class:
class PHC_Price_Model_Price extends Mage_Catalog_Model_Product_Type_Price {
public function getPrice() {
echo "overridden getPrice method called<br>";
}
public function getPHCDisplayPrice($product) {
echo "custom price function called<br>";
}
}
I'm able to successfully call the overridden getPrice() function from my template file as follows:
$product = Mage::getModel("catalog/product")->load($_product->entity_id);
$displayPrice = $product->getPrice();
However, when I try to call my custom price function with
$product = Mage::getModel("catalog/product")->load($_product->entity_id);
$displayPrice = $product->getPHCDisplayPrice();
I get absolutely nothing. Can anyone tell me what I'm missing?

It't normal that you don't get a result. I would be amazed if this worked.
You are overriding the class Mage_Catalog_Model_Product_Type_Price, but in your example the $product variable is an instance of Mage_Catalog_Model_Product. That class does not have the method getPHCDisplayPrice and it calls the __call method and returns null.
You get the expected result when calling getPrice by accident. It is because the getPrice method in Mage_Catalog_Model_Product looks like this:
public function getPrice()
{
if ($this->_calculatePrice || !$this->getData('price')) {
return $this->getPriceModel()->getPrice($this);
} else {
return $this->getData('price');
}
}
So when you call it, it calls $this->getPriceModel()->getPrice($this) and $this->getPriceModel() returns an instance of your class.

Related

Laravel eloquent: How does relation inherit functions from query builder?

how do they achieve, that Illuminate\Database\Eloquent\Relations\Relation has access to all query builder functions?
I see they have a $query property, but does not explain how all its methods are available inside relation
If you are aware of php magic methods then you will know __call method
this method will be called when you initialize a php object and you try to call a method which is not available in the class. By using __call method from the Illuminate\Database\Eloquent\Relations\Relation class they are forwarding the call to Illuminate\Database\Eloquent\Builder. I will explain it very clearly by pointing out the code.
Inside the laravel framework there is a trait named as ForwardsCalls . This trait is used in many classes to handle the call forwarding to another class.
So here is how the call from the Relation class is forwarded to Builder class. While initilting the new Relation class Builder class will be initialized. So when you try to call a method from reltion class which is not available it will call __call method. After that it will look for a available macros . So when a macros method is not found. Then it will use forwardDecoratedCallTo from ForwardsCalls Trait.
So forwardDecoratedCallTo will accept 3 arguments namely $object, $method and $parameters. Whereas
$object will be $this->query which has a Illuminate\Database\Eloquent\Builder instance.
$method will be the method the you try to access from Builder Method.
$parameters will be the all the parameters that is be passed to the method.
I will try to Demonstrate will the example without the traits and helpers from laravel
class ClassTwo {
public function classTwoMethodOne()
{
dd(__FUNCTION__.' has been called');
}
public function classTwoMethodTwo()
{
dd(__FUNCTION__.' has been called');
}
public function classTwoMethodThree()
{
//you cannot call this method dynamically
dd(__FUNCTION__.' has been called');
}
}
class ClassOne {
public function classOneMethodOne()
{
dd(__FUNCTION__.' has been called');
}
public function classOneMethodTwo()
{
dd(__FUNCTION__.' has been called');
}
public function __call($methodName, $arguments)
{
$methodsTobeForwarededtoClassTwo = [
'classTwoMethodOne',
'classTwoMethodTwo',
// 'classTwoMethodThree'
//i have commented this method so you cannot access it
//from dynamic calls
];
if(in_array($methodName,$methodsTobeForwarededtoClassTwo))
{
return (new ClassTwo)->{$methodName}($arguments);
}
dd(sprintf(
'Call to undefined method ClassTwo::%s()', $methodName
));
}
}
So here comes the testing part.
$classOneobj = new ClassOne;
Basic Test
dump($classOneobj->classOneMethodOne()); will output as classOneMethodOne has been called
dump($classOneobj->classOneMethodTwo()); will output as classOneMethodTwo has been called
Dynamic Call Test
dump($classOneobj->classTwoMethodOne()); will output as classTwoMethodOne has been called
dump($classOneobj->classTwoMethodTwo()); will output as classOneMethodTwo has been called
dump($classOneobj->classTwoMethodThree()); will output as Call to undefined method ClassTwo::classTwoMethodThree() Because i have commented that method in __call function in ClassOne.
If you still need clarity please post a comment

Get shipping address county in Magento 2 observer

Hi I have a custom module . I want to get shipping country inside
public function execute(\Magento\Framework\Event\Observer $observer)
{
Please let me know how can i get this this ?
I have seen this code for postcode , but i am not sure his is working or not
$postCode = $this->_checkoutSession->getQuote()-getShippingAddress()->getPostcode();
I need shipping address country name in public function execute. Please help .
declare a public variable and intialize the variable like below ,then you will be able to use it in your execute method
class Example {
public $_checkOutSession;
public function __construct(\Magento\Customer\Model\Session $checkOUtSession)
{
$this->_checkOutSession = $checkOutSession;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$postCode = $this->_checkoutSession->getQuote()->getShippingAddress()->getPostcode();
}
}
It depends on which observer do you want to get it. Can you provide a more specific scenario?
In which checkout session currently has a quote. You can use the above solution from Reggie.
Or else you need to initialize quote/order to get it.

Laravel policies - passing the class as a variable to $user->can() method doesn't work

I have a route with dynamic model recognition. In other words, I take the desired model as an argument and use it in the controller. I have complex authorization in my app and I need to pass the model class name as a variable to the $user->can() method for using policies, but for some reason it doesn't work. Here's my code:
Policy:
public function view($user, Model $model) {
return $user->model_id == $model_id;
}
public function create($user) {
return $user->isAdmin();
}
Controller:
public function createModel($model) {
$model_class = $model . '::class';
if (Auth::user()->can('create', $model_class)) {
return $model_class::create();
}
return 'invalid_permissions';
}
If I hardcode the model class name it works. For example, if my model is 'Car' and in the controller I put:
if (Auth::user()->can('create', Car::class)) {
Anybody got any ideas why this is so and how to fix it? I hope that it's possible because I would have to change my whole concept if it isn't.
*Note: this is example code, not my actuall classes

Magento calling parent function not working

I have a plugin: Simple Configurable Products. I've upgraded to 1.8.1 but have an issue with showing the price - it stops rendering the page.
I have found the line that's causing the issue:
parent::_toHtml();
The class that is calling that is as follows:
class OrganicInternet_SimpleConfigurableProducts_Catalog_Block_Product_Price
extends Mage_Catalog_Block_Product_Price
{
public function _toHtml() {
// Do some stuff
return parent::_toHtml();
}
}
So as I see it, the parent class should be: Mage_Catalog_Block_Product_Price. And the line that calls this should simply call the function _toHtml(). Taking this line out means it works, but returns no price. Ideally I need it to render the default/base price html.
Thanks in advance
Try calling it like this:
class OrganicInternet_SimpleConfigurableProducts_Catalog_Block_Product_Price
extends Mage_Catalog_Block_Product_Price {
public function _toHtml() {
// Do some stuff
return Mage_Catalog_Block_Product_Price::_toHtml();
}
}
Call the object by name instead of by parent::_toHtml()

calling a function within a class with a Joomla module

I have a Joomla helper class that I'm using for module development with a method I'm trying to call:
class modCamcloudReferralHelper
{
/*
* Sanitize email form
*/
public function isInjected($str) {
$inject = "/(\r|\t|%0A|%0D|%08|%09)+/i";
return (preg_match($inject, $str) > 0);
}
public static function sendEmail() {
$jinput = JFactory::getApplication()->input;
$email = $jinput->post->get('email', '', 'STRING');
//check email is fine
if (isInjected($email)){ //never get into this code and it causes some sort of failure
echo "blah";
}
}
}
Simple, right? But this code just gives me a blank page and I don't see any errors...anywhere. I can instead just put this code right into my sendEmail function and it works just fine:
$inject = "/(\r|\t|%0A|%0D|%08|%09)+/i";
if (preg_match($inject, $email) > 0){
echo "This works";
}
I've had this problem with my Joomla components I've built before. For some reason calling this function from inside the same class is not working. It must be a Joomla thing...or I'm going nuts. Any ideas?
You should call the method with a reference to its container, even if it's local.
So the right syntax here is:
if (self::isInjected($email))
of from another class:
modCamcloudReferralHelper::isInjected(
This is good for helpers: just make sure you declare the method you are invoking as static
public static function isInjected($str) {
If however you're calling a method on an instantiated class (a view, a template, a model, you should use
$this->method()

Resources