Search code examples
phpif-statementsymfony1logic

Checking if the referer is empty or if it is in an array


I am trying to write an if statement that basically checks if the users referrer is in a list of allowed referrers and if not fails.

I have two variables controlling this $this->allowAllReferer and $this->allowEmptyReferer, which as per their name decide whether every referrer should be allowed access and whether empty referrers are allowed, respectively. As well as $this->allowedReferers which is an array of allowed referrers.

I have this function below which I am pretty sure isn't working properly but I have been staring at and tweaking it for half an hour and i've got to the point where I can't tell if it's working or not.

//If the referee is empty and allow empty referrer is false
//or
//If it is not in the allowed list and allow all referer is false 
if(!(empty($_SERVER['HTTP_REFERER']) && $this->allowEmptyReferer)
    &&
   !(!$this->allowAllReferer && in_array(
      strtolower(empty($_SERVER['HTTP_REFERER']) ? null : $_SERVER['HTTP_REFERER']), //Silly php access null variable
      $this->allowedReferers)
    )) {
    throw new sfException("Internal server error. Please contact system administrator. File download disabled.");
} 

Do you know the correct or a better way to do this/can you confirm the above works?


Cases, hope this makes it more clear

empty_referrer | allowEmpty | in_array | allReferer | result
----------------------------------------------------------------
true           | true       | false    | false      | false - no error - empty allowed
false          | true       | false    | false      | true - error - not in array
false          | true       | false    | true       | false - no error - not in array but allowed
false          | false      | false    | false      | true - error - empty and now allowed

Solution

  • If you would like to keep the logic within one huge if block, then try the following:

    if (
        // throw an error if it's empty and it's not allowed to be
        (empty($_SERVER['HTTP_REFERER']) && !$this->allowEmptyReferer)
        || (
          // don't bother throwing an error if all are allowed or empty is allowed
          (!empty($_SERVER['HTTP_REFERER']) && !$this->allowAllReferer)
          // throw an error if it's not in the array
          && !in_array((empty($_SERVER['HTTP_REFERER']) ? null : strtolower($_SERVER['HTTP_REFERER'])), $this->allowedReferers)
        )
    )
    {
      throw new sfException("Internal server error. Please contact system administrator. File download disabled.");
    }
    

    The second check for empty will now skip the in_array if it's empty.