osclass / Osclass

With Osclass, get your own classifieds site for free. Build your own Osclass installation and start advertising real estate, jobs or whatever you want- in minutes!
http://osclass.org/
649 stars 342 forks source link

(feature/issue) plugin "A" call function from plugin "B" #2187

Closed dev-101 closed 6 years ago

dev-101 commented 7 years ago

Hi, not sure about where to post this (here or at forum), but is it possible that if a plugin "A" is registered and active/installed, it's function(s) be called inside plugin "B"?

Currently, I get function_exists() = returns false (or HTTP 500 / PHP throws fatal error that a function [from another plugin] does not exists if I bypass that check).

Is this possible at all through a function or model? What if I need to provide a simple API to other plugins?

edit To be more specific, problem is ajax related. When function x() from plugin "A" completes it's ajax action, that function/method should trigger another plugin's ("B") y() function/hook/method.

But, nothing happens (except HTTP 500) if I call (1) hook, (2) function or (3) class/method in model or index.php of the first plugin ("A").

I would like to avoid code/function duplication from other plugin, plus this is not optimal, as I must provide ways for other devs to interact or trigger certain action(s) from my plugin when they need it.

conejoninja commented 7 years ago

A PHP function, once loaded the file it is defined, is available anywhere in your code, you can not skip the check, function_exists (or if you are sure, you could check if the class is loaded too).

Instead of plugin A calling plugin B,... why not let plugin A run a hook, and that plugin B is the one which do something on said hook?

dev-101 commented 7 years ago

edited

Hi Conejo, I know all that and thought it would be as simple, but it's not... it does not work for some reason.

I've tested countless variations / multiple scenarios, embedded in every way I could figure, and everything that I've tried did not work. The function is simply not triggered, as it is not "seen" as registered.

quick example:

plugin "A": ajax.php

<?php
require_once('model/mymodelA.php');
if (isset(Params::getParam('mypluginparam'))) {
    MyModelA::pluginA_do_something(Params::getParamAsArray());
}
?>

then, in A model:

function pluginA_do_something() {
 // do something here in plugin A
osc_run_hook('plugin_A_hook', $params);
}

then, in plugin B:

function pluginB($params) {
// do some code here in plugin B
}
osc_add_hook('plugin_A_hook', 'pluginB');

Maybe it is because of ajax implementation or something (it is a standard way with $.ajax, does not use any internal method).

$(document).ready(function($) {
    $(document).on("submit", "#selector", function(event) {
        $.ajax({
            url: action,
            type: method,
            data: data,
            cache: false,
            success: function(data) {}
// and so on...

Because, $.ajax will trigger plugin's A function, that will call a model method, that should theoretically run any other functions via hook(s) from other files/plugins. And that does not happen.

Hook system in Osclass will ignore errors (it is by design, as calling a non-existent hook could break everything), so I cannot debug it. But, when I call a function directly (because I know it exists in another plugin), PHP throws error.

Thanks

conejoninja commented 7 years ago

Is plugin B installed and enabled? Because It has to work, $.ajax has nothing to do with PHP code, so here you either has a return before the hook or the name of the function has a typo. Calling it directly should work (if loaded).

Are you calling the ajax.php file directly or through a "route"?

dev-101 commented 7 years ago

Of course, both plugins are installed and running :)

All plugins work fine when called/executed from standard core hooks or from theme etc. Just, inter-communication does not seem to work.

I am currently tired, and have some tasks in upcoming days, but I will try to send you 2 concept plugins that you can test. So far, I have tested this only in one system (shared, php 7.0.19 or something like that). I have not had time to re-test this in different environments, but I will.

File is called directly, from a button embedded @ theme. It works (I mean, the plugin correctly runs everything) on its own. It just does not trigger another function from other plugin, that I need.

edit No, I definitely don't have a return before the hook @ method, I don't have a return in fact (does not make a difference).

conejoninja commented 7 years ago

ahhh that's the issue here. When you call (via ajax) a file directly, only the file is loaded (and any other file you include/require there), so no osclass function should be available. The correct way is to declare a route, and call the route via ajax. Routes load all required files by osclass (oc-load.php) so other plugins are available too there.

You could send my both your plugins, I will take a look at it, no problems.

dev-101 commented 7 years ago

Ok, thanks Conejo!

I new it had to be related to something, because the error that PHP throws that function does not exists, has to mean something related to loading.

I will send you 2 examples, just give me some time to get throw couple of days :)

dev-101 commented 7 years ago

Hi Conejo,

here's one market plugin that uses direct ajax call: https://market.osclass.org/plugins/ad-management/toggle-item-status_526

You can take a look at it's ajax code, it is essentially the same principle described above. There is just no way to run another plugin's function via hook (or directly), as you said.