[ Index ]

PHP Cross Reference of GlotPress

title

Body

[close]

/gp-includes/ -> route.php (source)

   1  <?php
   2  /**
   3   * Base controller class
   4   */
   5  class GP_Route {
   6  
   7      public $api = false;
   8  
   9      public $errors = array();
  10      public $notices = array();
  11  
  12      var $request_running = false;
  13      var $template_path = null;
  14  
  15      var $fake_request = false;
  16      var $exited = false;
  17      var $exit_message;
  18      var $redirected = false;
  19      var $redirected_to = null;
  20      var $rendered_template = false;
  21      var $loaded_template = null;
  22      var $template_output = null;
  23      var $headers = array();
  24      var $class_name;
  25      var $http_status;
  26      var $last_method_called;
  27  
  28  	public function __construct() {
  29  
  30      }
  31  
  32  	public function die_with_error( $message, $status = 500 ) {
  33          $this->status_header( $status );
  34          $this->exit_( $message );
  35      }
  36  
  37  	public function before_request() {
  38          /**
  39           * Fires before a route method is called.
  40           *
  41           * @since 1.0.0
  42           *
  43           * @param string $class_name         The class name of the route.
  44           * @param string $last_method_called The route method that will be called.
  45           */
  46          do_action( 'gp_before_request', $this->class_name, $this->last_method_called );
  47      }
  48  
  49  	public function after_request() {
  50          // we can't unregister a shutdown function
  51          // this check prevents this method from being run twice
  52          if ( !$this->request_running ) return;
  53          // set errors and notices
  54          if ( !headers_sent() ) {
  55              $this->set_notices_and_errors();
  56          }
  57  
  58          /**
  59           * Fires after a route method was called.
  60           *
  61           * @since 1.0.0
  62           *
  63           * @param string $class_name         The class name of the route.
  64           * @param string $last_method_called The route method that will be called.
  65           */
  66          do_action( 'gp_after_request', $this->class_name, $this->last_method_called );
  67      }
  68  
  69      /**
  70       * Validates a thing and add its errors to the route's errors.
  71       *
  72       * @param object $thing a GP_Thing instance to validate
  73       * @return bool whether the thing is valid
  74       */
  75  	public function validate( $thing ) {
  76          $verdict = $thing->validate();
  77          $this->errors = array_merge( $this->errors, $thing->errors );
  78          return $verdict;
  79      }
  80  
  81      /**
  82       * Same as validate(), but redirects to $url if the thing isn't valid.
  83       *
  84       * Note: this method calls $this->exit_() after the redirect and the code after it won't
  85       * be executed.
  86       *
  87       * @param object $thing a GP_Thing instance to validate
  88       * @param string $url where to redirect if the thing doesn't validate
  89       * @return bool whether the thing is valid
  90       */
  91  	public function invalid_and_redirect( $thing, $url = null ) {
  92          $valid = $this->validate( $thing );
  93          if ( !$valid ) {
  94              $this->redirect( $url );
  95              return true;
  96          }
  97          return false;
  98      }
  99  
 100      /**
 101       * Checks whether a user is allowed to do an action.
 102       *
 103       * @since 2.3.0 Added the `$extra` parameter.
 104       *
 105       * @param string      $action      The action.
 106       * @param string|null $object_type Optional. Type of an object. Default null.
 107       * @param int|null    $object_id   Optional. ID of an object. Default null.
 108       * @param array|null  $extra       Optional. Extra information for deciding the outcome.
 109       * @return bool       The verdict.
 110       */
 111  	public function can( $action, $object_type = null, $object_id = null, $extra = null ) {
 112          return GP::$permission->current_user_can( $action, $object_type, $object_id, $extra );
 113      }
 114  
 115      /**
 116       * Redirects and exits if the current user isn't allowed to do an action.
 117       *
 118       * @since 1.0.0
 119       *
 120       * @param string      $action      The action.
 121       * @param string|null $object_type Optional. Type of an object. Default null.
 122       * @param int|null    $object_id   Optional. ID of an object. Default null.
 123       * @param string|null $url         Optional. URL to redirect to. Default: referrer or index page, if referrer is missing.
 124       * @return bool Whether a redirect happened.
 125       */
 126  	public function cannot_and_redirect( $action, $object_type = null, $object_id = null, $url = null ) {
 127          $can = $this->can( $action, $object_type, $object_id );
 128          if ( ! $can ) {
 129              $this->redirect_with_error( __( 'You are not allowed to do that!', 'glotpress' ), $url );
 130              return true;
 131          }
 132          return false;
 133      }
 134  
 135      /**
 136       * Verifies a nonce for a route.
 137       *
 138       * @since 2.0.0
 139       *
 140       * @param string $action Context for the created nonce.
 141       * @return bool False if the nonce is invalid, true if valid.
 142       */
 143  	public function verify_nonce( $action ) {
 144          if ( empty( $_REQUEST['_gp_route_nonce'] ) ) {
 145              return false;
 146          }
 147  
 148          if ( ! wp_verify_nonce( $_REQUEST['_gp_route_nonce'], $action ) ) {
 149              return false;
 150          }
 151  
 152          return true;
 153      }
 154  
 155      /**
 156       * Verifies a nonce for a route and redirects in case the nonce is invalid.
 157       *
 158       * @since 2.0.0
 159       *
 160       * @param string      $action Context for the created nonce.
 161       * @param string|null $url    The URL to redirect. Default: 'null', the referrer.
 162       * @return bool False if the nonce is valid, true if the redirect has happened.
 163       */
 164  	public function invalid_nonce_and_redirect( $action, $url = null ) {
 165          if ( $this->verify_nonce( $action ) ) {
 166              return false;
 167          }
 168  
 169          $this->redirect_with_error( __( 'An error has occurred. Please try again.', 'glotpress' ), $url );
 170          return true;
 171      }
 172  
 173      /**
 174       * Determines whether a user can perfom an action and redirects in case of a failure.
 175       *
 176       * @since 1.0.0
 177       *
 178       * @param string      $action      The action.
 179       * @param string|null $object_type Optional. Type of an object. Default null.
 180       * @param int|null    $object_id   Optional. ID of an object. Default null.
 181       * @param string|null $message     Error message in case of a failure.
 182       *                                 Default: 'You are not allowed to do that!'.
 183       * @param array|null  $extra       Pass-through parameter to can().
 184       * @return false
 185       */
 186  	public function can_or_forbidden( $action, $object_type = null, $object_id = null, $message = null, $extra = null ) {
 187          if ( ! isset( $message ) ) {
 188              $message = __( 'You are not allowed to do that!', 'glotpress' );
 189          }
 190          if ( ! $this->can( $action, $object_type, $object_id, $extra ) ) {
 191              $this->die_with_error( $message, 403 );
 192          }
 193          return false;
 194      }
 195  
 196  	public function logged_in_or_forbidden() {
 197          if ( ! is_user_logged_in() ) {
 198              $this->die_with_error( 'Forbidden', 403 );
 199          }
 200      }
 201  
 202  	public function redirect_with_error( $message, $url = null ) {
 203          $this->errors[] = $message;
 204          $this->redirect( $url );
 205      }
 206  
 207  	public function redirect( $url = null ) {
 208          if ( $this->fake_request ) {
 209              $this->redirected = true;
 210              $this->redirected_to = $url;
 211              return;
 212          }
 213  
 214          $this->set_notices_and_errors();
 215  
 216          if ( is_null( $url ) ) {
 217              $url = $this->get_http_referer();
 218          }
 219  
 220          /*
 221           * TODO: do not redirect to projects, but to /.
 222           * Currently it goes to /projects, because / redirects too and the notice is gone.
 223           */
 224          if ( ! $url ) {
 225              $url = gp_url( '/projects' );
 226          }
 227  
 228          wp_redirect( $url );
 229          $this->tmpl( 'redirect', compact( 'url' ) );
 230      }
 231  
 232      /**
 233       * Retrieves referer from '_wp_http_referer' or HTTP referer.
 234       *
 235       * Unlike `wp_get_referer()`, it doesn't check if the referer is
 236       * the same as the current request URL.
 237       *
 238       * @since 2.0.0
 239       *
 240       * @return false|string False on failure. Referer URL on success.
 241       */
 242  	private function get_http_referer() {
 243          if ( ! function_exists( 'wp_validate_redirect' ) ) {
 244              return false;
 245          }
 246  
 247          $ref = $this->get_raw_referer();
 248          if ( $ref ) {
 249              return wp_validate_redirect( $ref, false );
 250          }
 251  
 252          return false;
 253      }
 254  
 255      /**
 256       * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
 257       *
 258       * @since 2.0.0
 259       *
 260       * @return string|false Referer URL on success, false on failure.
 261       */
 262  	private function get_raw_referer() {
 263          if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
 264              return wp_unslash( gp_array_get( $_REQUEST, '_wp_http_referer' ) );
 265          } else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
 266              return wp_unslash( gp_array_get( $_SERVER, 'HTTP_REFERER' ) );
 267          }
 268  
 269          return false;
 270      }
 271  
 272      /**
 273       * Sets HTTP headers for content download.
 274       *
 275       * @param string $filename      The name of the file.
 276       * @param string $last_modified Optional. Date when the file was last modified. Default: ''.
 277       */
 278  	public function headers_for_download( $filename, $last_modified = '' ) {
 279          $this->header( 'Content-Description: File Transfer' );
 280          $this->header( 'Pragma: public' );
 281          $this->header( 'Expires: 0' );
 282  
 283          if ( $last_modified ) {
 284              $this->header( sprintf( 'Last-Modified: %s', $last_modified ) );
 285          }
 286  
 287          $this->header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
 288          $this->header( "Content-Disposition: attachment; filename=\"$filename\"" );
 289          $this->header( 'Content-Type: application/octet-stream' );
 290          $this->header( 'Connection: close' );
 291      }
 292  
 293  	public function set_notices_and_errors() {
 294          if ( $this->fake_request ) return;
 295  
 296          foreach( $this->notices as $notice ) {
 297              gp_notice_set( $notice );
 298          }
 299          $this->notices = array();
 300  
 301          foreach( $this->errors as $error ) {
 302              gp_notice_set( $error, 'error' );
 303          }
 304          $this->errors = array();
 305      }
 306  
 307      /**
 308       * Loads a template.
 309       *
 310       * @param string $template template name to load
 311       * @param array $args Associative array with arguements, which will be exported in the template PHP file
 312       * @param bool|string $honor_api If this is true or 'api' and the route is processing an API request
 313       *         the template name will be suffixed with .api. The actual file loaded will be template.api.php
 314       */
 315  	public function tmpl( $template, $args = array(), $honor_api = true ) {
 316          if ( $this->fake_request ) {
 317              $this->rendered_template = true;
 318              $this->loaded_template = $template;
 319          }
 320          $this->set_notices_and_errors();
 321          if ( $this->api && $honor_api !== false && 'no-api' !== $honor_api ) {
 322              $template = $template.'.api';
 323              $this->header('Content-Type: application/json');
 324          } else {
 325              $this->header('Content-Type: text/html; charset=utf-8');
 326          }
 327          if ( $this->fake_request ) {
 328              $this->template_output = gp_tmpl_get_output( $template, $args, $this->template_path );
 329              return true;
 330          }
 331  
 332          return gp_tmpl_load( $template, $args, $this->template_path );
 333      }
 334  
 335  	public function die_with_404( $args = array() ) {
 336          $this->status_header( 404 );
 337          $this->tmpl( '404', $args + array( 'title' => __( 'Not Found', 'glotpress' ), 'http_status' => 404 ) );
 338          $this->exit_();
 339      }
 340  
 341  	public function exit_( $message = 0 ) {
 342          if ( $this->fake_request ) {
 343              $this->exited = true;
 344              $this->exit_message = $message;
 345              return;
 346          }
 347          exit( $message );
 348      }
 349  
 350  	public function header( $string ) {
 351          if ( $this->fake_request ) {
 352              list( $header, $value ) = explode( ':', $string, 2 );
 353              $this->headers[$header] = $value;
 354          } else {
 355              header( $string );
 356          }
 357      }
 358  
 359  	public function status_header( $status ) {
 360          if ( $this->fake_request ) {
 361              $this->http_status = $status;
 362              return;
 363          }
 364          return status_header( $status );
 365      }
 366  }


Generated: Tue Mar 19 01:01:50 2019 Cross-referenced by PHPXref 0.7.1