Welcome to the Question2Answer Q&A. There's also a demo if you just want to try it out.
+11 votes
2.6k views
in Q2A Core by

(This is mainly for the interest of plugin developers...)

Version 1.5 will include a generalized function overriding mechanism that lets you override some core Q2A functions with your own version, similarly to pluggable functions in WordPress.

However, it will improve on WordPress' mechanism in two key ways:

  1. Your overriding functions can optionally call through to the original function, so it will be more future-proof.
  2. The same function can be overridden multiple times by different plugins, with Q2A automatically building an inheritance chain so that each one calls through to the previous one.

Conceptually this mechanism is similar to layers, except you're overriding functions in the global scope rather than methods of the theme object. Here's a very simple (and silly) example of what you can do:

function qa_q_request($questionid, $title)
{
  return qa_q_request_base($questionid, strrev($title));
}
 
I'm looking for feedback on which specific Q2A core functions you would like to see pluggable. I can give this a reasonable guess for myself, but it would be helpful if you could post a list of those that you could see a need for. Thanks!

12 Answers

+5 votes
by
edited by

reCaptcha - to give possibility of providing other captcha, e.g. more simple, numbers only, image recognition, etc.

+3 votes
by
edited by

Enable to override declination mechanisms.

 
English nouns have one form in plural.
In other languages it can differ.
In Polish for example, the noun "vote" looks as follows:
1 głos, 2 głosy, BUT 5 głosów.
 
There is a rule of finding the correct noun form.
It could be in some overridable method and used very roughly like that:
 
$declin = getDeclination($upvotes, "1", "2", "5");
$fields['upvotes_view']=($declin==1) ? qa_lang_html_sub_split('main/1_liked', $upvoteshtml, '1')
: (($declin==2) ? qa_lang_html_sub_split('main/x_liked2', $upvoteshtml) : qa_lang_html_sub_split('main/x_liked', $upvoteshtml));
 
EDIT:
Maybe this method could be connected dynamically with the selected language ?
+3 votes
by

Hi Gideon!

Thanks for letting us give our input about that. I've looked through the modifications I made and here's what I think could be useful:

qa_send_notification in qa-app-email: Mainly to change the email content and force HTML, so another function that does just that could be created, passing the handle and all that stuff. I could also see that some might want to have better control on when email are sent.

qa_html_suggest_ask in qa-app-format: In my case, I've changed it just to not propose anything since one of my Q2A is a close FAQ

qa_db_table_definitions in qa-db-install: So I can create my own tables during the process of building the whole Q2A

I did modify the creating of the maintenance message to include the site title as a parameter in qa-page, but I don't see how this could be extracted since it isn't a function.

Other than that, many things can be done using the event module. I've made a lot of other changes, but they were to include moderation and external search, two upcoming features. If they aren't as I need, I may have more suggestions then! ;) 

I also did some modifications so I could propose tags from another source than Q2A in qa-page-ask, but this isn't part of a function. Maybe you could add a function just to get tags and I could add my own there.

Thanks for your work and your open mind!

Mélanie

+2 votes
by

The only one that springs to mind is qa_string_to_words and maybe others in qa-util-string.php.

Aside from that I don't have many core mods any more, apart from a mod to qa_handle_email_validate to prevent characters in a username (dunno if there's a need for it to be overridden), and to the inline code of qa-page-question.php to return a 404 header when a question is hidden or otherwise unviewable.

+3 votes
by
Nice!  Having finally grokked the layer mechanism magic, this sounds like a great idea.

I know I suggested this for 1.5 along with the hooks, but I realized after that I really need the hooks more than pluggable functions - so far, I can't think of any functions I would have overridden, just ones that I would want to cancel (events, mainly).

A set of functions I could see editing are those that output html, e.g. qa_post_html_fields(), but that can also be done in a layer, I think.

Actually, this would probably be a good way for a plugin to modify the recalc functions, no?  Suppose we wanted to check for extra points, we could just slip into qa_db_users_recalc_points() and... well, first I have to grok how that works :)  But yeah, all the recalc functions would be nice... oh, and now that I think of it,  qa_recalc_perform_step(), if there were some way to add an $operation for a totally new recalc function, that would be handy... maybe that's too much for 1.5, though :)
by
Thanks for your response. In Q2A 1.5 there aren't going to be hooks per se, but rather a combination of modules (for related groups of functionality) and pluggable functions (for more general purposes). I think almost any type of customization can be achieved via these two mechanisms, so my question about is really about what other types of customization people might want.
by
Okay, I get it now, thanks for the clarification.  Which would pre-event handling come under?
by
That would use pluggable functions for much of qa-app-post-create.php
+4 votes
by
edited by
Preventing comment spam with Akismet.

I'd like the ability for a plug-in to process any message before it's added to the system. This allows a plug-in to use the Akismet API to check with Akismet if the comment is spam or not.

Ideally, the plug-in will be able to mark a comment as hidden and flag it for the admin to view and approve/trash and ban the user.

For those who don't know, Akismet is a crowdsource anti-spam service that's from the makers of Wordpress. They have an API that lets you check comments and flag as spam. If someone else flagged a comment as spam, they can tell all others that their comment is spam too. Gmail does the same thing with email spam.
by
You should be able to do that now with an event plugin.
by
Awesome. I'll look into that plug-in next.
+1 vote
by

Append or override every function.

While I was building the Cache That plug-in, I needed to hook into a very early part of Q2A but also needed some core functions loaded first. My solution was to execute code right in the qa-plugin.php file and reproduce the functions I needed. It would’ve been easier to build and upgrade friendly if I were able to hook in after the core files were included.

Wordpress does a great job with hooks. I can add an action or filter to every part of the system. I can also remove the core action or filter and replace it with my own.

It would be great to have this ability with Q2A and it’ll allow for very advanced plug-ins in the future.

If it’s not possible to allow us to append to or override all functions, it would be good to get hooks into major parts of the life cycle.

+2 votes
by

Would certainly be helpful to offer a way how to load external Javascript in a standardized way similar to Wordpress so that there is no risk of loading it twice. (I encountered that problem with the Facebook login if the share widget is activated.)

+1 vote
by

Okay, some more come to mind now:

qa_redirect()

qa_get_permit_options()

qa_opt()

qa_fatal_error()

qa_report_event()

also, if this line:

$qa_plugin_files=glob(QA_PLUGIN_DIR.'*/qa-plugin.php');

could be functionized, then we could edit this list (the order, for example).

None of these are urgent by any means... please take them as suggestions, not requests.

One request I do have, and I think it is of this vein, is to make the whole theme output system pluggable, in the sense of not outputting anything until the last moment, and then letting each layer get one last crack at the full html output.  I guess that might be a problem for ajax calls that rely on partial output, but if it's possible, it would make certain tasks easier (read: lazy-proof smiley ).

by
You could do this now with PHP output buffering, doing your thing either side of the html() theme function.
+1 vote
by
Slightly off topic from your question but I'd like more places the plug-in gets called. Here's a problem i'm currently having:

I'm trying to get my Cache This plug-in to work with the Theme Switcher. To do this, I need Theme Switcher to initialize early so it can define the theme it wants to use. Then Cache This can see what theme is being requested and serve out the correct cache file. For this to work, Theme Switcher has to init first and then Cache This has to be able to execute shortly there after so it can serve cached data before database connections and other expensive functions are called.

It would also be great to have a var with a list of which plug-ins/layers have been loaded on the system so I can automatically disable the plug-in if there's a known conflict.
by
With the new hooks mechanism coming in 1.5, you should have tons more options for timing, e.g. upon connecting to the database.

As for listing modules, layers, etc... there are some functions in qa-base.php that you can make use of, e.g. qa_list_modules(...), or (unofficially) just take a peek at the globals $qa_layers, $qa_modules.
+1 vote
by
a couple more:

qa_admin_sub_navigation()

and

qa_qs_sub_navigation($sort)
by
I think I'll leave this to the layer's responsibility - if you override nav_list(...), you can pre-modify a navigation list before calling on through.
+2 votes
by
I think I posted this before, but it would be nice to have the ability to add privileges to the privilege list - I would add custom privileges to the privileges plugin if there were an easy way to include them in the "admin/permissions" tab.  Not sure what function this would go with, but just another on the list.
by
Yes, this happens via qa_get_permit_options(...) in qa-app-options.php, which will be pluggable in 1.5.
...