add custom function to Codeigniter config such as site_url() & base_url() - php

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();

Related

How to avoid the repeating of a path in a URL in php?

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.

phpunit how to test a method which uses the browser url

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?

Adding URL Variable on CodeIgniter

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.

Yii and multilingual URLs

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

An example of an MVC controller

I have been reading a lot about how and why to use an MVC approach in an application. I have seen and understand examples of a Model, I have seen and understand examples of the View.... but I am STILL kind of fuzzy on the controller. I would really love to see a thorough enough example of a controller(s). (in PHP if possible, but any language will help)
Thank you.
PS: It would also be great if I could see an example of an index.php page, which decides which controller to use and how.
EDIT: I know what the job of the controller is, I just don't really understand how to accomplish this in OOP.
Request example
Put something like this in your index.php:
<?php
// Holds data like $baseUrl etc.
include 'config.php';
$requestUrl = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$requestString = substr($requestUrl, strlen($baseUrl));
$urlParams = explode('/', $requestString);
// TODO: Consider security (see comments)
$controllerName = ucfirst(array_shift($urlParams)).'Controller';
$actionName = strtolower(array_shift($urlParams)).'Action';
// Here you should probably gather the rest as params
// Call the action
$controller = new $controllerName;
$controller->$actionName();
Really basic, but you get the idea... (I also didn't take care of loading the controller class, but I guess that can be done either via autoloading or you know how to do it.)
Simple controller example (controllers/login.php):
<?php
class LoginController
{
function loginAction()
{
$username = $this->request->get('username');
$password = $this->request->get('password');
$this->loadModel('users');
if ($this->users->validate($username, $password))
{
$userData = $this->users->fetch($username);
AuthStorage::save($username, $userData);
$this->redirect('secret_area');
}
else
{
$this->view->message = 'Invalid login';
$this->view->render('error');
}
}
function logoutAction()
{
if (AuthStorage::logged())
{
AuthStorage::remove();
$this->redirect('index');
}
else
{
$this->view->message = 'You are not logged in.';
$this->view->render('error');
}
}
}
As you see, the controller takes care of the "flow" of the application - the so-called application logic. It does not take care about data storage and presentation. It rather gathers all the necessary data (depending on the current request) and assigns it to the view...
Note that this would not work with any framework I know, but I'm sure you know what the functions are supposed to do.
Imagine three screens in a UI, a screen where a user enters some search criteria, a screen where a list of summaries of matching records is displayed and a screen where, once a record is selected it is displayed for editing. There will be some logic relating to the initial search on the lines of
if search criteria are matched by no records
redisplay criteria screen, with message saying "none found"
else if search criteria are matched by exactly one record
display edit screen with chosen record
else (we have lots of records)
display list screen with matching records
Where should that logic go? Not in the view or model surely? Hence this is the job of the controller. The controller would also be responsible for taking the criteria and invoking the Model method for the search.
<?php
class App {
protected static $router;
public static function getRouter() {
return self::$router;
}
public static function run($uri) {
self::$router = new Router($uri);
//get controller class
$controller_class = ucfirst(self::$router->getController()) . 'Controller';
//get method
$controller_method = strtolower((self::$router->getMethodPrefix() != "" ? self::$router->getMethodPrefix() . '_' : '') . self::$router->getAction());
if(method_exists($controller_class, $controller_method)){
$controller_obj = new $controller_class();
$view_path = $controller_obj->$controller_method();
$view_obj = new View($controller_obj->getData(), $view_path);
$content = $view_obj->render();
}else{
throw new Exception("Called method does not exists!");
}
//layout
$route_path = self::getRouter()->getRoute();
$layout = ROOT . '/views/layout/' . $route_path . '.phtml';
$layout_view_obj = new View(compact('content'), $layout);
echo $layout_view_obj->render();
}
public static function redirect($uri){
print("<script>window.location.href='{$uri}'</script>");
exit();
}
}
<?php
class Router {
protected $uri;
protected $controller;
protected $action;
protected $params;
protected $route;
protected $method_prefix;
/**
*
* #return mixed
*/
function getUri() {
return $this->uri;
}
/**
*
* #return mixed
*/
function getController() {
return $this->controller;
}
/**
*
* #return mixed
*/
function getAction() {
return $this->action;
}
/**
*
* #return mixed
*/
function getParams() {
return $this->params;
}
function getRoute() {
return $this->route;
}
function getMethodPrefix() {
return $this->method_prefix;
}
public function __construct($uri) {
$this->uri = urldecode(trim($uri, "/"));
//defaults
$routes = Config::get("routes");
$this->route = Config::get("default_route");
$this->controller = Config::get("default_controller");
$this->action = Config::get("default_action");
$this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : '';
//get uri params
$uri_parts = explode("?", $this->uri);
$path = $uri_parts[0];
$path_parts = explode("/", $path);
if(count($path_parts)){
//get route
if(in_array(strtolower(current($path_parts)), array_keys($routes))){
$this->route = strtolower(current($path_parts));
$this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : '';
array_shift($path_parts);
}
//get controller
if(current($path_parts)){
$this->controller = strtolower(current($path_parts));
array_shift($path_parts);
}
//get action
if(current($path_parts)){
$this->action = strtolower(current($path_parts));
array_shift($path_parts);
}
//reset is for parameters
//$this->params = $path_parts;
//processing params from url to array
$aParams = array();
if(current($path_parts)){
for($i=0; $i<count($path_parts); $i++){
$aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null;
$i++;
}
}
$this->params = (object)$aParams;
}
}
}
Create folder structure
Setup .htaccess & virtual hosts
Create config class to build config array
Controller
Create router class with protected non static, with getters
Create init.php with config include & autoload and include paths (lib, controlelrs,models)
Create config file with routes, default values (route, controllers, action)
Set values in router - defaults
Set uri paths, explode the uri and set route, controller, action, params ,process params.
Create app class to run the application by passing uri - (protected router obj, run func)
Create controller parent class to inherit all other controllers (protected data, model, params - non static)
set data, params in constructor.
Create controller and extend with above parent class and add default method.
Call the controller class and method in run function. method has to be with prefix.
Call the method if exisist
Views
Create a parent view class to generate views. (data, path) with default path, set controller, , render funcs to
return the full tempalte path (non static)
Create render function with ob_start(), ob_get_clean to return and send the content to browser.
Change app class to parse the data to view class. if path is returned, pass to view class too.
Layouts..layout is depend on router. re parse the layout html to view and render
Please check this:
<?php
global $conn;
require_once("../config/database.php");
require_once("../config/model.php");
$conn= new Db;
$event = isset($_GET['event']) ? $_GET['event'] : '';
if ($event == 'save') {
if($conn->insert("employee", $_POST)){
$data = array(
'success' => true,
'message' => 'Saving Successful!',
);
}
echo json_encode($data);
}
if ($event == 'update') {
if($conn->update("employee", $_POST, "id=" . $_POST['id'])){
$data = array(
'success' => true,
'message' => 'Update Successful!',
);
}
echo json_encode($data);
}
if ($event == 'delete') {
if($conn->delete("employee", "id=" . $_POST['id'])){
$data = array(
'success' => true,
'message' => 'Delete Successful!',
);
}
echo json_encode($data);
}
if ($event == 'edit') {
$data = $conn->get("select * from employee where id={$_POST['id']};")[0];
echo json_encode($data);
}
?>

Categories