diff --git a/framework/YiiBase.php b/framework/YiiBase.php index c7c8c05..ce196bd 100644 --- a/framework/YiiBase.php +++ b/framework/YiiBase.php @@ -117,8 +117,9 @@ class YiiBase * To import a class or a directory, one can use either path alias or class name (can be namespaced): * * - `@app/components/GoogleMap`: importing the `GoogleMap` class with a path alias; - * - `GoogleMap`: importing the `GoogleMap` class with a class name; - * - `@app/components/*`: importing the whole `components` directory with a path alias. + * - `@app/components/*`: importing the whole `components` directory with a path alias; + * - `GoogleMap`: importing the `GoogleMap` class with a class name. [[autoload()]] will be used + * when this class is used for the first time. * * @param string $alias path alias or a simple class name to be imported * @param boolean $forceInclude whether to include the class file immediately. If false, the class file @@ -160,7 +161,7 @@ class YiiBase require($path . "/$className.php"); self::$_imported[$alias] = $className; } else { - self::$classMap[$className] = $path . "/$className.php"; + self::$classMap[$className] = $path . DIRECTORY_SEPARATOR . "$className.php"; } return $className; } else { @@ -257,33 +258,39 @@ class YiiBase return true; } - // namespaced class, e.g. yii\base\Component if (strpos($className, '\\') !== false) { + // namespaced class, e.g. yii\base\Component // convert namespace to path alias, e.g. yii\base\Component to @yii/base/Component $alias = '@' . str_replace('\\', '/', ltrim($className, '\\')); if (($path = static::getAlias($alias)) !== false) { - include($path . '.php'); - return true; + $classFile = $path . '.php'; } - return false; - } - - // PEAR-styled class, e.g. PHPUnit_Framework_TestCase - if (($pos = strpos($className, '_')) !== false) { + } elseif (($pos = strpos($className, '_')) !== false) { + // PEAR-styled class, e.g. PHPUnit_Framework_TestCase // convert class name to path alias, e.g. PHPUnit_Framework_TestCase to @PHPUnit/Framework/TestCase $alias = '@' . str_replace('_', '/', $className); if (($path = static::getAlias($alias)) !== false) { - include($path . '.php'); - return true; + $classFile = $path . '.php'; } } - // search in include paths - foreach (self::$classPath as $path) { - $classFile = $path . DIRECTORY_SEPARATOR . $className . '.php'; - if (is_file($classFile)) { + if (!isset($classFile)) { + // search in include paths + foreach (self::$classPath as $path) { + $path .= DIRECTORY_SEPARATOR . $className . '.php'; + if (is_file($path)) { + $classFile = $path; + $alias = $className; + } + } + } + + if (isset($classFile, $alias)) { + if (!YII_DEBUG || basename(realpath($classFile)) === basename($alias) . '.php') { include($classFile); return true; + } else { + throw new \yii\base\Exception("Class name '$className' does not match the class file '" . realpath($classFile) . "'. Have you checked their case sensitivity?"); } } diff --git a/framework/base/Model.php b/framework/base/Model.php index e15125d..4a3ba3b 100644 --- a/framework/base/Model.php +++ b/framework/base/Model.php @@ -9,7 +9,7 @@ namespace yii\base; -use yii\util\Text; +use yii\util\StringHelper; /** * Model is the base class for data models. @@ -443,7 +443,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess */ public function generateAttributeLabel($name) { - return Text::camel2words($name, true); + return StringHelper::camel2words($name, true); } /** diff --git a/framework/base/View.php b/framework/base/View.php index 8ee2017..001e0e1 100644 --- a/framework/base/View.php +++ b/framework/base/View.php @@ -9,19 +9,70 @@ namespace yii\base; +use yii\util\FileHelper; + /** * @author Qiang Xue * @since 2.0 */ class View extends Component { - public function render($context, $_file_, $_data_ = array()) + public $file; + public $name; + /** + * @var string|array + */ + public $basePath; + public $owner; + public $locale; + + public function render($_params_ = array()) { - // we use special variable names here to avoid conflict with extracted variables - extract($_data_, EXTR_PREFIX_SAME, 'data'); + $this->resolveViewFile(); + extract($_params_, EXTR_OVERWRITE); ob_start(); ob_implicit_flush(false); - require($_file_); + require($this->file); return ob_get_clean(); } + + public function resolveViewFile() + { + if ($this->file !== null) { + return $this->file; + } + if ($this->name === null || $this->basePath) { + + } + + if(empty($viewName)) + return false; + + if($moduleViewPath===null) + $moduleViewPath=$basePath; + + if(($renderer=Yii::app()->getViewRenderer())!==null) + $extension=$renderer->fileExtension; + else + $extension='.php'; + if($viewName[0]==='/') + { + if(strncmp($viewName,'//',2)===0) + $viewFile=$basePath.$viewName; + else + $viewFile=$moduleViewPath.$viewName; + } + else if(strpos($viewName,'.')) + $viewFile=Yii::getPathOfAlias($viewName); + else + $viewFile=$viewPath.DIRECTORY_SEPARATOR.$viewName; + + if(is_file($viewFile.$extension)) + return Yii::app()->findLocalizedFile($viewFile.$extension); + else if($extension!=='.php' && is_file($viewFile.'.php')) + return Yii::app()->findLocalizedFile($viewFile.'.php'); + else + return false; + + } } \ No newline at end of file diff --git a/framework/db/ar/ActiveRecord.php b/framework/db/ar/ActiveRecord.php index b548bf1..35fd221 100644 --- a/framework/db/ar/ActiveRecord.php +++ b/framework/db/ar/ActiveRecord.php @@ -18,7 +18,7 @@ use yii\db\dao\Connection; use yii\db\dao\TableSchema; use yii\db\dao\Query; use yii\db\dao\Expression; -use yii\util\Text; +use yii\util\StringHelper; /** * ActiveRecord is the base class for classes representing relational data. @@ -247,14 +247,14 @@ abstract class ActiveRecord extends Model /** * Declares the name of the database table associated with this AR class. - * By default this method returns the class name as the table name by calling [[Text::camel2id()]]. + * By default this method returns the class name as the table name by calling [[StringHelper::camel2id()]]. * For example, 'Customer' becomes 'customer', and 'OrderDetail' becomes 'order_detail'. * You may override this method if the table is not named after this convention. * @return string the table name */ public static function tableName() { - return Text::camel2id(basename(get_called_class()), '_'); + return StringHelper::camel2id(basename(get_called_class()), '_'); } /** diff --git a/framework/util/File.php b/framework/util/File.php deleted file mode 100644 index 46d1941..0000000 --- a/framework/util/File.php +++ /dev/null @@ -1,139 +0,0 @@ - - * @author Alex Makarov - * @since 2.0 - */ -class File -{ - /** - * Copies a list of files from one place to another. - * @param array $fileList the list of files to be copied (name=>spec). - * The array keys are names displayed during the copy process, and array values are specifications - * for files to be copied. Each array value must be an array of the following structure: - * - * @see buildFileList - */ - public function copyFiles($fileList) - { - $overwriteAll=false; - foreach($fileList as $name=>$file) - { - $source=strtr($file['source'],'/\\',DIRECTORY_SEPARATOR); - $target=strtr($file['target'],'/\\',DIRECTORY_SEPARATOR); - $callback=isset($file['callback']) ? $file['callback'] : null; - $params=isset($file['params']) ? $file['params'] : null; - - if(is_dir($source)) - { - $this->ensureDirectory($target); - continue; - } - - if($callback!==null) - $content=call_user_func($callback,$source,$params); - else - $content=file_get_contents($source); - if(is_file($target)) - { - if($content===file_get_contents($target)) - { - echo " unchanged $name\n"; - continue; - } - if($overwriteAll) - echo " overwrite $name\n"; - else - { - echo " exist $name\n"; - echo " ...overwrite? [Yes|No|All|Quit] "; - $answer=trim(fgets(STDIN)); - if(!strncasecmp($answer,'q',1)) - return; - else if(!strncasecmp($answer,'y',1)) - echo " overwrite $name\n"; - else if(!strncasecmp($answer,'a',1)) - { - echo " overwrite $name\n"; - $overwriteAll=true; - } else - { - echo " skip $name\n"; - continue; - } - } - } else - { - $this->ensureDirectory(dirname($target)); - echo " generate $name\n"; - } - file_put_contents($target,$content); - } - } - - /** - * Builds the file list of a directory. - * This method traverses through the specified directory and builds - * a list of files and subdirectories that the directory contains. - * The result of this function can be passed to {@link copyFiles}. - * @param string $sourceDir the source directory - * @param string $targetDir the target directory - * @param string $baseDir base directory - * @return array the file list (see {@link copyFiles}) - */ - public function buildFileList($sourceDir, $targetDir, $baseDir='') - { - $list=array(); - $handle=opendir($sourceDir); - while(($file=readdir($handle))!==false) - { - if($file==='.' || $file==='..' || $file==='.svn' ||$file==='.yii') - continue; - $sourcePath=$sourceDir.DIRECTORY_SEPARATOR.$file; - $targetPath=$targetDir.DIRECTORY_SEPARATOR.$file; - $name=$baseDir===''?$file : $baseDir.'/'.$file; - $list[$name]=array('source'=>$sourcePath, 'target'=>$targetPath); - if(is_dir($sourcePath)) - $list=array_merge($list,$this->buildFileList($sourcePath,$targetPath,$name)); - } - closedir($handle); - return $list; - } - - /** - * Creates all parent directories if they do not exist. - * @param string $directory the directory to be checked - */ - public function ensureDirectory($directory) - { - if(!is_dir($directory)) - { - $this->ensureDirectory(dirname($directory)); - echo " mkdir ".strtr($directory,'\\','/')."\n"; - mkdir($directory); - } - } -} diff --git a/framework/util/FileHelper.php b/framework/util/FileHelper.php new file mode 100644 index 0000000..93186d4 --- /dev/null +++ b/framework/util/FileHelper.php @@ -0,0 +1,70 @@ + + * @author Alex Makarov + * @since 2.0 + */ +class FileHelper +{ + /** + * Returns the extension name of a file path. + * For example, the path "path/to/something.php" would return "php". + * @param string $path the file path + * @return string the extension name without the dot character. + */ + public static function getExtension($path) + { + return pathinfo($path, PATHINFO_EXTENSION); + } + + /** + * Returns the localized version of a specified file. + * + * The searching is based on the specified language code. In particular, + * a file with the same name will be looked for under the subdirectory + * whose name is same as the language code. For example, given the file "path/to/view.php" + * and language code "zh_cn", the localized file will be looked for as + * "path/to/zh_cn/view.php". If the file is not found, the original file + * will be returned. + * + * If the target and the source language codes are the same, + * the original file will be returned. + * + * For consistency, it is recommended that the language code is given + * in lower case and in the format of LanguageID_RegionID (e.g. "en_us"). + * + * @param string $file the original file + * @param string $targetLanguage the target language that the file should be localized to. + * If not set, the value of [[\yii\base\Application::language]] will be used. + * @param string $sourceLanguage the language that the original file is in. + * If not set, the value of [[\yii\base\Application::sourceLanguage]] will be used. + * @return string the matching localized file, or the original file if the localized version is not found. + * If the target and the source language codes are the same, the original file will be returned. + */ + public static function localize($file, $targetLanguage = null, $sourceLanguage = null) + { + if ($targetLanguage === null) { + $targetLanguage = \Yii::$application->getLanguage(); + } + if ($sourceLanguage === null) { + $sourceLanguage = \Yii::$application->sourceLanguage; + } + if ($targetLanguage === $sourceLanguage) { + return $file; + } + $desiredFile = dirname($file) . DIRECTORY_SEPARATOR . $sourceLanguage . DIRECTORY_SEPARATOR . basename($file); + return is_file($desiredFile) ? $desiredFile : $file; + } +} diff --git a/framework/util/Text.php b/framework/util/StringHelper.php similarity index 99% rename from framework/util/Text.php rename to framework/util/StringHelper.php index 6dde6b8..caf0c61 100644 --- a/framework/util/Text.php +++ b/framework/util/StringHelper.php @@ -16,7 +16,7 @@ namespace yii\util; * @author Alex Makarov * @since 2.0 */ -class Text +class StringHelper { /** * Converts a word to its plural form.