All user input is a bit much. Only common ground I can see is that all user input goes thorough some kind of forms. And the only thing that for sure happens before anything tries to save, is validation*.
Functions listed in #validate
can alter form state. Example definition shows they take form state by reference:
function test_form_validate($form, &$form_state) {
So the "only" thing you would have to do is to recursively iterate over all $form_state['values']
, and apply your removal function. It should be pretty safe, because by the very nature your function will not affect numerical inputs in any way.
Other approach might be a bit faster. You can use #element_validate
- prepend your removal function to validation array of each and every text field. Sadly, form element types may be added by modules, so you would have to prepend it to every element anyway (forgetting any significant boost due to validation only data that needs it, and paying a price of more function calls), or carefully inspect your modules and make sure you know what else, except textfield and textarea can accept text data (machine_name element is already safe, I omitted it on purpose).
All in all, I would prefer to just switch my MySQL to utf8mb4 charset, that supports all utf8 as it ought to be supported. You need MySQL 5.5.3 or greater to do this.
Hacking Drupal is usually not encouraged, but in this particular case we cannot expect a patch, so this is the only way to give users what they want. Also, it's method way less CPU consuming that altering all inputs.
* Of course you may create your own submit handler and make it a first one, but making sure it's always first is hard. Other module developers may try to have their handlers first, too. And if they decide to, for example, log something to MySQL, your fix becomes futile. Using validation is a bit of abuse, but it's an only way I would trust in this scenario.