- Yii Debugger
+ 'Back to main debug page']);?>
= $panel->getSummary() ?>
diff --git a/extensions/yii/gii/CHANGELOG.md b/extensions/yii/gii/CHANGELOG.md
index baa33d0..0174387 100644
--- a/extensions/yii/gii/CHANGELOG.md
+++ b/extensions/yii/gii/CHANGELOG.md
@@ -5,6 +5,7 @@ Yii Framework 2 gii extension Change Log
----------------------------
- Bug #1405: fixed disambiguation of relation names generated by gii (qiangxue)
+- Enh #1624: generate rules for unique indexes (lucianobaraglia)
2.0.0 alpha, December 1, 2013
-----------------------------
diff --git a/extensions/yii/jui/SliderInput.php b/extensions/yii/jui/SliderInput.php
index 8a43eb1..20599cf 100644
--- a/extensions/yii/jui/SliderInput.php
+++ b/extensions/yii/jui/SliderInput.php
@@ -15,7 +15,7 @@ use yii\helpers\Html;
* For example,
*
* ```
- * echo Slider::widget([
+ * echo SliderInput::widget([
* 'model' => $model,
* 'attribute' => 'amount',
* 'clientOptions' => [
@@ -28,7 +28,7 @@ use yii\helpers\Html;
* The following example will use the name property instead:
*
* ```
- * echo Slider::widget([
+ * echo SliderInput::widget([
* 'name' => 'amount',
* 'clientOptions' => [
* 'min' => 1,
@@ -75,8 +75,10 @@ class SliderInput extends InputWidget
if ($this->hasModel()) {
echo Html::activeHiddenInput($this->model, $this->attribute, $this->options);
+ $this->clientOptions['value'] = $this->model{$this->attribute};
} else {
echo Html::hiddenInput($this->name, $this->value, $this->options);
+ $this->clientOptions['value'] = $this->value;
}
if (!isset($this->clientEvents['slide'])) {
@@ -86,6 +88,5 @@ class SliderInput extends InputWidget
}
$this->registerWidget('slider', SliderAsset::className(), $this->containerOptions['id']);
- $this->getView()->registerJs('$("#' . $this->options['id'] . '").val($("#' . $this->id . '").slider("value"));');
}
}
diff --git a/extensions/yii/twig/CHANGELOG.md b/extensions/yii/twig/CHANGELOG.md
index 85b09d5..7c9a377 100644
--- a/extensions/yii/twig/CHANGELOG.md
+++ b/extensions/yii/twig/CHANGELOG.md
@@ -4,7 +4,7 @@ Yii Framework 2 twig extension Change Log
2.0.0 beta under development
----------------------------
-- no changes in this release.
+- Add File based Twig loader for better caching and usability of twig's file based function (dev-mraj, samdark)
2.0.0 alpha, December 1, 2013
-----------------------------
diff --git a/extensions/yii/twig/README.md b/extensions/yii/twig/README.md
index 8099e1c..bc04d92 100644
--- a/extensions/yii/twig/README.md
+++ b/extensions/yii/twig/README.md
@@ -15,6 +15,7 @@ return [
'class' => 'yii\twig\ViewRenderer',
//'cachePath' => '@runtime/Twig/cache',
//'options' => [], /* Array of twig options */
+ // ... see ViewRenderer for more options
],
],
],
diff --git a/extensions/yii/twig/TwigSimpleFileLoader.php b/extensions/yii/twig/TwigSimpleFileLoader.php
new file mode 100644
index 0000000..281d465
--- /dev/null
+++ b/extensions/yii/twig/TwigSimpleFileLoader.php
@@ -0,0 +1,74 @@
+
+ */
+class TwigSimpleFileLoader implements \Twig_LoaderInterface
+{
+ /**
+ * @var string Path to directory
+ */
+ private $_dir;
+
+ /**
+ * @param string $dir path to directory
+ */
+ public function __construct($dir)
+ {
+ $this->_dir = $dir;
+ }
+
+ /**
+ * Compare a file's freshness with previously stored timestamp
+ *
+ * @param $name string file name to check
+ * @param $time int timestamp to compare with
+ * @return boolean true if file is still fresh and not changes, false otherwise
+ */
+ public function isFresh($name, $time)
+ {
+ return filemtime($this->getFilePath($name)) <= $time;
+ }
+
+ /**
+ * Get the source of given file name
+ *
+ * @param string $name file name
+ * @return string contents of given file name
+ */
+ public function getSource($name)
+ {
+ return file_get_contents($this->getFilePath($name));
+ }
+
+ /**
+ * Get unique key that can represent this file uniquely among other files.
+ * @param string $name
+ * @return string
+ */
+ public function getCacheKey($name)
+ {
+ return $this->getFilePath($name);
+ }
+
+ /**
+ * internally used to get absolute path of given file name
+ * @param string $name file name
+ * @return string absolute path of file
+ */
+ protected function getFilePath($name){
+ return $this->_dir . '/' . $name;
+ }
+}
\ No newline at end of file
diff --git a/extensions/yii/twig/ViewRenderer.php b/extensions/yii/twig/ViewRenderer.php
index 7483f04..9348c30 100644
--- a/extensions/yii/twig/ViewRenderer.php
+++ b/extensions/yii/twig/ViewRenderer.php
@@ -28,35 +28,102 @@ class ViewRenderer extends BaseViewRenderer
public $cachePath = '@runtime/Twig/cache';
/**
- * @var array extentions list.
- */
- public $extensions = [];
-
- /**
* @var array Twig options
* @see http://twig.sensiolabs.org/doc/api.html#environment-options
*/
public $options = [];
- /**
- * @var \Twig_Environment
+ /**
+ * @var array Objects or static classes
+ * Keys of array are names to call in template, values - objects or names of static class as string
+ * Example: ['html' => '\yii\helpers\Html']
+ * Than in template: {{ html.link('Login', 'site/login') }}
+ */
+ public $globals = [];
+
+ /**
+ * @var array Custom functions
+ * Keys of array are names to call in template, values - names of functions or static methods of some class
+ * Example: ['rot13' => 'str_rot13', 'link' => '\yii\helpers\Html::link']
+ * Than in template: {{ rot13('test') }} or {{ link('Login', 'site/login') }}
+ */
+ public $functions = [];
+
+ /**
+ * @var array Custom filters
+ * Keys of array are names to call in template, values - names of functions or static methods of some class
+ * Example: ['rot13' => 'str_rot13', 'jsonEncode' => '\yii\helpers\Json::encode']
+ * Then in template: {{ 'test'|rot13 }} or {{ model|jsonEncode }}
+ */
+ public $filters = [];
+
+ /**
+ * @var array Custom extensions
+ * Example: ['Twig_Extension_Sandbox', 'Twig_Extension_Text']
+ */
+ public $extensions = [];
+
+ /**
+ * @var array Twig lexer options
+ * @see http://twig.sensiolabs.org/doc/recipes.html#customizing-the-syntax
+ * Example: Smarty-like syntax
+ * array(
+ * 'tag_comment' => ['{*', '*}'],
+ * 'tag_block' => ['{', '}'],
+ * 'tag_variable' => ['{$', '}']
+ * )
+ */
+ public $lexerOptions = [];
+
+ /**
+ * @var \Twig_Environment twig environment object that do all rendering twig templates
*/
public $twig;
public function init()
{
- $loader = new \Twig_Loader_String();
- $this->twig = new \Twig_Environment($loader, array_merge([
+ $this->twig = new \Twig_Environment(null, array_merge([
'cache' => Yii::getAlias($this->cachePath),
+ 'charset' => Yii::$app->charset,
], $this->options));
-
+
+ // Adding custom extensions
if (!empty($this->extensions)) {
foreach ($this->extensions as $extension) {
$this->twig->addExtension(new $extension());
}
}
+ // Adding custom globals (objects or static classes)
+ if (!empty($this->globals)) {
+ $this->addGlobals($this->globals);
+ }
+
+ // Adding custom functions
+ if (!empty($this->functions)) {
+ $this->addFunctions($this->functions);
+ }
+
+ // Adding custom filters
+ if (!empty($this->filters)) {
+ $this->addFilters($this->filters);
+ }
+
+ // Adding custom extensions
+ if (!empty($this->extensions)) {
+ $this->addExtensions($this->extensions);
+ }
+
+ // Change lexer syntax
+ if (!empty($this->lexerOptions)) {
+ $this->setLexerOptions($this->lexerOptions);
+ }
+
+ // Adding global 'void' function (usage: {{void(App.clientScript.registerScriptFile(...))}})
+ $this->twig->addFunction('void', new \Twig_Function_Function(function($argument){
+ }));
+
$this->twig->addFunction('path', new \Twig_Function_Function(function ($path, $args = []) {
return Html::url(array_merge([$path], $args));
}));
@@ -79,6 +146,92 @@ class ViewRenderer extends BaseViewRenderer
public function render($view, $file, $params)
{
$this->twig->addGlobal('this', $view);
- return $this->twig->render(file_get_contents($file), $params);
+ $this->twig->setLoader(new TwigSimpleFileLoader(dirname($file)));
+ return $this->twig->render(pathinfo($file, PATHINFO_BASENAME), $params);
+ }
+
+ /**
+ * Adds global objects or static classes
+ * @param array $globals @see self::$globals
+ */
+ public function addGlobals($globals)
+ {
+ foreach ($globals as $name => $value) {
+ if (!is_object($value)) {
+ $value = new ViewRendererStaticClassProxy($value);
+ }
+ $this->twig->addGlobal($name, $value);
+ }
+ }
+
+ /**
+ * Adds custom functions
+ * @param array $functions @see self::$functions
+ */
+ public function addFunctions($functions)
+ {
+ $this->_addCustom('Function', $functions);
+ }
+
+ /**
+ * Adds custom filters
+ * @param array $filters @see self::$filters
+ */
+ public function addFilters($filters)
+ {
+ $this->_addCustom('Filter', $filters);
+ }
+
+ /**
+ * Adds custom extensions
+ * @param array $extensions @see self::$extensions
+ */
+ public function addExtensions($extensions)
+ {
+ foreach ($extensions as $extName) {
+ $this->twig->addExtension(new $extName());
+ }
+ }
+
+ /**
+ * Sets Twig lexer options to change templates syntax
+ * @param array $options @see self::$lexerOptions
+ */
+ public function setLexerOptions($options)
+ {
+ $lexer = new \Twig_Lexer($this->twig, $options);
+ $this->twig->setLexer($lexer);
+ }
+
+ /**
+ * Adds custom function or filter
+ * @param string $classType 'Function' or 'Filter'
+ * @param array $elements Parameters of elements to add
+ * @throws \Exception
+ */
+ private function _addCustom($classType, $elements)
+ {
+ $classFunction = 'Twig_' . $classType . '_Function';
+
+ foreach ($elements as $name => $func) {
+ $twigElement = null;
+
+ switch ($func) {
+ // Just a name of function
+ case is_string($func):
+ $twigElement = new $classFunction($func);
+ break;
+ // Name of function + options array
+ case is_array($func) && is_string($func[0]) && isset($func[1]) && is_array($func[1]):
+ $twigElement = new $classFunction($func[0], $func[1]);
+ break;
+ }
+
+ if ($twigElement !== null) {
+ $this->twig->{'add'.$classType}($name, $twigElement);
+ } else {
+ throw new \Exception("Incorrect options for \"$classType\" $name.");
+ }
+ }
}
}
diff --git a/extensions/yii/twig/ViewRendererStaticClassProxy.php b/extensions/yii/twig/ViewRendererStaticClassProxy.php
new file mode 100644
index 0000000..3823ce0
--- /dev/null
+++ b/extensions/yii/twig/ViewRendererStaticClassProxy.php
@@ -0,0 +1,43 @@
+
+ */
+class ViewRendererStaticClassProxy
+{
+ private $_staticClassName;
+
+ public function __construct($staticClassName) {
+ $this->_staticClassName = $staticClassName;
+ }
+
+ public function __get($property)
+ {
+ $class = new \ReflectionClass($this->_staticClassName);
+ return $class->getStaticPropertyValue($property);
+ }
+
+ public function __set($property, $value)
+ {
+ $class = new \ReflectionClass($this->_staticClassName);
+ $class->setStaticPropertyValue($property, $value);
+ return $value;
+ }
+
+ public function __call($method, $arguments)
+ {
+ return call_user_func_array(array($this->_staticClassName, $method), $arguments);
+ }
+}
\ No newline at end of file
diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md
index 9126e71..471fcda 100644
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -16,6 +16,7 @@ Yii Framework 2 Change Log
- Bug #1591: StringValidator is accessing undefined property (qiangxue)
- Bug #1597: Added `enableAutoLogin` to basic and advanced application templates so "remember me" now works properly (samdark)
- Bug #1631: Charset is now explicitly set to UTF-8 when serving JSON (samdark)
+- Bug #1635: `yii\jui\SliderInput` wasn't properly initialized (samdark)
- Bug #1686: ActiveForm is creating duplicated messages in error summary (qiangxue)
- Bug: Fixed `Call to a member function registerAssetFiles() on a non-object` in case of wrong `sourcePath` for an asset bundle (samdark)
- Bug: Fixed incorrect event name for `yii\jui\Spinner` (samdark)
@@ -36,12 +37,13 @@ Yii Framework 2 Change Log
- Enh #1581: Added `ActiveQuery::joinWith()` and `ActiveQuery::innerJoinWith()` to support joining with relations (qiangxue)
- Enh #1601: Added support for tagName and encodeLabel parameters in ButtonDropdown (omnilight)
- Enh #1611: Added `BaseActiveRecord::markAttributeDirty()` (qiangxue)
+- Enh #1633: Advanced application template now works with MongoDB by default (samdark)
- Enh #1634: Use masked CSRF tokens to prevent BREACH exploits (qiangxue)
- Enh #1641: Added `BaseActiveRecord::updateAttributes()` (qiangxue)
- Enh #1646: Added postgresql `QueryBuilder::checkIntegrity` and `QueryBuilder::resetSequence` (Ragazzo)
- Enh #1645: Added `Connection::$pdoClass` property (Ragazzo)
- Enh #1681: Added support for automatically adjusting the "for" attribute of label generated by `ActiveField::label()` (qiangxue)
-- Enh: Added `favicon.ico` and `robots.txt` to defauly application templates (samdark)
+- Enh: Added `favicon.ico` and `robots.txt` to default application templates (samdark)
- Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue)
- Enh: Support for file aliases in console command 'message' (omnilight)
- Enh: Sort and Pagination can now create absolute URLs (cebe)