[ Index ]

PHP Cross Reference of GlotPress

title

Body

[close]

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

   1  <?php
   2  
   3  class GP_Router {
   4  
   5      public $api_prefix = 'api';
   6      private $urls      = array();
   7  
   8  	public function __construct( $urls = array() ) {
   9          $this->urls = $urls;
  10      }
  11  
  12      /**
  13       * Sets the default routes that GlotPress needs.
  14       */
  15  	public function set_default_routes() {
  16          $this->urls = array_merge( $this->urls, $this->default_routes() );
  17  
  18          /**
  19           * Fires after default routes have been set.
  20           *
  21           * @since 1.0.0
  22           *
  23           * @param GP_Router $router The router object.
  24           */
  25          do_action( 'gp_router_default_routes_set', $this );
  26      }
  27  
  28      /**
  29       * Returns the current request URI path, relative to
  30       * the application URI and without the query string
  31       */
  32  	public function request_uri() {
  33          global $wp;
  34          return urldecode( '/' . rtrim( $wp->query_vars['gp_route'], '/' ) );
  35      }
  36  
  37  	public function request_method() {
  38          return wp_unslash( gp_array_get( $_SERVER, 'REQUEST_METHOD', 'GET' ) );
  39      }
  40  
  41  	public function add( $re, $function, $method = 'get' ) {
  42          $this->urls[ "$method:$re" ] = $function;
  43      }
  44  
  45  	public function prepend( $re, $function, $method = 'get' ) {
  46          $this->urls = array( "$method:$re" => $function ) + $this->urls;
  47      }
  48  
  49  	public function remove( $re, $method = 'get' ) {
  50          if ( isset( $this->urls[ "$method:$re" ] ) ) {
  51              unset( $this->urls[ "$method:$re" ] );
  52              return true;
  53          }
  54  
  55          return false;
  56      }
  57  
  58  	private function default_routes() {
  59          $dir      = '([^_/][^/]*)';
  60          $path     = '(.+?)';
  61          $projects = 'projects';
  62          $project  = $projects . '/' . $path;
  63          $id       = '(\d+)';
  64          $locale   = '(' . implode( '|', wp_list_pluck( GP_Locales::locales(), 'slug' ) ) . ')';
  65          $set      = "$project/$locale/$dir";
  66  
  67          // overall structure
  68          return array(
  69              '/'                                               => array( 'GP_Route_Index', 'index' ),
  70  
  71              'get:/profile'                                    => array( 'GP_Route_Profile', 'profile_view' ),
  72              "get:/profile/$path"                              => array( 'GP_Route_Profile', 'profile_view' ),
  73  
  74              'get:/settings'                                   => array( 'GP_Route_Settings', 'settings_get' ),
  75              'post:/settings'                                  => array( 'GP_Route_Settings', 'settings_post' ),
  76  
  77              "get:(/languages)/$locale/$dir/glossary"          => array( 'GP_Route_Glossary_Entry', 'glossary_entries_get' ),
  78              "post:(/languages)/$locale/$dir/glossary"         => array( 'GP_Route_Glossary_Entry', 'glossary_entries_post' ),
  79              "post:(/languages)/$locale/$dir/glossary/-new"    => array( 'GP_Route_Glossary_Entry', 'glossary_entry_add_post' ),
  80              "post:(/languages)/$locale/$dir/glossary/-delete" => array( 'GP_Route_Glossary_Entry', 'glossary_entry_delete_post' ),
  81              "get:(/languages)/$locale/$dir/glossary/-export"  => array( 'GP_Route_Glossary_Entry', 'export_glossary_entries_get' ),
  82              "get:(/languages)/$locale/$dir/glossary/-import"  => array( 'GP_Route_Glossary_Entry', 'import_glossary_entries_get' ),
  83              "post:(/languages)/$locale/$dir/glossary/-import" => array( 'GP_Route_Glossary_Entry', 'import_glossary_entries_post' ),
  84  
  85              'get:/languages'                                  => array( 'GP_Route_Locale', 'locales_get' ),
  86              "get:/languages/$locale/$path"                    => array( 'GP_Route_Locale', 'single' ),
  87              "get:/languages/$locale"                          => array( 'GP_Route_Locale', 'single' ),
  88  
  89              "get:/$set/glossary"                              => array( 'GP_Route_Glossary_Entry', 'glossary_entries_get' ),
  90              "post:/$set/glossary"                             => array( 'GP_Route_Glossary_Entry', 'glossary_entries_post' ),
  91              "post:/$set/glossary/-new"                        => array( 'GP_Route_Glossary_Entry', 'glossary_entry_add_post' ),
  92              "post:/$set/glossary/-delete"                     => array( 'GP_Route_Glossary_Entry', 'glossary_entry_delete_post' ),
  93              "get:/$set/glossary/-export"                      => array( 'GP_Route_Glossary_Entry', 'export_glossary_entries_get' ),
  94              "get:/$set/glossary/-import"                      => array( 'GP_Route_Glossary_Entry', 'import_glossary_entries_get' ),
  95              "post:/$set/glossary/-import"                     => array( 'GP_Route_Glossary_Entry', 'import_glossary_entries_post' ),
  96  
  97              "get:/$project/import-originals"                  => array( 'GP_Route_Project', 'import_originals_get' ),
  98              "post:/$project/import-originals"                 => array( 'GP_Route_Project', 'import_originals_post' ),
  99  
 100              "get:/$project/-edit"                             => array( 'GP_Route_Project', 'edit_get' ),
 101              "post:/$project/-edit"                            => array( 'GP_Route_Project', 'edit_post' ),
 102  
 103              "get:/$project/-delete"                           => array( 'GP_Route_Project', 'delete_get' ),
 104              "post:/$project/-delete"                          => array( 'GP_Route_Project', 'delete_post' ),
 105  
 106              "post:/$project/-personal"                        => array( 'GP_Route_Project', 'personal_options_post' ),
 107  
 108              "get:/$project/-permissions"                      => array( 'GP_Route_Project', 'permissions_get' ),
 109              "post:/$project/-permissions"                     => array( 'GP_Route_Project', 'permissions_post' ),
 110              "get:/$project/-permissions/-delete/$dir"         => array( 'GP_Route_Project', 'permissions_delete' ),
 111  
 112              "get:/$project/-mass-create-sets"                 => array( 'GP_Route_Project', 'mass_create_sets_get' ),
 113              "post:/$project/-mass-create-sets"                => array( 'GP_Route_Project', 'mass_create_sets_post' ),
 114              "post:/$project/-mass-create-sets/preview"        => array( 'GP_Route_Project', 'mass_create_sets_preview_post' ),
 115  
 116              "get:/$project/-branch"                           => array( 'GP_Route_Project', 'branch_project_get' ),
 117              "post:/$project/-branch"                          => array( 'GP_Route_Project', 'branch_project_post' ),
 118  
 119              "get:/$projects"                                  => array( 'GP_Route_Project', 'index' ),
 120              "get:/$projects/-new"                             => array( 'GP_Route_Project', 'new_get' ),
 121              "post:/$projects/-new"                            => array( 'GP_Route_Project', 'new_post' ),
 122  
 123              "post:/$set/-bulk"                                => array( 'GP_Route_Translation', 'bulk_post' ),
 124              "get:/$set/import-translations"                   => array( 'GP_Route_Translation', 'import_translations_get' ),
 125              "post:/$set/import-translations"                  => array( 'GP_Route_Translation', 'import_translations_post' ),
 126              "post:/$set/-discard-warning"                     => array( 'GP_Route_Translation', 'discard_warning' ),
 127              "post:/$set/-set-status"                          => array( 'GP_Route_Translation', 'set_status' ),
 128  
 129              "/$set/export-translations"                       => array( 'GP_Route_Translation', 'export_translations_get' ),
 130              // Keep this below all URLs ending with a literal string, because it may catch one of them.
 131              "get:/$set"                                       => array( 'GP_Route_Translation', 'translations_get' ),
 132              "post:/$set"                                      => array( 'GP_Route_Translation', 'translations_post' ),
 133  
 134              // Keep this one at the bottom of the project, because it will catch anything starting with project.
 135              "/$project"                                       => array( 'GP_Route_Project', 'single' ),
 136  
 137              'get:/sets/-new'                                  => array( 'GP_Route_Translation_Set', 'new_get' ),
 138              'post:/sets/-new'                                 => array( 'GP_Route_Translation_Set', 'new_post' ),
 139              "get:/sets/$id"                                   => array( 'GP_Route_Translation_Set', 'single' ),
 140              "get:/sets/$id/-edit"                             => array( 'GP_Route_Translation_Set', 'edit_get' ),
 141              "post:/sets/$id/-edit"                            => array( 'GP_Route_Translation_Set', 'edit_post' ),
 142              "get:/sets/$id/-delete"                           => array( 'GP_Route_Translation_Set', 'delete_get' ),
 143              "post:/sets/$id/-delete"                          => array( 'GP_Route_Translation_Set', 'delete_post' ),
 144  
 145              'get:/glossaries/-new'                            => array( 'GP_Route_Glossary', 'new_get' ),
 146              'post:/glossaries/-new'                           => array( 'GP_Route_Glossary', 'new_post' ),
 147              "get:/glossaries/$id/-edit"                       => array( 'GP_Route_Glossary', 'edit_get' ),
 148              "post:/glossaries/$id/-edit"                      => array( 'GP_Route_Glossary', 'edit_post' ),
 149              "get:/glossaries/$id/-delete"                     => array( 'GP_Route_Glossary', 'delete_get' ),
 150              "post:/glossaries/$id/-delete"                    => array( 'GP_Route_Glossary', 'delete_post' ),
 151  
 152              "post:/originals/$id/set_priority"                => array( 'GP_Route_Original', 'set_priority' ),
 153          );
 154      }
 155  
 156  
 157  	public function route() {
 158          global $wp_query;
 159  
 160          $real_request_uri = $this->request_uri();
 161          $api_request_uri  = $real_request_uri;
 162          $request_method   = strtolower( $this->request_method() );
 163          $api              = gp_startswith( $real_request_uri, '/' . $this->api_prefix . '/' );
 164  
 165          /**
 166           * Filter the list of HTTP methods allowed
 167           *
 168           * @since 2.1
 169           *
 170           * @param array $http_methods Allowed http methods
 171           */
 172          $http_methods = apply_filters( 'gp_router_http_methods', array( 'get', 'post', 'head', 'put', 'delete' ) );
 173  
 174          if ( $api ) {
 175              $real_request_uri = substr( $real_request_uri, strlen( $this->api_prefix ) + 1 );
 176          }
 177  
 178          $url_path = gp_url_path( gp_url_public_root() );
 179  
 180          // If the request URL doesn't match our base URL, don't bother trying to match
 181          if ( $url_path && ! gp_startswith( wp_unslash( $_SERVER['REQUEST_URI'] ), $url_path ) ) {
 182              return;
 183          }
 184  
 185          foreach ( array( $api_request_uri, $real_request_uri ) as $request_uri ) {
 186              foreach ( $this->urls as $re => $func ) {
 187                  foreach ( $http_methods as $http_method ) {
 188                      if ( gp_startswith( $re, $http_method . ':' ) ) {
 189                          if ( $http_method != $request_method ) {
 190                              continue;
 191                          }
 192                          $re = substr( $re, strlen( $http_method . ':' ) );
 193                          break;
 194                      }
 195                  }
 196  
 197                  if ( preg_match( "@^$re$@", $request_uri, $matches ) ) {
 198                      /*
 199                       * WordPress will be returning a 404 status header by default for GlotPress pages
 200                       * as nothing is found by WP_Query.
 201                       * This overrides the status header and the `$is_404` property of WP_Query if we've matched
 202                       * something here. Route controllers still can return a 404 status header.
 203                       */
 204                      status_header( '200' );
 205                      $wp_query->is_404 = false;
 206  
 207                      if ( is_array( $func ) ) {
 208                          list( $class, $method )    = $func;
 209                          $route                     = new $class();
 210                          $route->api                = $api;
 211                          $route->last_method_called = $method;
 212                          $route->class_name         = $class;
 213                          GP::$current_route         = &$route;
 214                          $route->before_request();
 215                          $route->request_running = true;
 216                          // Make sure after_request() is called even if we $this->exit_() in the request.
 217                          register_shutdown_function( array( &$route, 'after_request' ) );
 218                          $route->$method( ...array_slice( $matches, 1 ) );
 219                          $route->after_request();
 220                          $route->request_running = false;
 221                      } else {
 222                          $func( ...array_slice( $matches, 1 ) );
 223                      }
 224                      exit;
 225                  }
 226              }
 227          }
 228  
 229          gp_tmpl_404();
 230      }
 231  
 232  }


Generated: Sat Sep 19 01:01:55 2020 Cross-referenced by PHPXref 0.7.1