Execute custom function after purchase a course/complete an order in LearnPress? - wordpress

I need to execute a function immediately when someone purchases a course or an order gets completed successfully. The function I am trying to execute is actually called an API. I don't see an appropriate Hook from LearnPress.
It works perfectly when I use "user_register"(when someone registers this hook fire) hook but it doesn't work when I use this "learn_press_confirm_order" hook given by LearnPress.
Do you guys know is there any appropriate way that I can follow and achieve this. Thank You for your time

First off, your Lime API key should be treated as a password - don't share it on the web! Go to your LimeLM Account right now, choose 'Settings', and choose 'Generate New Key'. I'll wait :)
There's nothing obviously wrong with your code, so I would debug it like this:
Put a die('setup'); immediately after the add_action. We want to be sure that this file is actually being called. If it is, remove the die.
Wordpress and LearnPress are fantastic, because you've got the source code. Go to wp-content/plugins/learnpress and type (on Linux or something *nix)
grep -R "learn_press_confirm_order" .
This will show you all the files that reference this action. There is only one:
./templates/order/confirm.php: transaction_method, $order->get_id() ); ?>
So pull up an editor and edit wp-content/plugins/learnpress/templates/order/confirm.php. You need to determine:
Whether the file is being run at all when you order. (Use die right at the top, or error_log if you can see your webserver/php log files.)
I'm fairly certain at this point you will have found the error, but there's a chance for some reason you're getting to this page, but the action isn't being called. So you might need to work out the exact flow of control on this confirm.php page. Again, die or error_log.
You can make live changes to the code of learnpress, to help you debug it. Most people are afraid to dig into other people's code, but that's the great power of open source. You can just reinstall learnpress when you're done.
Looking forward to hearing how it goes :)

Related

How to open a record on a subgrid using easyrepro?

https://github.com/Microsoft/EasyRepro/issues/178
Hi all,
I am using dynamics365 version 9.x
Using EasyRepro I can navigate into an account via the global search and then also use the xrmBrowser.Entity.ClickSubgridAddButton("foobar"); function to create a new record of that 'foobar' type. By doing this I know I am accessing the correct subgrid on the account record.
My question is....which function would I use to simply open up the record I have created. I have tried SelectSubgridLookup but I don't think that is the function I am looking for.
From the image you can see I have created the 'bonno bonno' contact but I cannot open the record using EasyRepro. any help would be greatly appreciated! :)
https://github.com/Microsoft/EasyRepro/issues/178
Hello #darthtang - sorry for the delayed reply to your post here. From reviewing, it appears this is a feature gap and needs to be enhanced.
While not ideal, if you wanted to open the record, you could try the following instead:
xrmBrowser.Entity.ClickSubgridGridViewButton(subgridName)
This should take you to the 'Associated View' via Related Navigation. From here, you could call:
optional:
xrmbrowser.Related.Search(contactrecordname);
xrmBrowser.Related.OpenGridRow(#)
At this point, you could then switch back to perform actions on the opened Contact entity record:
xrmBrowser.Entity.SomeMethod();
Please let me know if this set of steps help you with your scenario. I've added a feature enhancement to the backlog to allow opening of a record from a subgrid on a form.

Is it possible to show all options in Tokenize2?

Tokenize2 is a javacsript lib to select multiple options.
It provides a very neat UI to start writing and then get a list of options to select from. Selected options will show up as "tags" that can be removed with "x" link.
So far all is fine. But Right now you need to know what your looking for and start write at least one character to see matching alternatives.
In my scenario there are very few alternatives and they are not known to the user. I would like to show ALL options when the user clicks the input box. There is a configuration option named searchMinLength but it is already set to 0.
Is there a workaround that can be used? Maybe like triggering load and dropdown manually?
I know there are a lot of similar alternatives but I picked Tokenize2 because:
It looks clean and nice
It works in mobile browsers
I don't know if there is an "official" approach, but after some investigation I have found an acceptable workaround.
After downloading the Tokenizer2 sourceode I found the following line that triggered my attention:
if(this.input.val().length > 0){
this.trigger('tokenize:search', [this.input.val()]);
}
My interpretation is that the internal search command is not triggered unless the user input has at least one character. This line in sourcecode could easily be modified. I have filed a suggestion for this here: https://github.com/zellerda/Tokenize2/issues/26
My current workaround is to add an event listener for the select event and there trigger the internal search command. That works fine for my scenario and does not force a source code rewrite.
$("#my-dropdown").on("tokenize:select", function (e: Event, routedEvent: boolean) {
$("#my-dropdown").trigger('tokenize:search', "");
});
Tokenize2
This link worked for me GitHub
$('.tokenize-sample-demo1').on('tokenize:select', function(container){
$(this).tokenize2().trigger('tokenize:search', [$(this).tokenize2().input.val()]);
});

How do I register a MediatR post processor

I would like to try the new pipeline feature in MediatR: https://github.com/jbogard/MediatR/wiki/Behaviors
I tried the following, but it does not get executed
services.AddMediatR();
services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(PostHandler<,>));
What am I missing?
You need to register the behavior associated with post-processors, like this unit test shows.
Your registration code would look like:
services.AddMediatR();
services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(PostHandler<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
That behavior will get all the post-processors you registered and execute them.
Edit
After a comment about the post-processor running twice, I had a look at the code that registers MediatR in the ASP.NET Core built-in DI container, and it turns out instances of IRequestPreProcessor<TRequest, TResponse> and IRequestPostProcessor<TRequest, TResponse> are automatically registered as you can see here. What's left to do to get them running in the pipeline is just register the associated behavior. So the necessary registration is then:
services.AddMediatR();
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>));
I encountered the same issue as Larsi in the comment above. My code looked like this
services.AddScoped<IPipelineBehavior<AddMessageRequest, MessageResponse>, RequestPostProcessorBehavior<AddMessageRequest, MessageResponse>>();
but the behaviour still executed twice. My solution was to simply not register it manually, seems like the registration is handled otherwise now.
In my case services.AddMediatR(Assembly.GetExecutingAssembly()); was enough.
Would be nice if someone could expand on why this is.

How to work with hook_nodeapi after image thumbnail creation with ImageCache

A bit of a followup from a previous question.
As I mentioned in that question, my overall goal is to call a Ruby script after ImageCache does its magic with generating thumbnails and whatnot.
Sebi's suggestion from this question involved using hook_nodeapi.
Sadly, my Drupal knowledge of creating modules and/or hacking into existing modules is pretty limited.
So, for this question:
Should I create my own module or attempt to modify the ImageCache module?
How do I go about getting the generated thumbnail path (from ImageCache) to pass into my Ruby script?
edit
I found this question searching through SO...
Is it possible to do something similar in the _imagecache_cache function that would do what I want?
ie
function _imagecache_cache($presetname, $path) {
...
...
// check if deriv exists... (file was created between apaches request handler and reaching this code)
// otherwise try to create the derivative.
if (file_exists($dst) || imagecache_build_derivative($preset['actions'], $src, $dst)) {
imagecache_transfer($dst);
// call ruby script here
call('MY RUBY SCRIPT');
}
Don't hack into imagecache, remember every time you hack core/contrib modules god kills a kitten ;)
You should create a module that invokes hook_nodeapi, look at the api documentation to find the correct entry point for your script, nodeapi works on various different levels of the node process so you have to pick the correct one for you (it should become clear when you check the link out) http://api.drupal.org/api/function/hook_nodeapi
You won't be able to call the function you've shown because it is private so you'll have to find another route.
You could try and build the path up manually, you should be able to pull out the filename of the uploaded file and then append it to the directory structure, ugly but it should work. e.g.
If the uploaded file is called test123.jpg then it should be in /files/imagecache/thumbnails/test123/jpg (or something similar).
Hope it helps.

Correct way to force an invoice e-mail to be sent to a user in UberCart?

What is the correct way to force the system to send an invoice to a client. I'm trying to use:
uc_order_action_email($order, $settings);
But I keep getting:
Fatal error: Call to undefined function uc_price() in C:\xampp\htdocs\YourEstablishment\src\sites\all\modules\ubercart\payment\uc_payment\uc_payment.module on line 149
It might be a flaw in the module. The function that it's complaining about, uc_price, is defined in
ubercart/uc_store/includes/uc_price.ini
Since it's located in a ini file, that means that drupal wont include it by it self. I'm not familiar with ubercart, since I've never used it, but it seems like this could be a bug in the module. If no one here can come up with an explanation, you should go to the issue tracker.
A quick fix to your problem would be to add this before you call the function
require_once(drupal_get_path('module', 'uc_store') . '/includes/uc_price.inc');
it will include the needed file.

Resources