Custom URL Class

I’ve done the requisite googling but I couldn’t find much detail on this. I’ve got a custom URL class looking up some data from a DB, it’s a lot like the example of manufacture/model in the docs here.

Unless I’ve configured something wrong and it’s meant to happen automatically, it doesn’t detail how to add any other parameters to the end of returned URL or how to add them when reading back in. I’ll stick with the walkthrough’s example for clarity:

Creating a url with:




$this->createUrl('car/index', array('manufacturer'=>'Ford', 'model'=>'Focus', 'customParam'=>'hai'));



Should result in:




/Ford/Focus/customParam/hai



With the appropriate config set on the URL config obviously (path type etc.).

However, my custom class will only return /Ford/Focus and I can’t see any good way in the docs to append the extra params that were passed in, that my URL class didn’t use. I could manually do a createPathInfo with slashes but this seems wrong as I can’t take into account every option in the config without re-inventing the wheel on parameter parsing. Is there no built in way to do this with the remaining parameters?

try something like this:




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

        {   

                if ($route==='car/index')

                {   

                        $url = '';

if (isset($params['manufacturer'], $params['model']))

                $url = $params['manufacturer'] . '/' . $params['model'];

            else if (isset($params['manufacturer']))

                $url = $params['manufacturer'];

  else return false; // no model nor manufacturer

                                unset ($params['manufacturer']); // kick out already processed variables

unset ($params['model']); // might need to be checked if key exists

                                $rest = $manager->createPathInfo($params, '/', '/');

                                if ($rest == '') 

                                        return $url;

                                else

                                        return $url . '/' . $rest;

                        }   

                }   

                return false;  // this rule does not apply

        }   




Sorry for the messy indentation. I didn’t test the code but basically you just check if you have more parameters left in the $params array and process them, too (i.e. append to $url)

Edit: Well, I should have read your post slower, sorry about that. I guess you would have to make your regular expression in parseUrl more general in order to account for more parameters which should be doable. Allow for 1 or more words divided by "/" and for each pair in $matches assign value to key.

of course, you have to augment your regular expression in parseUrl in order to account for additional parameters.

Alternatively, you could use




$rest = $manager->createPathInfo($params, '=', '&');

                                if ($rest == '') 

                                        return $url;

                                else

                                        return $url . '?' . $rest;



to create urls such like

/Ford/Focus?customParam=hai

in this case, you don’t need to account for additional parameters in your parseUrl function (this might be handy if you have loads of possible parameters passed to this url.

Yeh thats more or less what I have now, I just wondered if there’s a way of letting yii handle the generation of the params. Because the param generation hinges on the urlManager configuration in the config file:

whether to include script file,

path or get format, etc.

I’d have to re-create all the configuration options. Seems a little wasteful when Yii already does it somewhere. I think createPathInfo is just a small piece of the url generation algorithm, but I’ll stick with just that as it fits for now.

Unless anyone else has any insight?

Thanks befi

Here is a solution for having more than two levels (controller/action) of params in the URL:

http://www.yiiframework.com/doc/guide/1.1/en/topics.url#c4393

It’s not that I want to be able to read them and can’t parse them (They’re just extraneous parameters). It’s that I can’t generate them into the created URL without manually taking into account all of Yii’s URLMAnager options.

Example using tutorials method:

Using this URL Generation function from the guide:




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

    {

        if ($route==='car/index')

        {

            if (isset($params['manufacturer'], $params['model']))

                return $params['manufacturer'] . '/' . $params['model'];

            else if (isset($params['manufacturer']))

                return $params['manufacturer'];

        }

        return false;  // this rule does not apply

    }



Given these arguments:




$manager => Yii::app()->urlManager

$route = 'car/index'

$params = array(

	'manufacturer'=>'Ford',

	'model'=>'Focus'

	'heebeegeebee'=>'aotherParam'

);

$ampersand = '/';



From what I can make out, and what my function is doing, I would get




/Ford/Focus



returned.

This is fine, it’s generating the URL like it should, but it’s missing the other parameter that was passed in. How can I generate the params While still taking into account all the confguration options in the main config file?




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

  if ($route==='car/index') {

    $myParams = '';

    if (isset($params['manufacturer'])) {

      $myParams .= $params['manufacturer'];

      if (isset($params['model'])) {

        $myParams .= '/'.$params['model'];

        if (isset($params['heebeegeebee'])) {

          $myParams .= '/'.$params['heebeegeebee'];

        }

      }

    }

    return $myParams;

  }

  return false;  // this rule does not apply

}



Anybody know a generic way to accomplish this? or should I just stick with the

[font="monospace"][size="2"]




$rest = $manager->createPathInfo($params, '=', '&');

if ($rest == '')

   	return $url;

else

	return $url . '?' . $rest;



[/size][/font]

[font=“monospace”][size=“2”]This isn’t as all encompassing as I’d like but it’ll work for now.[/size][/font]