Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,30 +11,46 @@
|
||||
namespace IPS\Http\Url;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Content;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member\Club;
|
||||
use IPS\Node\Model;
|
||||
use IPS\cms\Pages\Router;
|
||||
use IPS\Session;
|
||||
use IPS\Application;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function intval;
|
||||
use function is_numeric;
|
||||
use function is_string;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal URL
|
||||
*/
|
||||
class _Internal extends \IPS\Http\Url
|
||||
class Internal extends Url
|
||||
{
|
||||
/**
|
||||
* Create internal URL from components - all arguments should be UNENCODED
|
||||
*
|
||||
* @param string $base Key for the URL base
|
||||
* @param int|string|null $protocol Protocol (one of the PROTOCOL_* constants) or an actual scheme
|
||||
* @param string $path Path, relative to site's base URL
|
||||
* @param string|array|NULL $query Query
|
||||
* @param string|NULL $fragment Fragment
|
||||
* @return \IPS\Http\Url
|
||||
* @param string $base Key for the URL base
|
||||
* @param int|string|null $protocol Protocol (one of the PROTOCOL_* constants) or an actual scheme
|
||||
* @param string $path Path, relative to site's base URL
|
||||
* @param array|string|null $query Query
|
||||
* @param string|null $fragment Fragment
|
||||
* @return Url
|
||||
*/
|
||||
protected static function createInternalFromComponents( $base, $protocol, $path, $query = NULL, $fragment = NULL )
|
||||
protected static function createInternalFromComponents( string $base, int|string|null $protocol, string $path, array|string $query = NULL, string $fragment = NULL ): Url
|
||||
{
|
||||
$baseUrlData = parse_url( static::baseUrl( \is_numeric( $protocol ) ? $protocol : NULL ) );
|
||||
$baseUrlData = parse_url( static::baseUrl( is_numeric( $protocol ) ? $protocol : NULL ) );
|
||||
|
||||
$pathToUse = '';
|
||||
if ( isset( $baseUrlData['path'] ) and $baseUrlData['path'] )
|
||||
@@ -52,12 +68,12 @@ class _Internal extends \IPS\Http\Url
|
||||
|
||||
$return = static::createFromComponents(
|
||||
$baseUrlData['host'],
|
||||
( \is_string( $protocol ) and !\is_numeric( $protocol ) ) ? $protocol : ( ( isset( $baseUrlData['scheme'] ) AND $protocol !== NULL ) ? $baseUrlData['scheme'] : NULL ),
|
||||
( is_string( $protocol ) and !is_numeric( $protocol ) ) ? $protocol : ( ( isset( $baseUrlData['scheme'] ) AND $protocol !== NULL ) ? $baseUrlData['scheme'] : NULL ),
|
||||
$pathToUse ? "/{$pathToUse}" : '',
|
||||
$query,
|
||||
isset( $baseUrlData['port'] ) ? $baseUrlData['port'] : NULL,
|
||||
isset( $baseUrlData['user'] ) ? $baseUrlData['user'] : NULL,
|
||||
isset( $baseUrlData['pass'] ) ? $baseUrlData['pass'] : NULL,
|
||||
$baseUrlData['port'] ?? NULL,
|
||||
$baseUrlData['user'] ?? NULL,
|
||||
$baseUrlData['pass'] ?? NULL,
|
||||
$fragment
|
||||
);
|
||||
|
||||
@@ -68,21 +84,23 @@ class _Internal extends \IPS\Http\Url
|
||||
/**
|
||||
* @brief Does this URL have the SEO pagination (page/n/)?
|
||||
*/
|
||||
public $seoPagination = NULL;
|
||||
public ?bool $seoPagination = NULL;
|
||||
|
||||
/**
|
||||
* @brief Base
|
||||
*/
|
||||
public $base;
|
||||
public ?string $base = NULL;
|
||||
|
||||
/**
|
||||
* Get the friendly URL for this URL if there is one
|
||||
*
|
||||
* @return mixed The friendly URL if there is one, TRUE if there isn't, or NULL if not sure
|
||||
*/
|
||||
public function correctFriendlyUrl()
|
||||
public function correctFriendlyUrl(): mixed
|
||||
{
|
||||
foreach ( \IPS\Http\Url\Friendly::furlDefinition() as $seoTemplate => $furlDefinition )
|
||||
$return = FALSE;
|
||||
|
||||
foreach (Friendly::furlDefinition() as $seoTemplate => $furlDefinition )
|
||||
{
|
||||
if( mb_stripos( $this->data[ static::COMPONENT_QUERY ], $furlDefinition['real'] ) !== FALSE )
|
||||
{
|
||||
@@ -95,9 +113,6 @@ class _Internal extends \IPS\Http\Url
|
||||
switch ( mb_substr( $tag, 0, 1 ) )
|
||||
{
|
||||
case '#':
|
||||
$params[] = mb_substr( $tag, 1 );
|
||||
break;
|
||||
|
||||
case '@':
|
||||
$params[] = mb_substr( $tag, 1 );
|
||||
break;
|
||||
@@ -105,7 +120,7 @@ class _Internal extends \IPS\Http\Url
|
||||
}
|
||||
|
||||
/* If this definition requires a parameter, see if we have it. If not, skip to next definition to check. */
|
||||
if( \count( array_diff( $params, array_keys( $this->queryString ) ) ) )
|
||||
if( count( array_diff( $params, array_keys( $this->queryString ) ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -119,16 +134,15 @@ class _Internal extends \IPS\Http\Url
|
||||
/* Load it */
|
||||
try
|
||||
{
|
||||
if ( $return = $this->correctUrlFromVerifyClass( $furlDefinition['verify'] ) )
|
||||
if ( ! $return = $this->correctUrlFromVerifyClass( $furlDefinition['verify'] ) )
|
||||
{
|
||||
return $return;
|
||||
$return = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* It doesn't exist */
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
return NULL;
|
||||
$return = NULL;
|
||||
}
|
||||
}
|
||||
/* If not, we have to build it ourself */
|
||||
@@ -147,27 +161,62 @@ class _Internal extends \IPS\Http\Url
|
||||
|
||||
$seoTitles[] = $class::load( $this->queryString[ $queryParam ] )->$property;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
catch ( OutOfRangeException $e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
return \IPS\Http\Url::internal( $this->data['query'], 'front', $seoTemplate, $seoTitles );
|
||||
$return = Url::internal( $this->data['query'], 'front', $seoTemplate, $seoTitles );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
catch ( Exception $e ) {}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
/* If it it thinks it belongs to "pages", we might be able to be more accurate */
|
||||
if ( Application::appIsEnabled( 'cms' ) and ( $return instanceof Friendly and $return->seoTemplate === 'content_page_path' and isset( $this->queryString['path'] ) ) )
|
||||
{
|
||||
/* Try to find a page */
|
||||
try
|
||||
{
|
||||
/* Create it */
|
||||
$correctUrl = Router::loadFromUrl( $this )->url();
|
||||
|
||||
/* Set extra stuff in our query string */
|
||||
$paramsToSet = array();
|
||||
foreach ( $this->queryString as $k => $v )
|
||||
{
|
||||
if ( !array_key_exists( $k, $correctUrl->queryString ) and !array_key_exists( $k, $correctUrl->hiddenQueryString ) )
|
||||
{
|
||||
$paramsToSet[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
if ( count( $paramsToSet ) )
|
||||
{
|
||||
$correctUrl = $correctUrl->setQueryString( $paramsToSet );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
$return = $correctUrl;
|
||||
}
|
||||
/* Couldn't find one? Don't accept responsibility */
|
||||
catch (OutOfRangeException $e ){}
|
||||
}
|
||||
else if( $return !== NULL )
|
||||
{
|
||||
$return = TRUE;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct URL using a "verify" property from the FURL definition
|
||||
*
|
||||
* @param object $verify Class containing `preCorrectUrlFromVerifyClass()` method to check URL against
|
||||
* @return NULL|\IPS\Http\Url
|
||||
* @throws \OutOfRangeException
|
||||
* @param mixed $verify Class containing `preCorrectUrlFromVerifyClass()` method to check URL against
|
||||
* @return NULL|Url
|
||||
* @throws OutOfRangeException
|
||||
*/
|
||||
protected function correctUrlFromVerifyClass( $verify )
|
||||
protected function correctUrlFromVerifyClass( mixed $verify ): ?Url
|
||||
{
|
||||
/* Load it */
|
||||
if ( method_exists( $verify, 'preCorrectUrlFromVerifyClass' ) )
|
||||
@@ -179,11 +228,11 @@ class _Internal extends \IPS\Http\Url
|
||||
/* Check the currently logged in user can view it, as we don't want to reveal the correct
|
||||
URL to something the user has no permission to view */
|
||||
$canView = TRUE;
|
||||
if ( $contentObject instanceof \IPS\Content or $contentObject instanceof \IPS\Member\Club )
|
||||
if ( $contentObject instanceof Content or $contentObject instanceof Club )
|
||||
{
|
||||
$canView = $contentObject->canView();
|
||||
}
|
||||
elseif ( $contentObject instanceof \IPS\Node\Model )
|
||||
elseif ( $contentObject instanceof Model )
|
||||
{
|
||||
$canView = $contentObject->can('view');
|
||||
}
|
||||
@@ -204,7 +253,7 @@ class _Internal extends \IPS\Http\Url
|
||||
$paramsToSet[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
if ( \count( $paramsToSet ) )
|
||||
if ( count( $paramsToSet ) )
|
||||
{
|
||||
$correctUrl = $correctUrl->setQueryString( $paramsToSet );
|
||||
}
|
||||
@@ -216,26 +265,26 @@ class _Internal extends \IPS\Http\Url
|
||||
/**
|
||||
* Add CSRF check to query string
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return Url
|
||||
*/
|
||||
public function csrf()
|
||||
public function csrf(): Url
|
||||
{
|
||||
return $this->setQueryString( 'csrfKey', \IPS\Session::i()->csrfKey );
|
||||
return $this->setQueryString( 'csrfKey', Session::i()->csrfKey );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the page parameter to the URL
|
||||
*
|
||||
* @param string $param The page key, default is 'page'
|
||||
* @param int|NULL $number The page number to use
|
||||
* @return \IPS\Http\Url
|
||||
* @param string $param The page key, default is 'page'
|
||||
* @param int|null $number The page number to use
|
||||
* @return Url
|
||||
*/
|
||||
public function setPage( $param='page', $number=1 )
|
||||
public function setPage( string $param='page', ?int $number=1 ): Url
|
||||
{
|
||||
/* Remove any existing page param */
|
||||
$url = $this->stripQueryString( $param );
|
||||
|
||||
if ( \intval( $number ) > 1 )
|
||||
if ( intval( $number ) > 1 )
|
||||
{
|
||||
$url = $this->setQueryString( $param, $number );
|
||||
}
|
||||
@@ -248,7 +297,7 @@ class _Internal extends \IPS\Http\Url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function acpQueryString()
|
||||
public function acpQueryString(): string
|
||||
{
|
||||
$queryString = $this->queryString;
|
||||
unset( $queryString['csrf'] );
|
||||
@@ -261,7 +310,7 @@ class _Internal extends \IPS\Http\Url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function openRedirect()
|
||||
public function openRedirect(): bool
|
||||
{
|
||||
return isset( $this->queryString['app'] ) and $this->queryString['app'] === 'core' and isset( $this->queryString['module'] ) and $this->queryString['module'] === 'system' and isset( $this->queryString['controller'] ) and $this->queryString['controller'] === 'redirect';
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user