I have the following methods:
public function isAdmin()
{
$adminUrl = $this->getPage(2)->httpUrl;
/*
* Remove all segments except the first in the URL path
* to detect if current page is in admin view
*/
$currentUrl = preg_replace( // https://regex101.com/r/D0mOz9/1
sprintf(
'~(?<adminUrl>%s)(?<remove>.*)$~',
addslashes($adminUrl)
),
'$1',
$this->getPage()->httpUrl
);
return $adminUrl == $currentUrl || (!$currentUrl && !$this->getPage() instanceof NullPage);
}
public function getPage($page = null)
{
$wiredPage = $this->wire('page');
if (!is_null($wiredPage) && is_null($page)) {
$baseUrl = $this->wire('page')->url;
$urlSegmentStr = $this->wire('input')->urlSegmentStr;
if (strlen($urlSegmentStr)) {
$baseUrl = rtrim($baseUrl, '/') . "/$urlSegmentStr/";
}
return $this->pages->get($baseUrl);
}
if (is_null($page)) {
return $this->pages->get(parse_url(getenv('REQUEST_URI'), PHP_URL_PATH));
}
return $this->pages->get($page);
}
I check if for an admin page by getting the url to the admin page and compare it to the current url.
Now I want to write a test for it with PHPunit but I have no idea how to test a method which result is based on urls like this.
Is it possible to write a test for a case like this? How would I be able to do this?
Related
I have an URL path like
http://localhost:8080/laravel/api/data/create/
Where /laravel/api is the path from the config file
and /data/create/ is the path which I used in traits.
The problem is everytime when I run the function named connection()repeatedly,
In Tinker, If I do
$data = new Sample;
$data->connection();
http://localhost:8080/laravel/api/data/create/
$data->connection();
http://localhost:8080/laravel/api/data/create/data/create/
$data->connection();
http://localhost:8080/laravel/api/data/create/data/create/data/create/
The path /data/create/ is repeated every time when I perform connection().
It should not be like that, only once the path should be appended, if we perform connection(), like the below.
$data->connection();
http://localhost:8080/laravel/api/data/create/
I am using a method chaining for appending path .
protected $resource[]; //is declared already in the code
protected $url[];
public function addPath()
{
$old_uri = explode('/', $this->resource['path']);
$add_uri = explode('/', $this->path);
$new_uri = array_merge($old_uri, $add_uri);
$this->resource['path'] = '/'.implode('/', array_filter($new_uri));
return $this;
}
public function connection()
{
$this->addPath()->unparse_url();
return $url;
}
private function unparse_url()
{
$scheme = isset($this->resource['scheme']) ? $this->resource['scheme'].'://' : '';
$host = isset($this->resource['host']) ? $this->resource['host'] : '';
$port = isset($this->resource['port']) ? ':'.$this->resource['port'] : '';
$user = isset($this->resource['user']) ? $this->resource['user'] : '';
$pass = isset($this->resource['pass']) ? ':'.$this->resource['pass'] : '';
$pass = ($user || $pass) ? "$pass#" : '';
$path = isset($this->resource['path']) ? $this->resource['path'] : '';
$query = isset($this->resource['query']) ? '?'.$this->resource['query'] : '';
$fragment = isset($this->resource['fragment']) ? '#'.$this->resource['fragment'] : '';
$this->url = "$scheme$user$pass$host$port$path$query$fragment";
return $this;
}
Could someone please help to fix the issue?
Thanks.
If we disregard from your undefined variables, the issue is that your code appends the path every time you call the connection()-method since it calls the addPath()-method.
If you only want it to append it once, there are some alternatives.
Alternative 1
If you always want the path to be added, you can simple call the addPath()-method from the constructor instead.
public function __construct()
{
$this->addPath()->unparse_url();
}
and just have the connection()-method like this:
public function connection()
{
return $this->url;
}
This would work well as long as you don't need to use the original values of $this->url and $this->resource['path'] for anything since they will be changed when the class is instantiated.
Alternative 2
You can set class property as a flag, saying if the path already been added or not. Then you simply check that flag in your addPath()-method.
// Default value is false, since we haven't added it yet
protected $pathAdded = false;
public function addPath()
{
if ($this->pathAdded === false) {
// It's still false so it hasn't been added yet
$old_uri = explode('/', $this->resource['path']);
$add_uri = explode('/', $this->path);
$new_uri = array_merge($old_uri, $add_uri);
$this->resource['path'] = '/'.implode('/', array_filter($new_uri));
// Set the flag to true so we know it's already been done
$this->pathAdded = true;
}
return $this;
}
This way, it will only append the path on the first call to that method.
I want to add a new URL variable on CI 3.0 like site_url or base_url.
For example; I want to add an admin_url variable for administration area and assets_url variable for assets.
I checked CI 3.0 guide but couldn't find a solution.
Thanks in advance.
It's pretty straight forward.
Just go to your config.php which is located at /your_root/application/config directory
add at this line at the bottom of that file
$config["admin_url"] = "http://www.your_url.com/admin";
$config["assets_url"] = "http://www.your_url.com/assets";
To retrieve it anywhere in application use this
$your_admin_variable =$this->config->item("admin_url");
$your_assets_variable =$this->config->item("assets_url");
Your're in business :)
My solution.
Create new helper file and add this file to autoload.
So..
Create file application/helpers/global_helper.php
Inside your helper create functions for example:
<?php
function admin_url(){
return base_url() . "/admin/";
}
Now edit config/autoload.php
$autoload['helper'] = array('url','global');
Add to exists array your new helper.
And now anywhere you can use your function admin_url
in system/helpers/url_helper.php you will find
if ( ! function_exists('base_url'))
{
function base_url($uri = '')
{
$CI =& get_instance();
return $CI->config->base_url($uri);
}
}
so i guess if you create your own code like this
if ( ! function_exists('your_variable_name'))
{
function your_variable_name($uri = '')
{
$CI =& get_instance();
return $CI->config->your_variable_name($uri);
}
}
but it is better to extend the helper rather modifying it , so you can use the code above in application/helpers/MY_url_helper.php
and then you can call your custom variable as you normally do it with base_url
hope that helps
I got the answer now,
add these lines on system/helpers/url_helper.php file:
if ( ! function_exists('admin_css'))
{
/**
* Base URL
*
* Create a local URL based on your basepath.
* Segments can be passed in as a string or an array, same as site_url
* or a URL to a file can be passed in, e.g. to an image file.
*
* #param string $uri
* #param string $protocol
* #return string
*/
function admin_css($uri = '', $protocol = NULL)
{
return get_instance()->config->admin_css($uri, $protocol);
}
}
and add these lines on system/core/Config.php
public function admin_css($uri = '', $protocol = NULL)
{
$base_url = base_url('assets/staff/css').'/';
if (isset($protocol))
{
$base_url = $protocol.substr($base_url, strpos($base_url, '://'));
}
if (empty($uri))
{
return $base_url.$this->item('index_page');
}
$uri = $this->_uri_string($uri);
if ($this->item('enable_query_strings') === FALSE)
{
$suffix = isset($this->config['url_suffix']) ? $this->config['url_suffix'] : '';
if ($suffix !== '')
{
if (($offset = strpos($uri, '?')) !== FALSE)
{
$uri = substr($uri, 0, $offset).$suffix.substr($uri, $offset);
}
else
{
$uri .= $suffix;
}
}
return $base_url.$this->slash_item('index_page').$uri;
}
elseif (strpos($uri, '?') === FALSE)
{
$uri = '?'.$uri;
}
return $base_url.$this->item('index_page').$uri;
}
don't forget to autoload url_helper. With this way, you can use admin_css variable like this: <?php echo admin_css('foo.css'); ?>
If you use the other answers on this post, you can not use like <?php echo admin_css('foo.css'); ?>
Thank you all.
we need to have a new function such as base_url() , named main_site_url() to being able to use it exactly as the same as site_url().
I've just added this to main config file in application/config:
$config['main_site_url'] = 'http//iksna.com/';
and this code to /system/core/config.php
/**
* Main Site URL
* Returns main_site_url . index_page [. uri_string]
*
* #access public
* #param string the URI string
* #return string
*/
function main_site_url($uri = '')
{
if ($uri == '')
{
return $this->slash_item('main_site_url').$this->item('index_page');
}
if ($this->item('enable_query_strings') == FALSE)
{
$suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
return $this->slash_item('main_site_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix;
}
else
{
return $this->slash_item('main_site_url').$this->item('index_page').'?'.$this->_uri_string($uri);
}
}
// -------------------------------------------------------------
but now, it is not accessible by: main_site_url();
is it accessible by: $this->config->main_site_url();
i have this error when is use main_site_url();
error:
Call to undefined function main_site_url()
You can create your own by the following way:
Step 1:
In you application/config/config.php add this, $config['main_site_url'] = 'http//iksna.com/';
Step 2:
In system/core/Config.php add a new function main_site_url() like base_url(), site_url() which are already defined there:
public function main_site_url($uri = '', $protocol = NULL)
{
$main_site_url = $this->slash_item('main_site_url');
if (isset($protocol))
{
if ($protocol === '')
{
$main_site_url = substr($main_site_url, strpos($main_site_url, '//'));
}
else
{
$main_site_url = $protocol.substr($main_site_url, strpos($main_site_url, '://'));
}
}
return $main_site_url.ltrim($this->_uri_string($uri), '/');
}
Step 3:
Now add the following code in system/helpers/url_helper.php
if ( ! function_exists('main_site_url'))
{
function main_site_url($uri = '', $protocol = NULL)
{
return get_instance()->config->main_site_url($uri, $protocol);
}
}
Now you can use main_site_url() anywhere in your controllers, libraries and views just like base_url(), site_url() etc.
Go to
/system/application/libraries
Create one file named
custom_function.php
add function main_site_url inside custom_function.php
call function in controller file using
$this->custom_function->main_site_url();
I'm trying to create multilingual application. I've implemented ability of translationable content and next step should be showing it to user. I want to have ability of changing language depending on URL. I've found a couple of components for those purposes but they all create urls which I don't like. For example, my application's default language is English and I have content which is translated into French. I have page "contacts", for instance. And URLs which will be generated by application will be: mysite.com/en/contacts, mysite.com/fr/contacts, but I want to have mysite.com/contacts for default language and mysite.com/fr/contacts for French language. It's simillar for site's root too. mysite.com/ - for default language and mysite.com/fr for French.
Is there any methods for implementing these functionality?
I'm using XUrlManager extension XUrlManager on GitHub
Yii generates URL's based on UrlManager rules. If you want URL's without /lang/ code - you need just create correct rules. For example, if you dublicate records in rules array:
'rules'=>array(
'<_c:\w+>/<_a:\w+>'=>'<_c>/<_a>',
'<language:\w{2}>/<_c:\w+>/<_a:\w+>'=>'<_c>/<_a>',
);
your URL's will be generated withou /en/ and /fr/, but URL's with code works too. By default, XUrlManager use previously selected language and store this in session or cookie.
If you want only hide /en/ and use /fr/ and others always, you can change your XUrlManager extension with:
public function createUrl($route,$params=array(),$ampersand='&')
{
if(!isset($params['language']) && Yii::app()->language!=='en')
$params['language']=Yii::app()->language;
return parent::createUrl($route,$params,$ampersand);
}
I've found very elegant method for solving my problem on http://www.elisdn.ru
Reimplement CHttpRequest
class DLanguageHttpRequest extends CHttpRequest
{
private $_requestUri;
public function getRequestUri()
{
if ($this->_requestUri === null)
$this->_requestUri = DMultilangHelper::processLangInUrl(parent::getRequestUri());
return $this->_requestUri;
}
public function getOriginalUrl()
{
return $this->getOriginalRequestUri();
}
public function getOriginalRequestUri()
{
return DMultilangHelper::addLangToUrl($this->getRequestUri());
}
}
Reimplement CUrlManager
class DLanguageUrlManager extends CUrlManager
{
public function createUrl($route, $params=array(), $ampersand='&')
{
$url = parent::createUrl($route, $params, $ampersand);
return DMultilangHelper::addLangToUrl($url);
}
}
Change config
return array(
'sourceLanguage'=>'en',
'language'=>'ru',
'components'=>array(
'request'=>array(
'class'=>'DLanguageHttpRequest',
...
),
'urlManager'=>array(
'class'=>'DLanguageUrlManager',
...
),
),
...
'params'=>array(
'translatedLanguages'=>array(
'ru'=>'Russian',
'en'=>'English',
'de'=>'Deutsch',
),
'defaultLanguage'=>'ru',
),
);
Create DMultilangHelper
class DMultilangHelper
{
public static function enabled()
{
return count(Yii::app()->params['translatedLanguages']) > 1;
}
public static function suffixList()
{
$list = array();
$enabled = self::enabled();
foreach (Yii::app()->params['translatedLanguages'] as $lang => $name)
{
if ($lang === Yii::app()->params['defaultLanguage']) {
$suffix = '';
$list[$suffix] = $enabled ? $name : '';
} else {
$suffix = '_' . $lang;
$list[$suffix] = $name;
}
}
return $list;
}
public static function processLangInUrl($url)
{
if (self::enabled())
{
$domains = explode('/', ltrim($url, '/'));
$isLangExists = in_array($domains[0], array_keys(Yii::app()->params['translatedLanguages']));
$isDefaultLang = $domains[0] == Yii::app()->params['defaultLanguage'];
if ($isLangExists && !$isDefaultLang)
{
$lang = array_shift($domains);
Yii::app()->setLanguage($lang);
}
$url = '/' . implode('/', $domains);
}
return $url;
}
public static function addLangToUrl($url)
if (self::enabled())
{
$domains = explode('/', ltrim($url, '/'));
$isHasLang = in_array($domains[0], array_keys(Yii::app()->params['translatedLanguages']));
$isDefaultLang = Yii::app()->getLanguage() == Yii::app()->params['defaultLanguage'];
if ($isHasLang && $isDefaultLang)
array_shift($domains);
if (!$isHasLang && !$isDefaultLang)
array_unshift($domains, Yii::app()->getLanguage());
$url = '/' . implode('/', $domains);
}
return $url;
}
}
After all of these steps your application will have URLs which you want
More information here
Im using a code to separate pages that is HTTPS and HTTP in my website
The problem is: When Im on HTTP, links to HTTPS no have WWW and vice versa.
I did not find the problem in the script.
public function createUrl($route, $params = array(), $ampersand = '&')
{
$url = parent::createUrl($route, $params, $ampersand);
// If already an absolute URL, return it directly
if (strpos($url, 'http') === 0) {
return $url;
}
// Check if the current protocol matches the expected protocol of the route
// If not, prefix the generated URL with the correct host info.
$secureRoute = $this->isSecureRoute($route);
if (Yii::app()->request->isSecureConnection) {
return $secureRoute ? $url : 'http://' . Yii::app()->request->serverName . $url;
} else {
return $secureRoute ? 'https://' . Yii::app()->request->serverName . $url : $url;
}
}
public function parseUrl($request)
{
$route = parent::parseUrl($request);
// Perform a 301 redirection if the current protocol
// does not match the expected protocol
$secureRoute = $this->isSecureRoute($route);
$sslRequest = $request->isSecureConnection;
if ($secureRoute !== $sslRequest) {
$hostInfo = $secureRoute ? 'https://' . Yii::app()->request->serverName : 'http://' . Yii::app()->request->serverName;
if ((strpos($hostInfo, 'https') === 0) xor $sslRequest) {
$request->redirect($hostInfo . $request->url, true, 301);
}
}
return $route;
}
private $_secureMap;
/**
* #param string the URL route to be checked
* #return boolean if the give route should be serviced in SSL mode
*/
protected function isSecureRoute($route)
{
if ($this->_secureMap === null) {
foreach ($this->secureRoutes as $r) {
$this->_secureMap[strtolower($r)] = true;
}
}
$route = strtolower($route);
if (isset($this->_secureMap[$route])) {
return true;
} else {
return ($pos = strpos($route, '/')) !== false
&& isset($this->_secureMap[substr($route, 0, $pos)]);
}
}
}
Code adapted from: http://www.yiiframework.com/wiki/407/url-management-for-websites-with-secure-and-nonsecure-pages/
It's better to manage this at the controller level using filters.
In your components directory setup 2 filters HttpsFilter and HttpFilter as follows:-
class HttpsFilter extends CFilter {
protected function preFilter( $filterChain ) {
if ( !Yii::app()->getRequest()->isSecureConnection ) {
# Redirect to the secure version of the page.
$url = 'https://' .
Yii::app()->getRequest()->serverName .
Yii::app()->getRequest()->requestUri;
Yii::app()->request->redirect($url);
return false;
}
return true;
}
}
and
class HttpFilter extends CFilter {
protected function preFilter( $filterChain ) {
if ( Yii::app()->getRequest()->isSecureConnection ) {
# Redirect to the secure version of the page.
$url = 'http://' .
Yii::app()->getRequest()->serverName .
Yii::app()->getRequest()->requestUri;
Yii::app()->request->redirect($url);
return false;
}
return true;
}
}
then in each controller force https using the filters, optionally by action:
class SiteController extends Controller {
public function filters()
{
return array(
'https +index', // Force https, but only on login page
);
}
}
Edit: if the filters() function above doesn't seem to work for you, instead try
return array(
array('HttpsFilter +index'), // Force https, but only on login page
);
See http://www.yiiframework.com/doc/guide/1.1/en/basics.controller#filter (and comments on it).