├── .scrutinizer.yml ├── .styleci.yml ├── .travis.yml ├── LICENSE.md ├── Module.php ├── README.md ├── SettingsAction.php ├── components └── Settings.php ├── composer.json ├── controllers └── DefaultController.php ├── messages ├── de │ └── settings.php ├── es │ └── settings.php ├── fa-IR │ └── settings.php ├── gr │ └── settings.php ├── it │ └── settings.php ├── lv │ └── settings.php ├── messages.php ├── pl │ └── settings.php ├── pt-BR │ └── settings.php ├── ru │ └── settings.php ├── th │ └── settings.php ├── uk │ └── settings.php ├── vn │ └── settings.php ├── yii2mod.settings.php ├── zh-CN │ └── settings.php └── zh-TW │ └── settings.php ├── migrations ├── m140618_045255_create_settings.php └── m151126_091910_add_unique_index.php ├── models ├── BaseSetting.php ├── Setting.php ├── SettingInterface.php └── SettingSearch.php ├── phpunit.xml.dist ├── tests ├── BaseSettingModelTest.php ├── ComponentSettingTest.php ├── SettingModelTest.php ├── SettingSearchTest.php ├── TestCase.php └── bootstrap.php └── views └── default ├── _form.php ├── _search.php ├── create.php ├── index.php ├── update.php └── view.php /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - php 3 | 4 | tools: 5 | external_code_coverage: 6 | timeout: 1800 # Timeout in seconds. 7 | # disable copy paste detector and similarity analyzer as they have no real value 8 | # and a huge bunch of false-positives 9 | php_sim: false 10 | php_cpd: false -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: psr2 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | matrix: 4 | fast_finish: true 5 | 6 | php: 7 | - 5.6 8 | #- 7.1 9 | 10 | # cache vendor dirs 11 | cache: 12 | directories: 13 | - $HOME/.composer/cache 14 | - vendor 15 | 16 | services: 17 | - mysql 18 | 19 | install: 20 | - travis_retry composer self-update 21 | - composer config -g github-oauth.github.com dcb6b0049723eb6f56039b2d6389ac76eb29e352 22 | - travis_retry composer install --prefer-dist --no-interaction 23 | - travis_retry mysql -e 'CREATE DATABASE test;' 24 | 25 | before_script: 26 | - travis_retry composer self-update 27 | - travis_retry composer install --no-interaction --prefer-source --dev 28 | 29 | script: 30 | - ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover 31 | 32 | after_script: 33 | - wget https://scrutinizer-ci.com/ocular.phar 34 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Aris Karageorgos 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of Pheme nor the names of its contributors may 13 | be used to endorse or promote products derived from this software 14 | without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class Module extends \yii\base\Module 17 | { 18 | /** 19 | * @var string The controller namespace to use 20 | */ 21 | public $controllerNamespace = 'pheme\settings\controllers'; 22 | 23 | /** 24 | * 25 | * @var string source language for translation 26 | */ 27 | public $sourceLanguage = 'en-US'; 28 | 29 | /** 30 | * @var null|array The roles which have access to module controllers, eg. ['admin']. If set to `null`, there is no accessFilter applied 31 | */ 32 | public $accessRoles = null; 33 | 34 | /** 35 | * Init module 36 | */ 37 | public function init() 38 | { 39 | parent::init(); 40 | $this->registerTranslations(); 41 | } 42 | 43 | /** 44 | * Registers the translation files 45 | */ 46 | protected function registerTranslations() 47 | { 48 | Yii::$app->i18n->translations['extensions/yii2-settings/*'] = [ 49 | 'class' => 'yii\i18n\PhpMessageSource', 50 | 'sourceLanguage' => $this->sourceLanguage, 51 | 'basePath' => '@vendor/pheme/yii2-settings/messages', 52 | 'fileMap' => [ 53 | 'extensions/yii2-settings/settings' => 'settings.php', 54 | ], 55 | ]; 56 | } 57 | 58 | /** 59 | * Translates a message. This is just a wrapper of Yii::t 60 | * 61 | * @see Yii::t 62 | * 63 | * @param $category 64 | * @param $message 65 | * @param array $params 66 | * @param null $language 67 | * @return string 68 | */ 69 | public static function t($category, $message, $params = [], $language = null) 70 | { 71 | return Yii::t('extensions/yii2-settings/' . $category, $message, $params, $language); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![StyleCI](https://styleci.io/repos/99540308/shield?branch=master)](https://styleci.io/repos/99540308) 2 | [![Build Status](https://travis-ci.org/monster-hunter/yii2-settings.svg?branch=master)](https://travis-ci.org/monster-hunter/yii2-settings) 3 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/monster-hunter/yii2-settings/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/monster-hunter/yii2-settings/?branch=master) 4 | [![Code Coverage](https://scrutinizer-ci.com/g/monster-hunter/yii2-settings/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/monster-hunter/yii2-settings/?branch=master) 5 | 6 | 7 | Yii2 Settings 8 | ============= 9 | Yii2 Database settings 10 | 11 | Installation 12 | ------------ 13 | 14 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 15 | 16 | Either run 17 | 18 | ``` 19 | php composer.phar require --prefer-dist pheme/yii2-settings "*" 20 | ``` 21 | 22 | or add 23 | 24 | ``` 25 | "pheme/yii2-settings": "*" 26 | ``` 27 | 28 | to the require section of your `composer.json` file. 29 | 30 | Subsequently, run 31 | 32 | ```php 33 | ./yii migrate/up --migrationPath=@vendor/pheme/yii2-settings/migrations 34 | ``` 35 | 36 | in order to create the settings table in your database. 37 | 38 | 39 | Usage 40 | ----- 41 | 42 | There are 2 parts to this extension. A module and a component. 43 | The module provides a simple GUI to edit your settings. 44 | The component provides a way to retrieve and save settings programmatically. 45 | 46 | Add this to your main configuration's modules array 47 | 48 | ```php 49 | 'modules' => [ 50 | 'settings' => [ 51 | 'class' => 'pheme\settings\Module', 52 | 'sourceLanguage' => 'en' 53 | ], 54 | ... 55 | ], 56 | ``` 57 | 58 | Add this to your main configuration's components array 59 | 60 | ```php 61 | 'components' => [ 62 | 'settings' => [ 63 | 'class' => 'pheme\settings\components\Settings' 64 | ], 65 | ... 66 | ] 67 | ``` 68 | 69 | Typical component usage 70 | 71 | ```php 72 | 73 | $settings = Yii::$app->settings; 74 | 75 | $value = $settings->get('section.key'); 76 | 77 | $value = $settings->get('key', 'section'); 78 | 79 | $settings->set('section.key', 'value'); 80 | 81 | $settings->set('section.key', 'value', null, 'string'); 82 | 83 | $settings->set('key', 'value', 'section', 'integer'); 84 | 85 | // Automatically called on set(); 86 | $settings->clearCache(); 87 | 88 | ``` 89 | 90 | SettingsAction 91 | ----- 92 | 93 | To use a custom settings form, you can use the included `SettingsAction`. 94 | 95 | 1. Create a model class with your validation rules. 96 | 2. Create an associated view with an `ActiveForm` containing all the settings you need. 97 | 3. Add `pheme\settings\SettingsAction` to the controller's actions. 98 | 99 | The settings will be stored in section taken from the form name, with the key being the field name. 100 | 101 | __Model__: 102 | 103 | ```php 104 | class Site extends Model { 105 | 106 | public $siteName, $siteDescription; 107 | 108 | public function rules() 109 | { 110 | return [ 111 | [['siteName', 'siteDescription'], 'string'], 112 | ]; 113 | } 114 | 115 | public function fields() 116 | { 117 | return ['siteName', 'siteDescription']; 118 | } 119 | 120 | public function attributes() 121 | { 122 | return ['siteName', 'siteDescription']; 123 | } 124 | } 125 | ``` 126 | __Views__: 127 | ```php 128 | 'site-settings-form']); ?> 129 | 130 | field($model, 'siteName') ?> 131 | field($model, 'siteDescription') ?> 132 | 'btn btn-success']) ?> 133 | 134 | 135 | 136 | ``` 137 | __Controller__: 138 | ```php 139 | function actions(){ 140 | return [ 141 | //.... 142 | 'site-settings' => [ 143 | 'class' => 'pheme\settings\SettingsAction', 144 | 'modelClass' => 'app\models\Site', 145 | //'scenario' => 'site', // Change if you want to re-use the model for multiple setting form. 146 | //'section' => 'site', // By default use modelClass formname value 147 | 'viewName' => 'site-settings' // The form we need to render 148 | ], 149 | //.... 150 | ]; 151 | } 152 | ``` 153 | -------------------------------------------------------------------------------- /SettingsAction.php: -------------------------------------------------------------------------------- 1 | modelClass(); 39 | $section = ($this->section !== null) ? $this->section : $model->formName(); 40 | if ($this->scenario) { 41 | $model->setScenario($this->scenario); 42 | } 43 | if ($model->load(Yii::$app->request->post()) && $model->validate()) { 44 | foreach ($model->toArray() as $key => $value) { 45 | Yii::$app->settings->set($key, $value, $section); 46 | } 47 | Yii::$app->getSession()->addFlash('success', 48 | Module::t('settings', 'Successfully saved settings on {section}', 49 | ['section' => $model->formName()] 50 | ) 51 | ); 52 | } 53 | foreach ($model->attributes() as $key) { 54 | $model->{$key} = Yii::$app->settings->get($key, $section); 55 | } 56 | return $this->controller->render($this->viewName, ['model' => $model]); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /components/Settings.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class Settings extends Component 20 | { 21 | /** 22 | * @var string settings model. Make sure your settings model calls clearCache in the afterSave callback 23 | */ 24 | public $modelClass = 'pheme\settings\models\BaseSetting'; 25 | 26 | /** 27 | * Model to for storing and retrieving settings 28 | * @var \pheme\settings\models\SettingInterface 29 | */ 30 | protected $model; 31 | 32 | /** 33 | * @var Cache|string the cache object or the application component ID of the cache object. 34 | * Settings will be cached through this cache object, if it is available. 35 | * 36 | * After the Settings object is created, if you want to change this property, 37 | * you should only assign it with a cache object. 38 | * Set this property to null if you do not want to cache the settings. 39 | */ 40 | public $cache = 'cache'; 41 | 42 | /** 43 | * @var Cache|string the front cache object or the application component ID of the front cache object. 44 | * Front cache will be cleared through this cache object, if it is available. 45 | * 46 | * After the Settings object is created, if you want to change this property, 47 | * you should only assign it with a cache object. 48 | * Set this property to null if you do not want to clear the front cache. 49 | */ 50 | public $frontCache; 51 | 52 | /** 53 | * To be used by the cache component. 54 | * 55 | * @var string cache key 56 | */ 57 | public $cacheKey = 'pheme/settings'; 58 | 59 | /** 60 | * @var bool Whether to convert objects stored as JSON into an PHP array 61 | * @since 0.6 62 | */ 63 | public $autoDecodeJson = false; 64 | 65 | /** 66 | * Holds a cached copy of the data for the current request 67 | * 68 | * @var mixed 69 | */ 70 | private $_data = null; 71 | 72 | /** 73 | * Initialize the component 74 | * 75 | * @throws \yii\base\InvalidConfigException 76 | */ 77 | public function init() 78 | { 79 | parent::init(); 80 | 81 | $this->model = new $this->modelClass; 82 | 83 | if (is_string($this->cache)) { 84 | $this->cache = Yii::$app->get($this->cache, false); 85 | } 86 | if (is_string($this->frontCache)) { 87 | $this->frontCache = Yii::$app->get($this->frontCache, false); 88 | } 89 | } 90 | 91 | /** 92 | * Get's the value for the given key and section. 93 | * You can use dot notation to separate the section from the key: 94 | * $value = $settings->get('section.key'); 95 | * and 96 | * $value = $settings->get('key', 'section'); 97 | * are equivalent 98 | * 99 | * @param $key 100 | * @param string|null $section 101 | * @param string|null $default 102 | * @return mixed 103 | */ 104 | public function get($key, $section = null, $default = null) 105 | { 106 | if (is_null($section)) { 107 | $pieces = explode('.', $key, 2); 108 | if (count($pieces) > 1) { 109 | $section = $pieces[0]; 110 | $key = $pieces[1]; 111 | } else { 112 | $section = ''; 113 | } 114 | } 115 | 116 | $data = $this->getRawConfig(); 117 | 118 | if (isset($data[$section][$key][0])) { 119 | 120 | $value = $data[$section][$key][0]; 121 | $type = $data[$section][$key][1]; 122 | 123 | //convert value to needed type 124 | if (in_array($type, ['object', 'boolean', 'bool', 'integer', 'int', 'float', 'string', 'array'])) { 125 | if ($this->autoDecodeJson && $type === 'object') { 126 | $value = Json::decode($value); 127 | } else { 128 | settype($value, $type); 129 | } 130 | } 131 | } else { 132 | $value = $default; 133 | } 134 | return $value; 135 | } 136 | 137 | /** 138 | * Checks to see if a setting exists. 139 | * If $searchDisabled is set to true, calling this function will result in an additional query. 140 | * @param $key 141 | * @param string|null $section 142 | * @param boolean $searchDisabled 143 | * @return boolean 144 | */ 145 | public function has($key, $section = null, $searchDisabled = false) 146 | { 147 | if ($searchDisabled) { 148 | $setting = $this->model->findSetting($key, $section); 149 | } else { 150 | $setting = $this->get($key, $section); 151 | } 152 | return is_null($setting) ? false : true; 153 | } 154 | 155 | /** 156 | * @param $key 157 | * @param $value 158 | * @param null $section 159 | * @param null $type 160 | * @return boolean 161 | */ 162 | public function set($key, $value, $section = null, $type = null) 163 | { 164 | if (is_null($section)) { 165 | $pieces = explode('.', $key); 166 | $section = $pieces[0]; 167 | $key = $pieces[1]; 168 | } 169 | 170 | if ($this->model->setSetting($section, $key, $value, $type)) { 171 | return true; 172 | } 173 | return false; 174 | } 175 | 176 | /** 177 | * Returns the specified key or sets the key with the supplied (default) value 178 | * 179 | * @param $key 180 | * @param $value 181 | * @param null $section 182 | * @param null $type 183 | * 184 | * @return bool|mixed 185 | */ 186 | public function getOrSet($key, $value, $section = null, $type = null) 187 | { 188 | if ($this->has($key, $section, true)) { 189 | return $this->get($key, $section); 190 | } else { 191 | return $this->set($key, $value, $section, $type); 192 | } 193 | } 194 | 195 | /** 196 | * Deletes a setting 197 | * 198 | * @param $key 199 | * @param null|string $section 200 | * @return bool 201 | */ 202 | public function delete($key, $section = null) 203 | { 204 | if (is_null($section)) { 205 | $pieces = explode('.', $key); 206 | $section = $pieces[0]; 207 | $key = $pieces[1]; 208 | } 209 | return $this->model->deleteSetting($section, $key); 210 | } 211 | 212 | /** 213 | * Deletes all setting. Be careful! 214 | * 215 | * @return bool 216 | */ 217 | public function deleteAll() 218 | { 219 | return $this->model->deleteAllSettings(); 220 | } 221 | 222 | /** 223 | * Activates a setting 224 | * 225 | * @param $key 226 | * @param null|string $section 227 | * @return bool 228 | */ 229 | public function activate($key, $section = null) 230 | { 231 | if (is_null($section)) { 232 | $pieces = explode('.', $key); 233 | $section = $pieces[0]; 234 | $key = $pieces[1]; 235 | } 236 | return $this->model->activateSetting($section, $key); 237 | } 238 | 239 | /** 240 | * Deactivates a setting 241 | * 242 | * @param $key 243 | * @param null|string $section 244 | * @return bool 245 | */ 246 | public function deactivate($key, $section = null) 247 | { 248 | if (is_null($section)) { 249 | $pieces = explode('.', $key); 250 | $section = $pieces[0]; 251 | $key = $pieces[1]; 252 | } 253 | return $this->model->deactivateSetting($section, $key); 254 | } 255 | 256 | /** 257 | * Clears the settings cache on demand. 258 | * If you haven't configured cache this does nothing. 259 | * 260 | * @return boolean True if the cache key was deleted and false otherwise 261 | */ 262 | public function clearCache() 263 | { 264 | $this->_data = null; 265 | if ($this->frontCache instanceof Cache) { 266 | $this->frontCache->delete($this->cacheKey); 267 | } 268 | if ($this->cache instanceof Cache) { 269 | return $this->cache->delete($this->cacheKey); 270 | } 271 | return true; 272 | } 273 | 274 | /** 275 | * Returns the raw configuration array 276 | * 277 | * @return array 278 | */ 279 | public function getRawConfig() 280 | { 281 | if ($this->_data === null) { 282 | if ($this->cache instanceof Cache) { 283 | $data = $this->cache->get($this->cacheKey); 284 | if ($data === false) { 285 | $data = $this->model->getSettings(); 286 | $this->cache->set($this->cacheKey, $data); 287 | } 288 | } else { 289 | $data = $this->model->getSettings(); 290 | } 291 | $this->_data = $data; 292 | } 293 | return $this->_data; 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pheme/yii2-settings", 3 | "description": "Yii2 Database settings", 4 | "type": "yii2-extension", 5 | "keywords": [ 6 | "yii2", 7 | "config", 8 | "settings" 9 | ], 10 | "license": "BSD-3-Clause", 11 | "authors": [ 12 | { 13 | "name": "Aris Karageorgos", 14 | "email": "aris@phe.me" 15 | } 16 | ], 17 | "require": { 18 | "yiisoft/yii2": ">=2.0.6", 19 | "pheme/yii2-toggle-column": "*" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "~4.0" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "pheme\\settings\\": "" 27 | } 28 | }, 29 | "repositories": [ 30 | { 31 | "type": "composer", 32 | "url": "https://asset-packagist.org" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /controllers/DefaultController.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | class DefaultController extends Controller 26 | { 27 | /** 28 | * Defines the controller behaviors 29 | * @return array 30 | */ 31 | public function behaviors() 32 | { 33 | return [ 34 | 'verbs' => [ 35 | 'class' => VerbFilter::className(), 36 | 'actions' => [ 37 | 'delete' => ['post'], 38 | ], 39 | ], 40 | 'access' => [ 41 | 'class' => AccessControl::className(), 42 | 'rules' => [ 43 | [ 44 | 'allow' => true, 45 | 'roles' => $this->module->accessRoles, 46 | ], 47 | ], 48 | ], 49 | ]; 50 | } 51 | 52 | public function actions() 53 | { 54 | return [ 55 | 'toggle' => [ 56 | 'class' => ToggleAction::className(), 57 | 'modelClass' => 'pheme\settings\models\Setting', 58 | //'setFlash' => true, 59 | ] 60 | ]; 61 | } 62 | 63 | /** 64 | * Lists all Settings. 65 | * @return mixed 66 | */ 67 | public function actionIndex() 68 | { 69 | $searchModel = new SettingSearch(); 70 | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 71 | 72 | return $this->render( 73 | 'index', 74 | [ 75 | 'searchModel' => $searchModel, 76 | 'dataProvider' => $dataProvider, 77 | ] 78 | ); 79 | } 80 | 81 | /** 82 | * Displays the details of a single Setting. 83 | * @param integer $id 84 | * @return mixed 85 | */ 86 | public function actionView($id) 87 | { 88 | return $this->render( 89 | 'view', 90 | [ 91 | 'model' => $this->findModel($id), 92 | ] 93 | ); 94 | } 95 | 96 | /** 97 | * Creates a new Setting. 98 | * If creation is successful, the browser will be redirected to the 'view' page. 99 | * @return mixed 100 | */ 101 | public function actionCreate() 102 | { 103 | $model = new Setting(['active' => 1]); 104 | 105 | if ($model->load(Yii::$app->request->post()) && $model->save()) { 106 | return $this->redirect(['view', 'id' => $model->id]); 107 | } else { 108 | return $this->render( 109 | 'create', 110 | [ 111 | 'model' => $model, 112 | ] 113 | ); 114 | } 115 | } 116 | 117 | /** 118 | * Updates an existing Setting. 119 | * If update is successful, the browser will be redirected to the 'view' page. 120 | * @param integer $id 121 | * @return mixed 122 | */ 123 | public function actionUpdate($id) 124 | { 125 | $model = $this->findModel($id); 126 | 127 | if ($model->load(Yii::$app->request->post()) && $model->save()) { 128 | return $this->redirect(['view', 'id' => $model->id]); 129 | } else { 130 | return $this->render( 131 | 'update', 132 | [ 133 | 'model' => $model, 134 | ] 135 | ); 136 | } 137 | } 138 | 139 | /** 140 | * Deletes an existing Setting. 141 | * If deletion is successful, the browser will be redirected to the 'index' page. 142 | * @param integer $id 143 | * @return mixed 144 | */ 145 | public function actionDelete($id) 146 | { 147 | if (Yii::$app->request->isPost) { 148 | $this->findModel($id)->delete(); 149 | } 150 | return $this->redirect(['index']); 151 | } 152 | 153 | /** 154 | * Finds a Setting model based on its primary key value. 155 | * If the model is not found, a 404 HTTP exception will be thrown. 156 | * @param integer $id 157 | * @return Setting the loaded model 158 | * @throws NotFoundHttpException if the model cannot be found 159 | */ 160 | protected function findModel($id) 161 | { 162 | if (($model = Setting::findOne($id)) !== null) { 163 | return $model; 164 | } else { 165 | throw new NotFoundHttpException('The requested page does not exist.'); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /messages/de/settings.php: -------------------------------------------------------------------------------- 1 | 'Aktiv', 21 | 'Are you sure you want to delete this item?' => 'Wollen Sie diesen Eintrag wirklich löschen?', 22 | 'Change at your own risk' => 'Ändern auf eigene Gefahr', 23 | 'Create' => 'Erstellen', 24 | 'Create {modelClass}' => 'Erstellen {modelClass}', 25 | 'Created' => 'Erstellt', 26 | 'Delete' => 'Löschen', 27 | 'ID' => '', 28 | 'Key' => 'Schlüssel', 29 | 'Modified' => 'Modifiziert', 30 | 'Reset' => 'Zurücksetzen', 31 | 'Search' => 'Suche', 32 | 'Section' => 'Sektion', 33 | 'Setting' => 'Einstellung', 34 | 'Settings' => 'Einstellungen', 35 | 'Type' => 'Typ', 36 | 'Update' => 'Aktualisieren', 37 | 'Update {modelClass}: ' => 'Aktualisiere {modelClass}: ', 38 | 'Value' => 'Wert', 39 | '{attribute} "{value}" already exists for this section.' => '', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" must be a valid JSON object', 41 | 'Please select correct type' => 'Please select correct type', 42 | 'string' => 'String', 43 | 'integer' => 'Integer', 44 | 'boolean' => 'Boolean', 45 | 'float' => 'Number', 46 | 'email' => 'E-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | -------------------------------------------------------------------------------- /messages/es/settings.php: -------------------------------------------------------------------------------- 1 | 'Activo', 21 | 'Are you sure you want to delete this item?' => '¿Estás seguro que quieres eliminar esa configuración?', 22 | 'Change at your own risk' => 'Cámbialo bajo tu propio riesgo', 23 | 'Create' => 'Crear', 24 | 'Create {modelClass}' => 'Crear {modelClass}', 25 | 'Created' => 'Creado', 26 | 'Delete' => 'Eliminar', 27 | 'ID' => 'ID', 28 | 'Key' => 'Clave', 29 | 'Modified' => 'Modificado', 30 | 'Please select correct type' => 'Por favor selecciona el tipo correcto', 31 | 'Reset' => 'Restablecer', 32 | 'Search' => 'Buscar', 33 | 'Section' => 'Sección', 34 | 'Setting' => 'Configuración', 35 | 'Settings' => 'Configuraciones', 36 | 'Successfully saved settings on {section}' => 'Configuración guardada correctamente en la sección {section}', 37 | 'Type' => 'Tipo', 38 | 'Update' => 'Actualizar', 39 | 'Update {modelClass}: ' => 'Actualizar {modelClass}: ', 40 | 'Value' => 'Valor', 41 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" ya existe en esta sección.', 42 | '"{attribute}" must be a valid JSON object' => '"{attribute}" debe ser un objeto JSON válido', 43 | 'string' => 'Cadena de texto', 44 | 'integer' => 'Entero', 45 | 'boolean' => 'Booleano', 46 | 'float' => 'Decimal', 47 | 'email' => 'Correo electrónico', 48 | 'ip' => 'Dirección IP', 49 | 'url' => 'URL', 50 | 'object' => 'Objeto', 51 | ]; 52 | -------------------------------------------------------------------------------- /messages/fa-IR/settings.php: -------------------------------------------------------------------------------- 1 | 'فعال', 21 | 'Are you sure you want to delete this item?' => 'آیا مایل به حذف مورد انتخابی می باشید؟', 22 | 'Change at your own risk' => 'تغییر می تواند ریسک باشد', 23 | 'Create' => 'ایجاد', 24 | 'Create {modelClass}' => 'ایجاد {modelClass}', 25 | 'Created' => 'ایجاد شده', 26 | 'Delete' => 'حذف', 27 | 'ID' => 'شماره شناسایی', 28 | 'Key' => 'کلید', 29 | 'Modified' => 'ویرایش شده', 30 | 'Reset' => 'تنظیم مجدد', 31 | 'Search' => 'جستجو', 32 | 'Section' => 'قسمت', 33 | 'Setting' => 'تنظیم', 34 | 'Settings' => 'تنظیمات', 35 | 'Type' => 'نوع', 36 | 'Update' => 'بروز رسانی', 37 | 'Update {modelClass}: ' => 'بروز رسانی {modelClass}: ', 38 | 'Value' => 'مقدار', 39 | '{attribute} "{value}" already exists for this section.' => '', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" must be a valid JSON object', 41 | 'Please select correct type' => 'Please select correct type', 42 | 'string' => 'String', 43 | 'integer' => 'Integer', 44 | 'boolean' => 'Boolean', 45 | 'float' => 'Number', 46 | 'email' => 'E-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | -------------------------------------------------------------------------------- /messages/gr/settings.php: -------------------------------------------------------------------------------- 1 | '', 21 | 'Are you sure you want to delete this item?' => '', 22 | 'Change at your own risk' => '', 23 | 'Create' => '', 24 | 'Create {modelClass}' => '', 25 | 'Created' => '', 26 | 'Delete' => '', 27 | 'ID' => '', 28 | 'Key' => '', 29 | 'Modified' => '', 30 | 'Reset' => '', 31 | 'Search' => '', 32 | 'Section' => '', 33 | 'Setting' => '', 34 | 'Settings' => '', 35 | 'Type' => '', 36 | 'Update' => '', 37 | 'Update {modelClass}: ' => '', 38 | 'Value' => '', 39 | '{attribute} "{value}" already exists for this section.' => '', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" must be a valid JSON object', 41 | 'Please select correct type' => 'Please select correct type', 42 | 'string' => 'String', 43 | 'integer' => 'Integer', 44 | 'boolean' => 'Boolean', 45 | 'float' => 'Number', 46 | 'email' => 'E-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | -------------------------------------------------------------------------------- /messages/it/settings.php: -------------------------------------------------------------------------------- 1 | 'Attivo', 21 | 'Are you sure you want to delete this item?' => 'Sei sicuro di voler cancellare questo elemento?', 22 | 'Change at your own risk' => 'Cambia a tuo rischio', 23 | 'Create' => 'Crea', 24 | 'Create {modelClass}' => 'Crea {modelClass}', 25 | 'Created' => 'Creato', 26 | 'Delete' => 'Cancella', 27 | 'ID' => '', 28 | 'Key' => 'Chiave', 29 | 'Modified' => 'Modificato', 30 | 'Reset' => 'Resetta', 31 | 'Search' => 'Cerca', 32 | 'Section' => 'Sezione', 33 | 'Setting' => 'Impostazione', 34 | 'Settings' => 'Impostazioni', 35 | 'Successfully saved settings on {section}' => 'Impostazioni salvata correttamente nella sezione {section}', 36 | 'Type' => 'Tipo', 37 | 'Update' => 'Aggiorna', 38 | 'Update {modelClass}: ' => 'Aggiorna {modelClass}: ', 39 | 'Value' => 'Valore', 40 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" esiste già per questa sezione.', 41 | '"{attribute}" must be a valid JSON object' => '"{attribute}" deve essere un oggetto JSON valido', 42 | 'Please select correct type' => 'Seleziona il tipo corretto', 43 | 'string' => 'stringa', 44 | 'integer' => 'intero', 45 | 'boolean' => 'booleano', 46 | 'float' => 'float', 47 | 'email' => 'E-mail', 48 | 'ip' => 'IP', 49 | 'url' => 'URL', 50 | 'object' => 'ogetto', 51 | ]; 52 | -------------------------------------------------------------------------------- /messages/lv/settings.php: -------------------------------------------------------------------------------- 1 | 'Aktīvs', 21 | 'Are you sure you want to delete this item?' => 'Vai patiešām vēlaties dzēst šo ierakstu?', 22 | 'Change at your own risk' => 'Izmaiņas veiciet uz jūsu atbildību', 23 | 'Create' => 'Izveidot', 24 | 'Create {modelClass}' => 'Notiek {modelClass} izveidošana', 25 | 'Created' => 'Izveidots', 26 | 'Delete' => 'Dzēst', 27 | 'ID' => '', 28 | 'Key' => 'Atslēga', 29 | 'Modified' => 'Labots', 30 | 'Reset' => 'Atstatīt', 31 | 'Search' => 'Meklēt', 32 | 'Section' => 'Sadaļa', 33 | 'Setting' => 'Uzstādījums', 34 | 'Settings' => 'Uzstādījumi', 35 | 'Type' => 'Tips', 36 | 'Update' => 'Labot', 37 | 'Update {modelClass}: ' => 'Labot {modelClass}: ', 38 | 'Value' => 'Vērtība', 39 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" jau ir aktuālajā sadaļā', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" jābūt korektam JSON objektam', 41 | 'Please select correct type' => 'Izvēlaties pieejamo tipu', 42 | 'string' => 'Rinda', 43 | 'integer' => 'Vesels skaitlis', 44 | 'boolean' => '0 vai 1', 45 | 'float' => 'Decimālskaitlis', 46 | 'email' => 'Epasts', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | 52 | -------------------------------------------------------------------------------- /messages/messages.php: -------------------------------------------------------------------------------- 1 | __DIR__ . DIRECTORY_SEPARATOR . '..', 6 | // array, required, list of language codes that the extracted messages 7 | // should be translated to. For example, ['zh-CN', 'de']. 8 | 'languages' => ['de', 'fa-IR', 'gr', 'it', 'pl','ru', 'uk', 'vn','th', 'zh-CN', 'zh-TW', 'lv' ], 9 | // string, the name of the function for translating messages. 10 | // Defaults to 'Yii::t'. This is used as a mark to find the messages to be 11 | // translated. You may use a string for single function name or an array for 12 | // multiple function names. 13 | 'translator' => 'Module::t', 14 | // boolean, whether to sort messages by keys when merging new messages 15 | // with the existing ones. Defaults to false, which means the new (untranslated) 16 | // messages will be separated from the old (translated) ones. 17 | 'sort' => true, 18 | // boolean, whether to remove messages that no longer appear in the source code. 19 | // Defaults to false, which means each of these messages will be enclosed with a pair of '@@' marks. 20 | 'removeUnused' => true, 21 | // array, list of patterns that specify which files (not directories) should be processed. 22 | // If empty or not set, all files will be processed. 23 | // Please refer to "except" for details about the patterns. 24 | 'only' => ['*.php'], 25 | // array, list of patterns that specify which files/directories should NOT be processed. 26 | // If empty or not set, all files/directories will be processed. 27 | // A path matches a pattern if it contains the pattern string at its end. For example, 28 | // '/a/b' will match all files and directories ending with '/a/b'; 29 | // the '*.svn' will match all files and directories whose name ends with '.svn'. 30 | // and the '.svn' will match all files and directories named exactly '.svn'. 31 | // Note, the '/' characters in a pattern matches both '/' and '\'. 32 | // See helpers/FileHelper::findFiles() description for more details on pattern matching rules. 33 | // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. 34 | 'except' => [ 35 | '.svn', 36 | '.git', 37 | '.gitignore', 38 | '.gitkeep', 39 | '.hgignore', 40 | '.hgkeep', 41 | '/messages', 42 | ], 43 | 44 | // 'php' output format is for saving messages to php files. 45 | 'format' => 'php', 46 | // Root directory containing message translations. 47 | 'messagePath' => __DIR__, 48 | // boolean, whether the message file should be overwritten with the merged messages 49 | 'overwrite' => true, 50 | 51 | /* 52 | // Message categories to ignore 53 | 'ignoreCategories' => [ 54 | 'yii', 55 | ], 56 | */ 57 | 58 | /* 59 | // 'db' output format is for saving messages to database. 60 | 'format' => 'db', 61 | // Connection component to use. Optional. 62 | 'db' => 'db', 63 | // Custom source message table. Optional. 64 | // 'sourceMessageTable' => '{{%source_message}}', 65 | // Custom name for translation message table. Optional. 66 | // 'messageTable' => '{{%message}}', 67 | */ 68 | 69 | /* 70 | // 'po' output format is for saving messages to gettext po files. 71 | 'format' => 'po', 72 | // Root directory containing message translations. 73 | 'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages', 74 | // Name of the file that will be used for translations. 75 | 'catalog' => 'messages', 76 | // boolean, whether the message file should be overwritten with the merged messages 77 | 'overwrite' => true, 78 | */ 79 | ]; 80 | -------------------------------------------------------------------------------- /messages/pl/settings.php: -------------------------------------------------------------------------------- 1 | 'Aktywne', 21 | 'Are you sure you want to delete this item?' => 'Czy usunąć wpis?', 22 | 'Change at your own risk' => 'Zmiana na własne ryzyko', 23 | 'Create' => 'Dodaj', 24 | 'Create {modelClass}' => 'Dodaj {modelClass}', 25 | 'Created' => 'Dodane', 26 | 'Delete' => 'Usuń', 27 | 'ID' => 'ID', 28 | 'Key' => 'Klucz', 29 | 'Modified' => 'Zmienione', 30 | 'Reset' => 'Reset', 31 | 'Search' => 'Szukaj', 32 | 'Section' => 'Sekcja', 33 | 'Setting' => 'Ustawienie', 34 | 'Settings' => 'Ustawienia', 35 | 'Type' => 'Typ', 36 | 'Update' => 'Zmień', 37 | 'Update {modelClass}: ' => 'Zmień {modelClass}: ', 38 | 'Value' => 'Wartość', 39 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" już istnieje w sekcji.', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" musi być poprawnym objektem JSON', 41 | 'Please select correct type' => 'Proszę wybrać poprawny typ', 42 | 'string' => 'string', 43 | 'integer' => 'integer', 44 | 'boolean' => 'boolean', 45 | 'float' => 'float', 46 | 'email' => 'e-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | -------------------------------------------------------------------------------- /messages/pt-BR/settings.php: -------------------------------------------------------------------------------- 1 | 'Ativo', 21 | 'Are you sure you want to delete this item?' => 'Tem certeza que deseja excluir esse item?', 22 | 'Change at your own risk' => 'Altere por seu próprio risco', 23 | 'Create' => 'Criar', 24 | 'Create {modelClass}' => 'Criar {modelClass}', 25 | 'Created' => 'Criado', 26 | 'Delete' => 'Excluir', 27 | 'ID' => 'ID', 28 | 'Key' => 'Chave', 29 | 'Modified' => 'Modificado', 30 | 'Please select correct type' => 'Por favor selecione o tipo correto', 31 | 'Reset' => 'Redefinir', 32 | 'Search' => 'Pesquisar', 33 | 'Section' => 'Seção', 34 | 'Setting' => 'Configuração', 35 | 'Settings' => 'Configurações', 36 | 'Successfully saved settings on {section}' => 'Configuração gravada corretamente na {section}', 37 | 'Type' => 'Tipo', 38 | 'Update' => 'Alterar', 39 | 'Update {modelClass}: ' => 'Alterar {modelClass}: ', 40 | 'Value' => 'Valor', 41 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" já existe para essa seção.', 42 | '"{attribute}" must be a valid JSON object' => '"{attribute}" precisa ser um objeto JSON válido', 43 | 'string' => 'Texto', 44 | 'integer' => 'Inteiro', 45 | 'boolean' => 'Booleano', 46 | 'float' => 'Decimal', 47 | 'email' => 'E-mail', 48 | 'ip' => 'IP', 49 | 'url' => 'URL', 50 | 'object' => 'Objeto', 51 | ]; 52 | -------------------------------------------------------------------------------- /messages/ru/settings.php: -------------------------------------------------------------------------------- 1 | 'Активная', 21 | 'Are you sure you want to delete this item?' => 'Вы уверены, что хотите удалить эту запись?', 22 | 'Change at your own risk' => 'Меняете на свой страх и риск', 23 | 'Create' => 'Создать', 24 | 'Create {modelClass}' => 'Создание {modelClass}', 25 | 'Created' => 'Создано', 26 | 'Delete' => 'Удалить', 27 | 'ID' => '', 28 | 'Key' => 'Ключ', 29 | 'Modified' => 'Отредактировано', 30 | 'Reset' => 'Сбросить', 31 | 'Search' => 'Поиск', 32 | 'Section' => 'Раздел', 33 | 'Setting' => 'Настройка', 34 | 'Settings' => 'Настройки', 35 | 'Type' => 'Тип', 36 | 'Update' => 'Редактировать', 37 | 'Update {modelClass}: ' => 'Редактирование {modelClass}: ', 38 | 'Value' => 'Значение', 39 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" уже существует для данного раздела', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" должен содержать корректный JSON объект', 41 | 'Please select correct type' => 'Выберите допустимый тип', 42 | 'string' => 'Строка', 43 | 'integer' => 'Целое число', 44 | 'boolean' => '0 или 1', 45 | 'float' => 'Число', 46 | 'email' => 'E-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | 'Successfully saved settings on {section}' => 'Настройки удачно сохранены для {section}' 51 | ]; 52 | -------------------------------------------------------------------------------- /messages/th/settings.php: -------------------------------------------------------------------------------- 1 | 'พร้อมทำงาน', 21 | 'Are you sure you want to delete this item?' => 'คุณแน่ใจใช่ไหมว่าต้องการที่จะลบข้อมูลนี้?', 22 | 'Change at your own risk' => 'เปลี่ยนข้อมูลมีความเสี่ยง', 23 | 'Create' => 'สร้าง', 24 | 'Create {modelClass}' => 'สร้าง {modelClass}', 25 | 'Created' => 'สร้าง', 26 | 'Delete' => 'ลบ', 27 | 'ID' => 'ไอดี', 28 | 'Key' => 'คีย์', 29 | 'Modified' => 'แก้ไข', 30 | 'Reset' => 'คืนค่า', 31 | 'Search' => 'ค้นหา', 32 | 'Section' => 'ส่วน', 33 | 'Setting' => 'การตั้งค่า', 34 | 'Settings' => 'การตั้งค่า', 35 | 'Type' => 'ชนิด', 36 | 'Update' => 'ปรับปรุง', 37 | 'Update {modelClass}: ' => 'ปรับปรุง {modelClass}: ', 38 | 'Value' => 'ค่า', 39 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" มีแล้วในะระบบ', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" ต้องอยู่ในรูปแบบ JSON', 41 | 'Please select correct type' => 'เลือกให้ตรงชนิด', 42 | 'string' => 'ตัวอักษร', 43 | 'integer' => 'ตัวเลข', 44 | 'boolean' => '0 หรือ 1', 45 | 'float' => 'ค่าทศนิยม', 46 | 'email' => 'E-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | -------------------------------------------------------------------------------- /messages/uk/settings.php: -------------------------------------------------------------------------------- 1 | 'Активне', 21 | 'Are you sure you want to delete this item?' => 'Ви впевнені, що хочете видалити цей запис?', 22 | 'Change at your own risk' => 'Змінюєте на свій страх і ризик', 23 | 'Create' => 'Створити', 24 | 'Create {modelClass}' => 'Створити {modelClass}', 25 | 'Created' => 'Створено', 26 | 'Delete' => 'Видалити', 27 | 'ID' => '', 28 | 'Key' => 'Ключ', 29 | 'Modified' => 'Відредаговано', 30 | 'Reset' => 'Скинути', 31 | 'Search' => 'Пошук', 32 | 'Section' => 'Секція', 33 | 'Setting' => 'Налаштування', 34 | 'Settings' => 'Налаштування', 35 | 'Type' => 'Тип', 36 | 'Update' => 'Редагувати', 37 | 'Update {modelClass}: ' => 'Редагування {modelClass}: ', 38 | 'Value' => 'Значення', 39 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" уже існує в даній секції.', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" повинен містити корректний JSON об’єкт', 41 | 'Please select correct type' => 'Оберіть корректний тип', 42 | 'string' => 'Рядок', 43 | 'integer' => 'Ціле число', 44 | 'boolean' => '0 або 1', 45 | 'float' => 'Число', 46 | 'email' => 'E-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | -------------------------------------------------------------------------------- /messages/vn/settings.php: -------------------------------------------------------------------------------- 1 | 'Hoạt động', 21 | 'Are you sure you want to delete this item?' => 'Bạn có chắc chắn muốn xóa mục này?', 22 | 'Change at your own risk' => 'Cẩn thận khi thay đổi', 23 | 'Create' => 'Tạo mới', 24 | 'Create {modelClass}' => 'Tạo {modelClass}', 25 | 'Created' => 'Đã tạo', 26 | 'Delete' => 'Xóa bỏ', 27 | 'ID' => 'ID', 28 | 'Key' => 'Khóa', 29 | 'Modified' => 'Đã sửa đổi', 30 | 'Reset' => 'Đặt lại', 31 | 'Search' => 'Tìm kiếm', 32 | 'Section' => 'Mục', 33 | 'Setting' => 'Cài đặt', 34 | 'Settings' => 'Thiết lập', 35 | 'Type' => 'Kiểu', 36 | 'Update' => 'Cập nhật', 37 | 'Update {modelClass}: ' => 'Cập nhật {modelClass}: ', 38 | 'Value' => 'Giá trị', 39 | '{attribute} "{value}" already exists for this section.' => '', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" must be a valid JSON object', 41 | 'Please select correct type' => 'Please select correct type', 42 | 'string' => 'String', 43 | 'integer' => 'Integer', 44 | 'boolean' => 'Boolean', 45 | 'float' => 'Number', 46 | 'email' => 'E-mail', 47 | 'ip' => 'IP', 48 | 'url' => 'URL', 49 | 'object' => 'JSON', 50 | ]; 51 | -------------------------------------------------------------------------------- /messages/yii2mod.settings.php: -------------------------------------------------------------------------------- 1 | 'ID', 21 | 'Type' => 'Typ', 22 | 'Section' => 'Grupa', 23 | 'Key' => 'Klucz', 24 | 'Value' => 'Wartość', 25 | 'Status' => 'Status', 26 | 'Description' => 'Opis', 27 | 'Created Date' => 'Data utworzenia', 28 | 'Updated Date' => 'Data aktualizacji', 29 | 'Settings' => 'Konfiguracja', 30 | 'Create Setting' => 'Dodaj konfigurację', 31 | 'Select Type' => 'Wybierz typ', 32 | 'Select Section' => 'Wybierz grupę', 33 | 'Select Status' => 'Wybierz status', 34 | 'Actions' => 'Akcje', 35 | 'Active' => 'Aktywne', 36 | 'Inactive' => 'Nieaktywne', 37 | 'Update Setting: {0} -> {1}' => 'Edytuj konfigurację: {0} -> {1}', 38 | 'Update Setting' => 'Edytuj konfigurację', 39 | 'Update' => 'Aktualizuj', 40 | 'Create' => 'Dodaj', 41 | 'Delete' => 'Usuń', 42 | 'Go Back' => 'Wstecz', 43 | 'String' => 'Tekst', 44 | 'Integer' => 'Liczba całkowita', 45 | 'Boolean' => 'Prawda/Fałsz', 46 | 'Float' => 'Liczba zmiennoprzecinkowa', 47 | 'Null' => 'Null', 48 | 'Setting has been created.' => 'Konfiguracja została dodana.', 49 | 'Setting has been deleted.' => 'Konfiguracja została usunięta.', 50 | 'Setting has been updated.' => 'Konfiguracja została zaktualizowana.', 51 | 'The requested page does not exist.' => 'Szukana strona nie istnieje', 52 | ]; 53 | -------------------------------------------------------------------------------- /messages/zh-CN/settings.php: -------------------------------------------------------------------------------- 1 | '有效', 21 | 'Are you sure you want to delete this item?' => '确定要删除该项目吗?', 22 | 'Change at your own risk' => '更改需要自行承担风险', 23 | 'Create' => '创建', 24 | 'Create {modelClass}' => '创建 {modelClass}', 25 | 'Created' => '已创建', 26 | 'Delete' => '删除', 27 | 'ID' => 'ID', 28 | 'Key' => 'Key', 29 | 'Modified' => '已修改', 30 | 'Reset' => '重置', 31 | 'Search' => '搜索', 32 | 'Section' => '分组', 33 | 'Setting' => '设置', 34 | 'Settings' => '设置', 35 | 'Type' => '类型', 36 | 'Update' => '更新', 37 | 'Update {modelClass}: ' => '更新 {modelClass}: ', 38 | 'Value' => '值', 39 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" 已经存在于该分组中.', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" 必须是合法的JSON对象', 41 | 'Please select correct type' => '请选择正常的类型', 42 | 'string' => '字符串', 43 | 'integer' => '整数', 44 | 'boolean' => '布尔值', 45 | 'float' => '浮点型', 46 | 'email' => '邮箱', 47 | 'ip' => 'IP', 48 | 'url' => '链接', 49 | 'object' => '对象', 50 | 'Successfully saved settings on {section}'=>'{section} 的设置保存成功' 51 | ]; 52 | -------------------------------------------------------------------------------- /messages/zh-TW/settings.php: -------------------------------------------------------------------------------- 1 | '有效', 21 | 'Are you sure you want to delete this item?' => '確定要刪除該項目嗎?', 22 | 'Change at your own risk' => '更改需要自行承擔風險', 23 | 'Create' => '創建', 24 | 'Create {modelClass}' => '創建 {modelClass}', 25 | 'Created' => '已創建', 26 | 'Delete' => '刪除', 27 | 'ID' => 'ID', 28 | 'Key' => 'Key', 29 | 'Modified' => '已修改', 30 | 'Reset' => '重置', 31 | 'Search' => '搜尋', 32 | 'Section' => '分組', 33 | 'Setting' => '設置', 34 | 'Settings' => '設置', 35 | 'Type' => '類型', 36 | 'Update' => '更新', 37 | 'Update {modelClass}: ' => '更新 {modelClass}: ', 38 | 'Value' => '值', 39 | '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" 已經存在於該分組中.', 40 | '"{attribute}" must be a valid JSON object' => '"{attribute}" 必須是合法的JSON對象', 41 | 'Please select correct type' => '請選擇正確的類型', 42 | 'string' => '字符串', 43 | 'integer' => '整數', 44 | 'boolean' => '布爾值', 45 | 'float' => '浮點型', 46 | 'email' => '郵箱', 47 | 'ip' => 'IP', 48 | 'url' => '鏈接', 49 | 'object' => '對象', 50 | 'Successfully saved settings on {section}'=>'{section} 的設置保存成功' 51 | ]; 52 | -------------------------------------------------------------------------------- /migrations/m140618_045255_create_settings.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class m140618_045255_create_settings extends \yii\db\Migration 12 | { 13 | public function up() 14 | { 15 | $tableOptions = null; 16 | if ($this->db->driverName === 'mysql') { 17 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; 18 | } 19 | $this->createTable( 20 | '{{%settings}}', 21 | [ 22 | 'id' => $this->primaryKey(), 23 | 'type' => $this->string(255)->notNull(), 24 | 'section' => $this->string(255)->notNull(), 25 | 'key' => $this->string(255)->notNull(), 26 | 'value' => $this->text(), 27 | 'active' => $this->boolean(), 28 | 'created' => $this->dateTime(), 29 | 'modified' => $this->dateTime(), 30 | ], 31 | $tableOptions 32 | ); 33 | } 34 | 35 | public function down() 36 | { 37 | $this->dropTable('{{%settings}}'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /migrations/m151126_091910_add_unique_index.php: -------------------------------------------------------------------------------- 1 | createIndex('settings_unique_key_section', '{{%settings}}', ['section', 'key'], true); 15 | } 16 | 17 | public function safeDown() 18 | { 19 | $this->dropIndex('settings_unique_key_section', '{{%settings}}'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /models/BaseSetting.php: -------------------------------------------------------------------------------- 1 | 31 | */ 32 | class BaseSetting extends ActiveRecord implements SettingInterface 33 | { 34 | /** 35 | * @inheritdoc 36 | */ 37 | public static function tableName() 38 | { 39 | return '{{%settings}}'; 40 | } 41 | 42 | /** 43 | * @inheritdoc 44 | */ 45 | public function rules() 46 | { 47 | return [ 48 | [['value'], 'string'], 49 | [['section', 'key'], 'string', 'max' => 255], 50 | [ 51 | ['key'], 52 | 'unique', 53 | 'targetAttribute' => ['section', 'key'], 54 | ], 55 | ['type', 'in', 'range' => ['string', 'integer', 'boolean', 'float', 'double', 'object', 'null', 'ip', 'email', 'url']], 56 | [['created', 'modified'], 'safe'], 57 | [['active'], 'boolean'], 58 | ]; 59 | } 60 | 61 | public function afterSave($insert, $changedAttributes) 62 | { 63 | parent::afterSave($insert, $changedAttributes); 64 | Yii::$app->settings->clearCache(); 65 | } 66 | 67 | public function afterDelete() 68 | { 69 | parent::afterDelete(); 70 | Yii::$app->settings->clearCache(); 71 | } 72 | 73 | /** 74 | * @return array 75 | */ 76 | public function behaviors() 77 | { 78 | return [ 79 | 'timestamp' => [ 80 | 'class' => TimestampBehavior::className(), 81 | 'attributes' => [ 82 | ActiveRecord::EVENT_BEFORE_INSERT => 'created', 83 | ActiveRecord::EVENT_BEFORE_UPDATE => 'modified', 84 | ], 85 | 'value' => new Expression('NOW()'), 86 | ], 87 | ]; 88 | } 89 | 90 | /** 91 | * @inheritdoc 92 | */ 93 | public function getSettings() 94 | { 95 | $settings = static::find()->where(['active' => true])->asArray()->all(); 96 | return array_merge_recursive( 97 | ArrayHelper::map($settings, 'key', 'value', 'section'), 98 | ArrayHelper::map($settings, 'key', 'type', 'section') 99 | ); 100 | } 101 | 102 | /** 103 | * @inheritdoc 104 | */ 105 | public function setSetting($section, $key, $value, $type = null) 106 | { 107 | $model = static::findOne(['section' => $section, 'key' => $key]); 108 | 109 | if ($model === null) { 110 | $model = new static(); 111 | $model->active = 1; 112 | } 113 | $model->section = $section; 114 | $model->key = $key; 115 | $model->value = strval($value); 116 | 117 | if ($type !== null) { 118 | $model->type = $type; 119 | } elseif ( ! isset($model->type) ) { 120 | $type = $this->getValueType($value); 121 | $model->type = $type; 122 | } 123 | 124 | return $model->save(); 125 | } 126 | 127 | /** 128 | * @inheritdoc 129 | */ 130 | public function activateSetting($section, $key) 131 | { 132 | $model = static::findOne(['section' => $section, 'key' => $key]); 133 | 134 | if ($model && $model->active == 0) { 135 | $model->active = 1; 136 | return $model->save(); 137 | } 138 | return false; 139 | } 140 | 141 | /** 142 | * @inheritdoc 143 | */ 144 | public function deactivateSetting($section, $key) 145 | { 146 | $model = static::findOne(['section' => $section, 'key' => $key]); 147 | 148 | if ($model && $model->active == 1) { 149 | $model->active = 0; 150 | return $model->save(); 151 | } 152 | return false; 153 | } 154 | 155 | /** 156 | * @inheritdoc 157 | */ 158 | public function deleteSetting($section, $key) 159 | { 160 | $model = static::findOne(['section' => $section, 'key' => $key]); 161 | 162 | if ($model) { 163 | return $model->delete(); 164 | } 165 | return true; 166 | } 167 | 168 | /** 169 | * @inheritdoc 170 | */ 171 | public function deleteAllSettings() 172 | { 173 | return static::deleteAll(); 174 | } 175 | 176 | /** 177 | * @inheritdoc 178 | */ 179 | public function findSetting($key, $section = null) 180 | { 181 | if (is_null($section)) { 182 | $pieces = explode('.', $key, 2); 183 | if (count($pieces) > 1) { 184 | $section = $pieces[0]; 185 | $key = $pieces[1]; 186 | } else { 187 | $section = ''; 188 | } 189 | } 190 | return $this->find()->where(['section' => $section, 'key' => $key])->limit(1)->one(); 191 | } 192 | 193 | /** 194 | * @param $value 195 | * @return string|void 196 | */ 197 | protected function getValueType($value) 198 | { 199 | 200 | if (filter_var($value, FILTER_VALIDATE_EMAIL)) { 201 | return 'email'; 202 | } 203 | 204 | if (filter_var($value, FILTER_VALIDATE_URL)) { 205 | return 'url'; 206 | } 207 | 208 | if (filter_var($value, FILTER_VALIDATE_IP)) { 209 | return 'ip'; 210 | } 211 | 212 | if (filter_var($value, FILTER_VALIDATE_BOOLEAN)) { 213 | return 'boolean'; 214 | } 215 | 216 | if (filter_var($value, FILTER_VALIDATE_INT)) { 217 | return 'integer'; 218 | } 219 | 220 | if (filter_var($value, FILTER_VALIDATE_FLOAT)) { 221 | return 'float'; 222 | } 223 | 224 | $t = gettype($value); 225 | 226 | if ($t === 'object' && !empty($value)) { 227 | $error = false; 228 | try { 229 | Json::decode($value); 230 | } catch (InvalidArgumentException $e) { 231 | $error = true; 232 | } 233 | if (!$error) { 234 | $t = 'object'; 235 | } 236 | } 237 | return $t; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /models/Setting.php: -------------------------------------------------------------------------------- 1 | 20 | */ 21 | class Setting extends BaseSetting 22 | { 23 | /** 24 | * @param bool $forDropDown if false - return array or validators, true - key=>value for dropDown 25 | * @return array 26 | */ 27 | public function getTypes($forDropDown = true) 28 | { 29 | $values = [ 30 | 'string' => ['value', 'string'], 31 | 'integer' => ['value', 'integer'], 32 | 'boolean' => ['value', 'boolean', 'trueValue' => "1", 'falseValue' => "0", 'strict' => true], 33 | 'float' => ['value', 'number'], 34 | 'email' => ['value', 'email'], 35 | 'ip' => ['value', 'ip'], 36 | 'url' => ['value', 'url'], 37 | 'object' => [ 38 | 'value', 39 | function ($attribute, $params) { 40 | $object = null; 41 | try { 42 | Json::decode($this->$attribute); 43 | } catch (InvalidParamException $e) { 44 | $this->addError($attribute, Module::t('settings', '"{attribute}" must be a valid JSON object', [ 45 | 'attribute' => $attribute, 46 | ])); 47 | } 48 | } 49 | ], 50 | ]; 51 | 52 | if (!$forDropDown) { 53 | return $values; 54 | } 55 | 56 | $return = []; 57 | foreach ($values as $key => $value) { 58 | $return[$key] = Module::t('settings', $key); 59 | } 60 | 61 | return $return; 62 | } 63 | 64 | /** 65 | * @inheritdoc 66 | */ 67 | public function rules() 68 | { 69 | return [ 70 | [['value'], 'string'], 71 | [['section', 'key'], 'string', 'max' => 255], 72 | [ 73 | ['key'], 74 | 'unique', 75 | 'targetAttribute' => ['section', 'key'], 76 | 'message' => 77 | Module::t('settings', '{attribute} "{value}" already exists for this section.') 78 | ], 79 | ['type', 'in', 'range' => array_keys($this->getTypes(false))], 80 | [['type', 'created', 'modified'], 'safe'], 81 | [['active'], 'boolean'], 82 | ]; 83 | } 84 | 85 | public function beforeSave($insert) 86 | { 87 | $validators = $this->getTypes(false); 88 | if (!array_key_exists($this->type, $validators)) { 89 | $this->addError('type', Module::t('settings', 'Please select correct type')); 90 | return false; 91 | } 92 | 93 | $model = DynamicModel::validateData([ 94 | 'value' => $this->value 95 | ], [ 96 | $validators[$this->type], 97 | ]); 98 | 99 | if ($model->hasErrors()) { 100 | $this->addError('value', $model->getFirstError('value')); 101 | return false; 102 | } 103 | 104 | if ($this->hasErrors()) { 105 | return false; 106 | } 107 | 108 | return parent::beforeSave($insert); 109 | } 110 | 111 | /** 112 | * @inheritdoc 113 | */ 114 | public function attributeLabels() 115 | { 116 | return [ 117 | 'id' => Module::t('settings', 'ID'), 118 | 'type' => Module::t('settings', 'Type'), 119 | 'section' => Module::t('settings', 'Section'), 120 | 'key' => Module::t('settings', 'Key'), 121 | 'value' => Module::t('settings', 'Value'), 122 | 'active' => Module::t('settings', 'Active'), 123 | 'created' => Module::t('settings', 'Created'), 124 | 'modified' => Module::t('settings', 'Modified'), 125 | ]; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /models/SettingInterface.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | interface SettingInterface 17 | { 18 | 19 | /** 20 | * Gets a combined map of all the settings. 21 | * @return array 22 | */ 23 | public function getSettings(); 24 | 25 | /** 26 | * Saves a setting 27 | * 28 | * @param $section 29 | * @param $key 30 | * @param $value 31 | * @param $type 32 | * @return bool 33 | * @throws \yii\base\InvalidConfigException 34 | */ 35 | public function setSetting($section, $key, $value, $type); 36 | 37 | /** 38 | * Deletes a settings 39 | * 40 | * @param $key 41 | * @param $section 42 | * @return boolean True on success, false on error 43 | */ 44 | public function deleteSetting($section, $key); 45 | 46 | /** 47 | * Deletes all settings! Be careful! 48 | * @return boolean True on success, false on error 49 | */ 50 | public function deleteAllSettings(); 51 | 52 | /** 53 | * Activates a setting 54 | * 55 | * @param $key 56 | * @param $section 57 | * @return boolean True on success, false on error 58 | */ 59 | public function activateSetting($section, $key); 60 | 61 | /** 62 | * Deactivates a setting 63 | * 64 | * @param $key 65 | * @param $section 66 | * @return boolean True on success, false on error 67 | */ 68 | public function deactivateSetting($section, $key); 69 | 70 | /** 71 | * Finds a single setting 72 | * 73 | * @param $key 74 | * @param $section 75 | * @return SettingInterface single setting 76 | */ 77 | public function findSetting($section, $key); 78 | } 79 | -------------------------------------------------------------------------------- /models/SettingSearch.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class SettingSearch extends Setting 20 | { 21 | /** 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | [['id'], 'integer'], 28 | [['active'], 'boolean'], 29 | [['type', 'section', 'key', 'value', 'created', 'modified'], 'safe'], 30 | ]; 31 | } 32 | 33 | /** 34 | * @return array 35 | */ 36 | public function scenarios() 37 | { 38 | // bypass scenarios() implementation in the parent class 39 | return Model::scenarios(); 40 | } 41 | 42 | /** 43 | * @param $params 44 | * @return ActiveDataProvider 45 | */ 46 | public function search($params) 47 | { 48 | $query = Setting::find(); 49 | 50 | $dataProvider = new ActiveDataProvider( 51 | [ 52 | 'query' => $query, 53 | ] 54 | ); 55 | 56 | if (!($this->load($params) && $this->validate())) { 57 | return $dataProvider; 58 | } 59 | 60 | $query->andFilterWhere( 61 | [ 62 | 'id' => $this->id, 63 | 'active' => $this->active, 64 | 'section' => $this->section, 65 | ] 66 | ); 67 | 68 | $query->andFilterWhere(['like', 'key', $this->key]) 69 | ->andFilterWhere(['like', 'value', $this->value]); 70 | 71 | return $dataProvider; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | ./tests 13 | 14 | 15 | 16 | 17 | ./models 18 | ./components 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/BaseSettingModelTest.php: -------------------------------------------------------------------------------- 1 | setting = Yii::$app->settings; 19 | $this->model->value = "i am testSet value"; 20 | $this->model->section = "testSetKey"; 21 | $this->model->type = 'string'; 22 | $this->model->modified = time(); 23 | $this->model->active = "1"; 24 | $this->model->key = 'testSetKey'; 25 | $this->model->save(); 26 | } 27 | 28 | public function testSave() 29 | { 30 | $this->model->type = "double"; 31 | $this->assertFalse($this->model->save()); 32 | } 33 | 34 | public function testGetSettings() 35 | { 36 | $res = $this->model->getSettings()['testSetKey']['testSetKey']; 37 | $this->assertTrue($res[0] == 'i am testSet value'); 38 | $this->assertTrue($res[1] == 'string'); 39 | } 40 | 41 | public function testSetSetting() 42 | { 43 | $res = $this->model->setSetting("testSetKey", "testSetKey", "aa", "string"); 44 | $this->assertTrue($res); 45 | $res = $this->model->setSetting("testSetKey", "testSetKey1", "bb", "string"); 46 | $this->assertTrue($res); 47 | } 48 | 49 | public function testDeactivateSetting() 50 | { 51 | $res = $this->model->deactivateSetting("testSetKey", "testSetKey"); 52 | $this->assertTrue($res); 53 | $res = $this->model->deactivateSetting("testSetKey", "testSetKey"); 54 | $this->assertFalse($res); 55 | } 56 | 57 | public function testActivateSetting() 58 | { 59 | $res1 = $this->model->deactivateSetting("testSetKey", "testSetKey"); 60 | $res2 = $this->model->activateSetting("testSetKey", "testSetKey"); 61 | $this->assertTrue($res1 && $res2); 62 | $res3 = $this->model->activateSetting("testSetKey", "testSetKey"); 63 | $this->assertFalse($res3); 64 | } 65 | 66 | public function testDeleteSetting() 67 | { 68 | $res = $this->model->deleteSetting("testSetKey", "testSetKey"); 69 | $this->assertTrue($res == 1); 70 | } 71 | 72 | public function testDeleteAllSettings() 73 | { 74 | $res = $this->model->deleteAllSettings(); 75 | $this->assertTrue($res == 1); 76 | } 77 | 78 | public function testFindSetting() 79 | { 80 | $res = $this->model->findSetting("testSetKey", "testSetKey"); 81 | $this->assertTrue($res->id > 0); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tests/ComponentSettingTest.php: -------------------------------------------------------------------------------- 1 | setting = Yii::$app->settings; 25 | $this->setting->init(); 26 | $this->model->value = "i am testSet value"; 27 | $this->model->section = "testSetKey"; 28 | $this->model->type = 'string'; 29 | $this->model->modified = time(); 30 | $this->model->active = "0"; 31 | $this->model->key = 'testSetKey'; 32 | $this->model->save(); 33 | } 34 | 35 | public function testSet() 36 | { 37 | $res = $this->setting->set('testSetKey', "i am testSet value", 'testSetKey'); 38 | $this->assertTrue($res, '通过组件来修改testSetKey的section'); 39 | } 40 | 41 | public function testGet() 42 | { 43 | $this->setting->activate("testSetKey", "testSetKey"); 44 | $res = $this->setting->get("testSetKey", "testSetKey"); 45 | $this->assertTrue($res == "i am testSet value"); 46 | $res1 = $this->setting->get("testSetKey.testSetKey"); 47 | $this->assertTrue($res1 == "i am testSet value"); 48 | } 49 | 50 | public function testHas() 51 | { 52 | $this->setting->activate("testSetKey", "testSetKey"); 53 | $res = $this->setting->has("testSetKey", "testSetKey"); 54 | $this->assertTrue($res); 55 | } 56 | 57 | public function testDelete() 58 | { 59 | $res = $this->setting->delete("testSetKey", "testSetKey"); 60 | $this->assertTrue($res == 1); 61 | } 62 | 63 | public function testDeleteAll() 64 | { 65 | $res = $this->setting->deleteAll(); 66 | $this->assertTrue($res > 0); 67 | } 68 | 69 | public function testActivate() 70 | { 71 | $res = $this->setting->activate("testSetKey", "testSetKey"); 72 | $this->assertTrue($res); 73 | } 74 | 75 | public function testDeActivate() 76 | { 77 | $this->setting->activate("testSetKey", "testSetKey"); 78 | $res = $this->setting->deactivate("testSetKey", "testSetKey"); 79 | $this->assertTrue($res); 80 | } 81 | 82 | public function testGetRawConfig() 83 | { 84 | $this->setting->activate("testSetKey", "testSetKey"); 85 | $this->setting->get('testSetKey', "testSetKey"); 86 | $res = $this->setting->getRawConfig(); 87 | $this->assertTrue($res['testSetKey']['testSetKey'][0] == $this->model->value); 88 | } 89 | 90 | public function testClearCache() 91 | { 92 | $res = $this->setting->clearCache(); 93 | $this->assertTrue($res); 94 | } 95 | 96 | public function testGetModelClass() 97 | { 98 | $this->assertTrue($this->setting->modelClass == (new Settings())->modelClass); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /tests/SettingModelTest.php: -------------------------------------------------------------------------------- 1 | model->value = "1"; 31 | $this->model->section = "i am section"; 32 | $this->model->type = 'integer'; 33 | $this->model->modified = "i am created"; 34 | $this->model->active = "1"; 35 | $allowType = implode(',', $this->model->getTypes("true")); 36 | $this->assertTrue($this->model->validate(), "type must be in " . $allowType); 37 | $this->model->type = 'doubles'; 38 | $this->assertFalse($this->model->validate(), "type must be in " . $allowType); 39 | } 40 | 41 | /** 42 | * active must be boolean 43 | */ 44 | public function testRulesActive() 45 | { 46 | $this->model->value = "1"; 47 | $this->model->section = "i am section"; 48 | $this->model->type = 'integer'; 49 | $this->model->modified = "i am created"; 50 | $this->model->active = 2; 51 | $this->assertFalse($this->model->validate(), "active must be bool"); 52 | } 53 | 54 | public function testAdd() 55 | { 56 | $this->model->value = "i am value"; 57 | $this->model->section = "testAdd"; 58 | $this->model->type = 'integer'; 59 | $this->model->modified = "i am created"; 60 | $this->model->active = "1"; 61 | $this->model->save(); 62 | $this->assertFalse($this->model->save(), 'value must be integer'); 63 | $this->model->active = 0; 64 | $this->model->type = "string"; 65 | $this->model->save(); 66 | $this->assertTrue($this->model->save()); 67 | $this->assertTrue(1 == $this->model->delete()); 68 | } 69 | 70 | public function testUpdate() 71 | { 72 | $this->model->value = "i am value"; 73 | $this->model->section = "testUpdate"; 74 | $this->model->type = 'string'; 75 | $this->model->key = "testUpdate"; 76 | $this->model->active = "1"; 77 | $this->model->save(); 78 | $model = Setting::findOne(['id' => $this->model->id]); 79 | $model->section = "testUpdated"; 80 | $this->assertTrue($model->save()); 81 | } 82 | 83 | public function testDelete() 84 | { 85 | $this->model->value = "i am value"; 86 | $this->model->section = "testUpdate"; 87 | $this->model->type = 'string'; 88 | $this->model->key = "testUpdate"; 89 | $this->model->active = "1"; 90 | $this->model->save(); 91 | $model = Setting::findOne(['active' => '1']); 92 | $this->assertTrue(1 == $model->delete()); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/SettingSearchTest.php: -------------------------------------------------------------------------------- 1 | model->value = "i am value"; 18 | $this->model->section = "testUpdate"; 19 | $this->model->type = 'string'; 20 | $this->model->key = "testUpdate"; 21 | $this->model->active = "1"; 22 | $this->model->save(); 23 | $params = ['SettingSearch' => ['active' => 1]]; 24 | $model = new SettingSearch(); 25 | $res = $model->search($params); 26 | $this->assertTrue($res->count == 1); 27 | $res1 = $model->search(['SettingSearch'=>[]]); 28 | $this->assertTrue($res1->count == 1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | mockApplication(); 28 | $this->createTestDbData(); 29 | $this->model = new Setting(); 30 | } 31 | 32 | protected function tearDown() 33 | { 34 | $this->destroyTestDbData(); 35 | $this->destroyApplication(); 36 | } 37 | 38 | /** 39 | * Populates Yii::$app with a new application 40 | * The application will be destroyed on tearDown() automatically. 41 | * 42 | * @param array $config The application configuration, if needed 43 | * @param string $appClass name of the application class to create 44 | */ 45 | protected function mockApplication($config = [], $appClass = '\yii\console\Application') 46 | { 47 | return new $appClass(ArrayHelper::merge([ 48 | 'id' => 'testapp', 49 | 'basePath' => __DIR__, 50 | 'vendorPath' => $this->getVendorPath(), 51 | 'components' => [ 52 | 'db' => [ 53 | 'class' => 'yii\db\Connection', 54 | 'dsn' => 'mysql:host=localhost:3306;dbname=test', 55 | 'username' => 'root', 56 | 'password' => '', 57 | 'tablePrefix' => 'tb_' 58 | ], 59 | 'i18n' => [ 60 | 'translations' => [ 61 | '*' => [ 62 | 'class' => 'yii\i18n\PhpMessageSource', 63 | ] 64 | ] 65 | ], 66 | 'settings' => [ 67 | 'class' => 'pheme\settings\components\Settings' 68 | ], 69 | 'cache' =>[ 70 | 'class' =>'yii\caching\ArrayCache' 71 | ], 72 | ], 73 | 'modules' => [ 74 | 'settings' => [ 75 | 'class' => 'pheme\settings\Module', 76 | 'sourceLanguage' => 'en' 77 | ] 78 | ] 79 | ], $config)); 80 | } 81 | 82 | protected function mockWebApplication($config = [], $appClass = '\yii\web\Application') 83 | { 84 | return new $appClass(ArrayHelper::merge([ 85 | 'id' => 'testapp', 86 | 'basePath' => __DIR__, 87 | 'vendorPath' => $this->getVendorPath(), 88 | 'components' => [ 89 | 'db' => [ 90 | 'class' => 'yii\db\Connection', 91 | 'dsn' => 'mysql:host=localhost:3306;dbname=test', 92 | 'username' => 'root', 93 | 'password' => '', 94 | 'tablePrefix' => 'tb_' 95 | ], 96 | 'i18n' => [ 97 | 'translations' => [ 98 | '*' => [ 99 | 'class' => 'yii\i18n\PhpMessageSource', 100 | ] 101 | ] 102 | ], 103 | 'settings' => [ 104 | 'class' => 'pheme\settings\components\Settings' 105 | ], 106 | 'cache' =>[ 107 | 'class' =>'yii\caching\ArrayCache' 108 | ], 109 | ], 110 | 'modules' => [ 111 | 'settings' => [ 112 | 'class' => '\pheme\settings\Module', 113 | 'sourceLanguage' => 'en' 114 | ] 115 | ] 116 | 117 | ], $config)); 118 | } 119 | 120 | /** 121 | * @return string vendor path 122 | */ 123 | protected function getVendorPath() 124 | { 125 | return dirname(__DIR__) . '/vendor'; 126 | } 127 | 128 | /** 129 | * Destroys application in Yii::$app by setting it to null. 130 | */ 131 | protected function destroyApplication() 132 | { 133 | if (Yii::$app && Yii::$app->has('session', true)) { 134 | Yii::$app->session->close(); 135 | } 136 | Yii::$app = null; 137 | } 138 | 139 | protected function destroyTestDbData() 140 | { 141 | $db = Yii::$app->getDb(); 142 | $res = $db->createCommand()->dropTable('tb_settings')->execute(); 143 | } 144 | 145 | protected function createTestDbData() 146 | { 147 | //$this->mockApplication()->runAction('/migrate'); 148 | $db = Yii::$app->getDb(); 149 | try { 150 | $db->createCommand()->createTable('tb_settings', [ 151 | 'id' => 'pk', 152 | 'type' => "string(255) not null", 153 | 'section' => "string(255) not null", 154 | 'key' => "string(255) not null", 155 | 'value' => "text", 156 | 'active' => "tinyint(1)", 157 | 'created' => "datetime", 158 | 'modified' => "datetime", 159 | ])->execute(); 160 | } catch (Exception $e) { 161 | return; 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 | 22 | 23 | 24 | field($model, 'section')->textInput(['maxlength' => 255]) ?> 25 | 26 | field($model, 'key')->textInput(['maxlength' => 255]) ?> 27 | 28 | field($model, 'value')->textarea(['rows' => 6]) ?> 29 | 30 | field($model, 'active')->checkbox(['value' => 1]) ?> 31 | 32 | field($model, 'type')->dropDownList( 34 | $model->getTypes() 35 | )->hint(Module::t('settings', 'Change at your own risk')) ?> 36 | 37 |
38 | isNewRecord ? Module::t('settings', 'Create') : 41 | Module::t('settings', 'Update'), 42 | [ 43 | 'class' => $model->isNewRecord ? 44 | 'btn btn-success' : 'btn btn-primary' 45 | ] 46 | ) ?> 47 |
48 | 49 | 50 | 51 |
52 | -------------------------------------------------------------------------------- /views/default/_search.php: -------------------------------------------------------------------------------- 1 | 18 | 19 | 46 | -------------------------------------------------------------------------------- /views/default/create.php: -------------------------------------------------------------------------------- 1 | title = Module::t( 17 | 'settings', 18 | 'Create {modelClass}', 19 | [ 20 | 'modelClass' => Module::t('settings', 'Setting'), 21 | ] 22 | ); 23 | $this->params['breadcrumbs'][] = ['label' => Module::t('settings', 'Settings'), 'url' => ['index']]; 24 | $this->params['breadcrumbs'][] = $this->title; 25 | ?> 26 |
27 | 28 |

title) ?>

29 | 30 | render( 32 | '_form', 33 | [ 34 | 'model' => $model, 35 | ] 36 | ) ?> 37 | 38 |
39 | -------------------------------------------------------------------------------- /views/default/index.php: -------------------------------------------------------------------------------- 1 | title = Module::t('settings', 'Settings'); 22 | $this->params['breadcrumbs'][] = $this->title; 23 | ?> 24 |
25 | 26 |

title) ?>

27 | render('_search', ['model' => $searchModel]);?> 28 | 29 |

30 | Module::t('settings', 'Setting'), 37 | ] 38 | ), 39 | ['create'], 40 | ['class' => 'btn btn-success'] 41 | ) ?> 42 |

43 | 44 | $dataProvider, 48 | 'filterModel' => $searchModel, 49 | 'columns' => [ 50 | 'id', 51 | //'type', 52 | [ 53 | 'attribute' => 'section', 54 | 'filter' => ArrayHelper::map( 55 | Setting::find()->select('section')->distinct()->where(['<>', 'section', ''])->all(), 56 | 'section', 57 | 'section' 58 | ), 59 | ], 60 | 'key', 61 | 'value:ntext', 62 | [ 63 | 'class' => '\pheme\grid\ToggleColumn', 64 | 'attribute' => 'active', 65 | 'filter' => [1 => Yii::t('yii', 'Yes'), 0 => Yii::t('yii', 'No')], 66 | ], 67 | ['class' => 'yii\grid\ActionColumn'], 68 | ], 69 | ] 70 | ); ?> 71 | 72 |
73 | -------------------------------------------------------------------------------- /views/default/update.php: -------------------------------------------------------------------------------- 1 | title = Module::t( 17 | 'settings', 18 | 'Update {modelClass}: ', 19 | [ 20 | 'modelClass' => Module::t('settings', 'Setting'), 21 | ] 22 | ) . ' ' . $model->section. '.' . $model->key; 23 | 24 | $this->params['breadcrumbs'][] = ['label' => Module::t('settings', 'Settings'), 'url' => ['index']]; 25 | $this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; 26 | $this->params['breadcrumbs'][] = Module::t('settings', 'Update'); 27 | 28 | ?> 29 |
30 | 31 |

title) ?>

32 | 33 | render( 35 | '_form', 36 | [ 37 | 'model' => $model, 38 | ] 39 | ) ?> 40 | 41 |
42 | -------------------------------------------------------------------------------- /views/default/view.php: -------------------------------------------------------------------------------- 1 | title = $model->section. '.' . $model->key; 18 | $this->params['breadcrumbs'][] = ['label' => Module::t('settings', 'Settings'), 'url' => ['index']]; 19 | $this->params['breadcrumbs'][] = $this->title; 20 | ?> 21 |
22 | 23 |

title) ?>

24 | 25 |

26 | $model->id], ['class' => 'btn btn-primary']) ?> 27 | $model->id], 31 | [ 32 | 'class' => 'btn btn-danger', 33 | 'data' => [ 34 | 'confirm' => Module::t('settings', 'Are you sure you want to delete this item?'), 35 | 'method' => 'post', 36 | ], 37 | ] 38 | ) ?> 39 |

40 | 41 | $model, 45 | 'attributes' => [ 46 | 'id', 47 | 'type', 48 | 'section', 49 | 'active:boolean', 50 | 'key', 51 | 'value:ntext', 52 | 'created:datetime', 53 | 'modified:datetime', 54 | ], 55 | ] 56 | ) ?> 57 | 58 |
59 | --------------------------------------------------------------------------------