• Hello Fabrik Community

    Fabrik is now in the hands of the development team that brought you Fabrik for Joomla 4. We have recently transitioned the Fabrik site over to a new server and are busy trying to clean it up. We have upgraded the site to Joomla 4 and are running the latest version of Fabrik 4. We have also upgraded the Xenforo forum software to the latest version. Many of the widgets you might have been used to on the forum are no longer operational, many abandoned by the developers. We hope to bring back some of the important ones as we have time.

    Exciting times to be sure.

    The Fabrik 4.0 Official release is now available. In addition, the Fabrik codebase is now available in a public repository. See the notices about these in the announcements section

    We wish to shout out a very big Thank You to all of you who have made donations. They have really helped. But we can always use more...wink..wink..

    Also a big Thank You to those of you who have been assisting others in the forum. This takes a very big burden off of us as we work on bugs, the website and the future of Fabrik.

Declaring variables once

ahmedo

Member
Hi,

Is there a way to declare variables once upon loading a Form so that can be reused across different Calc fields?

Basically, I have four calculated fields which display our cost for a product in 4 different currency. At the moment, I go to each Calc field and declare the exchange rate in each one of them. And it works. But if the exchange rate changes, I will have to go to each Calc field and change the rate. Which is not really a good approach.

Thank you.
 
What I usually do is create a class somewhere, like in the PHP form plugin script folder, as a "Helper" class, and put common things I'm doing in there, then use it from wherever I need it (calcs, form submission scripts, etc), like ...

Code:
class MyHelper
{
   public static function getExchangeRate($currency = "USD")
   {
      // whatever code you want here that returns a value.  If you want it could even call an online API to get spot rates
      switch ($currency):
         case "UKP":
            return "0.000001";
            break;
         case "USD":
         case default:
            return "1.34";
   }
}

Then in your calc ...

Code:
require_once JPATH_ROOT . '/plugins/com_fabrik/php/scripts/myhelper.php';
$rxRate = MyHelper::getExchangeRate('YEN');

Then as you find other stuff you find yourself doing repeatedly, you can put that in your helper class as well.

I'm thinking for 3.9 of adding namespace support for a custom helper class into our autoloading, so if you add Custom.php to our ./libraries/fabrik/fabrik/helpers folder, you could then just automagically call Fabrik\Helpers\Custom::whatever(). But that doesn't exist yet.

-- hugh
 
Another thing I've been thinking about, as exchange rates are something we've had a lot of questions about over the years, is adding this Composer lib to our libraries:

https://github.com/florianv/swap

... which lets you very easily get up to date exchange rates from Fixer or Google, with code like ...

Code:
use Swap\Builder;
$swap = (new Builder())->add('fixer')->build();
$rate = $swap->latest('EUR/USD');

-- hugh
 
What I usually do is create a class somewhere, like in the PHP form plugin script folder, as a "Helper" class, and put common things I'm doing in there, then use it from wherever I need it (calcs, form submission scripts, etc), like ...

Code:
class MyHelper
{
   public static function getExchangeRate($currency = "USD")
   {
      // whatever code you want here that returns a value.  If you want it could even call an online API to get spot rates
      switch ($currency):
         case "UKP":
            return "0.000001";
            break;
         case "USD":
         case default:
            return "1.34";
   }
}

Then in your calc ...

Code:
require_once JPATH_ROOT . '/plugins/com_fabrik/php/scripts/myhelper.php';
$rxRate = MyHelper::getExchangeRate('YEN');

Then as you find other stuff you find yourself doing repeatedly, you can put that in your helper class as well.

I'm thinking for 3.9 of adding namespace support for a custom helper class into our autoloading, so if you add Custom.php to our ./libraries/fabrik/fabrik/helpers folder, you could then just automagically call Fabrik\Helpers\Custom::whatever(). But that doesn't exist yet.

-- hugh

Thank you for your help. Sadly I could not do it successfully.
Firstly, the path you gave I cannot find (/plugins/com_fabrik/php/scripts/) so I assumed it is this one (/plugins/fabrik_form/php/scripts/). If so, this is where I placed the myhelp.php

Next, when I try to view the List data (not even the form), I get this message on my browser instead without the "
"class MyHelper { public static function getExchangeRate($currency = "USD") { switch ($currency): case "UKP": return "0.000001"; break; case "USD": case default: return "1.34"; } }"

So I know the script is being called, but when nothing else is shown, I know I made a big blunder somewhere.

My Calc field has this
require_once JPATH_ROOT . '/plugins/fabrik_form/php/scripts/myhelper.php';
$rxRate = MyHelper::getExchangeRate('UKP');

BTW, the test is done on Fabrik Playground
Thanks anyway.
 
Thank you for your help. Sadly I could not do it successfully.
Firstly, the path you gave I cannot find (/plugins/com_fabrik/php/scripts/) so I assumed it is this one (/plugins/fabrik_form/php/scripts/). If so, this is where I placed the myhelp.php

Next, when I try to view the List data (not even the form), I get this message on my browser instead without the "
"class MyHelper { public static function getExchangeRate($currency = "USD") { switch ($currency): case "UKP": return "0.000001"; break; case "USD": case default: return "1.34"; } }"

So I know the script is being called, but when nothing else is shown, I know I made a big blunder somewhere.

My Calc field has this
require_once JPATH_ROOT . '/plugins/fabrik_form/php/scripts/myhelper.php';
$rxRate = MyHelper::getExchangeRate('UKP');

BTW, the test is done on Fabrik Playground
Thanks anyway.
Oops, put a php tag at the start of the file...

Code:
<?php

And in the calc, return a value. That was just an example fragment, I presume you'll multiply some other element's value by the exchange rate.

And the function itself is just example code, I don't know if you are dealing with multiple currencies. You could just have one line that returns a single value.

Sent from my HTC6545LVW using Tapatalk
 
Getting closer to getting right. Just one more question and I will post the whole thing. (had to go to w3school to know more about php) :)
I have an element called currency (dropbox type) -storing the Value
Value 1 Label USD
Value 2 Label SGD

I can get the value of the currency by using this {products___currency_raw)
I want to know how do I get the label value (example USD). I could throw few If statements, but I am thinking there must a better way. I tried {products_currency_label} but it did not work.
 
You can't really rely on being able to get at the labels for dropdowns or joins. Long story.

I would suggest rather than a dropdown, use a join element. Create a list for currencies, and put your exchange rate in that (relative to the base currency), so something like ...

id, code, rate
1, USD, 1
2, UKP, 1.23
3, SGD, 0.76

... etc. Obviously my example assumes USD is the base currency.

Then just pass the 'raw' currency id to your function, and do a database lookup in that ...

Code:
function getExchangeRate ($currencyId)
{
   $db = JFactory::getDbo();
   $query = $db->getQuery(true);
   $query->select('rate')->from('currencies')->where('id = ' . (int)$currencyId);
   $db->setQuery($query);
   return $db->loadResult();
}

The advantage of doing it this way is, when the exchange rates change, you only have to update the values in the list (which you can do through a simple Fabrik list/form), rather than modifying code.

You could also very easily add a scheduled task PHP plugin to update your currency table once a day (or whatever) from some trusted API source.

This assumes you are working on costs from a base currency, so are always converting from that to some other currency. If you need to convert between arbitrary currencies, that could still be done with a table based approach, although the table would then need to have more fields (id, from_code, to_code, rate), and a lot more rows (one, or perhaps two, for each currency pairing).

You might also want to improve that getExchangeRate() function to cache the result, to cut down on database queries. Or rather, I might want to, if you want to go this route.

-- hugh
 
Meh, apparently I'm a little OCD ... here's the function, with caching. So it only does the database lookup once, and loads the whole table one time, and if called again will use the cached value.

Code:
function getExchangeRate ($currencyId)
{
   static $currencies = null;

   if (!is_array($currencies))
   { 
      $db = JFactory::getDbo();
      $query = $db->getQuery(true);
      $query->select('*')->from('currencies');
      $db->setQuery($query);
      $currencies = $db->loadObjectList('id');
   }

   return $currencies[$currencyId]->rate;
}

The reason it's best to cache database qeuries when doing stuff from calc elements is that the calc code can wind up being run multiple times. Especially if you have "Calc on save only" set to No, so it's calc'ing every element in a list view.

-- hugh
 
From the start, I thought of putting the currency in a different list. But I was so scared of being unable to do what you wrote. It is a huge learning curve for me to code in a language that I never coded one line before. I know exactly what I want to do, and the options available. But it is the ability to code that fails me. So I am taking it a step at a time, considering my other responsibilities including running my own business.

I just managed to achieve what I want with you recommend before with the myhelp.ph. Along the way, I learnt few things. I can now talk to my PHP developers and ask them to do more.

Thank you once again.
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top