Renamed the next release to be 1.1.16.

This commit is contained in:
Qiang Xue
2014-06-29 20:22:19 -04:00
parent be5056957a
commit ba4c943039
5 changed files with 234 additions and 69 deletions

View File

@@ -1,9 +1,7 @@
Yii Framework Change Log
========================
Work in progress
----------------
Version 1.1.15 under development
Version 1.1.16 under development
--------------------------------
- Bug #268: Fixed Active Record count error when some field name starting from 'count' (nineinchnick)
- Bug #788: createIndex is not using the recommended way to create unique indexes on Postgres (nineinchnick)
@@ -112,6 +110,10 @@ Version 1.1.15 under development
- Chg #3298: ListView and GridView: Added check for the existence of a href attribute in link pager (dutchakdev)
- New #2955: Added official support for MariaDB (cebe, DaSourcerer)
Version 1.1.15 June 29, 2014
----------------------------
- Bug (CVE-2014-4672): CDetailView may be exploited to allow executing arbitrary PHP script on the server (cebe, qiangxue)
Version 1.1.14 August 11, 2013
------------------------------
- Bug: There was unnecessary echo in CRUD views generated by Gii (samdark)

View File

@@ -1,4 +1,4 @@
Upgrading Instructions for Yii Framework v1.1.15
Upgrading Instructions for Yii Framework v1.1.16
================================================
!!!IMPORTANT!!!
@@ -17,6 +17,9 @@ General upgrade instructions
- Check if everything is OK, if not — revert from backup and post
issues to Yii issue tracker.
Upgrading from v1.1.15
----------------------
Upgrading from v1.1.14
----------------------

View File

@@ -80,7 +80,7 @@ class YiiBase
*/
public static function getVersion()
{
return '1.1.15-dev';
return '1.1.16-dev';
}
/**
@@ -758,6 +758,7 @@ class YiiBase
'CLogRouter' => '/logging/CLogRouter.php',
'CLogger' => '/logging/CLogger.php',
'CProfileLogRoute' => '/logging/CProfileLogRoute.php',
'CSysLogRoute' => '/logging/CSysLogRoute.php',
'CWebLogRoute' => '/logging/CWebLogRoute.php',
'CDateTimeParser' => '/utils/CDateTimeParser.php',
'CFileHelper' => '/utils/CFileHelper.php',

View File

@@ -40,7 +40,7 @@ class YiiBase
private static $_logger;
public static function getVersion()
{
return '1.1.14';
return '1.1.16-dev';
}
public static function createWebApplication($config=null)
{
@@ -145,7 +145,8 @@ class YiiBase
}
if(($pos=strrpos($alias,'.'))===false) // a simple class name
{
if($forceInclude && self::autoload($alias))
// try to autoload the class with an autoloader if $forceInclude is true
if($forceInclude && (Yii::autoload($alias,true) || class_exists($alias,true)))
self::$_imports[$alias]=$alias;
return $alias;
}
@@ -211,13 +212,15 @@ class YiiBase
else
self::$_aliases[$alias]=rtrim($path,'\\/');
}
public static function autoload($className)
public static function autoload($className,$classMapOnly=false)
{
// use include so that the error PHP file may appear
if(isset(self::$classMap[$className]))
include(self::$classMap[$className]);
elseif(isset(self::$_coreClasses[$className]))
include(YII_PATH.self::$_coreClasses[$className]);
elseif($classMapOnly)
return false;
else
{
// include class file relying on include_path
@@ -420,6 +423,9 @@ class YiiBase
'CDbExpression' => '/db/schema/CDbExpression.php',
'CDbSchema' => '/db/schema/CDbSchema.php',
'CDbTableSchema' => '/db/schema/CDbTableSchema.php',
'CCubridColumnSchema' => '/db/schema/cubrid/CCubridColumnSchema.php',
'CCubridSchema' => '/db/schema/cubrid/CCubridSchema.php',
'CCubridTableSchema' => '/db/schema/cubrid/CCubridTableSchema.php',
'CMssqlColumnSchema' => '/db/schema/mssql/CMssqlColumnSchema.php',
'CMssqlCommandBuilder' => '/db/schema/mssql/CMssqlCommandBuilder.php',
'CMssqlPdoAdapter' => '/db/schema/mssql/CMssqlPdoAdapter.php',
@@ -461,6 +467,7 @@ class YiiBase
'CLogRouter' => '/logging/CLogRouter.php',
'CLogger' => '/logging/CLogger.php',
'CProfileLogRoute' => '/logging/CProfileLogRoute.php',
'CSysLogRoute' => '/logging/CSysLogRoute.php',
'CWebLogRoute' => '/logging/CWebLogRoute.php',
'CDateTimeParser' => '/utils/CDateTimeParser.php',
'CFileHelper' => '/utils/CFileHelper.php',
@@ -699,7 +706,7 @@ class CComponent
return call_user_func_array(array($object,$name),$parameters);
}
}
if(class_exists('Closure', false) && $this->canGetProperty($name) && $this->$name instanceof Closure)
if(class_exists('Closure', false) && ($this->canGetProperty($name) || property_exists($this, $name)) && $this->$name instanceof Closure)
return call_user_func_array($this->$name, $parameters);
throw new CException(Yii::t('yii','{class} and its behaviors do not have a method or closure named "{name}".',
array('{class}'=>get_class($this), '{name}'=>$name)));
@@ -1022,7 +1029,7 @@ abstract class CModule extends CComponent
{
return $this->_moduleConfig;
}
public function setModules($modules)
public function setModules($modules,$merge=true)
{
foreach($modules as $id=>$module)
{
@@ -1031,15 +1038,17 @@ abstract class CModule extends CComponent
$id=$module;
$module=array();
}
if(!isset($module['class']))
{
Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id);
$module['class']=$id.'.'.ucfirst($id).'Module';
}
if(isset($this->_moduleConfig[$id]))
if(isset($this->_moduleConfig[$id]) && $merge)
$this->_moduleConfig[$id]=CMap::mergeArray($this->_moduleConfig[$id],$module);
else
{
if(!isset($module['class']))
{
Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id);
$module['class']=$id.'.'.ucfirst($id).'Module';
}
$this->_moduleConfig[$id]=$module;
}
}
}
public function hasComponent($id)
@@ -1138,6 +1147,7 @@ abstract class CApplication extends CModule
public $name='My Application';
public $charset='UTF-8';
public $sourceLanguage='en_us';
public $localeClass='CLocale';
private $_id;
private $_basePath;
private $_runtimePath;
@@ -1289,15 +1299,19 @@ abstract class CApplication extends CModule
}
public function getLocale($localeID=null)
{
return CLocale::getInstance($localeID===null?$this->getLanguage():$localeID);
return call_user_func_array(array($this->localeClass, 'getInstance'),array($localeID===null?$this->getLanguage():$localeID));
}
public function getLocaleDataPath()
{
return CLocale::$dataPath===null ? Yii::getPathOfAlias('system.i18n.data') : CLocale::$dataPath;
$vars=get_class_vars($this->localeClass);
if(empty($vars['dataPath']))
return Yii::getPathOfAlias('system.i18n.data');
return $vars['dataPath'];
}
public function setLocaleDataPath($value)
{
CLocale::$dataPath=$value;
$property=new ReflectionProperty($this->localeClass,'dataPath');
$property->setValue($value);
}
public function getNumberFormatter()
{
@@ -1785,7 +1799,7 @@ class CWebApplication extends CApplication
$className=ucfirst($id).'Controller';
$classFile=$basePath.DIRECTORY_SEPARATOR.$className.'.php';
if($owner->controllerNamespace!==null)
$className=$owner->controllerNamespace.'\\'.$className;
$className=$owner->controllerNamespace.'\\'.str_replace('/','\\',$controllerID).$className;
if(is_file($classFile))
{
if(!class_exists($className,false))
@@ -2333,6 +2347,18 @@ class CHttpRequest extends CApplicationComponent
else
return $defaultValue;
}
public function getPatch($name,$defaultValue=null)
{
if($this->getIsPatchViaPostRequest())
return $this->getPost($name, $defaultValue);
if($this->getIsPatchRequest())
{
$restParams=$this->getRestParams();
return isset($restParams[$name]) ? $restParams[$name] : $defaultValue;
}
else
return $defaultValue;
}
public function getRestParams()
{
if($this->_restParams===null)
@@ -2447,7 +2473,13 @@ class CHttpRequest extends CApplicationComponent
$pathInfo=substr($_SERVER['PHP_SELF'],strlen($scriptUrl));
else
throw new CException(Yii::t('yii','CHttpRequest is unable to determine the path info of the request.'));
$this->_pathInfo=trim($pathInfo,'/');
if($pathInfo==='/')
$pathInfo='';
elseif($pathInfo[0]==='/')
$pathInfo=substr($pathInfo,1);
if(($posEnd=strlen($pathInfo)-1)>0 && $pathInfo[$posEnd]==='/')
$pathInfo=substr($pathInfo,0,$posEnd);
$this->_pathInfo=$pathInfo;
}
return $this->_pathInfo;
}
@@ -2508,13 +2540,15 @@ class CHttpRequest extends CApplicationComponent
}
public function getIsSecureConnection()
{
return isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']=='on' || $_SERVER['HTTPS']==1)
|| isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO']=='https';
return isset($_SERVER['HTTPS']) && (strcasecmp($_SERVER['HTTPS'],'on')===0 || $_SERVER['HTTPS']==1)
|| isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'],'https')===0;
}
public function getRequestType()
{
if(isset($_POST['_method']))
return strtoupper($_POST['_method']);
elseif(isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']))
return strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
return strtoupper(isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:'GET');
}
public function getIsPostRequest()
@@ -2537,6 +2571,14 @@ class CHttpRequest extends CApplicationComponent
{
return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'PUT');
}
public function getIsPatchRequest()
{
return (isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'PATCH')) || $this->getIsPatchViaPostRequest();
}
protected function getIsPatchViaPostRequest()
{
return isset($_POST['_method']) && !strcasecmp($_POST['_method'],'PATCH');
}
public function getIsAjaxRequest()
{
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
@@ -2736,10 +2778,23 @@ class CHttpRequest extends CApplicationComponent
}
return $this->_preferredLanguages;
}
public function getPreferredLanguage()
public function getPreferredLanguage($languages=array())
{
$preferredLanguages=$this->getPreferredLanguages();
return !empty($preferredLanguages) ? CLocale::getCanonicalID($preferredLanguages[0]) : false;
if(empty($languages)) {
return !empty($preferredLanguages) ? CLocale::getCanonicalID($preferredLanguages[0]) : false;
}
foreach ($preferredLanguages as $preferredLanguage) {
$preferredLanguage=CLocale::getCanonicalID($preferredLanguage);
foreach ($languages as $language) {
$language=CLocale::getCanonicalID($language);
// en_us==en_us, en==en_us, en_us==en
if($language===$acceptedLanguage || strpos($acceptedLanguage,$language.'_')===0 || strpos($language,$acceptedLanguage.'_')===0) {
return $language;
}
}
}
return reset($languages);
}
public function sendFile($fileName,$content,$mimeType=null,$terminate=true)
{
@@ -2866,6 +2921,7 @@ class CHttpRequest extends CApplicationComponent
{
if ($this->getIsPostRequest() ||
$this->getIsPutRequest() ||
$this->getIsPatchRequest() ||
$this->getIsDeleteRequest())
{
$cookies=$this->getCookies();
@@ -2878,6 +2934,9 @@ class CHttpRequest extends CApplicationComponent
case 'PUT':
$userToken=$this->getPut($this->csrfTokenName);
break;
case 'PATCH':
$userToken=$this->getPatch($this->csrfTokenName);
break;
case 'DELETE':
$userToken=$this->getDelete($this->csrfTokenName);
}
@@ -3237,6 +3296,7 @@ class CUrlRule extends CBaseUrlRule
}
$this->route=trim($route,'/');
$tr2['/']=$tr['/']='\\/';
$tr['.']='\\.';
if(strpos($route,'<')!==false && preg_match_all('/<(\w+)>/',$route,$matches2))
{
foreach($matches2[1] as $name)
@@ -3434,8 +3494,16 @@ abstract class CBaseController extends CComponent
{
ob_start();
ob_implicit_flush(false);
$widget=$this->createWidget($className,$properties);
$widget->run();
try
{
$widget=$this->createWidget($className,$properties);
$widget->run();
}
catch(Exception $e)
{
ob_end_clean();
throw $e;
}
return ob_get_clean();
}
else
@@ -4813,6 +4881,13 @@ class CHtml
public static function beginForm($action='',$method='post',$htmlOptions=array())
{
$htmlOptions['action']=$url=self::normalizeUrl($action);
if(strcasecmp($method,'get')!==0 && strcasecmp($method,'post')!==0)
{
$customMethod=$method;
$method='post';
}
else
$customMethod=false;
$htmlOptions['method']=$method;
$form=self::tag('form',$htmlOptions,false,false);
$hiddens=array();
@@ -4829,6 +4904,8 @@ class CHtml
$request=Yii::app()->request;
if($request->enableCsrfValidation && !strcasecmp($method,'post'))
$hiddens[]=self::hiddenField($request->csrfTokenName,$request->getCsrfToken(),array('id'=>false));
if($customMethod!==false)
$hiddens[]=self::hiddenField('_method',$customMethod);
if($hiddens!==array())
$form.="\n".implode("\n",$hiddens);
return $form;
@@ -4930,11 +5007,21 @@ class CHtml
}
return self::tag('label',$htmlOptions,$label);
}
public static function colorField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
return self::inputField('color',$name,$value,$htmlOptions);
}
public static function textField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
return self::inputField('text',$name,$value,$htmlOptions);
}
public static function searchField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
return self::inputField('search',$name,$value,$htmlOptions);
}
public static function numberField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
@@ -4955,6 +5042,21 @@ class CHtml
self::clientChange('change',$htmlOptions);
return self::inputField('time',$name,$value,$htmlOptions);
}
public static function dateTimeField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
return self::inputField('datetime',$name,$value,$htmlOptions);
}
public static function dateTimeLocalField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
return self::inputField('datetime-local',$name,$value,$htmlOptions);
}
public static function weekField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
return self::inputField('week',$name,$value,$htmlOptions);
}
public static function emailField($name,$value='',$htmlOptions=array())
{
self::clientChange('change',$htmlOptions);
@@ -5089,7 +5191,7 @@ class CHtml
public static function checkBoxList($name,$select,$data,$htmlOptions=array())
{
$template=isset($htmlOptions['template'])?$htmlOptions['template']:'{input} {label}';
$separator=isset($htmlOptions['separator'])?$htmlOptions['separator']:"<br/>\n";
$separator=isset($htmlOptions['separator'])?$htmlOptions['separator']:self::tag('br');
$container=isset($htmlOptions['container'])?$htmlOptions['container']:'span';
unset($htmlOptions['template'],$htmlOptions['separator'],$htmlOptions['container']);
if(substr($name,-2)!=='[]')
@@ -5166,7 +5268,7 @@ EOD;
public static function radioButtonList($name,$select,$data,$htmlOptions=array())
{
$template=isset($htmlOptions['template'])?$htmlOptions['template']:'{input} {label}';
$separator=isset($htmlOptions['separator'])?$htmlOptions['separator']:"<br/>\n";
$separator=isset($htmlOptions['separator'])?$htmlOptions['separator']:self::tag('br');
$container=isset($htmlOptions['container'])?$htmlOptions['container']:'span';
unset($htmlOptions['template'],$htmlOptions['separator'],$htmlOptions['container']);
$labelOptions=isset($htmlOptions['labelOptions'])?$htmlOptions['labelOptions']:array();
@@ -5175,7 +5277,7 @@ EOD;
{
if(!is_array($htmlOptions['empty']))
$htmlOptions['empty']=array(''=>$htmlOptions['empty']);
$data=array_merge($htmlOptions['empty'],$data);
$data=CMap::mergeArray($htmlOptions['empty'],$data);
unset($htmlOptions['empty']);
}
$items=array();
@@ -5363,6 +5465,30 @@ EOD;
self::clientChange('change',$htmlOptions);
return self::activeInputField('time',$model,$attribute,$htmlOptions);
}
public static function activeDateTimeField($model,$attribute,$htmlOptions=array())
{
self::resolveNameID($model,$attribute,$htmlOptions);
self::clientChange('change',$htmlOptions);
return self::activeInputField('datetime',$model,$attribute,$htmlOptions);
}
public static function activeDateTimeLocalField($model,$attribute,$htmlOptions=array())
{
self::resolveNameID($model,$attribute,$htmlOptions);
self::clientChange('change',$htmlOptions);
return self::activeInputField('datetime-local',$model,$attribute,$htmlOptions);
}
public static function activeWeekField($model,$attribute,$htmlOptions=array())
{
self::resolveNameID($model,$attribute,$htmlOptions);
self::clientChange('change',$htmlOptions);
return self::activeInputField('week',$model,$attribute,$htmlOptions);
}
public static function activeColorField($model,$attribute,$htmlOptions=array())
{
self::resolveNameID($model,$attribute,$htmlOptions);
self::clientChange('change',$htmlOptions);
return self::activeInputField('color',$model,$attribute,$htmlOptions);
}
public static function activeTelField($model,$attribute,$htmlOptions=array())
{
self::resolveNameID($model,$attribute,$htmlOptions);
@@ -5633,7 +5759,9 @@ EOD;
protected static function activeInputField($type,$model,$attribute,$htmlOptions)
{
$htmlOptions['type']=$type;
if($type==='text' || $type==='password')
if($type==='text'||$type==='password'||$type==='color'||$type==='date'||$type==='datetime'||
$type==='datetime-local'||$type==='email'||$type==='month'||$type==='number'||$type==='range'||
$type==='search'||$type==='tel'||$type==='time'||$type==='url'||$type==='week')
{
if(!isset($htmlOptions['maxlength']))
{
@@ -5844,9 +5972,9 @@ EOD;
public static function renderAttributes($htmlOptions)
{
static $specialAttributes=array(
'async'=>1,
'autofocus'=>1,
'autoplay'=>1,
'async'=>1,
'checked'=>1,
'controls'=>1,
'declare'=>1,
@@ -5885,7 +6013,10 @@ EOD;
{
if(isset($specialAttributes[$name]))
{
if($value)
if($value===false && $name==='async') {
$html .= ' ' . $name.'="false"';
}
elseif($value)
{
$html .= ' ' . $name;
if(self::$renderSpecialAttributesValue)
@@ -6184,13 +6315,14 @@ class CClientScript extends CApplicationComponent
$scriptContent = $scriptValue['content'];
unset($scriptValue['content']);
$scriptHtmlOptions = $scriptValue;
ksort($scriptHtmlOptions);
}
else
{
$scriptContent = $scriptValue;
$scriptHtmlOptions = array();
}
$key=serialize(ksort($scriptHtmlOptions));
$key=serialize($scriptHtmlOptions);
$scriptBatches[$key]['htmlOptions']=$scriptHtmlOptions;
$scriptBatches[$key]['scripts'][]=$scriptContent;
}
@@ -6395,6 +6527,10 @@ class CClientScript extends CApplicationComponent
$params=func_get_args();
$this->recordCachingAction('clientScript','registerCoreScript',$params);
}
elseif(YII_DEBUG)
throw new CException('There is no CClientScript package: '.$name);
else
Yii::log('There is no CClientScript package: '.$name,CLogger::LEVEL_WARNING,'system.web.CClientScript');
return $this;
}
public function registerCssFile($url,$media='')
@@ -7401,7 +7537,10 @@ abstract class CActiveRecord extends CModel
}
public function tableName()
{
return get_class($this);
$tableName = get_class($this);
if(($pos=strrpos($tableName,'\\')) !== false)
return substr($tableName,$pos+1);
return $tableName;
}
public function primaryKey()
{
@@ -7641,7 +7780,7 @@ abstract class CActiveRecord extends CModel
if($this->beforeSave())
{
$builder=$this->getCommandBuilder();
$table=$this->getMetaData()->tableSchema;
$table=$this->getTableSchema();
$command=$builder->createInsertCommand($table,$this->getAttributes($attributes));
if($command->execute())
{
@@ -7767,7 +7906,7 @@ abstract class CActiveRecord extends CModel
}
public function getPrimaryKey()
{
$table=$this->getMetaData()->tableSchema;
$table=$this->getTableSchema();
if(is_string($table->primaryKey))
return $this->{$table->primaryKey};
elseif(is_array($table->primaryKey))
@@ -7783,7 +7922,7 @@ abstract class CActiveRecord extends CModel
public function setPrimaryKey($value)
{
$this->_pk=$this->getPrimaryKey();
$table=$this->getMetaData()->tableSchema;
$table=$this->getTableSchema();
if(is_string($table->primaryKey))
$this->{$table->primaryKey}=$value;
elseif(is_array($table->primaryKey))
@@ -7808,7 +7947,7 @@ abstract class CActiveRecord extends CModel
{
if(!$all)
$criteria->limit=1;
$command=$this->getCommandBuilder()->createFindCommand($this->getTableSchema(),$criteria,$this->getTableAlias());
$command=$this->getCommandBuilder()->createFindCommand($this->getTableSchema(),$criteria);
return $all ? $this->populateRecords($command->queryAll(), true, $criteria->index) : $this->populateRecord($command->queryRow());
}
else
@@ -7936,8 +8075,8 @@ abstract class CActiveRecord extends CModel
}
public function count($condition='',$params=array())
{
$builder=$this->getCommandBuilder();
$this->beforeCount();
$builder=$this->getCommandBuilder();
$criteria=$builder->createCriteria($condition,$params);
$this->applyScopes($criteria);
if(empty($criteria->with))
@@ -8106,6 +8245,7 @@ class CBaseActiveRelation extends CComponent
public $params=array();
public $group='';
public $join='';
public $joinOptions='';
public $having='';
public $order='';
public function __construct($name,$className,$foreignKey,$options=array())
@@ -8174,6 +8314,7 @@ class CStatRelation extends CBaseActiveRelation
{
public $select='COUNT(*)';
public $defaultValue=0;
public $scopes;
public function mergeWith($criteria,$fromScope=false)
{
if($criteria instanceof CDbCriteria)
@@ -8350,9 +8491,10 @@ class CDbConnection extends CApplicationComponent
public $tablePrefix;
public $initSQLs;
public $driverMap=array(
'cubrid'=>'CCubridSchema', // CUBRID
'pgsql'=>'CPgsqlSchema', // PostgreSQL
'mysqli'=>'CMysqlSchema', // MySQL
'mysql'=>'CMysqlSchema', // MySQL
'mysql'=>'CMysqlSchema', // MySQL,MariaDB
'sqlite'=>'CSqliteSchema', // sqlite 3
'sqlite2'=>'CSqliteSchema', // sqlite 2
'mssql'=>'CMssqlSchema', // Mssql driver on windows hosts
@@ -8361,6 +8503,7 @@ class CDbConnection extends CApplicationComponent
'oci'=>'COciSchema', // Oracle driver
);
public $pdoClass = 'PDO';
private $_driverName;
private $_attributes=array();
private $_active=false;
private $_pdo;
@@ -8444,9 +8587,8 @@ class CDbConnection extends CApplicationComponent
protected function createPdoInstance()
{
$pdoClass=$this->pdoClass;
if(($pos=strpos($this->connectionString,':'))!==false)
if(($driver=$this->getDriverName())!==null)
{
$driver=strtolower(substr($this->connectionString,0,$pos));
if($driver==='mssql' || $driver==='dblib')
$pdoClass='CMssqlPdoAdapter';
elseif($driver==='sqlsrv')
@@ -8588,9 +8730,15 @@ class CDbConnection extends CApplicationComponent
}
public function getDriverName()
{
if(($pos=strpos($this->connectionString, ':'))!==false)
return strtolower(substr($this->connectionString, 0, $pos));
// return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
if($this->_driverName!==null)
return $this->_driverName;
elseif(($pos=strpos($this->connectionString,':'))!==false)
return $this->_driverName=strtolower(substr($this->connectionString,0,$pos));
//return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
}
public function setDriverName($driverName)
{
$this->_driverName=strtolower($driverName);
}
public function getClientVersion()
{
@@ -8815,7 +8963,7 @@ abstract class CDbSchema extends CComponent
else
return $type;
}
public function createTable($table, $columns, $options=null)
public function createTable($table,$columns,$options=null)
{
$cols=array();
foreach($columns as $name=>$type)
@@ -8828,7 +8976,7 @@ abstract class CDbSchema extends CComponent
$sql="CREATE TABLE ".$this->quoteTableName($table)." (\n".implode(",\n",$cols)."\n)";
return $options===null ? $sql : $sql.' '.$options;
}
public function renameTable($table, $newName)
public function renameTable($table,$newName)
{
return 'RENAME TABLE ' . $this->quoteTableName($table) . ' TO ' . $this->quoteTableName($newName);
}
@@ -8840,58 +8988,61 @@ abstract class CDbSchema extends CComponent
{
return "TRUNCATE TABLE ".$this->quoteTableName($table);
}
public function addColumn($table, $column, $type)
public function addColumn($table,$column,$type)
{
return 'ALTER TABLE ' . $this->quoteTableName($table)
. ' ADD ' . $this->quoteColumnName($column) . ' '
. $this->getColumnType($type);
}
public function dropColumn($table, $column)
public function dropColumn($table,$column)
{
return "ALTER TABLE ".$this->quoteTableName($table)
." DROP COLUMN ".$this->quoteColumnName($column);
}
public function renameColumn($table, $name, $newName)
public function renameColumn($table,$name,$newName)
{
return "ALTER TABLE ".$this->quoteTableName($table)
. " RENAME COLUMN ".$this->quoteColumnName($name)
. " TO ".$this->quoteColumnName($newName);
}
public function alterColumn($table, $column, $type)
public function alterColumn($table,$column,$type)
{
return 'ALTER TABLE ' . $this->quoteTableName($table) . ' CHANGE '
. $this->quoteColumnName($column) . ' '
. $this->quoteColumnName($column) . ' '
. $this->getColumnType($type);
}
public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete=null, $update=null)
public function addForeignKey($name,$table,$columns,$refTable,$refColumns,$delete=null,$update=null)
{
$columns=preg_split('/\s*,\s*/',$columns,-1,PREG_SPLIT_NO_EMPTY);
if(is_string($columns))
$columns=preg_split('/\s*,\s*/',$columns,-1,PREG_SPLIT_NO_EMPTY);
foreach($columns as $i=>$col)
$columns[$i]=$this->quoteColumnName($col);
$refColumns=preg_split('/\s*,\s*/',$refColumns,-1,PREG_SPLIT_NO_EMPTY);
if(is_string($refColumns))
$refColumns=preg_split('/\s*,\s*/',$refColumns,-1,PREG_SPLIT_NO_EMPTY);
foreach($refColumns as $i=>$col)
$refColumns[$i]=$this->quoteColumnName($col);
$sql='ALTER TABLE '.$this->quoteTableName($table)
.' ADD CONSTRAINT '.$this->quoteColumnName($name)
.' FOREIGN KEY ('.implode(', ', $columns).')'
.' FOREIGN KEY ('.implode(', ',$columns).')'
.' REFERENCES '.$this->quoteTableName($refTable)
.' ('.implode(', ', $refColumns).')';
.' ('.implode(', ',$refColumns).')';
if($delete!==null)
$sql.=' ON DELETE '.$delete;
if($update!==null)
$sql.=' ON UPDATE '.$update;
return $sql;
}
public function dropForeignKey($name, $table)
public function dropForeignKey($name,$table)
{
return 'ALTER TABLE '.$this->quoteTableName($table)
.' DROP CONSTRAINT '.$this->quoteColumnName($name);
}
public function createIndex($name, $table, $column, $unique=false)
public function createIndex($name,$table,$columns,$unique=false)
{
$cols=array();
$columns=preg_split('/\s*,\s*/',$column,-1,PREG_SPLIT_NO_EMPTY);
if(is_string($columns))
$columns=preg_split('/\s*,\s*/',$columns,-1,PREG_SPLIT_NO_EMPTY);
foreach($columns as $col)
{
if(strpos($col,'(')!==false)
@@ -8903,7 +9054,7 @@ abstract class CDbSchema extends CComponent
. $this->quoteTableName($name).' ON '
. $this->quoteTableName($table).' ('.implode(', ',$cols).')';
}
public function dropIndex($name, $table)
public function dropIndex($name,$table)
{
return 'DROP INDEX '.$this->quoteTableName($name).' ON '.$this->quoteTableName($table);
}
@@ -8915,7 +9066,7 @@ abstract class CDbSchema extends CComponent
$columns[$i]=$this->quoteColumnName($col);
return 'ALTER TABLE ' . $this->quoteTableName($table) . ' ADD CONSTRAINT '
. $this->quoteColumnName($name) . ' PRIMARY KEY ('
. implode(', ', $columns). ' )';
. implode(', ',$columns). ' )';
}
public function dropPrimaryKey($name,$table)
{
@@ -8927,9 +9078,11 @@ class CSqliteSchema extends CDbSchema
{
public $columnTypes=array(
'pk' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
'bigpk' => 'integer PRIMARY KEY AUTOINCREMENT NOT NULL',
'string' => 'varchar(255)',
'text' => 'text',
'integer' => 'integer',
'bigint' => 'integer',
'float' => 'float',
'decimal' => 'decimal',
'datetime' => 'datetime',
@@ -9297,7 +9450,7 @@ class CDbCommand extends CComponent
&& ($cache=Yii::app()->getComponent($this->_connection->queryCacheID))!==null)
{
$this->_connection->queryCachingCount--;
$cacheKey='yii:dbquery'.$this->_connection->connectionString.':'.$this->_connection->username;
$cacheKey='yii:dbquery'.':'.$method.':'.$this->_connection->connectionString.':'.$this->_connection->username;
$cacheKey.=':'.$this->getText().':'.serialize(array_merge($this->_paramLog,$params));
if(($result=$cache->get($cacheKey))!==false)
{
@@ -9348,8 +9501,6 @@ class CDbCommand extends CComponent
$sql.=' '.(!empty($query['select']) ? $query['select'] : '*');
if(!empty($query['from']))
$sql.="\nFROM ".$query['from'];
else
throw new CDbException(Yii::t('yii','The DB query must contain the "from" portion.'));
if(!empty($query['join']))
$sql.="\n".(is_array($query['join']) ? implode("\n",$query['join']) : $query['join']);
if(!empty($query['where']))
@@ -9508,6 +9659,14 @@ class CDbCommand extends CComponent
{
return $this->joinInternal('natural join', $table);
}
public function naturalLeftJoin($table)
{
return $this->joinInternal('natural left join', $table);
}
public function naturalRightJoin($table)
{
return $this->joinInternal('natural right join', $table);
}
public function group($columns)
{
if(is_string($columns) && strpos($columns,'(')!==false)
@@ -9723,9 +9882,9 @@ class CDbCommand extends CComponent
{
return $this->setText($this->getConnection()->getSchema()->dropForeignKey($name, $table))->execute();
}
public function createIndex($name, $table, $column, $unique=false)
public function createIndex($name, $table, $columns, $unique=false)
{
return $this->setText($this->getConnection()->getSchema()->createIndex($name, $table, $column, $unique))->execute();
return $this->setText($this->getConnection()->getSchema()->createIndex($name, $table, $columns, $unique))->execute();
}
public function dropIndex($name, $table)
{
@@ -9927,7 +10086,7 @@ abstract class CValidator extends CComponent
public static function createValidator($name,$object,$attributes,$params=array())
{
if(is_string($attributes))
$attributes=preg_split('/[\s,]+/',$attributes,-1,PREG_SPLIT_NO_EMPTY);
$attributes=preg_split('/\s*,\s*/',$attributes,-1,PREG_SPLIT_NO_EMPTY);
if(isset($params['on']))
{
if(is_array($params['on']))

View File

@@ -211,7 +211,7 @@ class CDetailView extends CWidget
if(!isset($attribute['type']))
$attribute['type']='text';
if(isset($attribute['value']))
$value=($attribute['value'] instanceof Closure) ? call_user_func($attribute['value'],$this->data) : $attribute['value'];
$value=is_object($attribute['value']) && get_class($attribute['value']) === 'Closure' ? call_user_func($attribute['value'],$this->data) : $attribute['value'];
elseif(isset($attribute['name']))
$value=CHtml::value($this->data,$attribute['name']);
else