├── .gitignore
├── Bootstrap.php
├── CHANGELOG.md
├── LICENSE
├── README.md
├── behaviors
└── ChangelogBehavior.php
├── components
└── LogsStorage.php
├── composer.json
├── composer.lock
├── debug
├── models
│ └── search
│ │ └── ChangelogSearch.php
├── panels
│ └── ChangelogPanel.php
└── views
│ └── panels
│ └── changelog
│ ├── detail.php
│ └── summary.php
├── interfaces
├── ChangelogModelInterface.php
├── LoggableInterface.php
└── LogsStorageInterface.php
├── migrations
└── m150816_130733_changelog.php
└── resources
├── Changelog.php
├── Log.php
└── queries
└── ChangelogQuery.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | /vendor
3 | /coverage
4 |
--------------------------------------------------------------------------------
/Bootstrap.php:
--------------------------------------------------------------------------------
1 | on(Application::EVENT_AFTER_REQUEST, function () {
27 | /** @var LogsStorage $Storage */
28 | $Storage = Instance::ensure([
29 | 'class' => LogsStorage::className(),
30 | ]);
31 |
32 | $Storage::save();
33 | });
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | 2016-10-05 - 1.0.1
2 | ------------------
3 | * Bugfix #1
4 |
5 | 2016-07-14 - 1.0.0
6 | ------------------
7 | * Change mysql table engine to `ARCHIVE`.
8 | * Added collector log for the bulk insert.
9 | * Global refactoring.
10 |
11 | 2016-06-01 - 0.1.4
12 | ------------------
13 | * Added the ability to use his model to save log.
14 |
15 | 2016-04-21 - 0.1.2
16 | ------------------
17 | * Update summary debug panel view to new css.
18 | * Updated packages.
19 |
20 | 2015-12-28 - 0.1.1
21 | -------------------
22 | * Rename `excludeAttributes` to `ignoreAttributes`.
23 |
24 | 2015-12-28 - 0.1.0
25 | -------------------
26 | * Initial extension.
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Revin Roman Borisovich
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Active record changelog extension for Yii 2 framework
2 | =====================================================
3 |
4 | This extension provides a changelog functional.
5 |
6 | For license information check the [LICENSE](https://github.com/rmrevin/yii2-changelog/blob/master/LICENSE)-file.
7 |
8 | Support
9 | -------
10 | * [GitHub issues](https://github.com/rmrevin/yii2-changelog/issues)
11 | * [Public chat](https://gitter.im/rmrevin/support)
12 |
13 | Installation
14 | ------------
15 |
16 | The preferred way to install this extension is through [composer](https://getcomposer.org/).
17 |
18 | Either run
19 |
20 | ```bash
21 | composer require "rmrevin/yii2-changelog:~1.0"
22 | ```
23 |
24 | or add
25 |
26 | ```
27 | "rmrevin/yii2-changelog": "~1.0",
28 | ```
29 |
30 | to the `require` section of your `composer.json` file.
31 |
32 | Execute migrations:
33 | ```
34 | php yii migrate --migrationPath=@rmrevin/yii/changelog/migrations
35 | ```
36 |
37 | Usage
38 | -----
39 |
40 | To view the history, you can use a special panel for debug.
41 | Or make your own section to view the data in your administration panel.
42 |
43 | To enable the debug panel, add the following code in the module configuration debug.
44 | ```php
45 | 'modules' => [
46 | // ...
47 | 'debug' => [
48 | 'class' => yii\debug\Module::className(),
49 | 'panels' => [
50 | rmrevin\yii\changelog\debug\panels\ChangelogPanel::class,
51 | ],
52 | ],
53 | ],
54 |
55 | ```
56 |
57 | For `ActiveRecord` models for which you want to track changes,
58 | you must implement the interface `rmrevin\yii\changelog\interfaces\LoggableInterface`
59 | and add the behavior of `rmrevin\yii\changelog\behaviors\ChangelogBehavior`.
60 |
61 | Example:
62 | ```php
63 | number, $this->title);
88 | }
89 |
90 | /**
91 | * @inheritdoc
92 | */
93 | public function behaviors()
94 | {
95 | return [
96 | // ...
97 | [
98 | 'class' => ChangelogBehavior::class,
99 | 'ignoreAttributes' => [ // these attributes are not tracked
100 | 'updated_at',
101 | 'synchronized_at',
102 | ],
103 | ],
104 | ];
105 | }
106 | }
107 | ```
108 |
109 | Done
110 | ----
111 | Now when you try to create, modify or delete an instance of a model `ShopItem`
112 | in the table `{{%changelog}}` will be recorded relevant information.
113 |
--------------------------------------------------------------------------------
/behaviors/ChangelogBehavior.php:
--------------------------------------------------------------------------------
1 | 'logInsert',
35 | BaseActiveRecord::EVENT_AFTER_UPDATE => 'logUpdate',
36 | BaseActiveRecord::EVENT_AFTER_DELETE => 'logDelete',
37 | ];
38 | }
39 |
40 | /**
41 | * @param \yii\db\AfterSaveEvent $Event
42 | */
43 | public function logInsert($Event)
44 | {
45 | $Storage = $this->getStorage();
46 |
47 | /** @var BaseActiveRecord $Model */
48 | $Model = $Event->sender;
49 |
50 | $attributes = $Model->attributes;
51 |
52 | $this->unsetIgnoreAttributes($attributes);
53 |
54 | /** @var Log $Log */
55 | $Log = Instance::ensure(['class' => Log::className()]);
56 | $Log->action($Storage::ACTION_INSERT)
57 | ->entity($Model)
58 | ->changes(['insert' => $attributes]);
59 |
60 | $Storage::store($Log);
61 | }
62 |
63 | /**
64 | * @param \yii\db\AfterSaveEvent $Event
65 | */
66 | public function logUpdate($Event)
67 | {
68 | $Storage = $this->getStorage();
69 |
70 | /** @var BaseActiveRecord $Model */
71 | $Model = $Event->sender;
72 |
73 | $attributes = $Model->attributes;
74 |
75 | $changedAttributes = $Event->changedAttributes;
76 |
77 | $this->unsetIgnoreAttributes($attributes, $changedAttributes);
78 |
79 | $newAttributes = [];
80 | foreach ($attributes as $k => $v) {
81 | if (isset($changedAttributes[$k])) {
82 | $newAttributes[$k] = $v;
83 | }
84 | }
85 |
86 | if (!empty($changedAttributes)) {
87 | /** @var Log $Log */
88 | $Log = Instance::ensure(['class' => Log::className()]);
89 | $Log->action($Storage::ACTION_UPDATE)
90 | ->entity($Model)
91 | ->changes([
92 | 'update' => [
93 | 'from' => $changedAttributes,
94 | 'to' => $newAttributes,
95 | ],
96 | ]);
97 |
98 | $Storage::store($Log);
99 | }
100 | }
101 |
102 | /**
103 | * @param \yii\base\Event $Event
104 | */
105 | public function logDelete($Event)
106 | {
107 | $Storage = $this->getStorage();
108 |
109 | /** @var BaseActiveRecord $Model */
110 | $Model = $Event->sender;
111 |
112 | $attributes = $Model->attributes;
113 |
114 | $this->unsetIgnoreAttributes($attributes);
115 |
116 | /** @var Log $Log */
117 | $Log = Instance::ensure(['class' => Log::className()]);
118 | $Log->action($Storage::ACTION_DELETE)
119 | ->entity($Model)
120 | ->changes(['delete' => $attributes]);
121 |
122 | $Storage::store($Log);
123 | }
124 |
125 | /**
126 | * @return LogsStorage
127 | */
128 | protected function getStorage()
129 | {
130 | /** @var LogsStorage $Storage */
131 | $Storage = Instance::ensure([
132 | 'class' => LogsStorage::className(),
133 | ]);
134 |
135 | return $Storage;
136 | }
137 |
138 | /**
139 | * @param array $attributes
140 | * @param array $changedAttributes
141 | */
142 | protected function unsetIgnoreAttributes(array &$attributes, array &$changedAttributes = [])
143 | {
144 | $ignoreAttributes = $this->ignoreAttributes;
145 |
146 | if (!empty($ignoreAttributes)) {
147 | foreach ($ignoreAttributes as $field) {
148 | if (isset($attributes[$field])) {
149 | unset($attributes[$field]);
150 | }
151 |
152 | if (isset($changedAttributes[$field])) {
153 | unset($changedAttributes[$field]);
154 | }
155 | }
156 | }
157 | }
158 |
159 | /**
160 | * @return array
161 | */
162 | protected function getEnvData()
163 | {
164 | $result = [
165 | 'ENV' => $_ENV,
166 | 'SERVER' => $_SERVER,
167 | ];
168 |
169 | $Request = Instance::ensure('request', Request::className());
170 |
171 | if ($Request instanceof \yii\web\Request) {
172 | $result['COOKIE'] = $_COOKIE;
173 | $result['GET'] = $Request->get();
174 | $result['POST'] = $Request->post();
175 | $result['REQUEST_BODY'] = $Request->getRawBody();
176 | }
177 |
178 | // @todo add gzip compress
179 | return $result;
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/components/LogsStorage.php:
--------------------------------------------------------------------------------
1 | Changelog::className(),
42 | ]);
43 |
44 | /** @var Log $Log */
45 | $Log = Instance::ensure([
46 | 'class' => Log::className(),
47 | ]);
48 |
49 | $columns = $Log::schema();
50 |
51 | $rows = [];
52 |
53 | $Logs = static::$storage;
54 | if (!empty($Logs)) {
55 | foreach ($Logs as $Log) {
56 | $rows[] = $Log->export();
57 | }
58 | }
59 |
60 | if (!empty($rows)) {
61 | /** @var \yii\db\Connection $DB */
62 | $DB = \Yii::$app->get('db');
63 | $DB->createCommand()
64 | ->batchInsert($Model::tableName(), $columns, $rows)
65 | ->execute();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rmrevin/yii2-changelog",
3 | "description": "Active record changelog extension for Yii 2 framework",
4 | "keywords": [
5 | "yii",
6 | "activerecord",
7 | "history",
8 | "changelog"
9 | ],
10 | "type": "yii2-extension",
11 | "license": "MIT",
12 | "minimum-stability": "stable",
13 | "support": {
14 | "issues": "https://github.com/rmrevin/yii2-changelog/issues",
15 | "source": "https://github.com/rmrevin/yii2-changelog"
16 | },
17 | "authors": [
18 | {
19 | "name": "Revin Roman",
20 | "email": "roman@rmrevin.com",
21 | "homepage": "https://rmrevin.com/"
22 | }
23 | ],
24 | "require": {
25 | "php": ">=5.4.0",
26 |
27 | "yiisoft/yii2": "2.0.*"
28 | },
29 | "require-dev": {
30 | "yiisoft/yii2-debug": "2.0.*"
31 | },
32 | "autoload": {
33 | "psr-4": {
34 | "rmrevin\\yii\\changelog\\": ""
35 | }
36 | },
37 | "extra": {
38 | "bootstrap": "rmrevin\\yii\\changelog\\Bootstrap",
39 | "asset-installer-paths": {
40 | "npm-asset-library": "vendor/npm",
41 | "bower-asset-library": "vendor/bower"
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "a467b45c2a0f5668335a7dd5c6bfa42f",
8 | "content-hash": "876d3444c9828ddcc9d8a3ee62d63937",
9 | "packages": [
10 | {
11 | "name": "bower-asset/jquery",
12 | "version": "2.2.3",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/jquery/jquery-dist.git",
16 | "reference": "af22a351b2ea5801ffb1695abb3bb34d5bed9198"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/af22a351b2ea5801ffb1695abb3bb34d5bed9198",
21 | "reference": "af22a351b2ea5801ffb1695abb3bb34d5bed9198",
22 | "shasum": ""
23 | },
24 | "type": "bower-asset-library",
25 | "extra": {
26 | "bower-asset-main": "dist/jquery.js",
27 | "bower-asset-ignore": [
28 | "package.json"
29 | ]
30 | },
31 | "license": [
32 | "MIT"
33 | ],
34 | "keywords": [
35 | "browser",
36 | "javascript",
37 | "jquery",
38 | "library"
39 | ]
40 | },
41 | {
42 | "name": "bower-asset/jquery.inputmask",
43 | "version": "3.2.7",
44 | "source": {
45 | "type": "git",
46 | "url": "https://github.com/RobinHerbots/jquery.inputmask.git",
47 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38"
48 | },
49 | "dist": {
50 | "type": "zip",
51 | "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/5a72c563b502b8e05958a524cdfffafe9987be38",
52 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38",
53 | "shasum": ""
54 | },
55 | "require": {
56 | "bower-asset/jquery": ">=1.7"
57 | },
58 | "type": "bower-asset-library",
59 | "extra": {
60 | "bower-asset-main": [
61 | "./dist/inputmask/inputmask.js"
62 | ],
63 | "bower-asset-ignore": [
64 | "**/*",
65 | "!dist/*",
66 | "!dist/inputmask/*",
67 | "!dist/min/*",
68 | "!dist/min/inputmask/*",
69 | "!extra/bindings/*",
70 | "!extra/dependencyLibs/*",
71 | "!extra/phone-codes/*"
72 | ]
73 | },
74 | "license": [
75 | "http://opensource.org/licenses/mit-license.php"
76 | ],
77 | "description": "jquery.inputmask is a jquery plugin which create an input mask.",
78 | "keywords": [
79 | "form",
80 | "input",
81 | "inputmask",
82 | "jquery",
83 | "mask",
84 | "plugins"
85 | ]
86 | },
87 | {
88 | "name": "bower-asset/punycode",
89 | "version": "v1.3.2",
90 | "source": {
91 | "type": "git",
92 | "url": "https://github.com/bestiejs/punycode.js.git",
93 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
94 | },
95 | "dist": {
96 | "type": "zip",
97 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
98 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3",
99 | "shasum": ""
100 | },
101 | "type": "bower-asset-library",
102 | "extra": {
103 | "bower-asset-main": "punycode.js",
104 | "bower-asset-ignore": [
105 | "coverage",
106 | "tests",
107 | ".*",
108 | "component.json",
109 | "Gruntfile.js",
110 | "node_modules",
111 | "package.json"
112 | ]
113 | }
114 | },
115 | {
116 | "name": "bower-asset/yii2-pjax",
117 | "version": "v2.0.6",
118 | "source": {
119 | "type": "git",
120 | "url": "https://github.com/yiisoft/jquery-pjax.git",
121 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978"
122 | },
123 | "dist": {
124 | "type": "zip",
125 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/60728da6ade5879e807a49ce59ef9a72039b8978",
126 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978",
127 | "shasum": ""
128 | },
129 | "require": {
130 | "bower-asset/jquery": ">=1.8"
131 | },
132 | "type": "bower-asset-library",
133 | "extra": {
134 | "bower-asset-main": "./jquery.pjax.js",
135 | "bower-asset-ignore": [
136 | ".travis.yml",
137 | "Gemfile",
138 | "Gemfile.lock",
139 | "CONTRIBUTING.md",
140 | "vendor/",
141 | "script/",
142 | "test/"
143 | ]
144 | },
145 | "license": [
146 | "MIT"
147 | ]
148 | },
149 | {
150 | "name": "cebe/markdown",
151 | "version": "1.1.0",
152 | "source": {
153 | "type": "git",
154 | "url": "https://github.com/cebe/markdown.git",
155 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2"
156 | },
157 | "dist": {
158 | "type": "zip",
159 | "url": "https://api.github.com/repos/cebe/markdown/zipball/54a2c49de31cc44e864ebf0500a35ef21d0010b2",
160 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2",
161 | "shasum": ""
162 | },
163 | "require": {
164 | "lib-pcre": "*",
165 | "php": ">=5.4.0"
166 | },
167 | "require-dev": {
168 | "cebe/indent": "*",
169 | "facebook/xhprof": "*@dev",
170 | "phpunit/phpunit": "4.1.*"
171 | },
172 | "bin": [
173 | "bin/markdown"
174 | ],
175 | "type": "library",
176 | "extra": {
177 | "branch-alias": {
178 | "dev-master": "1.1.x-dev"
179 | }
180 | },
181 | "autoload": {
182 | "psr-4": {
183 | "cebe\\markdown\\": ""
184 | }
185 | },
186 | "notification-url": "https://packagist.org/downloads/",
187 | "license": [
188 | "MIT"
189 | ],
190 | "authors": [
191 | {
192 | "name": "Carsten Brandt",
193 | "email": "mail@cebe.cc",
194 | "homepage": "http://cebe.cc/",
195 | "role": "Creator"
196 | }
197 | ],
198 | "description": "A super fast, highly extensible markdown parser for PHP",
199 | "homepage": "https://github.com/cebe/markdown#readme",
200 | "keywords": [
201 | "extensible",
202 | "fast",
203 | "gfm",
204 | "markdown",
205 | "markdown-extra"
206 | ],
207 | "time": "2015-03-06 05:28:07"
208 | },
209 | {
210 | "name": "ezyang/htmlpurifier",
211 | "version": "v4.6.0",
212 | "source": {
213 | "type": "git",
214 | "url": "https://github.com/ezyang/htmlpurifier.git",
215 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd"
216 | },
217 | "dist": {
218 | "type": "zip",
219 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6f389f0f25b90d0b495308efcfa073981177f0fd",
220 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd",
221 | "shasum": ""
222 | },
223 | "require": {
224 | "php": ">=5.2"
225 | },
226 | "type": "library",
227 | "autoload": {
228 | "psr-0": {
229 | "HTMLPurifier": "library/"
230 | },
231 | "files": [
232 | "library/HTMLPurifier.composer.php"
233 | ]
234 | },
235 | "notification-url": "https://packagist.org/downloads/",
236 | "license": [
237 | "LGPL"
238 | ],
239 | "authors": [
240 | {
241 | "name": "Edward Z. Yang",
242 | "email": "admin@htmlpurifier.org",
243 | "homepage": "http://ezyang.com"
244 | }
245 | ],
246 | "description": "Standards compliant HTML filter written in PHP",
247 | "homepage": "http://htmlpurifier.org/",
248 | "keywords": [
249 | "html"
250 | ],
251 | "time": "2013-11-30 08:25:19"
252 | },
253 | {
254 | "name": "yiisoft/yii2",
255 | "version": "2.0.7",
256 | "source": {
257 | "type": "git",
258 | "url": "https://github.com/yiisoft/yii2-framework.git",
259 | "reference": "f45651582cb853b4326730d9d187a0f7a44a45a3"
260 | },
261 | "dist": {
262 | "type": "zip",
263 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/f45651582cb853b4326730d9d187a0f7a44a45a3",
264 | "reference": "f45651582cb853b4326730d9d187a0f7a44a45a3",
265 | "shasum": ""
266 | },
267 | "require": {
268 | "bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable",
269 | "bower-asset/jquery.inputmask": "~3.2.2",
270 | "bower-asset/punycode": "1.3.*",
271 | "bower-asset/yii2-pjax": "~2.0.1",
272 | "cebe/markdown": "~1.0.0 | ~1.1.0",
273 | "ext-ctype": "*",
274 | "ext-mbstring": "*",
275 | "ezyang/htmlpurifier": "4.6.*",
276 | "lib-pcre": "*",
277 | "php": ">=5.4.0",
278 | "yiisoft/yii2-composer": "~2.0.4"
279 | },
280 | "bin": [
281 | "yii"
282 | ],
283 | "type": "library",
284 | "extra": {
285 | "branch-alias": {
286 | "dev-master": "2.0.x-dev"
287 | }
288 | },
289 | "autoload": {
290 | "psr-4": {
291 | "yii\\": ""
292 | }
293 | },
294 | "notification-url": "https://packagist.org/downloads/",
295 | "license": [
296 | "BSD-3-Clause"
297 | ],
298 | "authors": [
299 | {
300 | "name": "Qiang Xue",
301 | "email": "qiang.xue@gmail.com",
302 | "homepage": "http://www.yiiframework.com/",
303 | "role": "Founder and project lead"
304 | },
305 | {
306 | "name": "Alexander Makarov",
307 | "email": "sam@rmcreative.ru",
308 | "homepage": "http://rmcreative.ru/",
309 | "role": "Core framework development"
310 | },
311 | {
312 | "name": "Maurizio Domba",
313 | "homepage": "http://mdomba.info/",
314 | "role": "Core framework development"
315 | },
316 | {
317 | "name": "Carsten Brandt",
318 | "email": "mail@cebe.cc",
319 | "homepage": "http://cebe.cc/",
320 | "role": "Core framework development"
321 | },
322 | {
323 | "name": "Timur Ruziev",
324 | "email": "resurtm@gmail.com",
325 | "homepage": "http://resurtm.com/",
326 | "role": "Core framework development"
327 | },
328 | {
329 | "name": "Paul Klimov",
330 | "email": "klimov.paul@gmail.com",
331 | "role": "Core framework development"
332 | },
333 | {
334 | "name": "Dmitry Naumenko",
335 | "email": "d.naumenko.a@gmail.com",
336 | "role": "Core framework development"
337 | }
338 | ],
339 | "description": "Yii PHP Framework Version 2",
340 | "homepage": "http://www.yiiframework.com/",
341 | "keywords": [
342 | "framework",
343 | "yii2"
344 | ],
345 | "time": "2016-02-14 14:45:55"
346 | },
347 | {
348 | "name": "yiisoft/yii2-composer",
349 | "version": "2.0.4",
350 | "source": {
351 | "type": "git",
352 | "url": "https://github.com/yiisoft/yii2-composer.git",
353 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464"
354 | },
355 | "dist": {
356 | "type": "zip",
357 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/7452fd908a5023b8bb5ea1b123a174ca080de464",
358 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464",
359 | "shasum": ""
360 | },
361 | "require": {
362 | "composer-plugin-api": "^1.0"
363 | },
364 | "type": "composer-plugin",
365 | "extra": {
366 | "class": "yii\\composer\\Plugin",
367 | "branch-alias": {
368 | "dev-master": "2.0.x-dev"
369 | }
370 | },
371 | "autoload": {
372 | "psr-4": {
373 | "yii\\composer\\": ""
374 | }
375 | },
376 | "notification-url": "https://packagist.org/downloads/",
377 | "license": [
378 | "BSD-3-Clause"
379 | ],
380 | "authors": [
381 | {
382 | "name": "Qiang Xue",
383 | "email": "qiang.xue@gmail.com"
384 | }
385 | ],
386 | "description": "The composer plugin for Yii extension installer",
387 | "keywords": [
388 | "composer",
389 | "extension installer",
390 | "yii2"
391 | ],
392 | "time": "2016-02-06 00:49:24"
393 | }
394 | ],
395 | "packages-dev": [
396 | {
397 | "name": "bower-asset/bootstrap",
398 | "version": "v3.3.5",
399 | "source": {
400 | "type": "git",
401 | "url": "https://github.com/twbs/bootstrap.git",
402 | "reference": "16b48259a62f576e52c903c476bd42b90ab22482"
403 | },
404 | "dist": {
405 | "type": "zip",
406 | "url": "https://api.github.com/repos/twbs/bootstrap/zipball/16b48259a62f576e52c903c476bd42b90ab22482",
407 | "reference": "16b48259a62f576e52c903c476bd42b90ab22482",
408 | "shasum": ""
409 | },
410 | "require": {
411 | "bower-asset/jquery": ">=1.9.1"
412 | },
413 | "type": "bower-asset-library",
414 | "extra": {
415 | "bower-asset-main": [
416 | "less/bootstrap.less",
417 | "dist/js/bootstrap.js"
418 | ],
419 | "bower-asset-ignore": [
420 | "/.*",
421 | "_config.yml",
422 | "CNAME",
423 | "composer.json",
424 | "CONTRIBUTING.md",
425 | "docs",
426 | "js/tests",
427 | "test-infra"
428 | ]
429 | },
430 | "license": [
431 | "MIT"
432 | ],
433 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
434 | "keywords": [
435 | "css",
436 | "framework",
437 | "front-end",
438 | "js",
439 | "less",
440 | "mobile-first",
441 | "responsive",
442 | "web"
443 | ]
444 | },
445 | {
446 | "name": "yiisoft/yii2-bootstrap",
447 | "version": "2.0.6",
448 | "source": {
449 | "type": "git",
450 | "url": "https://github.com/yiisoft/yii2-bootstrap.git",
451 | "reference": "3fd2b8c950cce79d60e9702d6bcb24eb3c80f6c5"
452 | },
453 | "dist": {
454 | "type": "zip",
455 | "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/3fd2b8c950cce79d60e9702d6bcb24eb3c80f6c5",
456 | "reference": "3fd2b8c950cce79d60e9702d6bcb24eb3c80f6c5",
457 | "shasum": ""
458 | },
459 | "require": {
460 | "bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*",
461 | "yiisoft/yii2": ">=2.0.6"
462 | },
463 | "type": "yii2-extension",
464 | "extra": {
465 | "branch-alias": {
466 | "dev-master": "2.0.x-dev"
467 | },
468 | "asset-installer-paths": {
469 | "npm-asset-library": "vendor/npm",
470 | "bower-asset-library": "vendor/bower"
471 | }
472 | },
473 | "autoload": {
474 | "psr-4": {
475 | "yii\\bootstrap\\": ""
476 | }
477 | },
478 | "notification-url": "https://packagist.org/downloads/",
479 | "license": [
480 | "BSD-3-Clause"
481 | ],
482 | "authors": [
483 | {
484 | "name": "Qiang Xue",
485 | "email": "qiang.xue@gmail.com"
486 | }
487 | ],
488 | "description": "The Twitter Bootstrap extension for the Yii framework",
489 | "keywords": [
490 | "bootstrap",
491 | "yii2"
492 | ],
493 | "time": "2016-03-17 03:29:28"
494 | },
495 | {
496 | "name": "yiisoft/yii2-debug",
497 | "version": "2.0.6",
498 | "source": {
499 | "type": "git",
500 | "url": "https://github.com/yiisoft/yii2-debug.git",
501 | "reference": "55ed2e853ed8050a34415f63a4da84f88a56f895"
502 | },
503 | "dist": {
504 | "type": "zip",
505 | "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/55ed2e853ed8050a34415f63a4da84f88a56f895",
506 | "reference": "55ed2e853ed8050a34415f63a4da84f88a56f895",
507 | "shasum": ""
508 | },
509 | "require": {
510 | "yiisoft/yii2": ">=2.0.4",
511 | "yiisoft/yii2-bootstrap": "*"
512 | },
513 | "type": "yii2-extension",
514 | "extra": {
515 | "branch-alias": {
516 | "dev-master": "2.0.x-dev"
517 | }
518 | },
519 | "autoload": {
520 | "psr-4": {
521 | "yii\\debug\\": ""
522 | }
523 | },
524 | "notification-url": "https://packagist.org/downloads/",
525 | "license": [
526 | "BSD-3-Clause"
527 | ],
528 | "authors": [
529 | {
530 | "name": "Qiang Xue",
531 | "email": "qiang.xue@gmail.com"
532 | }
533 | ],
534 | "description": "The debugger extension for the Yii framework",
535 | "keywords": [
536 | "debug",
537 | "debugger",
538 | "yii2"
539 | ],
540 | "time": "2016-03-17 03:50:19"
541 | }
542 | ],
543 | "aliases": [],
544 | "minimum-stability": "stable",
545 | "stability-flags": [],
546 | "prefer-stable": false,
547 | "prefer-lowest": false,
548 | "platform": {
549 | "php": ">=5.4.0"
550 | },
551 | "platform-dev": []
552 | }
553 |
--------------------------------------------------------------------------------
/debug/models/search/ChangelogSearch.php:
--------------------------------------------------------------------------------
1 | \Yii::t('app', 'Action'),
54 | 'entity_type' => \Yii::t('app', 'Type'),
55 | 'entity_id' => \Yii::t('app', 'ID'),
56 | ];
57 | }
58 |
59 | /**
60 | * Returns data provider with filled models. Filter applied if needed.
61 | *
62 | * @param array $params an array of parameter values indexed by parameter names
63 | * @return ActiveDataProvider
64 | */
65 | public function search($params)
66 | {
67 | $this->load($params) && $this->validate();
68 |
69 | /** @var \yii\db\BaseActiveRecord $Model */
70 | $Model = Instance::ensure([
71 | 'class' => Changelog::className(),
72 | ]);
73 |
74 | /** @var ChangelogQuery $ChangelogQuery */
75 | $ChangelogQuery = $Model::find();
76 |
77 | if (!empty($this->action)) {
78 | $ChangelogQuery->byAction($this->action);
79 | }
80 |
81 | if (!empty($this->entity_type)) {
82 | $ChangelogQuery->byEntityType($this->entity_type);
83 | }
84 |
85 | if (!empty($this->entity_id)) {
86 | $ChangelogQuery->byEntityId($this->entity_id);
87 | }
88 |
89 | /** @var ActiveDataProvider $DataProvider */
90 | $DataProvider = \Yii::createObject([
91 | 'class' => ActiveDataProvider::className(),
92 | 'query' => $ChangelogQuery,
93 | 'sort' => [
94 | 'defaultOrder' => ['created_at' => SORT_DESC],
95 | ],
96 | ]);
97 |
98 | return $DataProvider;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/debug/panels/ChangelogPanel.php:
--------------------------------------------------------------------------------
1 | view->render($this->summaryViewAlias, [
53 | 'panel' => $this,
54 | ]);
55 | }
56 |
57 | /**
58 | * @inheritdoc
59 | */
60 | public function getDetail()
61 | {
62 | /** @var \yii\web\Request $request */
63 | $request = \Yii::$app->get($this->request);
64 |
65 | /** @var \yii\web\View $view */
66 | $view = \Yii::$app->get($this->view);
67 |
68 | /** @var ChangelogSearch $searchModel */
69 | $searchModel = \Yii::createObject(ChangelogSearch::className());
70 |
71 | $dataProvider = $searchModel
72 | ->search($request->getQueryParams());
73 |
74 | return $view->render($this->detailViewAlias, [
75 | 'panel' => $this,
76 | 'dataProvider' => $dataProvider,
77 | 'searchModel' => $searchModel,
78 | ]);
79 | }
80 | }
--------------------------------------------------------------------------------
/debug/views/panels/changelog/detail.php:
--------------------------------------------------------------------------------
1 | Changelog::className(),
23 | ]);
24 |
25 | echo Html::tag('h1', $panel->getName());
26 |
27 | Pjax::begin();
28 | echo GridView::widget([
29 | 'dataProvider' => $dataProvider,
30 | 'id' => 'db-panel-detailed-grid',
31 | 'options' => ['class' => 'detail-grid-view table-responsive'],
32 | 'filterModel' => $searchModel,
33 | 'filterUrl' => $panel->getUrl(),
34 | 'columns' => [
35 | ['class' => 'yii\grid\SerialColumn'],
36 | [
37 | 'attribute' => 'action',
38 | 'filter' => $Model::getActions(),
39 | 'value' => function ($data) use($Model) {
40 | return empty($data['action'])
41 | ? \Yii::t('app', 'Unknown')
42 | : $Model::getActions()[$data['action']];
43 | },
44 | 'options' => [
45 | 'width' => '10%',
46 | ],
47 | ],
48 | [
49 | 'format' => 'raw',
50 | 'attribute' => 'entity_type',
51 | 'filter' => $Model::getAllEntityTypes(),
52 | 'value' => function ($data) {
53 | $result = empty($data['entity_type']) ? \Yii::t('app', 'Unknown type') : $data['entity_type'];
54 |
55 | if (!empty($data['present'])) {
56 | $result .= '
' . Html::tag('small', sprintf(' > %s', $data['present']));
57 | }
58 |
59 | return $result;
60 | },
61 | ],
62 | [
63 | 'attribute' => 'entity_id',
64 | 'options' => [
65 | 'width' => '10%',
66 | ],
67 | ],
68 | [
69 | 'format' => 'raw',
70 | 'attribute' => 'changes',
71 | 'value' => function ($data) {
72 | $content = Html::tag('div', VarDumper::dumpAsString(unserialize($data['changes']), 10, true), [
73 | 'class' => 'content changes hidden',
74 | 'data-id' => $data['id'],
75 | ]);
76 |
77 | return empty($data['changes']) ? null : Html::a(\Yii::t('app', 'show'), '#', [
78 | 'data-role' => 'show-changes',
79 | 'data-id' => $data['id'],
80 | ]) . $content;
81 | },
82 | 'options' => [
83 | 'width' => '7%',
84 | ],
85 | ],
86 | [
87 | 'format' => 'raw',
88 | 'attribute' => 'env',
89 | 'value' => function ($data) {
90 | $content = Html::tag('div', VarDumper::dumpAsString(unserialize($data['env']), 10, true), [
91 | 'class' => 'content env hidden',
92 | 'data-id' => $data['id'],
93 | ]);
94 |
95 | return empty($data['env']) ? null : Html::a(\Yii::t('app', 'show'), '#', [
96 | 'data-role' => 'show-env',
97 | 'data-id' => $data['id'],
98 | ]) . $content;
99 | },
100 | 'options' => [
101 | 'width' => '7%',
102 | ],
103 | ],
104 | [
105 | 'attribute' => 'created_at',
106 | 'value' => function ($data) {
107 | return Yii::$app->get('formatter')->asDatetime($data['created_at']);
108 | },
109 | 'options' => [
110 | 'width' => '20%',
111 | ],
112 | ],
113 | ],
114 | ]);
115 | Pjax::end();
116 |
117 | $this->registerJs('initializePopUps();');
118 |
119 | echo Modal::widget([
120 | 'id' => 'detail-content',
121 | 'header' => 'Detail information',
122 | ]);
123 |
124 | ?>
125 |
126 |
149 |
--------------------------------------------------------------------------------
/debug/views/panels/changelog/summary.php:
--------------------------------------------------------------------------------
1 |
13 |