CTheme->getLayoutFile() return wrong path

On Windows platform development, use the character ‘/’ as directory separator in the construction of the path leading to incorrect resolving path.

In code




        public function getLayoutFile($controller,$layoutName)

        {

                $moduleViewPath=$basePath=$this->getViewPath();

                $module=$controller->getModule();

                if(empty($layoutName))

                {

                        while($module!==null)

                        {

                                if($module->layout===false)

                                        return false;

                                if(!empty($module->layout))

                                        break;

                                $module=$module->getParentModule();

                        }

                        if($module===null)

                                $layoutName=Yii::app()->layout;

                        else

                        {

                                $layoutName=$module->layout;

                                $moduleViewPath.='/'.$module->getId();

                        }

                }

                else if($module!==null)

                        $moduleViewPath.='/'.$module->getId();


                return $controller->resolveViewFile($layoutName,$moduleViewPath.'/layouts',$basePath,$moduleViewPath);

        }



see it:

      $moduleViewPath.=[color="#FF0000"][b]'/'.[/b][/color]$module->getId();

twice and

      return $controller->resolveViewFile($layoutName,$moduleViewPath.'[color="#FF0000"][b]/[/b][/color]layouts',$basePath,$moduleViewPath);

Using DIRECTORY_SEPARATOR instead ‘/’ will be better.




//define DIRECTORY_SEPARATOR automatically


if (!defined('DIRECTORY_SEPARATOR')) {

    define('DIRECTORY_SEPARATOR',

        strtoupper(substr(PHP_OS, 0, 3) == 'WIN') ? '\\' : '/'

    );



The same goes for CTheme->getViewFile()

Should be noted other function of class CTheme already use DIRECTORY_SEPARATOR:

getViewPath();

getSystemViewPath();

getSkinPath();

Correct code:




        public function getViewFile($controller,$viewName)

        {

                $moduleViewPath=$this->getViewPath();

                if(($module=$controller->getModule())!==null)

                        $moduleViewPath.=DIRECTORY_SEPARATOR.$module->getId();

                return $controller->resolveViewFile($viewName,$this->getViewPath().DIRECTORY_SEPARATOR.$controller->getUniqueId(),$this->getViewPath(),$moduleViewPath);

        }


        /**

         * Finds the layout file for the specified controller's layout.

         * @param CController $controller the controller

         * @param string $layoutName the layout name

         * @return string the layout file path. False if the file does not exist.

         */

public function getLayoutFile($controller,$layoutName)

	{

		$moduleViewPath=$basePath=$this->getViewPath();

		$module=$controller->getModule();

		if(empty($layoutName))

		{

			while($module!==null)

			{

				if($module->layout===false)

					return false;

				if(!empty($module->layout))

					break;

				$module=$module->getParentModule();

			}

			if($module===null)

				$layoutName=Yii::app()->layout;

			else

			{

				$layoutName=$module->layout;

				$moduleViewPath.=DIRECTORY_SEPARATOR.$module->getId();

			}

		}

		else if($module!==null)

			$moduleViewPath.=DIRECTORY_SEPARATOR.$module->getId();


		return $controller->resolveViewFile($layoutName,$moduleViewPath.DIRECTORY_SEPARATOR.'layouts',$basePath,$moduleViewPath);

	}



There shouldn’t be any problem with this as php will work with ‘/’ as if it was ‘\’ on windows.