Url Encoding

Hi,

I want to encode Yii URL parameters

Example: /index.php/books/1/subject/2

1 and 2 must be encoded.

Whats the simplest way in Yii to achieve this.

Regards,

Praveen J

The simplest way is to encode them yourself. For example, you encode those values before you use them with createUrl() command.

Hi Roman,

Thanks for the suggestion… :) wat i meant was to encode only parameters in urls by extending CBaseUrlRule

Currently m using following code and facing problems with url which contains parameters, i am currently debugging the code and trying to get it work properly. Lemme know if u have any suggestion for the same,

in conifg/main.php , i am having,

‘rules’ => array(

            '' => 'site/index', // normal URL rules


            array(// your custom URL handler


                'class' => 'application.components.CustomUrlRule',


            ),


        ),

and my component CustomUrlRule,

class CustomUrlRule extends CBaseUrlRule {

public function createUrl($manager, $route, $params, $ampersand) {


    $key = "testKey";


    return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $route, MCRYPT_MODE_CBC, md5(md5($key))));


}





public function parseUrl($manager, $request, $pathInfo, $rawPathInfo) {


    $key = "testKey";


    return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($pathInfo), MCRYPT_MODE_CBC, md5(md5($key))), "\0");


}

}

This will output --> index.php/sTK7yXb5Pu22d4n5tbGgT6hwQxhvlrzAe5KWJ0Y4020=

i was intending to convert index.php/user/1/department/1 to index.php/user/(encoded)/department/(encoded)

Thank You,

Praveen J

Try something like this, only encrypting the values of $params array:




	public function createUrl($manager, $route, $params, $ampersand) {

		$key = "testKey";

		foreach ($params as $k => $v) {

			$params[$k] = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $v, MCRYPT_MODE_CBC, md5(md5($key))));

		}

		return $route;

	}



I haven’t tested if this works, just trying to give you an idea what to change and where.

Er … the standard base64 output will contain a few characters that aren’t url-friendly. Just saying.

Hi,

Thanks for the suggestio romen, yeah was i trying to implement something like that for the url parameters.

Thanks for the suggestion Sourcerer, oh ok once i get the URL encoding done, will implement a better encryption decryption method which are url friendly.

Regards,

Praveen J.

Hi,

Have Created CustomUrlRule for encrypted URL’s likes - index.php/test/admin/id/20/user/24 .

In Main,

‘urlManager’ => array(

        'urlFormat' => 'path',


        'rules' => array(


            '' => 'site/index', // normal URL rules


            array(// your custom URL handler


                'class' => 'application.components.CustomUrlRule',


            ),


        ),


    ),

//Place this in protected/component/CustomUrlRule.php

class CustomUrlRule extends CBaseUrlRule {

var $skey = "key123456789"; // you can change it





public function createUrl($manager, $route, $params, $ampersand) {


    $paramString = array();


    foreach ($params as $key => $value) {


        $paramString[] = $key;


        $paramString[] = $value;


    }


    $paramString = implode(",", $paramString);


    $paramStringEncoded = $this->encode($paramString);


    return $route . '/' . $paramStringEncoded;


}





public function parseUrl($manager, $request, $pathInfo, $rawPathInfo) {


    $pathParams = explode("/", $pathInfo);


    if (isset($pathParams[2])) {


        $paramStringDecoded = $this->decode($pathParams[2]);


        $params = explode(",", $paramStringDecoded);


        for ($i = 0; $i < count($params); $i+= 2) {


            $_GET[$params[$i]] = $params[$i + 1];


            $_REQUEST[$params[$i]] = $params[$i + 1];


        }


    }


    return $pathInfo;


}





public function safe_b64encode($string) {





    $data = base64_encode($string);


    $data = str_replace(array('+', '/', '='), array('-', '_', ''), $data);


    return $data;


}





public function safe_b64decode($string) {


    $data = str_replace(array('-', '_'), array('+', '/'), $string);


    $mod4 = strlen($data) % 4;


    if ($mod4) {


        $data .= substr('====', $mod4);


    }


    return base64_decode($data);


}





public function encode($value) {





    if (!$value) {


        return false;


    }


    $text = $value;


    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);


    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);


    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);


    return trim($this->safe_b64encode($crypttext));


}





public function decode($value) {





    if (!$value) {


        return false;


    }


    $crypttext = $this->safe_b64decode($value);


    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);


    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);


    $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);


    return trim($decrypttext);


}

}

Any Enhancements or suggestions are welcome… :)

Regards,

Praveen J.

Hello Preveen,

I have use this class for URL Encoding. Its working perfectly for simple Controller Action. But i have an issue for filtering the data in gridview. Means, Whenever i am searching any word in CGridview Filter, It throws an error as :

Error 500: <h1>PHP Error [8]</h1>

<p>Array to string conversion</p>

Another issue is that, when i am accessign a controller from module. It throws an error “Undefind Offset”. Because in “$pathParams[2]” i am getting simple string value. Because my module controller URL is like : ‘module/controller/action’.

Thank,

Karmraj Zala.

Problem with the solved CGridview Filter,


public function createUrl($manager, $route, $params, $ampersand) {

        $paramString = array();

        foreach ($params as $key => $value) {

            $paramString[] = $key;

            if (is_array($value)) {

                foreach ($value as $key2 => $value2) {

                    $paramString[] = $key2;

                    $paramString[] = $value2;

                }

            }

            else

                $paramString[] = $value;

        }

        //var_dump($paramString);

        if (is_array($paramString))

            $urlString = implode(",", $paramString);

        else

            $urlString = $paramString;

        $paramStringEncoded = $this->encode($urlString);

        return $route . '/' . $paramStringEncoded;

    }