0

I have a lot of ajax functions in my php application like this :

$.post('index.php?controller=suivi&action=ajax_intervention_save', {
            id: root.find('#id').val(),
            begin: begin,
            end: end,
        }, function(res) {
            //if is not an ID
            if (res && isNaN(res)) {
                error();
                SUIVI.showButton();
            } else {
                displaySuccess("Fiche saved");
            }
        });

And i want to block the access at my application when i have a maintenance_mode == 1. So i add this condition :

$.post('index.php?controller=suivi&action=ajax_intervention_save', {
            id: root.find('#id').val(),
            begin: begin,
            end: end,
        }, function(res) {
        if(res === 'MAINTENANCE'){
            error(res);
            return;
        }
            //if is not an ID
            if (res && isNaN(res)) {
                error();
                SUIVI.showButton();
            } else {
                displaySuccess("Fiche saved");
            }
        });

My problem that I have a lot of functions like this in others files. How can I do to not copy the code res === 'MAINTENANCE' in all functions? I want a way that tells can display 'maintenance mode message for all ajax functions when mode == 1

This is my index.php redirection :

if(\app\models\Config::getValue('maintenance_mode')){
if (Tools::isAjax())
    die('MAINTENANCE');
elseif(!isset($_GET['action']) || $_GET['action'] !== 'maintenance'){
    header('Location:index.php?module=general&action=maintenance');
}

}

Thanks

Hyyan Abo Fakher
  • 3,497
  • 3
  • 21
  • 35
prozbk
  • 57
  • 1
  • 8

4 Answers4

0

In my opinion, the best approach would be the following: You'd have a global function, which expects the URL, which should be called, and an array for the information to send with the request.

That function should do all of your ajax requests with the given injected information. Then, you'd change all your ajax calls, that you've implemented yet, to call that function.

With that, you'd have one single point where you can make the needed changes.

But I guess that this question is primarily opinion based.

KhorneHoly
  • 4,666
  • 6
  • 43
  • 75
  • Thanks for your answer, but that will refactor all my application and take a lot o time. Can you give me an express solution or idea ? – prozbk Sep 10 '18 at 15:48
0

Before die() you could set a status header that is not in 200 range and thus would error out $.post and not call it's success callback.

header("HTTP/1.1 503 SERVICE UNAVAILABLE");
die('MAINTENANCE');

Then use jQuery global ajaxError() to look for that error status on all requests


Example using post to http://httpbin.org/ which has test routes for status codes

// will see all ajax errors in page
$(document).ajaxError(function(event, xhr) {

  var maintenanceMessage = "SERVICE UNAVAILABLE" // default 503 message
  
  if (xhr.status === 503 && xhr.statusText === maintenanceMessage) {
    // do something to notify user of maintenance mode      
    console.log('Status::', [xhr.status, xhr.statusText])
  }
  // else ...do things for other errors also  
});

// make simple request in order to trigger error
var url = 'http://httpbin.org/status/503';
$.post(url, function() {
  console.log('Should not see this due to status code error')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Note there are various approaches to setting status headers using php, see https://stackoverflow.com/a/12018482/1175966

charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

If you don't want to refactor all your other code then you could override your success callback. You can do this by setting up a global beforeSend callback and change the success, error, or any of the other callback properties of the options object passed to it

$.ajaxSetup({
  beforeSend:function(xhr,options){
    //save the original callback
    var original = options.success;

    //setup the new callback
    options.success = function(data){
      if(data == "MAINTENANCE"){
        error();
        return;
      }
      //call the original callback if no error
      original.apply(this,arguments);
    }
  }
})

Note though if the ajax calls use the promise callbacks this will not intercept them. So for instance if you had:

$.post().then(function(){
  //code
});

Your then() callback would be called even if you had the beforeSend setup.

Patrick Evans
  • 41,991
  • 6
  • 74
  • 87
0

You could try this :

if(res !== 'MAINTENANCE'){
$.post('index.php?controller=suivi&action=ajax_intervention_save', {
        id: root.find('#id').val(),
        begin: begin,
        end: end,
    }, function(res) {
        //if is not an ID
        if (res && isNaN(res)) {
            error();
            SUIVI.showButton();
        } else {
            displaySuccess("Fiche saved");
        }
    });
}
JamesBond
  • 312
  • 2
  • 17