vote module added, minor fixes
This commit is contained in:
parent
f5180f1568
commit
af24d129fd
25 changed files with 1508 additions and 5 deletions
32
assets/css/vote/vote.css
Normal file
32
assets/css/vote/vote.css
Normal file
|
@ -0,0 +1,32 @@
|
|||
.vote-options-wrapper p.subject,
|
||||
.vote-results-wrapper p.subject {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.vote-options-wrapper ul,
|
||||
.vote-results-wrapper ul {
|
||||
margin: 0px 4px 10px;
|
||||
padding: 0px;
|
||||
list-style-type: none;
|
||||
}
|
||||
.vote-options-wrapper ul li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.vote-options-wrapper ul label {
|
||||
font-weight: normal;
|
||||
margin-left: 7px;
|
||||
}
|
||||
.vote-results-line {
|
||||
height: 7px;
|
||||
background: #ADADAD;
|
||||
border-radius: 3px;
|
||||
}
|
||||
ul.vote-results {
|
||||
margin: 0px;
|
||||
}
|
||||
ul.vote-results li {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
ul.vote-results li .vote-result {
|
||||
color: #7B6D7E;
|
||||
font-weight: bold;
|
||||
}
|
File diff suppressed because one or more lines are too long
172
assets/js/vote/dash.js
Normal file
172
assets/js/vote/dash.js
Normal file
|
@ -0,0 +1,172 @@
|
|||
var dash_votes_install = function() {
|
||||
var selected = desk_window_selected(this);
|
||||
if (selected && typeof(selected.items)!="undefined" && selected.items.length>0) {
|
||||
desk_window_request(this, url('vote/dash/install'),{'votes':selected.items});
|
||||
}
|
||||
};
|
||||
|
||||
var dash_votes_select = function() {
|
||||
var selected = this.getSelectedContentItems();
|
||||
if (selected && selected.length>0) {
|
||||
this.disableItemsByProperty('typo','install');
|
||||
for (var i=0; i<selected.length; i++) {
|
||||
if (typeof(selected[i].inactive)!="undefined" && selected[i].inactive) {
|
||||
this.enableItemsByProperty('typo','install');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selected && selected.length && selected.length==1 && (typeof(this.info_last_item)=="undefined" || this.info_last_item!=selected[0].data || $(this.element).find('.vote-infobar').html().length==0)) {
|
||||
this.info_last_item = selected[0].data;
|
||||
$(this.element).find('.vote-infobar').html('');
|
||||
try { window.clearTimeout(this.timer); } catch(err) {};
|
||||
this.timer = window.setTimeout(this.bind(this,function(){
|
||||
$(this.element).find('.vote-infobar').html('');
|
||||
var selected = this.getSelectedContentItems();
|
||||
if (!selected || !selected.length || selected.length!=1) return;
|
||||
desk_post(url('vote/dash/info'),{'item':selected[0].data, 'token':token()}, this.bind(this, function(response){
|
||||
if (response && response.length>0) {
|
||||
$(this.element).find('.vote-infobar').append('<div style="cursor:default;padding:0px;margin:10px 0px 0px"><span class="glyphicon glyphicon-info-sign"></span> '+t('Information')+':</div>');
|
||||
$(this.element).find('.vote-infobar').append('<div style="border-top:1px solid #B3B6D1;border-bottom:1px solid #EDEDF6;height:1px;padding:0px;margin:10px 0px"></div>');
|
||||
for (var i=0; i<response.length; i++) {
|
||||
$(this.element).find('.vote-infobar').append('<div style="font-weight:normal;padding:2px 0px;cursor:default;text-overflow:ellipsis;overflow:hidden" title="'+response[i].split('>').slice(-1)[0]+'">'+response[i]+'</div>');
|
||||
}
|
||||
}
|
||||
}));
|
||||
}),1000);
|
||||
}
|
||||
};
|
||||
|
||||
var dash_votes_load = function() {
|
||||
for (var i=0; i<this.options.bodyItems.length; i++) {
|
||||
if (typeof(this.options.bodyItems[i].inactive)!="undefined" && this.options.bodyItems[i].inactive) {
|
||||
$(this.options.bodyItems[i].element).addClass('inactive');
|
||||
}
|
||||
}
|
||||
$(this.element).find('.vote-infobar').html('');
|
||||
};
|
||||
|
||||
var dash_votes_options = function() {
|
||||
var selected = this.getSelectedContentItems();
|
||||
if (selected && selected.length==1) {
|
||||
var data = {
|
||||
'data':desk_window_selected(this,1),
|
||||
'reload': this.className,
|
||||
'onClose':function(){
|
||||
desk_window_reload_all(this.options.reload);
|
||||
}
|
||||
};
|
||||
desk_call(dash_votes_options_wnd, null, data);
|
||||
}
|
||||
};
|
||||
|
||||
var dash_votes_add_option = function() {
|
||||
desk_prompt(t('Enter text'), this.bind(this, function(txt){
|
||||
desk_window_request(this, url('vote/dash/option'),{'content':txt, 'vote': this.options.data.items[0]});
|
||||
}));
|
||||
};
|
||||
|
||||
var dash_votes_edit_option = function() {
|
||||
var selected = this.getSelectedContentItems();
|
||||
if (selected && selected.length==1) {
|
||||
desk_prompt(t('Enter text'), this.bind(this, function(txt){
|
||||
desk_window_request(this, url('vote/dash/option'),{'content':txt, 'vote': this.options.data.items[0], 'option':selected[0].data});
|
||||
}));
|
||||
$('#zira-prompt-dialog input[name=modal-input]').val(selected[0].tooltip);
|
||||
}
|
||||
};
|
||||
|
||||
var dash_votes_delete_options = function() {
|
||||
var selected = desk_window_selected(this);
|
||||
if (selected && selected.items.length>0) {
|
||||
desk_window_request(this, url('vote/dash/deloptions'), {'options':selected.items, 'vote': this.options.data.items[0]});
|
||||
}
|
||||
};
|
||||
|
||||
var dash_vote_options_drag = function() {
|
||||
this.isContentDragging = false;
|
||||
this.dragStartY = null;
|
||||
this.dragStartItem = null;
|
||||
this.dragOverItem = null;
|
||||
this.dragReplaced = false;
|
||||
this.dragImage = new Image();
|
||||
this.dragImage.src=dash_votes_blank_src;
|
||||
$(this.content).bind('dragstart',this.bind(this,function(e){
|
||||
if (this.isDisabled()) return;
|
||||
if (typeof(e.originalEvent.target)=="undefined") return;
|
||||
if ($(e.originalEvent.target).parents('li').children('a').hasClass('inactive')) return;
|
||||
this.isContentDragging = true;
|
||||
this.dragStartY = e.originalEvent.pageY;
|
||||
this.dragStartItem = $(e.originalEvent.target).parents('li').children('a').attr('id');
|
||||
e.originalEvent.dataTransfer.setDragImage(this.dragImage,-10,0);
|
||||
$(this.content).find('#'+this.dragStartItem).parent('li').css('opacity',.5);
|
||||
for (var i=0; i<this.options.bodyItems.length; i++) {
|
||||
this.options.bodyItems[i].is_dragged = false;
|
||||
}
|
||||
}));
|
||||
$(this.content).bind('dragover',this.bind(this,function(e){
|
||||
if (this.isDisabled()) return;
|
||||
if (typeof(e.originalEvent.target)=="undefined" || !this.isContentDragging) return;
|
||||
var item = $(e.originalEvent.target).parents('li').children('a');
|
||||
if ($(item).length==0 || $(item).parents('#'+this.getId()).length==0) return;
|
||||
if ($(item).hasClass('inactive') || $(item).parent('li').hasClass('tmp-drag-options-item')) return;
|
||||
if (this.dragReplaced && $(item).attr('id') == this.dragStartItem) {
|
||||
var startItem = this.findBodyItemByProperty('id',this.dragStartItem);
|
||||
var endItem = this.findBodyItemByProperty('id',this.dragOverItem);
|
||||
if (startItem && endItem && typeof(startItem.sort_order)!="undefined" && typeof(endItem.sort_order)!="undefined") {
|
||||
var start_order = startItem.sort_order;
|
||||
var end_order = endItem.sort_order;
|
||||
startItem.sort_order = end_order;
|
||||
endItem.sort_order = start_order;
|
||||
startItem.is_dragged = true;
|
||||
endItem.is_dragged = true;
|
||||
}
|
||||
this.dragOverItem = null;
|
||||
this.dragStartY = e.originalEvent.pageY;
|
||||
this.dragReplaced = false;
|
||||
}
|
||||
if (this.dragStartItem!=$(item).attr('id') && this.dragOverItem!=$(item).attr('id')) {
|
||||
this.dragOverItem=$(item).attr('id');
|
||||
var tmp = '<li class="tmp-drag-options-item"></li>';
|
||||
if (e.originalEvent.pageY > this.dragStartY) {
|
||||
$(this.content).find('#'+this.dragOverItem).parent('li').after(tmp);
|
||||
} else {
|
||||
$(this.content).find('#'+this.dragOverItem).parent('li').before(tmp);
|
||||
}
|
||||
$(this.content).find('li.tmp-drag-options-item').replaceWith($(this.content).find('#'+this.dragStartItem).parent('li'));
|
||||
this.dragReplaced = true;
|
||||
}
|
||||
}));
|
||||
$(this.content).bind('drop',this.bind(this,function(e){
|
||||
if (this.isDisabled()) return;
|
||||
var dragged = [];
|
||||
var orders = [];
|
||||
for (var i=0; i<this.options.bodyItems.length; i++) {
|
||||
if (typeof(this.options.bodyItems[i].sort_order)!="undefined" && typeof(this.options.bodyItems[i].is_dragged)!="undefined" && this.options.bodyItems[i].is_dragged) {
|
||||
dragged.push(this.options.bodyItems[i].data);
|
||||
orders.push(this.options.bodyItems[i].sort_order);
|
||||
}
|
||||
}
|
||||
if (dragged.length>1 && orders.length>1) {
|
||||
desk_window_request(this, url('vote/dash/drag'),{'item':this.options.data.items[0], 'options':dragged,'orders':orders});
|
||||
}
|
||||
}));
|
||||
$(this.content).bind('dragend',this.bind(this,function(e){
|
||||
$(this.content).find('#'+this.dragStartItem).parent('li').css('opacity',1);
|
||||
this.isContentDragging = false;
|
||||
this.dragStartY = null;
|
||||
this.dragStartItem = null;
|
||||
this.dragOverItem = null;
|
||||
this.dragReplaced = false;
|
||||
$(this.content).find('li.tmp-drag-options-item').remove();
|
||||
}));
|
||||
};
|
||||
|
||||
var dash_votes_results = function() {
|
||||
var selected = this.getSelectedContentItems();
|
||||
if (selected && selected.length==1) {
|
||||
desk_window_request(this, url('vote/dash/results'),{'item':selected[0].data}, this.bind(this, function(result){
|
||||
desk_message(t('Vote results')+':<div style="color:black;padding:10px 16px">'+result.join('<br />')+'</div>');
|
||||
}));
|
||||
}
|
||||
};
|
31
assets/js/vote/vote.js
Normal file
31
assets/js/vote/vote.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
(function($){
|
||||
$(document).ready(function(){
|
||||
$('.vote-options-wrapper .vote-submit').click(function(){
|
||||
var vote_id = $(this).data('vote_id');
|
||||
var url = $(this).data('url');
|
||||
var token = $(this).data('token');
|
||||
if (typeof(vote_id)=="undefined" || typeof(url)=="undefined" || typeof(token)=="undefined") return;
|
||||
|
||||
var opts = $(this).parent('.vote-options-wrapper').find('input:checked');
|
||||
if ($(opts).length==0) return;
|
||||
|
||||
var o = [];
|
||||
$(opts).each(function(){
|
||||
o.push($(this).val());
|
||||
});
|
||||
|
||||
$(this).attr('disabled','disabled');
|
||||
$(this).parent('.vote-options-wrapper').append('<div class="zira-loader-wrapper"><span class="zira-loader"></span></div>');
|
||||
|
||||
$.post(url, {
|
||||
'vote_id': vote_id,
|
||||
'options': o,
|
||||
'token': token
|
||||
}, zira_bind(this, function(response){
|
||||
$(this).parent('.vote-options-wrapper').children('ul').replaceWith(response);
|
||||
$(this).parent('.vote-options-wrapper').children('.zira-loader-wrapper').remove();
|
||||
$(this).remove();
|
||||
}),'html');
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
|
@ -26,6 +26,7 @@ class Emoji {
|
|||
}
|
||||
|
||||
public function bootstrap() {
|
||||
Zira\View::addDefaultAssets();
|
||||
Zira\View::addStyle('emoji/emoji.css');
|
||||
Zira\View::addScript('emoji/emoji.js');
|
||||
|
||||
|
|
5
languages/en/vote.php
Normal file
5
languages/en/vote.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return array(
|
||||
'Activated %s widgets' => array('Activated %s widget', 'Activated %s widgets')
|
||||
);
|
20
languages/ru/vote.php
Normal file
20
languages/ru/vote.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
return array(
|
||||
'Vote' => 'Голосование',
|
||||
'Votes' => 'Голосование',
|
||||
'Let your website visitors to vote' => 'Дайте вашим пользователям возможность голосовать',
|
||||
'Vote subject' => 'Тема голосования',
|
||||
'New vote subject' => 'Новая тема для голосования',
|
||||
'Subject' => 'Тема',
|
||||
'Multiple selection' => 'Множественный выбор',
|
||||
'Widget placeholder' => 'Расположение виджета',
|
||||
'Activated %s widgets' => array('Активирован %s виджет', 'Активировано %s виджета', 'Активировано %s виджетов'),
|
||||
'Vote options' => 'Опции для выбора',
|
||||
'Add vote option' => 'Добавить опцию выбора',
|
||||
'Enter text' => 'Введите текст',
|
||||
'Votes: %s' => 'Голосов: %s',
|
||||
'Vote!' => 'Голосовать!',
|
||||
'Vote results' => 'Результаты голосования',
|
||||
'Results' => 'Результаты'
|
||||
);
|
26
themes/default/vote/options.php
Normal file
26
themes/default/vote/options.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php if (count($options)>0): ?>
|
||||
<div class="vote-options-wrapper block">
|
||||
<?php if ($is_sidebar): ?>
|
||||
<h2><?php echo tm('Vote','vote') ?></h2>
|
||||
<?php else: ?>
|
||||
<div class="page-header">
|
||||
<h2><?php echo tm('Vote','vote') ?></h2>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<p class="subject"><?php echo t(Zira\Helper::html($subject)) ?></p>
|
||||
<ul>
|
||||
<?php foreach($options as $option): ?>
|
||||
<?php $id = 'vote-'.$vote_id.'-option-'.$option->id; ?>
|
||||
<li>
|
||||
<?php if ($multiple): ?>
|
||||
<?php echo Zira\Form\Form::checkbox($token, 'vote_options', $option->id, array('id'=>$id)) ?>
|
||||
<?php else: ?>
|
||||
<?php echo Zira\Form\Form::radio($token, 'vote_options', $option->id, array('id'=>$id)) ?>
|
||||
<?php endif; ?>
|
||||
<?php echo '<label for="'.Zira\Helper::html($id).'">'.t(Zira\Helper::html($option->content)).'</label>' ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<button class="btn btn-primary vote-submit" data-token="<?php echo Zira\Helper::html($token); ?>" data-vote_id="<?php echo Zira\Helper::html($vote_id); ?>" data-url="<?php echo Zira\Helper::url('vote/index/index'); ?>"><?php echo tm('Vote!','vote') ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
24
themes/default/vote/results.php
Normal file
24
themes/default/vote/results.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php if (count($options)>0): ?>
|
||||
<?php if (!$is_ajax): ?>
|
||||
<div class="vote-results-wrapper block">
|
||||
<?php if ($is_sidebar): ?>
|
||||
<h2><?php echo tm('Vote','vote') ?></h2>
|
||||
<?php else: ?>
|
||||
<div class="page-header">
|
||||
<h2><?php echo tm('Vote','vote') ?></h2>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<p class="subject"><?php echo t(Zira\Helper::html($subject)) ?></p>
|
||||
<?php endif; ?>
|
||||
<ul class="vote-results">
|
||||
<?php foreach($options as $option): ?>
|
||||
<li>
|
||||
<?php echo '<div>'.t(Zira\Helper::html($option->content)).' — <span class="vote-result">'.Zira\Helper::html($option->count).'</span></div>' ?>
|
||||
<div class="vote-results-line" style="width:<?php echo round(($option->count/$total)*100) ?>%"></div>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php if (!$is_ajax): ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
76
vote/controllers/dash.php
Normal file
76
vote/controllers/dash.php
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* index.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Controllers;
|
||||
|
||||
use Zira;
|
||||
use Vote;
|
||||
|
||||
class Dash extends \Dash\Controller {
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
Zira\View::setAjax(true);
|
||||
}
|
||||
|
||||
protected function getWindowModel() {
|
||||
$window = new Vote\Windows\Votes();
|
||||
return new Vote\Models\Votes($window);
|
||||
}
|
||||
|
||||
public function install() {
|
||||
if (Zira\Request::isPost()) {
|
||||
$items = Zira\Request::post('votes');
|
||||
$response = $this->getWindowModel()->install($items);
|
||||
Zira\Page::render($response);
|
||||
}
|
||||
}
|
||||
|
||||
public function option() {
|
||||
if (Zira\Request::isPost()) {
|
||||
$vote = Zira\Request::post('vote');
|
||||
$content = Zira\Request::post('content');
|
||||
$option = Zira\Request::post('option');
|
||||
$response = $this->getWindowModel()->option($vote, $content, $option);
|
||||
Zira\Page::render($response);
|
||||
}
|
||||
}
|
||||
|
||||
public function deloptions() {
|
||||
if (Zira\Request::isPost()) {
|
||||
$vote = Zira\Request::post('vote');
|
||||
$options = Zira\Request::post('options');
|
||||
$response = $this->getWindowModel()->deleteOptions($vote, $options);
|
||||
Zira\Page::render($response);
|
||||
}
|
||||
}
|
||||
|
||||
public function drag() {
|
||||
if (Zira\Request::isPost()) {
|
||||
$vote = Zira\Request::post('item');
|
||||
$options = Zira\Request::post('options');
|
||||
$orders = Zira\Request::post('orders');
|
||||
$response = $this->getWindowModel()->drag($vote, $options, $orders);
|
||||
Zira\Page::render($response);
|
||||
}
|
||||
}
|
||||
|
||||
public function info() {
|
||||
if (Zira\Request::isPost()) {
|
||||
$vote = Zira\Request::post('item');
|
||||
$response = $this->getWindowModel()->info($vote);
|
||||
Zira\Page::render($response);
|
||||
}
|
||||
}
|
||||
|
||||
public function results() {
|
||||
if (Zira\Request::isPost()) {
|
||||
$vote = Zira\Request::post('item');
|
||||
$response = $this->getWindowModel()->results($vote);
|
||||
Zira\Page::render($response);
|
||||
}
|
||||
}
|
||||
}
|
102
vote/controllers/index.php
Normal file
102
vote/controllers/index.php
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* index.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Controllers;
|
||||
|
||||
use Zira;
|
||||
use Vote;
|
||||
|
||||
class Index extends Zira\Controller {
|
||||
public function index() {
|
||||
if (Zira\Request::isPost()) {
|
||||
$vote_id = Zira\Request::post('vote_id');
|
||||
$options = Zira\Request::post('options');
|
||||
$token = Zira\Request::post('token');
|
||||
|
||||
if (empty($vote_id) || empty($options) || !is_array($options) || empty($token)) return;
|
||||
if (!Zira\User::checkToken($token)) return;
|
||||
|
||||
$user_id = Zira\User::isAuthorized() ? Zira\User::getCurrent()->id : 0;
|
||||
$anonymous_id = Zira\User::getAnonymousUserId();
|
||||
if (empty($user_id) && empty($anonymous_id)) return;
|
||||
|
||||
$vote = new Vote\Models\Vote($vote_id);
|
||||
if (!$vote->loaded()) return;
|
||||
|
||||
if (!$vote->multiple && count($options)>1) {
|
||||
$options = array_slice($options, 0, 1);
|
||||
}
|
||||
|
||||
$query = Vote\Models\Voteresult::getCollection()
|
||||
->count()
|
||||
->where('vote_id','=',$vote->id);
|
||||
|
||||
if (!empty($user_id)) {
|
||||
$query->and_where();
|
||||
$query->open_where();
|
||||
$query->where('user_id','=',$user_id);
|
||||
$query->or_where('anonymous_id','=',$anonymous_id);
|
||||
$query->close_where();
|
||||
} else if (!empty($anonymous_id)) {
|
||||
$query->and_where('anonymous_id','=',$anonymous_id);
|
||||
}
|
||||
|
||||
$co = $query->get('co');
|
||||
|
||||
if ($co==0) {
|
||||
foreach($options as $option_id) {
|
||||
$res = new Vote\Models\Voteresult();
|
||||
$res->vote_id = $vote->id;
|
||||
$res->option_id = $option_id;
|
||||
$res->user_id = $user_id;
|
||||
$res->anonymous_id = $anonymous_id;
|
||||
$res->creation_date = date('Y-m-d H:i:s');
|
||||
$res->save();
|
||||
}
|
||||
$vote->votes++;
|
||||
$vote->save();
|
||||
}
|
||||
|
||||
// results
|
||||
$options = \Vote\Models\Voteoption::getCollection()
|
||||
->select(array('id','content'))
|
||||
->where('vote_id','=',$vote->id)
|
||||
->order_by('sort_order', 'asc')
|
||||
->get();
|
||||
|
||||
$results = Vote\Models\Voteresult::getCollection()
|
||||
->select('option_id')
|
||||
->count()
|
||||
->where('vote_id','=',$vote->id)
|
||||
->group_by('option_id')
|
||||
->get();
|
||||
|
||||
$vals = array();
|
||||
foreach($results as $result) {
|
||||
$vals[$result->option_id] = $result->co;
|
||||
}
|
||||
|
||||
$total = 0;
|
||||
for($i=0; $i<count($options); $i++) {
|
||||
if (array_key_exists($options[$i]->id, $vals)) {
|
||||
$options[$i]->count = $vals[$options[$i]->id];
|
||||
} else {
|
||||
$options[$i]->count = 0;
|
||||
}
|
||||
$total += $options[$i]->count;
|
||||
}
|
||||
|
||||
Zira\View::renderView(array(
|
||||
'vote_id' => $vote->id,
|
||||
'subject' => $vote->subject,
|
||||
'options' => $options,
|
||||
'total' => $total,
|
||||
'is_ajax' => true
|
||||
), 'vote/results');
|
||||
}
|
||||
}
|
||||
}
|
70
vote/forms/vote.php
Normal file
70
vote/forms/vote.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* vote.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Forms;
|
||||
|
||||
use Zira;
|
||||
use Zira\Form;
|
||||
use Zira\Locale;
|
||||
|
||||
class Vote extends Form
|
||||
{
|
||||
protected $_id = 'vote-vote-form';
|
||||
|
||||
protected $_label_class = 'col-sm-4 control-label';
|
||||
protected $_input_wrap_class = 'col-sm-8';
|
||||
protected $_input_offset_wrap_class = 'col-sm-offset-4 col-sm-8';
|
||||
protected $_select_wrapper_class = 'col-sm-8';
|
||||
|
||||
protected $_checkbox_inline_label = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct($this->_id);
|
||||
}
|
||||
|
||||
protected function _init()
|
||||
{
|
||||
$this->setRenderPanel(false);
|
||||
$this->setFormClass('form-horizontal dash-window-form');
|
||||
}
|
||||
|
||||
protected function _render()
|
||||
{
|
||||
$html = $this->open();
|
||||
|
||||
$id = $this->getValue('id');
|
||||
if (empty($id)) {
|
||||
$placeholders = Zira\Models\Widget::getPlaceholders();
|
||||
$html .= $this->selectDropdown(Locale::t('Widget placeholder').'*','placeholder',$placeholders);
|
||||
}
|
||||
$html .= $this->input(Locale::tm('Subject','vote'), 'subject');
|
||||
$html .= $this->checkbox(Locale::tm('Multiple selection','vote'), 'multiple', null, false);
|
||||
$html .= $this->hidden('id');
|
||||
$html .= $this->close();
|
||||
return $html;
|
||||
}
|
||||
|
||||
protected function _validate() {
|
||||
$validator = $this->getValidator();
|
||||
|
||||
$validator->registerString('subject',null,255,false,Locale::t('Invalid value "%s"',Locale::tm('Subject','vote')));
|
||||
$validator->registerNoTags('subject',Locale::t('Invalid value "%s"',Locale::tm('Subject','vote')));
|
||||
$validator->registerUtf8('subject',Locale::t('Invalid value "%s"',Locale::tm('Subject','vote')));
|
||||
|
||||
$id = $this->getValue('id');
|
||||
if (empty($id)) {
|
||||
$validator->registerString('placeholder', null, 255, true, Locale::t('Invalid value "%s"',Locale::tm('Widget placeholder','vote')));
|
||||
$validator->registerCustom(array(get_class(), 'checkPlaceholder'), 'placeholder', Locale::t('Invalid value "%s"',Locale::tm('Widget placeholder','vote')));
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkPlaceholder($placeholder) {
|
||||
$placeholders = Zira\Models\Widget::getPlaceholders();
|
||||
return array_key_exists($placeholder, $placeholders);
|
||||
}
|
||||
}
|
49
vote/install/vote.php
Normal file
49
vote/install/vote.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* vote.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Install;
|
||||
|
||||
use Zira\Db\Table;
|
||||
use Zira\Db\Field;
|
||||
|
||||
class Vote extends Table {
|
||||
protected $_table = 'votes';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct($this->_table);
|
||||
}
|
||||
|
||||
public function getFields() {
|
||||
return array(
|
||||
'id' => Field::primary(),
|
||||
'creator_id' => Field::int(true, true),
|
||||
'subject' => Field::string(true),
|
||||
'placeholder' => Field::string(true),
|
||||
'multiple' => Field::tinyint(true, true, 0),
|
||||
'votes' => Field::int(true, true, 0),
|
||||
'date_created' => Field::datetime(true)
|
||||
);
|
||||
}
|
||||
|
||||
public function getKeys() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
public function getUnique() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
public function getDefaults() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
}
|
46
vote/install/voteoption.php
Normal file
46
vote/install/voteoption.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* voteoption.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Install;
|
||||
|
||||
use Zira\Db\Table;
|
||||
use Zira\Db\Field;
|
||||
|
||||
class Voteoption extends Table {
|
||||
protected $_table = 'vote_options';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct($this->_table);
|
||||
}
|
||||
|
||||
public function getFields() {
|
||||
return array(
|
||||
'id' => Field::primary(),
|
||||
'vote_id' => Field::int(true, true),
|
||||
'content' => Field::string(true),
|
||||
'sort_order' => Field::int(true, false, 0)
|
||||
);
|
||||
}
|
||||
|
||||
public function getKeys() {
|
||||
return array(
|
||||
'vote' => array('vote_id', 'sort_order')
|
||||
);
|
||||
}
|
||||
|
||||
public function getUnique() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
public function getDefaults() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
}
|
48
vote/install/voteresult.php
Normal file
48
vote/install/voteresult.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* voteresult.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Install;
|
||||
|
||||
use Zira\Db\Table;
|
||||
use Zira\Db\Field;
|
||||
|
||||
class Voteresult extends Table {
|
||||
protected $_table = 'vote_results';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct($this->_table);
|
||||
}
|
||||
|
||||
public function getFields() {
|
||||
return array(
|
||||
'id' => Field::primary(),
|
||||
'vote_id' => Field::int(true, true),
|
||||
'option_id' => Field::int(true, true),
|
||||
'user_id' => Field::int(true, true),
|
||||
'anonymous_id' => Field::string(true),
|
||||
'creation_date' => Field::datetime(true)
|
||||
);
|
||||
}
|
||||
|
||||
public function getKeys() {
|
||||
return array(
|
||||
'vote' => array('vote_id', 'option_id', 'user_id', 'anonymous_id')
|
||||
);
|
||||
}
|
||||
|
||||
public function getUnique() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
public function getDefaults() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
}
|
37
vote/models/vote.php
Normal file
37
vote/models/vote.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* vote.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Models;
|
||||
|
||||
use Zira;
|
||||
use Zira\Orm;
|
||||
|
||||
class Vote extends Orm {
|
||||
const WIDGET_CLASS = '\Vote\Widgets\Vote';
|
||||
|
||||
public static $table = 'votes';
|
||||
public static $pk = 'id';
|
||||
public static $alias = 'vot';
|
||||
|
||||
public static function getTable() {
|
||||
return self::$table;
|
||||
}
|
||||
|
||||
public static function getPk() {
|
||||
return self::$pk;
|
||||
}
|
||||
|
||||
public static function getAlias() {
|
||||
return self::$alias;
|
||||
}
|
||||
|
||||
public static function getReferences() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
}
|
35
vote/models/voteoption.php
Normal file
35
vote/models/voteoption.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* voteoption.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Models;
|
||||
|
||||
use Zira;
|
||||
use Zira\Orm;
|
||||
|
||||
class Voteoption extends Orm {
|
||||
public static $table = 'vote_options';
|
||||
public static $pk = 'id';
|
||||
public static $alias = 'vot_opt';
|
||||
|
||||
public static function getTable() {
|
||||
return self::$table;
|
||||
}
|
||||
|
||||
public static function getPk() {
|
||||
return self::$pk;
|
||||
}
|
||||
|
||||
public static function getAlias() {
|
||||
return self::$alias;
|
||||
}
|
||||
|
||||
public static function getReferences() {
|
||||
return array(
|
||||
Vote::getClass() => 'vote_id'
|
||||
);
|
||||
}
|
||||
}
|
35
vote/models/voteresult.php
Normal file
35
vote/models/voteresult.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* voteresult.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Models;
|
||||
|
||||
use Zira;
|
||||
use Zira\Orm;
|
||||
|
||||
class Voteresult extends Orm {
|
||||
public static $table = 'vote_results';
|
||||
public static $pk = 'id';
|
||||
public static $alias = 'vot_rst';
|
||||
|
||||
public static function getTable() {
|
||||
return self::$table;
|
||||
}
|
||||
|
||||
public static function getPk() {
|
||||
return self::$pk;
|
||||
}
|
||||
|
||||
public static function getAlias() {
|
||||
return self::$alias;
|
||||
}
|
||||
|
||||
public static function getReferences() {
|
||||
return array(
|
||||
|
||||
);
|
||||
}
|
||||
}
|
261
vote/models/votes.php
Normal file
261
vote/models/votes.php
Normal file
|
@ -0,0 +1,261 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* votes.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Models;
|
||||
|
||||
use Zira;
|
||||
use Dash;
|
||||
use Vote;
|
||||
use Zira\Permission;
|
||||
|
||||
class Votes extends Dash\Models\Model {
|
||||
public function save($data) {
|
||||
if (!Permission::check(Permission::TO_CHANGE_OPTIONS)) {
|
||||
return array('error' => Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
|
||||
$form = new Vote\Forms\Vote();
|
||||
if ($form->isValid()) {
|
||||
$id = (int)$form->getValue('id');
|
||||
|
||||
if ($id) {
|
||||
$vote = new Vote\Models\Vote($id);
|
||||
if (!$vote->loaded()) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
} else {
|
||||
$vote = new Vote\Models\Vote();
|
||||
$vote->placeholder = $form->getValue('placeholder');
|
||||
$vote->creator_id = Zira\User::getCurrent()->id;
|
||||
$vote->date_created = date('Y-m-d H:i:s');
|
||||
$vote->votes = 0;
|
||||
}
|
||||
$vote->subject = $form->getValue('subject');
|
||||
$vote->multiple = (int)$form->getValue('multiple');
|
||||
|
||||
$vote->save();
|
||||
|
||||
if (empty($id)) {
|
||||
$max_order = Zira\Models\Widget::getCollection()->max('sort_order')->get('mx');
|
||||
|
||||
$widget = new Zira\Models\Widget();
|
||||
$widget->name = Vote\Models\Vote::WIDGET_CLASS;
|
||||
$widget->module = 'vote';
|
||||
$widget->placeholder = $form->getValue('placeholder');
|
||||
$widget->params = $vote->id;
|
||||
$widget->category_id = null;
|
||||
$widget->sort_order = ++$max_order;
|
||||
$widget->active = Zira\Models\Widget::STATUS_ACTIVE;
|
||||
$widget->save();
|
||||
}
|
||||
|
||||
Zira\Cache::clear();
|
||||
|
||||
return array('message'=>Zira\Locale::t('Successfully saved'), 'close'=>true);
|
||||
} else {
|
||||
return array('error'=>$form->getError());
|
||||
}
|
||||
}
|
||||
|
||||
public function install($votes) {
|
||||
if (empty($votes) || !is_array($votes)) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
return array('error'=>Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
|
||||
$widgets = array();
|
||||
$rows = Zira\Models\Widget::getCollection()
|
||||
->where('name','=',Vote\Models\Vote::WIDGET_CLASS)
|
||||
->get()
|
||||
;
|
||||
foreach($rows as $row) {
|
||||
if (!is_numeric($row->params)) continue;
|
||||
$widgets[] = $row->params;
|
||||
}
|
||||
|
||||
$max_order = Zira\Models\Widget::getCollection()->max('sort_order')->get('mx');
|
||||
|
||||
$co=0;
|
||||
foreach($votes as $vote_id) {
|
||||
$vote = new Vote\Models\Vote(intval($vote_id));
|
||||
if (!$vote->loaded()) continue;
|
||||
if (in_array($vote->id,$widgets)) continue;
|
||||
$widget = new Zira\Models\Widget();
|
||||
$widget->name = Vote\Models\Vote::WIDGET_CLASS;
|
||||
$widget->module = 'vote';
|
||||
$widget->placeholder = $vote->placeholder;
|
||||
$widget->params = $vote->id;
|
||||
$widget->category_id = null;
|
||||
$widget->sort_order = ++$max_order;
|
||||
$widget->active = Zira\Models\Widget::STATUS_ACTIVE;
|
||||
$widget->save();
|
||||
|
||||
$co++;
|
||||
}
|
||||
|
||||
Zira\Cache::clear();
|
||||
|
||||
return array('message' => Zira\Locale::t('Activated %s widgets', $co), 'reload'=>$this->getJSClassName());
|
||||
}
|
||||
|
||||
public function delete($data) {
|
||||
if (empty($data) || !is_array($data)) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
return array('error'=>Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
|
||||
foreach($data as $vote_id) {
|
||||
$vote = new Vote\Models\Vote($vote_id);
|
||||
if (!$vote->loaded()) {
|
||||
return array('error' => Zira\Locale::t('An error occurred'));
|
||||
};
|
||||
$vote->delete();
|
||||
|
||||
Zira\Models\Widget::getCollection()
|
||||
->where('name','=',Vote\Models\Vote::WIDGET_CLASS)
|
||||
->and_where('params','=',$vote_id)
|
||||
->delete()
|
||||
->execute();
|
||||
|
||||
Vote\Models\Voteoption::getCollection()
|
||||
->where('vote_id','=',$vote_id)
|
||||
->delete()
|
||||
->execute();
|
||||
|
||||
Vote\Models\Voteresult::getCollection()
|
||||
->where('vote_id','=',$vote_id)
|
||||
->delete()
|
||||
->execute();
|
||||
}
|
||||
|
||||
Zira\Cache::clear();
|
||||
|
||||
return array('reload' => $this->getJSClassName());
|
||||
}
|
||||
|
||||
public function option($vote_id, $content, $option_id = null) {
|
||||
if (empty($vote_id) || empty($content)) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
return array('error'=>Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
$vote = new Vote\Models\Vote(intval($vote_id));
|
||||
if (!$vote->loaded()) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
|
||||
if ($option_id === null) {
|
||||
$max_order = Vote\Models\Voteoption::getCollection()->max('sort_order')->get('mx');
|
||||
|
||||
$option = new Vote\Models\Voteoption();
|
||||
$option->vote_id = $vote->id;
|
||||
$option->sort_order = ++$max_order;
|
||||
} else {
|
||||
$option = new Vote\Models\Voteoption($option_id);
|
||||
if (!$option->loaded()) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
}
|
||||
|
||||
$option->content = strip_tags($content);
|
||||
$option->save();
|
||||
|
||||
return array('reload' => Dash\Dash::getInstance()->getWindowJSName(Vote\Windows\Options::getClass()));
|
||||
}
|
||||
|
||||
public function drag($vote_id, $options, $orders) {
|
||||
if (empty($vote_id)) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
if (empty($options) || !is_array($options) || count($options)<2 || empty($orders) || !is_array($orders) || count($orders)<2 || count($options)!=count($orders)) {
|
||||
return array('error' => Zira\Locale::t('An error occurred'));
|
||||
}
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
return array('error'=>Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
|
||||
$_options = array();
|
||||
$_orders = array();
|
||||
foreach($options as $id) {
|
||||
$_option = new Vote\Models\Voteoption($id);
|
||||
if (!$_option->loaded() || $_option->vote_id != $vote_id) {
|
||||
return array('error' => Zira\Locale::t('An error occurred'));
|
||||
}
|
||||
$_options []= $_option;
|
||||
$_orders []= $_option->sort_order;
|
||||
}
|
||||
foreach($orders as $order) {
|
||||
if (!in_array($order, $_orders)) {
|
||||
return array('error' => Zira\Locale::t('An error occurred'));
|
||||
}
|
||||
}
|
||||
foreach($_options as $index=>$option) {
|
||||
$option->sort_order = intval($orders[$index]);
|
||||
$option->save();
|
||||
}
|
||||
|
||||
return array('reload'=>Dash\Dash::getInstance()->getWindowJSName(Vote\Windows\Options::getClass()));
|
||||
}
|
||||
|
||||
public function deleteOptions($vote_id, $options) {
|
||||
if (empty($vote_id)) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
if (empty($options) || !is_array($options)) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
return array('error'=>Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
|
||||
foreach($options as $option_id) {
|
||||
$option = new Vote\Models\Voteoption($option_id);
|
||||
if (!$option->loaded() || $option->vote_id != $vote_id) {
|
||||
return array('error' => Zira\Locale::t('An error occurred'));
|
||||
};
|
||||
$option->delete();
|
||||
}
|
||||
|
||||
return array('reload' => Dash\Dash::getInstance()->getWindowJSName(Vote\Windows\Options::getClass()));
|
||||
}
|
||||
|
||||
public function info($id) {
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$info = array();
|
||||
|
||||
$vote = new Vote\Models\Vote($id);
|
||||
if (!$vote->loaded()) return array();
|
||||
|
||||
$info[] = '<span class="glyphicon glyphicon-tag"></span> ' . Zira\Helper::html($vote->subject);
|
||||
$info[] = '<span class="glyphicon glyphicon-thumbs-up"></span> ' . Zira\Locale::tm('Votes: %s', 'vote', Zira\Helper::html($vote->votes));
|
||||
$info[] = '<span class="glyphicon glyphicon-time"></span> ' . date(Zira\Config::get('date_format'), strtotime($vote->date_created));
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function results($vote_id) {
|
||||
$options = \Vote\Models\Voteoption::getCollection()
|
||||
->select(array('id','content'))
|
||||
->where('vote_id','=',$vote_id)
|
||||
->order_by('sort_order', 'asc')
|
||||
->get();
|
||||
|
||||
$results = Vote\Models\Voteresult::getCollection()
|
||||
->select('option_id')
|
||||
->count()
|
||||
->where('vote_id','=',$vote_id)
|
||||
->group_by('option_id')
|
||||
->get();
|
||||
|
||||
$vals = array();
|
||||
foreach($results as $result) {
|
||||
$vals[$result->option_id] = $result->co;
|
||||
}
|
||||
|
||||
$return = array();
|
||||
foreach($options as $option) {
|
||||
if (array_key_exists($option->id, $vals)) {
|
||||
$count = $vals[$option->id];
|
||||
} else {
|
||||
$count = 0;
|
||||
}
|
||||
$return []= '• '.$option->content.' — '.$count;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
5
vote/module.meta
Normal file
5
vote/module.meta
Normal file
|
@ -0,0 +1,5 @@
|
|||
[meta]
|
||||
name = Vote
|
||||
description = Let your website visitors to vote
|
||||
author = Zira
|
||||
version = 1.0
|
41
vote/vote.php
Normal file
41
vote/vote.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* vote.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote;
|
||||
|
||||
use Zira;
|
||||
use Dash;
|
||||
|
||||
class Vote {
|
||||
private static $_instance;
|
||||
|
||||
public static function getInstance() {
|
||||
if (self::$_instance === null) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
public function beforeDispatch() {
|
||||
Zira\Assets::registerCSSAsset('vote/vote.css');
|
||||
Zira\Assets::registerJSAsset('vote/vote.js');
|
||||
}
|
||||
|
||||
public function bootstrap() {
|
||||
Zira\View::addDefaultAssets();
|
||||
Zira\View::addStyle('vote/vote.css');
|
||||
Zira\View::addScript('vote/vote.js');
|
||||
|
||||
if (ENABLE_CONFIG_DATABASE && Dash\Dash::getInstance()->isPanelEnabled() && Zira\Permission::check(Zira\Permission::TO_ACCESS_DASHBOARD) && Zira\Permission::check(Zira\Permission::TO_CHANGE_OPTIONS)) {
|
||||
Dash\Dash::getInstance()->addPanelModulesGroupItem('glyphicon glyphicon-stats', Zira\Locale::tm('Votes', 'vote'), null, 'votesWindow()');
|
||||
Dash\Dash::getInstance()->registerModuleWindowClass('votesWindow', 'Vote\Windows\Votes', 'Vote\Models\Votes');
|
||||
Dash\Dash::getInstance()->registerModuleWindowClass('voteWindow', 'Vote\Windows\Vote', 'Vote\Models\Votes');
|
||||
Dash\Dash::getInstance()->registerModuleWindowClass('voteOptionsWindow', 'Vote\Windows\Options', 'Vote\Models\Votes');
|
||||
}
|
||||
}
|
||||
}
|
127
vote/widgets/vote.php
Normal file
127
vote/widgets/vote.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* vote.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Widgets;
|
||||
|
||||
use Zira;
|
||||
|
||||
class Vote extends Zira\Widget {
|
||||
protected $_title = 'Vote';
|
||||
protected static $_titles;
|
||||
|
||||
protected function _init() {
|
||||
$this->setDynamic(true);
|
||||
$this->setCaching(false);
|
||||
$this->setOrder(0);
|
||||
$this->setPlaceholder(Zira\View::VAR_CONTENT_BOTTOM);
|
||||
}
|
||||
|
||||
protected function getTitles() {
|
||||
if (self::$_titles===null) {
|
||||
self::$_titles = array();
|
||||
$rows = \Vote\Models\Vote::getCollection()->get();
|
||||
foreach($rows as $row) {
|
||||
self::$_titles[$row->id] = $row->subject;
|
||||
}
|
||||
}
|
||||
return self::$_titles;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$id = $this->getData();
|
||||
if (is_numeric($id)) {
|
||||
$titles = $this->getTitles();
|
||||
if (empty($titles) || !array_key_exists($this->getData(), $titles)) return parent::getTitle();
|
||||
return Zira\Locale::t('Vote') . ' - ' . $titles[$id];
|
||||
} else {
|
||||
return parent::getTitle();
|
||||
}
|
||||
}
|
||||
|
||||
protected function _render() {
|
||||
$id = $this->getData();
|
||||
$user_id = Zira\User::isAuthorized() ? Zira\User::getCurrent()->id : 0;
|
||||
$anonymous_id = Zira\User::getAnonymousUserId();
|
||||
if (empty($user_id) && empty($anonymous_id)) return;
|
||||
|
||||
$options = \Vote\Models\Voteoption::getCollection()
|
||||
->select(array('id'=>'id','content'=>'content'))
|
||||
->join(\Vote\Models\Vote::getClass(), array('vote_id'=>'id','subject'=>'subject', 'multiple'=>'multiple'))
|
||||
->where('vote_id','=',$id)
|
||||
->order_by('sort_order', 'asc')
|
||||
->get();
|
||||
|
||||
if (!$options || count($options)==0) return;
|
||||
|
||||
$vote_id = $options[0]->vote_id;
|
||||
$subject = $options[0]->subject;
|
||||
$multiple = $options[0]->multiple;
|
||||
|
||||
$is_sidebar = $this->getPlaceholder() == Zira\View::VAR_SIDEBAR_LEFT || $this->getPlaceholder() == Zira\View::VAR_SIDEBAR_RIGHT;
|
||||
|
||||
|
||||
|
||||
$query = \Vote\Models\Voteresult::getCollection()
|
||||
->count()
|
||||
->where('vote_id','=',$id);
|
||||
|
||||
if (!empty($user_id)) {
|
||||
$query->and_where();
|
||||
$query->open_where();
|
||||
$query->where('user_id','=',$user_id);
|
||||
$query->or_where('anonymous_id','=',$anonymous_id);
|
||||
$query->close_where();
|
||||
} else if (!empty($anonymous_id)) {
|
||||
$query->and_where('anonymous_id','=',$anonymous_id);
|
||||
}
|
||||
|
||||
$co = $query->get('co');
|
||||
|
||||
if ($co==0) {
|
||||
Zira\View::renderView(array(
|
||||
'token' => Zira\User::getToken(),
|
||||
'vote_id' => $vote_id,
|
||||
'subject' => $subject,
|
||||
'multiple' => $multiple,
|
||||
'options' => $options,
|
||||
'is_sidebar' => $is_sidebar
|
||||
), 'vote/options');
|
||||
} else {
|
||||
// results
|
||||
$results = \Vote\Models\Voteresult::getCollection()
|
||||
->select('option_id')
|
||||
->count()
|
||||
->where('vote_id', '=', $id)
|
||||
->group_by('option_id')
|
||||
->get();
|
||||
|
||||
$vals = array();
|
||||
foreach ($results as $result) {
|
||||
$vals[$result->option_id] = $result->co;
|
||||
}
|
||||
|
||||
$total = 0;
|
||||
for ($i = 0; $i < count($options); $i++) {
|
||||
if (array_key_exists($options[$i]->id, $vals)) {
|
||||
$options[$i]->count = $vals[$options[$i]->id];
|
||||
} else {
|
||||
$options[$i]->count = 0;
|
||||
}
|
||||
$total += $options[$i]->count;
|
||||
}
|
||||
|
||||
Zira\View::renderView(array(
|
||||
'vote_id' => $vote_id,
|
||||
'subject' => $subject,
|
||||
'options' => $options,
|
||||
'total' => $total,
|
||||
'is_ajax' => false,
|
||||
'is_sidebar' => $is_sidebar
|
||||
), 'vote/results');
|
||||
}
|
||||
}
|
||||
}
|
86
vote/windows/options.php
Normal file
86
vote/windows/options.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* options.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Windows;
|
||||
|
||||
use Dash;
|
||||
use Zira;
|
||||
use Zira\Permission;
|
||||
|
||||
class Options extends Dash\WIndows\Window {
|
||||
protected static $_icon_class = 'glyphicon glyphicon-th-list';
|
||||
protected static $_title = 'Vote options';
|
||||
|
||||
public $item;
|
||||
|
||||
public function init() {
|
||||
$this->setIconClass(self::$_icon_class);
|
||||
$this->setTitle(Zira\Locale::t(self::$_title));
|
||||
$this->setSidebarEnabled(false);
|
||||
$this->setBodyViewListVertical(true);
|
||||
|
||||
$this->addDefaultMenuDropdownItem(
|
||||
$this->createMenuDropdownItem(Zira\Locale::t($this->_create_action_text), 'glyphicon glyphicon-file', 'desk_call(dash_votes_add_option, this);', 'create', false)
|
||||
);
|
||||
$this->addDefaultContextMenuItem(
|
||||
$this->createContextMenuItem(Zira\Locale::t($this->_create_action_text), 'glyphicon glyphicon-file', 'desk_call(dash_votes_add_option, this);', 'create', false)
|
||||
);
|
||||
|
||||
$this->setOnEditItemJSCallback(
|
||||
$this->createJSCallback('desk_call(dash_votes_edit_option, this)')
|
||||
);
|
||||
$this->setOnDeleteItemsJSCallback(
|
||||
$this->createJSCallback('desk_call(dash_votes_delete_options, this)')
|
||||
);
|
||||
}
|
||||
|
||||
public function create() {
|
||||
$this->addDefaultToolbarItem(
|
||||
$this->createToolbarButton(Zira\Locale::tm('Add vote option', 'vote'), Zira\Locale::tm('Add option', 'vote'), 'glyphicon glyphicon-plus-sign', 'desk_call(dash_votes_add_option, this)', 'create')
|
||||
);
|
||||
$this->setOnOpenJSCallback(
|
||||
$this->createJSCallback(
|
||||
'desk_call(dash_vote_options_drag, this);'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addStrings(array(
|
||||
'Enter text'
|
||||
));
|
||||
|
||||
$this->addVariables(array(
|
||||
'dash_votes_blank_src' => Zira\Helper::imgUrl('blank.png')
|
||||
));
|
||||
|
||||
$this->setData(array(
|
||||
'items' => array($this->item)
|
||||
));
|
||||
}
|
||||
|
||||
public function load() {
|
||||
if (!empty($this->item)) $this->item=intval($this->item);
|
||||
else return array('error' => Zira\Locale::t('An error occurred'));
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
return array('error' => Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
$vote = new \Vote\Models\Vote($this->item);
|
||||
if (!$vote->loaded()) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
|
||||
$options = \Vote\Models\Voteoption::getCollection()
|
||||
->where('vote_id','=',$vote->id)
|
||||
->order_by('sort_order', 'asc')
|
||||
->get();
|
||||
$items = array();
|
||||
foreach ($options as $option) {
|
||||
$items[]=$this->createBodyItem($option->content, $option->content, Zira\Helper::imgUrl('drag.png'), $option->id, null, false, array('sort_order'=>$option->sort_order));
|
||||
}
|
||||
|
||||
$this->setBodyItems($items);
|
||||
|
||||
$this->setTitle(Zira\Locale::t(self::$_title).' - '.$vote->subject);
|
||||
}
|
||||
}
|
57
vote/windows/vote.php
Normal file
57
vote/windows/vote.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* vote.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Windows;
|
||||
|
||||
use Zira;
|
||||
use Dash;
|
||||
use Zira\Permission;
|
||||
|
||||
class Vote extends Dash\Windows\Window {
|
||||
protected static $_icon_class = 'glyphicon glyphicon-list-alt';
|
||||
protected static $_title = 'Vote subject';
|
||||
|
||||
public $item;
|
||||
|
||||
public function init() {
|
||||
$this->setIconClass(self::$_icon_class);
|
||||
$this->setTitle(Zira\Locale::t(self::$_title));
|
||||
$this->setSidebarEnabled(false);
|
||||
|
||||
$this->setSaveActionEnabled(true);
|
||||
}
|
||||
|
||||
public function create() {
|
||||
$this->setOnLoadJSCallback(
|
||||
$this->createJSCallback(
|
||||
'desk_window_form_init(this);'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function load() {
|
||||
if (!empty($this->item)) $this->item=intval($this->item);
|
||||
if (!Permission::check(Permission::TO_CHANGE_OPTIONS)) {
|
||||
return array('error' => Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
|
||||
$form = new \Vote\Forms\Vote();
|
||||
if (!empty($this->item)) {
|
||||
$vote = new \Vote\Models\Vote($this->item);
|
||||
if (!$vote->loaded()) return array('error' => Zira\Locale::t('An error occurred'));
|
||||
$form->setValues($vote->toArray());
|
||||
$this->setTitle(Zira\Locale::tm(self::$_title,'vote').' - '.$vote->subject);
|
||||
} else {
|
||||
$form->setValues(array(
|
||||
'placeholder' => Zira\View::VAR_CONTENT_BOTTOM
|
||||
));
|
||||
$this->setTitle(Zira\Locale::tm('New vote subject','vote'));
|
||||
}
|
||||
|
||||
$this->setBodyContent($form);
|
||||
}
|
||||
}
|
114
vote/windows/votes.php
Normal file
114
vote/windows/votes.php
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
/**
|
||||
* Zira project.
|
||||
* votes.php
|
||||
* (c)2016 http://dro1d.ru
|
||||
*/
|
||||
|
||||
namespace Vote\Windows;
|
||||
|
||||
use Dash;
|
||||
use Zira;
|
||||
use Vote;
|
||||
use Zira\Permission;
|
||||
|
||||
class Votes extends Dash\WIndows\Window {
|
||||
protected static $_icon_class = 'glyphicon glyphicon-stats';
|
||||
protected static $_title = 'Votes';
|
||||
|
||||
|
||||
public function init() {
|
||||
$this->setIconClass(self::$_icon_class);
|
||||
$this->setTitle(Zira\Locale::t(self::$_title));
|
||||
$this->setViewSwitcherEnabled(true);
|
||||
$this->setSelectionLinksEnabled(true);
|
||||
$this->setBodyViewListVertical(true);
|
||||
|
||||
$this->setCreateActionWindowClass(Vote\Windows\Vote::getClass());
|
||||
$this->setEditActionWindowClass(Vote\Windows\Vote::getClass());
|
||||
|
||||
$this->setDeleteActionEnabled(true);
|
||||
}
|
||||
|
||||
public function create() {
|
||||
$this->addDefaultSidebarItem(
|
||||
$this->createSidebarItem(Zira\Locale::tm('Results','vote'), 'glyphicon glyphicon-stats', 'desk_call(dash_votes_results, this);', 'edit', true, array('typo'=>'results'))
|
||||
);
|
||||
|
||||
$this->addDefaultMenuDropdownItem(
|
||||
$this->createMenuDropdownSeparator()
|
||||
);
|
||||
$this->addDefaultMenuDropdownItem(
|
||||
$this->createMenuDropdownItem(Zira\Locale::tm('Vote options','vote'), 'glyphicon glyphicon-th-list', 'desk_call(dash_votes_options, this);', 'edit', true, array('typo'=>'options'))
|
||||
);
|
||||
$this->addDefaultMenuDropdownItem(
|
||||
$this->createMenuDropdownItem(Zira\Locale::tm('Vote results','vote'), 'glyphicon glyphicon-stats', 'desk_call(dash_votes_results, this);', 'edit', true, array('typo'=>'results'))
|
||||
);
|
||||
$this->addDefaultMenuDropdownItem(
|
||||
$this->createMenuDropdownSeparator()
|
||||
);
|
||||
$this->addDefaultMenuDropdownItem(
|
||||
$this->createMenuDropdownItem(Zira\Locale::t('Create widget'), 'glyphicon glyphicon-modal-window', 'desk_call(dash_votes_install, this);', 'delete', true, array('typo'=>'install'))
|
||||
);
|
||||
|
||||
$this->addDefaultContextMenuItem(
|
||||
$this->createContextMenuSeparator()
|
||||
);
|
||||
$this->addDefaultContextMenuItem(
|
||||
$this->createContextMenuItem(Zira\Locale::tm('Vote options','vote'), 'glyphicon glyphicon-th-list', 'desk_call(dash_votes_options, this);', 'edit', true, array('typo'=>'options'))
|
||||
);
|
||||
$this->addDefaultContextMenuItem(
|
||||
$this->createContextMenuItem(Zira\Locale::tm('Vote results','vote'), 'glyphicon glyphicon-stats', 'desk_call(dash_votes_results, this);', 'edit', true, array('typo'=>'results'))
|
||||
);
|
||||
$this->addDefaultContextMenuItem(
|
||||
$this->createContextMenuSeparator()
|
||||
);
|
||||
$this->addDefaultContextMenuItem(
|
||||
$this->createContextMenuItem(Zira\Locale::t('Create widget'), 'glyphicon glyphicon-modal-window', 'desk_call(dash_votes_install, this);', 'delete', true, array('typo'=>'install'))
|
||||
);
|
||||
|
||||
$this->setSidebarContent('<div class="vote-infobar" style="white-space:nowrap;text-overflow: ellipsis;width:100%;overflow:hidden"></div>');
|
||||
|
||||
$this->setOnSelectJSCallback(
|
||||
$this->createJSCallback(
|
||||
'desk_call(dash_votes_select, this);'
|
||||
)
|
||||
);
|
||||
|
||||
$this->addDefaultOnLoadScript('desk_call(dash_votes_load, this);');
|
||||
|
||||
$this->addStrings(array(
|
||||
'Vote results'
|
||||
));
|
||||
|
||||
$this->addVariables(array(
|
||||
'dash_votes_options_wnd' => Dash\Dash::getInstance()->getWindowJSName(Options::getClass())
|
||||
));
|
||||
|
||||
$this->includeJS('vote/dash');
|
||||
}
|
||||
|
||||
public function load() {
|
||||
if (!Permission::check(Permission::TO_CHANGE_LAYOUT)) {
|
||||
$this->setBodyItems(array());
|
||||
return array('error'=>Zira\Locale::t('Permission denied'));
|
||||
}
|
||||
|
||||
$widgets = array();
|
||||
$rows = Zira\Models\Widget::getCollection()
|
||||
->where('name','=',Vote\Models\Vote::WIDGET_CLASS)
|
||||
->get()
|
||||
;
|
||||
foreach($rows as $row) {
|
||||
if (!is_numeric($row->params)) continue;
|
||||
$widgets[] = $row->params;
|
||||
}
|
||||
$votes = Vote\Models\Vote::getCollection()->get();
|
||||
|
||||
$items = array();
|
||||
foreach($votes as $vote) {
|
||||
$items[]=$this->createBodyFileItem($vote->subject, $vote->subject, $vote->id, 'desk_call(dash_votes_options,this);', false, array('type'=>'txt','inactive'=>in_array($vote->id,$widgets) ? 0 : 1));
|
||||
}
|
||||
$this->setBodyItems($items);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue