search id in post backend

This commit is contained in:
Kerim 2022-12-31 02:25:25 +05:00
parent daf1fad957
commit 17e4aecc58
19 changed files with 1037 additions and 9 deletions

View File

@ -0,0 +1,19 @@
# MIT license
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,64 @@
<?php namespace Indikator\BlogStat;
use System\Classes\PluginBase;
use Backend;
use Event;
class Plugin extends PluginBase
{
public $require = ['RainLab.Blog'];
public function pluginDetails()
{
return [
'name' => 'indikator.blogstat::lang.plugin.name',
'description' => 'indikator.blogstat::lang.plugin.description',
'author' => 'indikator.blogstat::lang.plugin.author',
'icon' => 'icon-area-chart',
'homepage' => 'https://github.com/gergo85/oc-blogstat'
];
}
public function boot()
{
Event::listen('backend.menu.extendItems', function($manager)
{
$manager->addSideMenuItems('RainLab.Blog', 'blog', [
'statistics' => [
'label' => 'indikator.blogstat::lang.menu.statistics',
'icon' => 'icon-area-chart',
'code' => 'statistics',
'owner' => 'Indikator.BlogStat',
'url' => Backend::url('indikator/blogstat/statistics')
]
]);
});
}
public function registerReportWidgets()
{
return [
'Indikator\BlogStat\ReportWidgets\Posts' => [
'label' => 'indikator.blogstat::lang.widget.posts',
'context' => 'dashboard',
'permissions' => ['indikator.blogstat.statistics']
],
'Indikator\BlogStat\ReportWidgets\Categories' => [
'label' => 'indikator.blogstat::lang.widget.categories',
'context' => 'dashboard',
'permissions' => ['indikator.blogstat.statistics']
]
];
}
public function registerPermissions()
{
return [
'indikator.blogstat.statistics' => [
'tab' => 'rainlab.blog::lang.blog.tab',
'label' => 'indikator.blogstat::lang.permission.statistics',
'roles' => ['publisher']
]
];
}
}

View File

@ -0,0 +1,37 @@
# Statistics and Graphs for Blog
This plugin extend the [RainLab Blog](https://github.com/rainlab/blog-plugin) to beautiful graphs and useful dashboard widgets.
## Main features
* Add interactive graphs
* Add dashboard widgets
## Statistics and graphs
* Graph - Posts in this year
* Graph - Posts in last year
* List - TOP 10 longest posts
* List - TOP 10 shortest posts
## Available widgets
* Post statistics
* Category statistics
## Available languages
* en - English
* de - Deutsch
* ru - Pу́сский
* hu - Magyar
* pl - Polski
## Installation
1. Go to the __Settings > Updates & Plugins__ page in the Backend.
1. Click on the __Install plugins__ button.
1. Type the __Blog Stat__ text in the search field.
## Add backend widgets
1. Go to the __Dashboard__ page in the Backend.
1. Click on the __Manage widgets > Add widget__ button.
1. Select the any __Blog widgets__ from the list.
## Credits
* [Morris.js](http://morrisjs.github.io/morris.js)
* [Raphaël JS](http://dmitrybaranovskiy.github.io/raphael)

View File

@ -0,0 +1,40 @@
.statboard .statbox {
background: #fff;
-webkit-box-shadow: 3px 3px 11px 0 rgba(217, 217, 217, 1);
-moz-box-shadow: 3px 3px 11px 0 rgba(217, 217, 217, 1);
box-shadow: 3px 3px 11px 0 rgba(217, 217, 217, 1);
margin: 10px 0 20px 0;
padding: 0 20px;
}
.statboard h4 {
border-bottom: 1px solid #cae1e2;
margin: 25px 0;
padding-bottom: 5px;
}
.morris-hover {
position: absolute;
z-index: 1000
}
.morris-hover.morris-default-style {
background: rgba(255,255,255,0.8);
border: solid 2px rgba(230,230,230,0.8);
border-radius: 10px;
color: #666;
font-family: sans-serif;
font-size: 12px;
padding: 6px;
text-align:center;
}
.morris-hover.morris-default-style .morris-hover-row-label {
font-weight: bold;
margin: 0.25em 0;
}
.morris-hover.morris-default-style .morris-hover-point {
margin: 0.1em 0;
white-space: nowrap;
}

View File

@ -0,0 +1,11 @@
{
"name": "indikator/blogstat-plugin",
"type": "october-plugin",
"description": "This plugin extend the RainLab Blog to beautiful graphs and useful dashboard widgets.",
"homepage": "https://octobercms.com/plugin/indikator-blogstat",
"keywords": ["october", "octobercms", "blog"],
"license": "MIT",
"require": {
"composer/installers": "~1.0"
}
}

View File

@ -0,0 +1,130 @@
<?php namespace Indikator\BlogStat\Controllers;
use Backend\Classes\Controller;
use BackendMenu;
use Backend;
use RainLab\Blog\Models\Post;
use RainLab\Blog\Models\Category;
class Statistics extends Controller
{
public $requiredPermissions = ['indikator.blogstat.statistics'];
public function __construct()
{
parent::__construct();
BackendMenu::setContext('RainLab.Blog', 'blog', 'statistics');
}
public function index()
{
$this->pageTitle = 'indikator.blogstat::lang.menu.statistics';
$this->addCss('/plugins/indikator/blogstat/assets/css/statistics.css');
$this->vars['countPost'] = Post::count();
$this->vars['countCategory'] = Category::count();
$this->getGraphs();
$this->getPostsInfo();
$this->getLongestPosts();
$this->getShortestPosts();
}
public function getGraphs()
{
$this->vars['thisYear'] = $this->vars['lastYear'] = array_fill(0, 13, 0);
$this->vars['now'] = date('Y');
$blog = Post::where('published_at', '>', 0)->get();
foreach ($blog as $item) {
$year = substr($item->published_at, 0, 4);
if ($year == $this->vars['now']) {
$this->vars['thisYear'][(int)substr($item->published_at, 5, 2)]++;
}
else if ($year == $this->vars['now'] - 1) {
$this->vars['lastYear'][(int)substr($item->published_at, 5, 2)]++;
$this->vars['lastYear'][0]++;
}
}
}
public function getPostsInfo()
{
$blog = Post::get();
$this->vars['length'] = $this->vars['title'] = [];
foreach ($blog as $item) {
$this->vars['length'][$item->id] = strlen(trim(preg_replace('/\s+/', ' ', strip_tags($item->excerpt.$item->content))));
$this->vars['title'][$item->id] = $item->title;
}
}
public function getLongestPosts()
{
$length = $this->vars['length'];
$title = $this->vars['title'];
arsort($length);
$this->vars['longest'] = '';
$index = 1;
foreach ($length as $id => $value) {
$this->vars['longest'] .= '
<div class="col-md-1 col-sm-1">
'.$index.'.
</div>
<div class="col-md-9 col-sm-9">
<a href="'.Backend::url('rainlab/blog/posts/update/'.$id).'">'.$title[$id].'</a>
</div>
<div class="col-md-2 col-sm-2 text-right">
'.number_format($value, 0, '.', ' ').'
</div>
<div class="clearfix"></div>
';
if ($index == 10) {
break;
}
$index++;
}
}
public function getShortestPosts()
{
$length = $this->vars['length'];
$title = $this->vars['title'];
asort($length);
$this->vars['shortest'] = '';
$index = 1;
foreach ($length as $id => $value) {
$this->vars['shortest'] .= '
<div class="col-md-1 col-sm-1">
'.$index.'.
</div>
<div class="col-md-9 col-sm-9">
<a href="'.Backend::url('rainlab/blog/posts/update/'.$id).'">'.$title[$id].'</a>
</div>
<div class="col-md-2 col-sm-2 text-right">
'.number_format($value, 0, '.', ' ').'
</div>
<div class="clearfix"></div>
';
if ($index == 10) {
break;
}
$index++;
}
}
}

View File

@ -0,0 +1,372 @@
<div class="control-breadcrumb">
<ul>
<li><?= e(trans('indikator.blogstat::lang.menu.statistics')) ?></li>
<li>
<span class="text-info"><strong><?= $countPost ?></strong> <?= e(trans_choice('indikator.blogstat::lang.menu.posts', $countPost)) ?></span>
&nbsp; | &nbsp;
<span class="text-warning"><strong><?= $countCategory ?></strong> <?= e(trans_choice('indikator.blogstat::lang.menu.categories', $countCategory)) ?></span>
</li>
</ul>
</div>
<div class="scoreboard statboard">
<div class="row">
<div class="col-md-6">
<div class="statbox">
<br>
<strong><?= $now ?></strong>
<div id="thisYear" style="height: 220px; opacity: 0;"></div>
<br>
<?php if ($lastYear[0] > 0): ?>
<strong><?= ($now - 1) ?></strong>
<div id="lastYear" style="height: 220px; opacity: 0;"></div>
<?php endif ?>
</div>
</div>
<div class="col-md-6">
<div class="statbox">
<br>
<strong><?= e(trans('indikator.blogstat::lang.stat.longest')) ?></strong>
<div class="clearfix"></div><br>
<?= $longest ?>
<br>
<strong><?= e(trans('indikator.blogstat::lang.stat.shortest')) ?></strong>
<div class="clearfix"></div><br>
<?= $shortest ?>
<br>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.8/raphael.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Variables
var date = new Date();
var year = date.getFullYear();
var lang = $('html').attr('lang');
// Translates
if (lang == 'hu') {
var trans = {
all: 'Összesen',
jan: 'január',
feb: 'február',
mar: 'március',
apr: 'április',
may: 'május',
jun: 'június',
jul: 'július',
aug: 'augusztus',
sep: 'szeptember',
oct: 'október',
nov: 'november',
dec: 'december'
};
}
else if (lang == 'de') {
var trans = {
all: 'Alle',
jan: 'Januar',
feb: 'Februar',
mar: 'März',
apr: 'April',
may: 'Mai',
jun: 'Juni',
jul: 'Juli',
aug: 'August',
sep: 'September',
oct: 'Oktober',
nov: 'November',
dec: 'Dezember'
};
}
else if (lang == 'ru') {
var trans = {
all: 'Всего',
jan: 'Январь',
feb: 'Февраль',
mar: 'Март',
apr: 'Апрель',
may: 'Май',
jun: 'Июнь',
jul: 'Июль',
aug: 'Август',
sep: 'Сентябрь',
oct: 'Октябрь',
nov: 'Ноябрь',
dec: 'Декабрь'
};
}
else if (lang == 'pl') {
var trans = {
all: 'Wszystko',
jan: 'styczeń',
feb: 'luty',
mar: 'marzec',
apr: 'kwiecień',
may: 'maj',
jun: 'czerwiec',
jul: 'lipiec',
aug: 'sierpień',
sep: 'wrzesień',
oct: 'październik',
nov: 'listopad',
dec: 'grudzień'
};
}
else {
var trans = {
all: 'All',
jan: 'January',
feb: 'February',
mar: 'March',
apr: 'April',
may: 'May',
jun: 'June',
jul: 'July',
aug: 'August',
sep: 'September',
oct: 'October',
nov: 'November',
dec: 'December'
};
}
// Graph
new Morris.Line({
element: 'thisYear',
data: [
{ year: year + '-01', 'all': <?= $thisYear[1] ?> },
{ year: year + '-02', 'all': <?= $thisYear[2] ?> },
{ year: year + '-03', 'all': <?= $thisYear[3] ?> },
{ year: year + '-04', 'all': <?= $thisYear[4] ?> },
{ year: year + '-05', 'all': <?= $thisYear[5] ?> },
{ year: year + '-06', 'all': <?= $thisYear[6] ?> },
{ year: year + '-07', 'all': <?= $thisYear[7] ?> },
{ year: year + '-08', 'all': <?= $thisYear[8] ?> },
{ year: year + '-09', 'all': <?= $thisYear[9] ?> },
{ year: year + '-10', 'all': <?= $thisYear[10] ?> },
{ year: year + '-11', 'all': <?= $thisYear[11] ?> },
{ year: year + '-12', 'all': <?= $thisYear[12] ?> }
],
xkey: 'year',
ykeys: ['all'],
labels: [trans.all],
lineColors: ['#31708f'],
hideHover: 'auto',
xLabelFormat: function(x) {
var IndexToMonth = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
return IndexToMonth[x.getMonth()];
},
dateFormat: function(d) {
var IndexToMonth = [trans.jan, trans.feb, trans.mar, trans.apr, trans.may, trans.jun, trans.jul, trans.aug, trans.sep, trans.oct, trans.nov, trans.dec];
return month = IndexToMonth[new Date(d).getMonth()];
},
resize: true,
gridIntegers: true,
ymin: 0
});
// This year
$('#thisYear').fadeTo(1200, 1);
// Last year
if ($('#lastYear').length == 1) {
new Morris.Line({
element: 'lastYear',
data: [
{ year: (year - 1) + '-01', 'all': <?= $lastYear[1] ?> },
{ year: (year - 1) + '-02', 'all': <?= $lastYear[2] ?> },
{ year: (year - 1) + '-03', 'all': <?= $lastYear[3] ?> },
{ year: (year - 1) + '-04', 'all': <?= $lastYear[4] ?> },
{ year: (year - 1) + '-05', 'all': <?= $lastYear[5] ?> },
{ year: (year - 1) + '-06', 'all': <?= $lastYear[6] ?> },
{ year: (year - 1) + '-07', 'all': <?= $lastYear[7] ?> },
{ year: (year - 1) + '-08', 'all': <?= $lastYear[8] ?> },
{ year: (year - 1) + '-09', 'all': <?= $lastYear[9] ?> },
{ year: (year - 1) + '-10', 'all': <?= $lastYear[10] ?> },
{ year: (year - 1) + '-11', 'all': <?= $lastYear[11] ?> },
{ year: (year - 1) + '-12', 'all': <?= $lastYear[12] ?> }
],
xkey: 'year',
ykeys: ['all'],
labels: [trans.all],
lineColors: ['#31708f'],
hideHover: 'auto',
xLabelFormat: function(x) {
var IndexToMonth = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
return IndexToMonth[x.getMonth()];
},
dateFormat: function(d) {
var IndexToMonth = [trans.jan, trans.feb, trans.mar, trans.apr, trans.may, trans.jun, trans.jul, trans.aug, trans.sep, trans.oct, trans.nov, trans.dec];
return month = IndexToMonth[new Date(d).getMonth()];
},
resize: true,
gridIntegers: true,
ymin: 0
});
setTimeout(function() {
$('#lastYear').fadeTo(1200, 1);
}, 300);
}
});
// Graph
(function() {
var $, MyMorris;
MyMorris = window.MyMorris = {};
$ = jQuery;
MyMorris = Object.create(Morris);
MyMorris.Grid.prototype.gridDefaults["gridIntegers"] = false;
MyMorris.Grid.prototype.setData = function (data, redraw) {
var e, idx, index, maxGoal, minGoal, ret, row, step, total, y, ykey, ymax, ymin, yval, _ref;
if (redraw == null) {
redraw = true;
}
this.options.data = data;
if ((data == null) || data.length === 0) {
this.data = [];
this.raphael.clear();
if (this.hover != null) {
this.hover.hide();
}
return;
}
ymax = this.cumulative ? 0 : null;
ymin = this.cumulative ? 0 : null;
if (this.options.goals.length > 0) {
minGoal = Math.min.apply(Math, this.options.goals);
maxGoal = Math.max.apply(Math, this.options.goals);
ymin = ymin != null ? Math.min(ymin, minGoal) : minGoal;
ymax = ymax != null ? Math.max(ymax, maxGoal) : maxGoal;
}
this.data = (function () {
var _i, _len, _results;
_results = [];
for (index = _i = 0, _len = data.length; _i < _len; index = ++_i) {
row = data[index];
ret = {
src: row
};
ret.label = row[this.options.xkey];
if (this.options.parseTime) {
ret.x = Morris.parseDate(ret.label);
if (this.options.dateFormat) {
ret.label = this.options.dateFormat(ret.x);
} else if (typeof ret.label === 'number') {
ret.label = new Date(ret.label).toString();
}
} else {
ret.x = index;
if (this.options.xLabelFormat) {
ret.label = this.options.xLabelFormat(ret);
}
}
total = 0;
ret.y = (function () {
var _j, _len1, _ref, _results1;
_ref = this.options.ykeys;
_results1 = [];
for (idx = _j = 0, _len1 = _ref.length; _j < _len1; idx = ++_j) {
ykey = _ref[idx];
yval = row[ykey];
if (typeof yval === 'string') {
yval = parseFloat(yval);
}
if ((yval != null) && typeof yval !== 'number') {
yval = null;
}
if (yval != null) {
if (this.cumulative) {
total += yval;
} else {
if (ymax != null) {
ymax = Math.max(yval, ymax);
ymin = Math.min(yval, ymin);
} else {
ymax = ymin = yval;
}
}
}
if (this.cumulative && (total != null)) {
ymax = Math.max(total, ymax);
ymin = Math.min(total, ymin);
}
_results1.push(yval);
}
return _results1;
}).call(this);
_results.push(ret);
}
return _results;
}).call(this);
if (this.options.parseTime) {
this.data = this.data.sort(function (a, b) {
return (a.x > b.x) - (b.x > a.x);
});
}
this.xmin = this.data[0].x;
this.xmax = this.data[this.data.length - 1].x;
this.events = [];
if (this.options.events.length > 0) {
if (this.options.parseTime) {
this.events = (function () {
var _i, _len, _ref, _results;
_ref = this.options.events;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
e = _ref[_i];
_results.push(Morris.parseDate(e));
}
return _results;
}).call(this);
} else {
this.events = this.options.events;
}
this.xmax = Math.max(this.xmax, Math.max.apply(Math, this.events));
this.xmin = Math.min(this.xmin, Math.min.apply(Math, this.events));
}
if (this.xmin === this.xmax) {
this.xmin -= 1;
this.xmax += 1;
}
this.ymin = this.yboundary('min', ymin);
this.ymax = this.yboundary('max', ymax);
if (this.ymin === this.ymax) {
if (ymin) {
this.ymin -= 1;
}
this.ymax += 1;
}
if (((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') || this.options.grid === true) {
if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) {
this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines);
this.ymin = Math.min(this.ymin, this.grid[0]);
this.ymax = Math.max(this.ymax, this.grid[this.grid.length - 1]);
} else {
step = (this.ymax - this.ymin) / (this.options.numLines - 1);
if (this.options.gridIntegers) {
step = Math.max(1, Math.round(step));
}
this.grid = (function () {
var _i, _ref1, _ref2, _results;
_results = [];
for (y = _i = _ref1 = this.ymin, _ref2 = this.ymax; step > 0 ? _i <= _ref2 : _i >= _ref2; y = _i += step) {
_results.push(y);
}
return _results;
}).call(this);
}
}
this.dirty = true;
if (redraw) {
return this.redraw();
}
};
}).call(this);
</script>

View File

@ -0,0 +1,33 @@
<?php
return [
'plugin' => [
'name' => 'Blog Statistiken und Grafiken',
'description' => 'Erweitertes Plugin für RainLab Blog.',
'author' => 'Gergő Szabó'
],
'menu' => [
'statistics' => 'Statistiken',
'posts' => 'Post|Post',
'categories' => 'Kategorie|Kategorien'
],
'stat' => [
'longest' => 'Am längsten',
'shortest' => 'Kürzeste'
],
'widget' => [
'posts' => 'Blog - Post',
'categories' => 'Blog - Kategorien',
'show_total' => 'Zeige gesamte',
'show_active' => 'Zeige aktiv',
'show_inactive' => 'Zeige inaktiv',
'show_empty' => 'Zeige leer',
'total' => 'Gesamt',
'active' => 'Aktiv',
'inactive' => 'Inaktiv',
'empty' => 'Leer'
],
'permission' => [
'statistics' => 'Statistiken anzeigen'
]
];

View File

@ -0,0 +1,33 @@
<?php
return [
'plugin' => [
'name' => 'Blog Stats & Graphs',
'description' => 'Extended plugin for RainLab Blog.',
'author' => 'Gergő Szabó'
],
'menu' => [
'statistics' => 'Statistics',
'posts' => 'Post|Posts',
'categories' => 'Category|Categories'
],
'stat' => [
'longest' => 'Longest',
'shortest' => 'Shortest'
],
'widget' => [
'posts' => 'Blog - Posts',
'categories' => 'Blog - Categories',
'show_total' => 'Show total',
'show_active' => 'Show active',
'show_inactive' => 'Show inactive',
'show_empty' => 'Show empty',
'total' => 'Total',
'active' => 'Active',
'inactive' => 'Inactive',
'empty' => 'Empty'
],
'permission' => [
'statistics' => 'View statistics'
]
];

View File

@ -0,0 +1,33 @@
<?php
return [
'plugin' => [
'name' => 'Blog statisztika',
'description' => 'Kiegészítő a hivatalos Blog bővítményhez.',
'author' => 'Szabó Gergő'
],
'menu' => [
'statistics' => 'Statisztika',
'posts' => 'Bejegyzés|Bejegyzés',
'categories' => 'Kategória|Kategória'
],
'stat' => [
'longest' => 'Leghosszabb',
'shortest' => 'Legrövidebb'
],
'widget' => [
'posts' => 'Blog - Bejegyzések',
'categories' => 'Blog - Kategóriák',
'show_total' => 'Összes mutatása',
'show_active' => 'Aktívak mutatása',
'show_inactive' => 'Inaktívak mutatása',
'show_empty' => 'Üresek mutatása',
'total' => 'Összes',
'active' => 'Aktív',
'inactive' => 'Inaktív',
'empty' => 'Üres'
],
'permission' => [
'statistics' => 'Statisztika megtekintése'
]
];

View File

@ -0,0 +1,33 @@
<?php
return [
'plugin' => [
'name' => 'Blog Statystyki i wykresy',
'description' => 'Extended plugin for RainLab Blog.',
'author' => 'Gergő Szabó'
],
'menu' => [
'statistics' => 'Statystyka',
'posts' => 'post|blogach',
'categories' => 'kategoria|Kategorie'
],
'stat' => [
'longest' => 'Najdłuższy',
'shortest' => 'Najkrótsza'
],
'widget' => [
'posts' => 'Aktualności - Posty',
'categories' => 'Aktualności - Kategorie',
'show_total' => 'Pokaż wszystkie',
'show_active' => 'Pokaż aktywne',
'show_inactive' => 'Pokaż nieaktywne',
'show_empty' => 'Pokaż pusty',
'total' => 'Razem',
'active' => 'Aktywny',
'inactive' => 'Nieaktywny',
'empty' => 'Pusty'
],
'permission' => [
'statistics' => 'Zobacz statystyki'
]
];

View File

@ -0,0 +1,33 @@
<?php
return [
'plugin' => [
'name' => 'Блог Статистика и Графики',
'description' => 'Extended plugin for RainLab Blog.',
'author' => 'Gergő Szabó'
],
'menu' => [
'statistics' => 'Статистика',
'posts' => '{0} Записей|{1} Запись|[2,4] Записи|[5,Inf] Записей',
'categories' => '{1} категория|[2,4] категории|[5,Inf] категорий'
],
'stat' => [
'longest' => 'Cамый длинный',
'shortest' => 'Cамый короткий'
],
'widget' => [
'posts' => 'Блог - Посты',
'categories' => 'Блог - Категории',
'show_total' => 'Показать все',
'show_active' => 'Показать активные',
'show_inactive' => 'Показать неактивные',
'show_empty' => 'Показать пустой',
'total' => 'Всего',
'active' => 'Активных',
'inactive' => 'Неактивных',
'empty' => 'пустой'
],
'permission' => [
'statistics' => 'Просмотр статистики'
]
];

View File

@ -0,0 +1,60 @@
<?php namespace Indikator\BlogStat\ReportWidgets;
use Backend\Classes\ReportWidgetBase;
use Exception;
use RainLab\Blog\Models\Category;
use Db;
class Categories extends ReportWidgetBase
{
public function render()
{
try {
$this->loadData();
}
catch (Exception $ex) {
$this->vars['error'] = $ex->getMessage();
}
return $this->makePartial('widget');
}
public function defineProperties()
{
return [
'title' => [
'title' => 'backend::lang.dashboard.widget_title_label',
'default' => 'rainlab.blog::lang.blog.categories',
'type' => 'string',
'validationPattern' => '^.+$',
'validationMessage' => 'backend::lang.dashboard.widget_title_error'
],
'total' => [
'title' => 'indikator.blogstat::lang.widgets.show_total',
'default' => true,
'type' => 'checkbox'
],
'empty' => [
'title' => 'indikator.blogstat::lang.widgets.show_empty',
'default' => true,
'type' => 'checkbox'
]
];
}
protected function loadData()
{
$this->vars['total'] = Category::count();
$empty = 0;
$categories = Category::all();
foreach ($categories as $category) {
if (Db::table('rainlab_blog_posts_categories')->where('category_id', $category->id)->count() == 0) {
$empty++;
}
}
$this->vars['empty'] = $empty;
}
}

View File

@ -0,0 +1,55 @@
<?php namespace Indikator\BlogStat\ReportWidgets;
use Backend\Classes\ReportWidgetBase;
use Exception;
use RainLab\Blog\Models\Post;
class Posts extends ReportWidgetBase
{
public function render()
{
try {
$this->loadData();
}
catch (Exception $ex) {
$this->vars['error'] = $ex->getMessage();
}
return $this->makePartial('widget');
}
public function defineProperties()
{
return [
'title' => [
'title' => 'backend::lang.dashboard.widget_title_label',
'default' => 'rainlab.blog::lang.blog.posts',
'type' => 'string',
'validationPattern' => '^.+$',
'validationMessage' => 'backend::lang.dashboard.widget_title_error'
],
'total' => [
'title' => 'indikator.blogstat::lang.widgets.show_total',
'default' => true,
'type' => 'checkbox'
],
'active' => [
'title' => 'indikator.blogstat::lang.widgets.show_active',
'default' => true,
'type' => 'checkbox'
],
'inactive' => [
'title' => 'indikator.blogstat::lang.widgets.show_inactive',
'default' => true,
'type' => 'checkbox'
]
];
}
protected function loadData()
{
$this->vars['active'] = Post::where('published', true)->count();
$this->vars['inactive'] = Post::where('published', false)->count();
$this->vars['total'] = $this->vars['active'] + $this->vars['inactive'];
}
}

View File

@ -0,0 +1,25 @@
<div class="report-widget">
<h3><?= e(trans($this->property('title'))) ?></h3>
<?php if (!isset($error)): ?>
<div class="control-status-list">
<ul>
<?php if ($this->property('total')): ?>
<li>
<span class="status-text"><?= e(trans('indikator.blogstat::lang.widget.total')) ?></span>
<span class="status-label primary"><?= $total ?></span>
</li>
<?php endif ?>
<?php if ($this->property('empty')): ?>
<li>
<span class="status-text"><?= e(trans('indikator.blogstat::lang.widget.empty')) ?></span>
<span class="status-label primary"><?= $empty ?></span>
</li>
<?php endif ?>
</ul>
</div>
<?php else: ?>
<p class="flash-message static warning"><?= e($error) ?></p>
<?php endif ?>
</div>

View File

@ -0,0 +1,31 @@
<div class="report-widget">
<h3><?= e(trans($this->property('title'))) ?></h3>
<?php if (!isset($error)): ?>
<div class="control-status-list">
<ul>
<?php if ($this->property('total')): ?>
<li>
<span class="status-text"><?= e(trans('indikator.blogstat::lang.widget.total')) ?></span>
<span class="status-label primary"><?= $total ?></span>
</li>
<?php endif ?>
<?php if ($this->property('active')): ?>
<li>
<span class="status-text"><?= e(trans('indikator.blogstat::lang.widget.active')) ?></span>
<span class="status-label primary"><?= $active ?></span>
</li>
<?php endif ?>
<?php if ($this->property('inactive')): ?>
<li>
<span class="status-text"><?= e(trans('indikator.blogstat::lang.widget.inactive')) ?></span>
<span class="status-label primary"><?= $inactive ?></span>
</li>
<?php endif ?>
</ul>
</div>
<?php else: ?>
<p class="flash-message static warning"><?= e($error) ?></p>
<?php endif ?>
</div>

View File

@ -0,0 +1,7 @@
1.0.0: First version of Blog Stats & Graphs.
1.0.1: Added more post statistics.
1.0.2: Minor improvements and bugfix.
1.0.3: Redesigned the report widgets.
1.0.4: !!! Updated for October 420+.
1.0.5: Minor visual and code improvements.
1.0.6: Added permission to Dashboard widgets.

View File

@ -4,6 +4,13 @@
scopes:
id:
label: Id Post
type: text
modelClass: RainLab\Blog\Models\Post
scope: FilterId
# conditions: id in (:filtered)
category:
# Filter name
@ -41,7 +48,7 @@ scopes:
# SQL Conditions
conditions: created_at >= ':after' AND created_at <= ':before'
language:
# Filter name
@ -55,9 +62,9 @@ scopes:
# Apply query scope
scope: FilterLocale
# options
options:
ru: RU
en: EN
tm: TM
tm: TM

View File

@ -176,13 +176,13 @@ class Post extends Model
}else{
$fields->type_post->hidden = true;
}
if($this->category_groups->where('type', 'media')->count()){
$fields->video_file->hidden = false;
}else{
$fields->video_file->hidden = true;
}
if($this->category_groups->where('type', 'afisha')->count()){
$fields->afisha_phone->hidden = false;
$fields->afisha_address->hidden = false;
@ -386,10 +386,10 @@ class Post extends Model
if ($typePost !==null) {
$typePost = is_array($typePost) ? $typePost : [$typePost];
$query->whereIn('type_post',$typePost);
}
// if ($groupId !==null) {
@ -400,11 +400,11 @@ class Post extends Model
if(isset($featured)){
$query-> where('featured',$featured);
}
if(isset($morque)){
$query-> where('on_morque',$morque);
}
$date = trim($date);
if(strtotime($date)){
@ -532,6 +532,11 @@ class Post extends Model
});
}
public function scopeFilterId($query, $id)
{
return $query->where('id', $id);
}
public function scopeFilterLocale($query, array $types) {
foreach ($types as $type) {
switch ($type) {