Browse Source
* master: (27 commits) form wip form wip form WIP script WIP Minor change about twig alias. Added Controller::populate(). Added bootstrap. form WIP form wip form wip Refactored UrlManager. refactored AccessControl activeform WIP Removed the $value parameter from radio and checkbox. Support alternative URL rule syntax. Support default standard component class. updated view renderers docs activeform wip Refactored view renderers. updated view renderers docs refactoring activeform. ...tags/2.0.0-beta
Carsten Brandt
12 years ago
36 changed files with 11653 additions and 344 deletions
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 12 KiB |
File diff suppressed because one or more lines are too long
@ -0,0 +1,51 @@
|
||||
<?php |
||||
/** |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace app\models; |
||||
|
||||
use Yii; |
||||
use yii\base\Model; |
||||
|
||||
/** |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class LoginForm extends Model |
||||
{ |
||||
public $username; |
||||
public $password; |
||||
public $rememberMe = true; |
||||
|
||||
public function rules() |
||||
{ |
||||
return array( |
||||
array('username', 'required'), |
||||
array('password', 'required'), |
||||
array('password', 'validatePassword'), |
||||
array('rememberMe', 'boolean'), |
||||
); |
||||
} |
||||
|
||||
public function validatePassword() |
||||
{ |
||||
$user = User::findByUsername($this->username); |
||||
if (!$user || !$user->validatePassword($this->password)) { |
||||
$this->addError('password', 'Incorrect username or password.'); |
||||
} |
||||
} |
||||
|
||||
public function login() |
||||
{ |
||||
if ($this->validate()) { |
||||
$user = User::findByUsername($this->username); |
||||
Yii::$app->getUser()->login($user, $this->rememberMe ? 3600*24*30 : 0); |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,22 @@
|
||||
<?php |
||||
use yii\helpers\Html; |
||||
/** |
||||
* @var yii\base\View $this |
||||
* @var yii\widgets\ActiveForm $form |
||||
* @var app\models\LoginForm $model |
||||
*/ |
||||
?> |
||||
<h1>Login</h1> |
||||
|
||||
<p>Please fill out the following fields to login:</p> |
||||
|
||||
<?php $form = $this->beginWidget('yii\widgets\ActiveForm', array('options' => array('class' => 'form-horizontal'))); ?> |
||||
<?php echo $form->field($model, 'username')->textInput(); ?> |
||||
<?php echo $form->field($model, 'password')->passwordInput(); ?> |
||||
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?> |
||||
<div class="control-group"> |
||||
<div class="controls"> |
||||
<?php echo Html::submitButton('Login', null, null, array('class' => 'btn btn-primary')); ?> |
||||
</div> |
||||
</div> |
||||
<?php $this->endWidget(); ?> |
@ -0,0 +1,51 @@
|
||||
Yii2 view renderers |
||||
=================== |
||||
|
||||
By default Yii uses PHP as template language but you can configure it to be able |
||||
to render templates with special engines such as Twig or Smarty. |
||||
|
||||
The component responsible for rendering a view is called `view`. You can add |
||||
a custom template engines as follows: |
||||
|
||||
```php |
||||
array( |
||||
'components' => array( |
||||
'view' => array( |
||||
'class' => 'yii\base\View', |
||||
'renderers' => array( |
||||
'tpl' => array( |
||||
'class' => 'yii\renderers\SmartyViewRenderer', |
||||
), |
||||
'twig' => array( |
||||
'class' => 'yii\renderers\TwigViewRenderer', |
||||
), |
||||
// ... |
||||
), |
||||
), |
||||
), |
||||
) |
||||
``` |
||||
|
||||
Twig |
||||
---- |
||||
|
||||
In order to use Twig you need to put you templates in files with extension `.twig` |
||||
(or another one if configured differently). |
||||
Also you need to specify this extension explicitly when calling `$this->render()` |
||||
or `$this->renderPartial()` from your controller: |
||||
|
||||
```php |
||||
echo $this->render('renderer.twig', array('username' => 'Alex')); |
||||
``` |
||||
|
||||
Smarty |
||||
------ |
||||
|
||||
In order to use Smarty you need to put you templates in files with extension `.tpl` |
||||
(or another one if configured differently). |
||||
Also you need to specify this extension explicitly when calling `$this->render()` |
||||
or `$this->renderPartial()` from your controller: |
||||
|
||||
```php |
||||
echo $this->render('renderer.tpl', array('username' => 'Alex')); |
||||
``` |
@ -1,5 +1,31 @@
|
||||
<?php |
||||
|
||||
return array( |
||||
'basePath' => __DIR__ . '/web/assets', |
||||
'jquery' => array( |
||||
'sourcePath' => __DIR__ . '/assets', |
||||
'js' => array( |
||||
'jquery.min.js', |
||||
), |
||||
), |
||||
'yii' => array( |
||||
'sourcePath' => __DIR__ . '/assets', |
||||
'js' => array( |
||||
'yii.js', |
||||
), |
||||
'depends' => array('jquery'), |
||||
), |
||||
'yii/validation' => array( |
||||
'sourcePath' => __DIR__ . '/assets', |
||||
'js' => array( |
||||
'yii.validation.js', |
||||
), |
||||
'depends' => array('yii'), |
||||
), |
||||
'yii/form' => array( |
||||
'sourcePath' => __DIR__ . '/assets', |
||||
'js' => array( |
||||
'yii.activeForm.js', |
||||
), |
||||
'depends' => array('yii', 'yii/validation'), |
||||
), |
||||
); |
File diff suppressed because one or more lines are too long
@ -0,0 +1,421 @@
|
||||
/** |
||||
* Yii form widget. |
||||
* |
||||
* This is the JavaScript widget used by the yii\widgets\ActiveForm widget. |
||||
* |
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/
|
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
(function ($) { |
||||
|
||||
$.fn.yiiActiveForm = function (method) { |
||||
if (methods[method]) { |
||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); |
||||
} else if (typeof method === 'object' || !method) { |
||||
return methods.init.apply(this, arguments); |
||||
} else { |
||||
$.error('Method ' + method + ' does not exist on jQuery.yiiActiveForm'); |
||||
return false; |
||||
} |
||||
}; |
||||
|
||||
var defaults = { |
||||
// whether it is waiting for ajax submission result
|
||||
submitting: false |
||||
}; |
||||
|
||||
var methods = { |
||||
/** |
||||
* Initializes the plugin. |
||||
* @param attributes array attribute configurations. Each attribute may contain the following options: |
||||
* |
||||
* - id: 'ModelClass_attribute', // the unique attribute ID
|
||||
* - model: 'ModelClass', // the model class name
|
||||
* - name: 'name', // attribute name
|
||||
* - inputID: 'input-tag-id', |
||||
* - errorID: 'error-tag-id', |
||||
* - value: undefined, |
||||
* - status: 0, // 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating
|
||||
* - validationDelay: 200, |
||||
* - validateOnChange: true, |
||||
* - validateOnType: false, |
||||
* - hideErrorMessage: false, |
||||
* - inputContainer: undefined, |
||||
* - errorCssClass: 'error', |
||||
* - successCssClass: 'success', |
||||
* - validatingCssClass: 'validating', |
||||
* - enableAjaxValidation: true, |
||||
* - enableClientValidation: true, |
||||
* - clientValidation: undefined, // function (value, messages, attribute) | client-side validation
|
||||
* - beforeValidateAttribute: undefined, // function (form, attribute) | boolean
|
||||
* - afterValidateAttribute: undefined, // function (form, attribute, data, hasError)
|
||||
* |
||||
* @param options object the configuration for the plugin. The following options can be set: |
||||
*/ |
||||
init: function (attributes, options) { |
||||
return this.each(function () { |
||||
var $form = $(this); |
||||
if ($form.data('yiiActiveForm')) { |
||||
return; |
||||
} |
||||
|
||||
var settings = $.extend(defaults, options || {}); |
||||
if (settings.validationUrl === undefined) { |
||||
settings.validationUrl = $form.attr('action'); |
||||
} |
||||
$.each(attributes, function (i) { |
||||
this.value = getInputValue($form.find('#' + this.inputID)); |
||||
attributes[i] = $.extend(settings, this); |
||||
}); |
||||
$form.data('yiiActiveForm', { |
||||
settings: settings, |
||||
attributes: attributes |
||||
}); |
||||
|
||||
bindAttributes(attributes); |
||||
|
||||
$form.bind('reset', resetForm); |
||||
|
||||
if (settings.validateOnSubmit) { |
||||
$form.on('mouseup keyup', ':submit', function () { |
||||
$form.data('submitObject', $(this)); |
||||
}); |
||||
var validated = false; |
||||
$form.submit(function () { |
||||
if (validated) { |
||||
validated = false; |
||||
return true; |
||||
} |
||||
if (settings.timer !== undefined) { |
||||
clearTimeout(settings.timer); |
||||
} |
||||
settings.submitting = true; |
||||
if (settings.beforeValidate === undefined || settings.beforeValidate($form)) { |
||||
$.fn.yiiactiveform.validate($form, function (data) { |
||||
var hasError = false; |
||||
$.each(settings.attributes, function () { |
||||
hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; |
||||
}); |
||||
$.fn.yiiactiveform.updateSummary($form, data); |
||||
if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) { |
||||
if (!hasError) { |
||||
validated = true; |
||||
var $button = $form.data('submitObject') || $form.find(':submit:first'); |
||||
// TODO: if the submission is caused by "change" event, it will not work
|
||||
if ($button.length) { |
||||
$button.click(); |
||||
} else { // no submit button in the form
|
||||
$form.submit(); |
||||
} |
||||
return; |
||||
} |
||||
} |
||||
settings.submitting = false; |
||||
}); |
||||
} else { |
||||
settings.submitting = false; |
||||
} |
||||
return false; |
||||
}); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
destroy: function () { |
||||
return this.each(function () { |
||||
$(window).unbind('.yiiActiveForm'); |
||||
$(this).removeData('yiiActiveForm'); |
||||
}) |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* Returns the value of the specified input element. |
||||
* This method will perform additional checks to get proper values |
||||
* for checkbox, radio, checkbox list and radio list. |
||||
* @param $e jQuery the jQuery object of the input element |
||||
* @return string the input value |
||||
*/ |
||||
var getInputValue = function ($e) { |
||||
var type, |
||||
c = []; |
||||
if (!$e.length) { |
||||
return undefined; |
||||
} |
||||
if ($e[0].tagName.toLowerCase() === 'div') { |
||||
$e.find(':checked').each(function () { |
||||
c.push(this.value); |
||||
}); |
||||
return c.join(','); |
||||
} |
||||
type = $e.attr('type'); |
||||
if (type === 'checkbox' || type === 'radio') { |
||||
return $e.filter(':checked').val(); |
||||
} else { |
||||
return $e.val(); |
||||
} |
||||
}; |
||||
|
||||
var bindAttributes = function (attributes) { |
||||
$.each(attributes, function (i, attribute) { |
||||
if (this.validateOnChange) { |
||||
$form.find('#' + this.inputID).change(function () { |
||||
validateAttribute(attribute, false); |
||||
}).blur(function () { |
||||
if (attribute.status !== 2 && attribute.status !== 3) { |
||||
validateAttribute(attribute, !attribute.status); |
||||
} |
||||
}); |
||||
} |
||||
if (this.validateOnType) { |
||||
$form.find('#' + this.inputID).keyup(function () { |
||||
if (attribute.value !== getAFValue($(this))) { |
||||
validateAttribute(attribute, false); |
||||
} |
||||
}); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* Performs the ajax validation request. |
||||
* This method is invoked internally to trigger the ajax validation. |
||||
* @param form jquery the jquery representation of the form |
||||
* @param successCallback function the function to be invoked if the ajax request succeeds |
||||
* @param errorCallback function the function to be invoked if the ajax request fails |
||||
*/ |
||||
var validateForm = function (form, successCallback, errorCallback) { |
||||
var $form = $(form), |
||||
settings = $form.data('settings'), |
||||
needAjaxValidation = false, |
||||
messages = {}; |
||||
$.each(settings.attributes, function () { |
||||
var value, |
||||
msg = []; |
||||
if (this.clientValidation !== undefined && (settings.submitting || this.status === 2 || this.status === 3)) { |
||||
value = getInputValue($form.find('#' + this.inputID)); |
||||
this.clientValidation(value, msg, this); |
||||
if (msg.length) { |
||||
messages[this.id] = msg; |
||||
} |
||||
} |
||||
if (this.enableAjaxValidation && !msg.length && (settings.submitting || this.status === 2 || this.status === 3)) { |
||||
needAjaxValidation = true; |
||||
} |
||||
}); |
||||
|
||||
if (!needAjaxValidation || settings.submitting && !$.isEmptyObject(messages)) { |
||||
if (settings.submitting) { |
||||
// delay callback so that the form can be submitted without problem
|
||||
setTimeout(function () { |
||||
successCallback(messages); |
||||
}, 200); |
||||
} else { |
||||
successCallback(messages); |
||||
} |
||||
return; |
||||
} |
||||
|
||||
var $button = $form.data('submitObject'), |
||||
extData = '&' + settings.ajaxVar + '=' + $form.attr('id'); |
||||
if ($button && $button.length) { |
||||
extData += '&' + $button.attr('name') + '=' + $button.attr('value'); |
||||
} |
||||
|
||||
$.ajax({ |
||||
url: settings.validationUrl, |
||||
type: $form.attr('method'), |
||||
data: $form.serialize() + extData, |
||||
dataType: 'json', |
||||
success: function (data) { |
||||
if (data !== null && typeof data === 'object') { |
||||
$.each(settings.attributes, function () { |
||||
if (!this.enableAjaxValidation) { |
||||
delete data[this.id]; |
||||
} |
||||
}); |
||||
successCallback($.extend({}, messages, data)); |
||||
} else { |
||||
successCallback(messages); |
||||
} |
||||
}, |
||||
error: function () { |
||||
if (errorCallback !== undefined) { |
||||
errorCallback(); |
||||
} |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
var validateAttribute = function (attribute, forceValidate) { |
||||
if (forceValidate) { |
||||
attribute.status = 2; |
||||
} |
||||
$.each(attributes, function () { |
||||
if (this.value !== getInputValue($form.find('#' + this.inputID))) { |
||||
this.status = 2; |
||||
forceValidate = true; |
||||
} |
||||
}); |
||||
if (!forceValidate) { |
||||
return; |
||||
} |
||||
|
||||
if (settings.timer !== undefined) { |
||||
clearTimeout(settings.timer); |
||||
} |
||||
settings.timer = setTimeout(function () { |
||||
if (settings.submitting || $form.is(':hidden')) { |
||||
return; |
||||
} |
||||
if (attribute.beforeValidateAttribute === undefined || attribute.beforeValidateAttribute($form, attribute)) { |
||||
$.each(settings.attributes, function () { |
||||
if (this.status === 2) { |
||||
this.status = 3; |
||||
$.fn.yiiactiveform.getInputContainer(this, $form).addClass(this.validatingCssClass); |
||||
} |
||||
}); |
||||
$.fn.yiiactiveform.validate($form, function (data) { |
||||
var hasError = false; |
||||
$.each(settings.attributes, function () { |
||||
if (this.status === 2 || this.status === 3) { |
||||
hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; |
||||
} |
||||
}); |
||||
if (attribute.afterValidateAttribute !== undefined) { |
||||
attribute.afterValidateAttribute($form, attribute, data, hasError); |
||||
} |
||||
}); |
||||
} |
||||
}, attribute.validationDelay); |
||||
}; |
||||
|
||||
var resetForm = function () { |
||||
/* |
||||
* In case of resetting the form we need to reset error messages |
||||
* NOTE1: $form.reset - does not exist |
||||
* NOTE2: $form.on('reset', ...) does not work |
||||
*/ |
||||
/* |
||||
* because we bind directly to a form reset event, not to a reset button (that could or could not exist), |
||||
* when this function is executed form elements values have not been reset yet, |
||||
* because of that we use the setTimeout |
||||
*/ |
||||
setTimeout(function () { |
||||
$.each(settings.attributes, function () { |
||||
this.status = 0; |
||||
var $error = $form.find('#' + this.errorID), |
||||
$container = $.fn.yiiactiveform.getInputContainer(this, $form); |
||||
|
||||
$container.removeClass( |
||||
this.validatingCssClass + ' ' + |
||||
this.errorCssClass + ' ' + |
||||
this.successCssClass |
||||
); |
||||
|
||||
$error.html('').hide(); |
||||
|
||||
/* |
||||
* without the setTimeout() we would get here the current entered value before the reset instead of the reseted value |
||||
*/ |
||||
this.value = getAFValue($form.find('#' + this.inputID)); |
||||
}); |
||||
/* |
||||
* If the form is submited (non ajax) with errors, labels and input gets the class 'error' |
||||
*/ |
||||
$form.find('label, input').each(function () { |
||||
$(this).removeClass(settings.errorCss); |
||||
}); |
||||
$('#' + settings.summaryID).hide().find('ul').html(''); |
||||
//.. set to initial focus on reset
|
||||
if (settings.focus !== undefined && !window.location.hash) { |
||||
$form.find(settings.focus).focus(); |
||||
} |
||||
}, 1); |
||||
}; |
||||
|
||||
|
||||
/** |
||||
* Returns the container element of the specified attribute. |
||||
* @param attribute object the configuration for a particular attribute. |
||||
* @param form the form jQuery object |
||||
* @return jQuery the jQuery representation of the container |
||||
*/ |
||||
var getInputContainer = function (attribute, form) { |
||||
if (attribute.inputContainer === undefined) { |
||||
return form.find('#' + attribute.inputID).closest('div'); |
||||
} else { |
||||
return form.find(attribute.inputContainer).filter(':has("#' + attribute.inputID + '")'); |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* updates the error message and the input container for a particular attribute. |
||||
* @param attribute object the configuration for a particular attribute. |
||||
* @param messages array the json data obtained from the ajax validation request |
||||
* @param form the form jQuery object |
||||
* @return boolean whether there is a validation error for the specified attribute |
||||
*/ |
||||
var updateInput = function (attribute, messages, form) { |
||||
attribute.status = 1; |
||||
var $error, $container, |
||||
hasError = false, |
||||
$el = form.find('#' + attribute.inputID), |
||||
errorCss = form.data('settings').errorCss; |
||||
|
||||
if ($el.length) { |
||||
hasError = messages !== null && $.isArray(messages[attribute.id]) && messages[attribute.id].length > 0; |
||||
$error = form.find('#' + attribute.errorID); |
||||
$container = $.fn.yiiactiveform.getInputContainer(attribute, form); |
||||
|
||||
$container.removeClass( |
||||
attribute.validatingCssClass + ' ' + |
||||
attribute.errorCssClass + ' ' + |
||||
attribute.successCssClass |
||||
); |
||||
$container.find('label, input').each(function () { |
||||
$(this).removeClass(errorCss); |
||||
}); |
||||
|
||||
if (hasError) { |
||||
$error.html(messages[attribute.id][0]); |
||||
$container.addClass(attribute.errorCssClass); |
||||
} else if (attribute.enableAjaxValidation || attribute.clientValidation) { |
||||
$container.addClass(attribute.successCssClass); |
||||
} |
||||
if (!attribute.hideErrorMessage) { |
||||
$error.toggle(hasError); |
||||
} |
||||
|
||||
attribute.value = getAFValue($el); |
||||
} |
||||
return hasError; |
||||
}; |
||||
|
||||
/** |
||||
* updates the error summary, if any. |
||||
* @param form jquery the jquery representation of the form |
||||
* @param messages array the json data obtained from the ajax validation request |
||||
*/ |
||||
var updateSummary = function (form, messages) { |
||||
var settings = $(form).data('settings'), |
||||
content = ''; |
||||
if (settings.summaryID === undefined) { |
||||
return; |
||||
} |
||||
if (messages) { |
||||
$.each(settings.attributes, function () { |
||||
if ($.isArray(messages[this.id])) { |
||||
$.each(messages[this.id], function (j, message) { |
||||
content = content + '<li>' + message + '</li>'; |
||||
}); |
||||
} |
||||
}); |
||||
} |
||||
$('#' + settings.summaryID).toggle(content !== '').find('ul').html(content); |
||||
}; |
||||
|
||||
})(window.jQuery); |
@ -0,0 +1,30 @@
|
||||
/** |
||||
* Yii JavaScript module. |
||||
* |
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/
|
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
yii = (function ($) { |
||||
var pub = { |
||||
version: '2.0' |
||||
}; |
||||
return pub; |
||||
})(jQuery); |
||||
|
||||
jQuery(document).ready(function ($) { |
||||
// call the init() method of every module
|
||||
var init = function (module) { |
||||
if ($.isFunction(module.init) && (module.trigger == undefined || $(module.trigger).length)) { |
||||
module.init(); |
||||
} |
||||
$.each(module, function () { |
||||
if ($.isPlainObject(this)) { |
||||
init(this); |
||||
} |
||||
}); |
||||
}; |
||||
init(yii); |
||||
}); |
@ -0,0 +1,17 @@
|
||||
/** |
||||
* Yii validation module. |
||||
* |
||||
* This is the JavaScript widget used by the yii\widgets\ActiveForm widget. |
||||
* |
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/
|
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
|
||||
yii.validation = (function ($) { |
||||
var pub = { |
||||
}; |
||||
return pub; |
||||
})(jQuery); |
@ -0,0 +1,72 @@
|
||||
<?php |
||||
/** |
||||
* Smarty view renderer class file. |
||||
* |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\renderers; |
||||
|
||||
use Yii; |
||||
use Smarty; |
||||
use yii\base\View; |
||||
use yii\base\ViewRenderer; |
||||
|
||||
/** |
||||
* SmartyViewRenderer allows you to use Smarty templates in views. |
||||
* |
||||
* @author Alexander Makarov <sam@rmcreative.ru> |
||||
* @since 2.0 |
||||
*/ |
||||
class SmartyViewRenderer extends ViewRenderer |
||||
{ |
||||
/** |
||||
* @var string the directory or path alias pointing to where Smarty code is located. |
||||
*/ |
||||
public $smartyPath = '@app/vendors/Smarty'; |
||||
|
||||
/** |
||||
* @var string the directory or path alias pointing to where Smarty cache will be stored. |
||||
*/ |
||||
public $cachePath = '@app/runtime/Smarty/cache'; |
||||
|
||||
/** |
||||
* @var string the directory or path alias pointing to where Smarty compiled templates will be stored. |
||||
*/ |
||||
public $compilePath = '@app/runtime/Smarty/compile'; |
||||
|
||||
/** |
||||
* @var Smarty |
||||
*/ |
||||
public $smarty; |
||||
|
||||
public function init() |
||||
{ |
||||
require_once(Yii::getAlias($this->smartyPath) . '/Smarty.class.php'); |
||||
$this->smarty = new Smarty(); |
||||
$this->smarty->setCompileDir(Yii::getAlias($this->compilePath)); |
||||
$this->smarty->setCacheDir(Yii::getAlias($this->cachePath)); |
||||
} |
||||
|
||||
/** |
||||
* Renders a view file. |
||||
* |
||||
* This method is invoked by [[View]] whenever it tries to render a view. |
||||
* Child classes must implement this method to render the given view file. |
||||
* |
||||
* @param View $view the view object used for rendering the file. |
||||
* @param string $file the view file. |
||||
* @param array $params the parameters to be passed to the view file. |
||||
* |
||||
* @return string the rendering result |
||||
*/ |
||||
public function render($view, $file, $params) |
||||
{ |
||||
$ext = pathinfo($file, PATHINFO_EXTENSION); |
||||
/** @var \Smarty_Internal_Template $template */ |
||||
$template = $this->smarty->createTemplate($file, null, null, $params, true); |
||||
return $template->fetch(); |
||||
} |
||||
} |
@ -0,0 +1,74 @@
|
||||
<?php |
||||
/** |
||||
* Twig view renderer class file. |
||||
* |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\renderers; |
||||
|
||||
use Yii; |
||||
use yii\base\View; |
||||
use yii\base\ViewRenderer; |
||||
|
||||
/** |
||||
* TwigViewRenderer allows you to use Twig templates in views. |
||||
* |
||||
* @author Alexander Makarov <sam@rmcreative.ru> |
||||
* @since 2.0 |
||||
*/ |
||||
class TwigViewRenderer extends ViewRenderer |
||||
{ |
||||
/** |
||||
* @var string the directory or path alias pointing to where Twig code is located. |
||||
*/ |
||||
public $twigPath = '@Twig'; |
||||
|
||||
/** |
||||
* @var string the directory or path alias pointing to where Twig cache will be stored. |
||||
*/ |
||||
public $cachePath = '@app/runtime/Twig/cache'; |
||||
|
||||
/** |
||||
* @var array Twig options |
||||
* @see http://twig.sensiolabs.org/doc/api.html#environment-options |
||||
*/ |
||||
public $options = array(); |
||||
|
||||
/** |
||||
* @var \Twig_Environment |
||||
*/ |
||||
public $twig; |
||||
|
||||
public function init() |
||||
{ |
||||
if (!isset(Yii::$aliases['@Twig'])) { |
||||
Yii::setAlias('@Twig', $this->twigPath); |
||||
} |
||||
|
||||
$loader = new \Twig_Loader_String(); |
||||
|
||||
$this->twig = new \Twig_Environment($loader, array_merge(array( |
||||
'cache' => Yii::getAlias($this->cachePath), |
||||
), $this->options)); |
||||
} |
||||
|
||||
/** |
||||
* Renders a view file. |
||||
* |
||||
* This method is invoked by [[View]] whenever it tries to render a view. |
||||
* Child classes must implement this method to render the given view file. |
||||
* |
||||
* @param View $view the view object used for rendering the file. |
||||
* @param string $file the view file. |
||||
* @param array $params the parameters to be passed to the view file. |
||||
* |
||||
* @return string the rendering result |
||||
*/ |
||||
public function render($view, $file, $params) |
||||
{ |
||||
return $this->twig->render(file_get_contents($file), $params); |
||||
} |
||||
} |
@ -0,0 +1,407 @@
|
||||
<?php |
||||
/** |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright (c) 2008 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\widgets; |
||||
|
||||
use yii\base\Component; |
||||
use yii\helpers\Html; |
||||
use yii\base\Model; |
||||
|
||||
/** |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class ActiveField extends Component |
||||
{ |
||||
/** |
||||
* @var ActiveForm the form that this field is associated with. |
||||
*/ |
||||
public $form; |
||||
/** |
||||
* @var Model the data model that this field is associated with |
||||
*/ |
||||
public $model; |
||||
/** |
||||
* @var string the model attribute that this field is associated with |
||||
*/ |
||||
public $attribute; |
||||
/** |
||||
* @var string the tag name for the field container. |
||||
*/ |
||||
public $tag = 'div'; |
||||
/** |
||||
* @var array the HTML attributes (name-value pairs) for the field container tag. |
||||
* The values will be HTML-encoded using [[Html::encode()]]. |
||||
* If a value is null, the corresponding attribute will not be rendered. |
||||
*/ |
||||
public $options = array( |
||||
'class' => 'control-group', |
||||
); |
||||
/** |
||||
* @var string the template that is used to arrange the label, the input and the error message. |
||||
* The following tokens will be replaced when [[render()]] is called: `{label}`, `{input}` and `{error}`. |
||||
*/ |
||||
public $template = "{label}\n<div class=\"controls\">\n{input}\n{error}\n</div>"; |
||||
/** |
||||
* @var array the default options for the error message. This property is used when calling [[error()]] |
||||
* without the `$options` parameter. |
||||
*/ |
||||
public $errorOptions = array('tag' => 'span', 'class' => 'help-inline'); |
||||
/** |
||||
* @var array the default options for the label. This property is used when calling [[label()]] |
||||
* without the `$options` parameter. |
||||
*/ |
||||
public $labelOptions = array('class' => 'control-label'); |
||||
|
||||
|
||||
public function begin() |
||||
{ |
||||
$options = $this->options; |
||||
$class = isset($options['class']) ? array($options['class']) : array(); |
||||
$class[] = 'field-' . Html::getInputId($this->model, $this->attribute); |
||||
if ($this->model->isAttributeRequired($this->attribute)) { |
||||
$class[] = $this->form->requiredCssClass; |
||||
} |
||||
if ($this->model->hasErrors($this->attribute)) { |
||||
$class[] = $this->form->errorCssClass; |
||||
} |
||||
$options['class'] = implode(' ', $class); |
||||
return Html::beginTag($this->tag, $options); |
||||
} |
||||
|
||||
public function end() |
||||
{ |
||||
return Html::endTag($this->tag); |
||||
} |
||||
|
||||
/** |
||||
* Generates a label tag for [[attribute]]. |
||||
* The label text is the label associated with the attribute, obtained via [[Model::getAttributeLabel()]]. |
||||
* @param array $options the tag options in terms of name-value pairs. If this is null, [[labelOptions]] will be used. |
||||
* The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded |
||||
* using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. |
||||
* |
||||
* The following options are specially handled: |
||||
* |
||||
* - label: this specifies the label to be displayed. Note that this will NOT be [[encoded()]]. |
||||
* If this is not set, [[Model::getAttributeLabel()]] will be called to get the label for display |
||||
* (after encoding). |
||||
* |
||||
* @return string the generated label tag |
||||
*/ |
||||
public function label($options = null) |
||||
{ |
||||
if ($options === null) { |
||||
$options = $this->labelOptions; |
||||
} |
||||
return Html::activeLabel($this->model, $this->attribute, $options); |
||||
} |
||||
|
||||
/** |
||||
* Generates a tag that contains the first validation error of [[attribute]]. |
||||
* If there is no validation, the tag will be returned and styled as hidden. |
||||
* @param array $options the tag options in terms of name-value pairs. If this is null, [[errorOptions]] will be used. |
||||
* The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded |
||||
* using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. |
||||
* |
||||
* The following options are specially handled: |
||||
* |
||||
* - tag: this specifies the tag name. If not set, "span" will be used. |
||||
* |
||||
* @return string the generated label tag |
||||
*/ |
||||
public function error($options = null) |
||||
{ |
||||
if ($options === null) { |
||||
$options = $this->errorOptions; |
||||
} |
||||
$attribute = Html::getAttributeName($this->attribute); |
||||
$error = $this->model->getFirstError($attribute); |
||||
if ($error === null) { |
||||
$options['style'] = isset($options['style']) ? rtrim($options['style'], ';') . '; display:none' : 'display:none'; |
||||
} |
||||
$tag = isset($options['tag']) ? $options['tag'] : 'span'; |
||||
unset($options['tag']); |
||||
return Html::tag($tag, Html::encode($error), $options); |
||||
} |
||||
|
||||
/** |
||||
* Renders the field with the given input HTML. |
||||
* This method will generate the label and error tags, and return them together with the given |
||||
* input HTML according to [[template]]. |
||||
* @param string $input the input HTML |
||||
* @return string the rendering result |
||||
*/ |
||||
public function render($input) |
||||
{ |
||||
return $this->begin() . "\n" . strtr($this->template, array( |
||||
'{input}' => $input, |
||||
'{label}' => $this->label(), |
||||
'{error}' => $this->error(), |
||||
)) . "\n" . $this->end(); |
||||
} |
||||
|
||||
/** |
||||
* Generates an input tag for the given model attribute. |
||||
* @param string $type the input type (e.g. 'text', 'password') |
||||
* @param array $options the tag options in terms of name-value pairs. These will be rendered as |
||||
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. |
||||
* @return string the generated input tag |
||||
*/ |
||||
public function input($type, $options = array()) |
||||
{ |
||||
return $this->render(Html::activeInput($type, $this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a text input tag for the given model attribute. |
||||
* This method will generate the "name" and "value" tag attributes automatically for the model attribute |
||||
* unless they are explicitly specified in `$options`. |
||||
* @param array $options the tag options in terms of name-value pairs. These will be rendered as |
||||
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. |
||||
* @return string the generated input tag |
||||
*/ |
||||
public function textInput($options = array()) |
||||
{ |
||||
return $this->render(Html::activeTextInput($this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a hidden input tag for the given model attribute. |
||||
* This method will generate the "name" and "value" tag attributes automatically for the model attribute |
||||
* unless they are explicitly specified in `$options`. |
||||
* @param array $options the tag options in terms of name-value pairs. These will be rendered as |
||||
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. |
||||
* @return string the generated input tag |
||||
*/ |
||||
public function hiddenInput($options = array()) |
||||
{ |
||||
return $this->render(Html::activeHiddenInput($this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a password input tag for the given model attribute. |
||||
* This method will generate the "name" and "value" tag attributes automatically for the model attribute |
||||
* unless they are explicitly specified in `$options`. |
||||
* @param array $options the tag options in terms of name-value pairs. These will be rendered as |
||||
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. |
||||
* @return string the generated input tag |
||||
*/ |
||||
public function passwordInput($options = array()) |
||||
{ |
||||
return $this->render(Html::activePasswordInput($this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a file input tag for the given model attribute. |
||||
* This method will generate the "name" and "value" tag attributes automatically for the model attribute |
||||
* unless they are explicitly specified in `$options`. |
||||
* @param array $options the tag options in terms of name-value pairs. These will be rendered as |
||||
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. |
||||
* @return string the generated input tag |
||||
*/ |
||||
public function fileInput($options = array()) |
||||
{ |
||||
return $this->render(Html::activeFileInput($this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a textarea tag for the given model attribute. |
||||
* The model attribute value will be used as the content in the textarea. |
||||
* @param array $options the tag options in terms of name-value pairs. These will be rendered as |
||||
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]]. |
||||
* @return string the generated textarea tag |
||||
*/ |
||||
public function textarea($options = array()) |
||||
{ |
||||
return $this->render(Html::activeTextarea($this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a radio button tag for the given model attribute. |
||||
* This method will generate the "name" tag attribute automatically unless it is explicitly specified in `$options`. |
||||
* This method will generate the "checked" tag attribute according to the model attribute value. |
||||
* @param array $options the tag options in terms of name-value pairs. The following options are specially handled: |
||||
* |
||||
* - uncheck: string, the value associated with the uncheck state of the radio button. If not set, |
||||
* it will take the default value '0'. This method will render a hidden input so that if the radio button |
||||
* is not checked and is submitted, the value of this attribute will still be submitted to the server |
||||
* via the hidden input. |
||||
* |
||||
* The rest of the options will be rendered as the attributes of the resulting tag. The values will |
||||
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. |
||||
* @return string the generated radio button tag |
||||
*/ |
||||
public function radio($options = array()) |
||||
{ |
||||
return $this->render(Html::activeRadio($this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a checkbox tag for the given model attribute. |
||||
* This method will generate the "name" tag attribute automatically unless it is explicitly specified in `$options`. |
||||
* This method will generate the "checked" tag attribute according to the model attribute value. |
||||
* @param array $options the tag options in terms of name-value pairs. The following options are specially handled: |
||||
* |
||||
* - uncheck: string, the value associated with the uncheck state of the radio button. If not set, |
||||
* it will take the default value '0'. This method will render a hidden input so that if the radio button |
||||
* is not checked and is submitted, the value of this attribute will still be submitted to the server |
||||
* via the hidden input. |
||||
* |
||||
* The rest of the options will be rendered as the attributes of the resulting tag. The values will |
||||
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. |
||||
* @return string the generated checkbox tag |
||||
*/ |
||||
public function checkbox($options = array()) |
||||
{ |
||||
return $this->render(Html::activeCheckbox($this->model, $this->attribute, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a drop-down list for the given model attribute. |
||||
* The selection of the drop-down list is taken from the value of the model attribute. |
||||
* @param array $items the option data items. The array keys are option values, and the array values |
||||
* are the corresponding option labels. The array can also be nested (i.e. some array values are arrays too). |
||||
* For each sub-array, an option group will be generated whose label is the key associated with the sub-array. |
||||
* If you have a list of data models, you may convert them into the format described above using |
||||
* [[\yii\helpers\ArrayHelper::map()]]. |
||||
* |
||||
* Note, the values and labels will be automatically HTML-encoded by this method, and the blank spaces in |
||||
* the labels will also be HTML-encoded. |
||||
* @param array $options the tag options in terms of name-value pairs. The following options are specially handled: |
||||
* |
||||
* - prompt: string, a prompt text to be displayed as the first option; |
||||
* - options: array, the attributes for the select option tags. The array keys must be valid option values, |
||||
* and the array values are the extra attributes for the corresponding option tags. For example, |
||||
* |
||||
* ~~~ |
||||
* array( |
||||
* 'value1' => array('disabled' => true), |
||||
* 'value2' => array('label' => 'value 2'), |
||||
* ); |
||||
* ~~~ |
||||
* |
||||
* - groups: array, the attributes for the optgroup tags. The structure of this is similar to that of 'options', |
||||
* except that the array keys represent the optgroup labels specified in $items. |
||||
* |
||||
* The rest of the options will be rendered as the attributes of the resulting tag. The values will |
||||
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. |
||||
* |
||||
* @return string the generated drop-down list tag |
||||
*/ |
||||
public function dropDownList($items, $options = array()) |
||||
{ |
||||
return $this->render(Html::activeDropDownList($this->model, $this->attribute, $items, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a list box. |
||||
* The selection of the list box is taken from the value of the model attribute. |
||||
* @param array $items the option data items. The array keys are option values, and the array values |
||||
* are the corresponding option labels. The array can also be nested (i.e. some array values are arrays too). |
||||
* For each sub-array, an option group will be generated whose label is the key associated with the sub-array. |
||||
* If you have a list of data models, you may convert them into the format described above using |
||||
* [[\yii\helpers\ArrayHelper::map()]]. |
||||
* |
||||
* Note, the values and labels will be automatically HTML-encoded by this method, and the blank spaces in |
||||
* the labels will also be HTML-encoded. |
||||
* @param array $options the tag options in terms of name-value pairs. The following options are specially handled: |
||||
* |
||||
* - prompt: string, a prompt text to be displayed as the first option; |
||||
* - options: array, the attributes for the select option tags. The array keys must be valid option values, |
||||
* and the array values are the extra attributes for the corresponding option tags. For example, |
||||
* |
||||
* ~~~ |
||||
* array( |
||||
* 'value1' => array('disabled' => true), |
||||
* 'value2' => array('label' => 'value 2'), |
||||
* ); |
||||
* ~~~ |
||||
* |
||||
* - groups: array, the attributes for the optgroup tags. The structure of this is similar to that of 'options', |
||||
* except that the array keys represent the optgroup labels specified in $items. |
||||
* - unselect: string, the value that will be submitted when no option is selected. |
||||
* When this attribute is set, a hidden field will be generated so that if no option is selected in multiple |
||||
* mode, we can still obtain the posted unselect value. |
||||
* |
||||
* The rest of the options will be rendered as the attributes of the resulting tag. The values will |
||||
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered. |
||||
* |
||||
* @return string the generated list box tag |
||||
*/ |
||||
public function listBox($items, $options = array()) |
||||
{ |
||||
return $this->render(Html::activeListBox($this->model, $this->attribute, $items, $options)); |
||||
} |
||||
|
||||
/** |
||||
* Generates a list of checkboxes. |
||||
* A checkbox list allows multiple selection, like [[listBox()]]. |
||||
* As a result, the corresponding submitted value is an array. |
||||
* The selection of the checkbox list is taken from the value of the model attribute. |
||||
* @param array $items the data item used to generate the checkboxes. |
||||
* The array keys are the labels, while the array values are the corresponding checkbox values. |
||||
* Note that the labels will NOT be HTML-encoded, while the values will. |
||||
* @param array $options options (name => config) for the checkbox list. The following options are specially handled: |
||||
* |
||||
* - unselect: string, the value that should be submitted when none of the checkboxes is selected. |
||||
* By setting this option, a hidden input will be generated. |
||||
* - separator: string, the HTML code that separates items. |
||||
* - item: callable, a callback that can be used to customize the generation of the HTML code |
||||
* corresponding to a single item in $items. The signature of this callback must be: |
||||
* |
||||
* ~~~ |
||||
* function ($index, $label, $name, $checked, $value) |
||||
* ~~~ |
||||
* |
||||
* where $index is the zero-based index of the checkbox in the whole list; $label |
||||
* is the label for the checkbox; and $name, $value and $checked represent the name, |
||||
* value and the checked status of the checkbox input. |
||||
* @return string the generated checkbox list |
||||
*/ |
||||
public function checkboxList($items, $options = array()) |
||||
{ |
||||
return $this->render( |
||||
'<div id="' . Html::getInputId($this->model, $this->attribute) . '">' |
||||
. Html::activeCheckboxList($this->model, $this->attribute, $items, $options) |
||||
. '</div>' |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Generates a list of radio buttons. |
||||
* A radio button list is like a checkbox list, except that it only allows single selection. |
||||
* The selection of the radio buttons is taken from the value of the model attribute. |
||||
* @param array $items the data item used to generate the radio buttons. |
||||
* The array keys are the labels, while the array values are the corresponding radio button values. |
||||
* Note that the labels will NOT be HTML-encoded, while the values will. |
||||
* @param array $options options (name => config) for the radio button list. The following options are specially handled: |
||||
* |
||||
* - unselect: string, the value that should be submitted when none of the radio buttons is selected. |
||||
* By setting this option, a hidden input will be generated. |
||||
* - separator: string, the HTML code that separates items. |
||||
* - item: callable, a callback that can be used to customize the generation of the HTML code |
||||
* corresponding to a single item in $items. The signature of this callback must be: |
||||
* |
||||
* ~~~ |
||||
* function ($index, $label, $name, $checked, $value) |
||||
* ~~~ |
||||
* |
||||
* where $index is the zero-based index of the radio button in the whole list; $label |
||||
* is the label for the radio button; and $name, $value and $checked represent the name, |
||||
* value and the checked status of the radio button input. |
||||
* @return string the generated radio button list |
||||
*/ |
||||
public function radioList($items, $options = array()) |
||||
{ |
||||
return $this->render( |
||||
'<div id="' . Html::getInputId($this->model, $this->attribute) . '">' |
||||
. Html::activeRadioList($this->model, $this->attribute, $items, $options) |
||||
. '</div>' |
||||
); |
||||
} |
||||
} |
Loading…
Reference in new issue