GithubHelp home page GithubHelp logo

chiliec / yii2-vote Goto Github PK

View Code? Open in Web Editor NEW
72.0 10.0 29.0 173 KB

Provides voting for any model :+1: :-1:

License: BSD 3-Clause "New" or "Revised" License

PHP 100.00%
yii2-extension vote php yii2 rating voting

yii2-vote's People

Contributors

chiliec avatar skatox avatar teranchristian avatar yurkinx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yii2-vote's Issues

Asset для виджета

Вылезла еще одна проблемка при использовании кеша.
При первом выводе списка виджет отрабатывает верно. Затем список кешируется и вне этого списка остается js-функция vote. Следовательно, при клике на кнопки голосования, функция эта не находится и появляются ошибки.

Правильно, наверно, ее будет вынести в отдельный ассет и подключать (регистрировать принудительно) там, где выводится закешированный список.

Предложения по модулю

Спасибо за полезное расширение!
Писал схожий функционал на CI, обратил внимание на ваше за счет aggregate_rating.
А потому из своих наработок, да и после знакомства с вашим есть что предложить :).
А там, если что-то будет полезное - оформлю в виде отдельного issue.

1. По базе

1.1 Добавить индексы для user_id и model_id
1.2 User_id сделать int. Ip адрес (для гостей) записывать через ip2long()

2. По виджету

2.1 По аналогии с action column в GridView разработать несколько свойств

  • $up_class, $down_class - класс для vote Up и vote Down
  • $up_tpl, $down_tpl - шаблоны для up и down

Например:
сейчас в виде генерируется

<span style="cursor:pointer;" onclick="vote('article',9,'like'); return false;" class="glyphicon glyphicon-thumbs-up" id="vote-up-article9">3</span>

хотелось бы получить (из своего)

<a title="нравится" id="up_47839_0" class="it_vote btn btn-success btn-xs" href="http://new.loveorigami.info/world/action"> 
<span class="glyphicon glyphicon-thumbs-up"></span> <span class="ch">0</span>
</a>

с учетом вышепредложенного

// $up_class = btn btn-success btn-xs
// $up_tpl = <span class="glyphicon glyphicon-thumbs-up"></span> <span class="ch">0</span>

<a title="нравится" id="up_47839_0" class="it_vote $up_class" href="http://new.loveorigami.info/world/action"> $up_tpl </a>

чтоб в результате получить
2015-01-26_12-11-43

Избранное

Наряду с голосованием, еще на сайте присутствует возможность добавления в избранное наиболее понравившееся записи.
Избранное - это как следствие положительного голоса, который пользователь хочет сохранить для себя...

Поэтому предлагаю добавить кнопку "добавить в избранное"...
Принцип поведения для избранного, структуры таблицы и действий аналогичен с голосованием. С той лишь разницей, что намного проще.
Таблица

    protected $tableName = '{{%favorites}}';
    {
        $this->createTable($this->tableName, [
            'id' => Schema::TYPE_PK,
            'model_id' => Schema::TYPE_SMALLINT . ' NOT NULL',
            'target_id' => Schema::TYPE_INTEGER . ' NOT NULL',
            'user_id' => Schema::TYPE_STRING . ' NOT NULL',
            'date' => Schema::TYPE_INTEGER. ' NOT NULL',
        ], $tableOptions);
    }

в модель добавляем

ALTER TABLE `YOUR_TARGET_TABLE_NAME` ADD (
  `fav` smallint(6) NOT NULL,
)

Создаем favAction, где все аналогично, как https://github.com/Chiliec/yii2-vote/tree/master/actions,
окромя пересчета рейтинга (он тут не нужен)

В конфиге

'modules' => [
    'vote' => [
        'class' => 'chiliec\vote\Module',
        // global values for all models
        // 'allowGuests' => true,
        // 'allowChangeVote' => true,
        'allowFav' =>true
        'models' => [
            // example declaration of models
            // \common\models\Post::className(),
            // 'backend\models\Post',
            // 2 => 'frontend\models\Story',
            // 3 => [
            //     'modelName' => \backend\models\Mail::className(),
            //     you can rewrite global values for specific model
            //     'allowGuests' => false,
            //     'allowChangeVote' => false,
            // ],
        ],      
    ],
],

и если есть параметр 'allowFav' =>true, тогда в виджете отрисовать кнопку с добавлением в избранное рядом с кнопками голосования

Преимущество в том, что абсолютно аналогичные операции с голосованием и избранным будут в одном модуле, будут использовать один и тот же конфиг с одними и теми же подключенными моделями.

Вместо двух модулей, конфигов, виджетов, вызовов в виде и тп... все будет в одном модуле.

Не считает Aggregate rating

Сделал все по инструкции, добавил в таблицу поля

  • rating smallint(6)
  • aggregate_rating float(3,2)

Выполнил голосование под 3 уч. записями
Поле rating изменило свое значение на 3, а aggregate_rating осталось пустым.
01
02

Суммарный рейтинг

Опционально добавить показ суммарного рейтинга между кнопками голосования.

Trying to get property of non-object

Ошибка aggregate

in C:\wamp\www\radiopitut\vendor\chiliec\yii2-vote\widgets\Vote.php at line 118
109110111112113114115116117118119120121122123124 ");
$this->view->registerJs($js, View::POS_END, $this->jsCodeKey);
}

public function run()
{
    return $this->render('vote', [
        'modelId' => Rating::getModelIdByName($this->model->className()),
        'targetId' => $this->model->{$this->model->primaryKey()[0]},
        **_'likes' => $this->model->aggregate->likes ?: 0,
        'dislikes' => $this->model->aggregate->dislikes ?: 0,
        'rating' => $this->model->aggregate->rating ?: 0.0,_**
        'showAggregateRating' => $this->showAggregateRating,
    ]);
}

}

Много запросов + сортировка

Установил новый виджет.
Получил 105 запросов к базе, вместо 40, как было...
Видимо, что то связано с кешем, но то такое...

Мне то нужно все равно делать сортировку записей по рейтингу.
Вот что получилось

В модель Post добавил relation и объявил константу MODEL_ID

    public function getRatings()
    {
        return $this->hasOne(AggregateRating::className(), ['target_id' => 'id'])->onCondition(['model_id' => self::MODEL_ID]);
    }

В модели PostSearch делаю поиск с учетом связи

        $query = $this->find();
        $query->modelClass = get_parent_class($this);
        $query->joinWith('ratings')->published();

Для виджета listVeiw добавил параметр сортировки aggregate_rating

        $dataProvider->sort->attributes['aggregate_rating'] = [
            'asc' => [AggregateRating::tableName() . '.rating' => SORT_ASC],
            'desc' => [AggregateRating::tableName() . '.rating' => SORT_DESC],
            'label' => $this->getAttributeLabel('aggregate_rating'),
        ];

И в самом listView могу теперь получить количество likes, dislikes и rating
Отключил виджет Vote

Количество запросов к базе уменьшилось до 40. А все данные для отрисовки виджета у меня есть

$model->ratings->likes
$model->ratings->dislikes
$model->ratings->rating

Relation model?

Hi, how should look relation model? e.g I have table post. What I need that it working?

Пропадает пробел

Здравствуйте. Подскажите пожалуйста, где поправить следующее? :
в файле widgets/views/vote.php я изменил вид лайков/дизлайков.

<button type="button" class="btn btn-default5">
		<span id="vote-up-<?=$modelId?>-<?=$targetId?>" class="fa fa-icons fa-heart" onclick="vote(<?=$modelId?>, <?=$targetId?>, 'like'); return false;" style="cursor: pointer;">&nbsp;<?=$likes?></span>
	</button>

Перед количеством есть &nbsp;. Когда заходишь на страницу, все хорошо http://joxi.ru/brRjnNQtqwj1r1. Но когда проголосуешь, то пробел пропадает http://joxi.ru/a2XDY0KijxXk2g.

Trigger event после успешного голосования

Мне кажется, будет полезно триггерить event после успешного сохранения голоса. Таким образом можно будет подписаться на это событие и сделать, например, логирование действия пользователя, или любую другую логику.

Bug: Class m160209_074651_add_indexes_for_aggregate_rating_table does not exist

When i try do "php yii migrate/down" i get this error:

Exception 'ReflectionException' with message 'Class m160209_074651_add_indexes_for_aggregate_rating_table does not exist'

in /home/dignity/vendor/yiisoft/yii2/di/Container.php:428

Stack trace:
#0 /home/dignity/vendor/yiisoft/yii2/di/Container.php(428): ReflectionClass->__construct('m160209_074651_...')
#1 /home/dignity/vendor/yiisoft/yii2/di/Container.php(364): yii\di\Container->getDependencies('m160209_074651_...')
#2 /home/dignity/vendor/yiisoft/yii2/di/Container.php(156): yii\di\Container->build('m160209_074651_...', Array, Array)
#3 /home/dignity/vendor/yiisoft/yii2/BaseYii.php(349): yii\di\Container->get('m160209_074651_...', Array, Array)
#4 /home/dignity/vendor/yiisoft/yii2/console/controllers/MigrateController.php(201): yii\BaseYii::createObject(Array)
#5 /home/dignity/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(752): yii\console\controllers\MigrateController->createMigration('m160209_074651_...')
#6 /home/dignity/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(261): yii\console\controllers\BaseMigrateController->migrateDown('m160209_074651_...')
#7 [internal function]: yii\console\controllers\BaseMigrateController->actionDown(1)
#8 /home/dignity/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#9 /home/dignity/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#10 /home/dignity/vendor/yiisoft/yii2/console/Controller.php(148): yii\base\Controller->runAction('down', Array)
#11 /home/dignity/vendor/yiisoft/yii2/base/Module.php(528): yii\console\Controller->runAction('down', Array)
#12 /home/dignity/vendor/yiisoft/yii2/console/Application.php(180): yii\base\Module->runAction('migrate/down', Array)
#13 /home/dignity/vendor/yiisoft/yii2/console/Application.php(147): yii\console\Application->runAction('migrate/down', Array)
#14 /home/dignity/vendor/yiisoft/yii2/base/Application.php(386): yii\console\Application->handleRequest(Object(yii\console\Request))
#15 /home/dignity/yii(16): yii\base\Application->run()
#16 {main}

Возможность переопределения моделей

Нет возможности простым способом переопределить модели.

Единственный доступный способ без переписывания всего модуля целиком - переопределить глобально классы на уровне приложения. (Yii::$classMap)

Считаю, что было бы очень хорошо сделать переопределение моделей, таким же способом, как в расширении "dektrium/yii2-user".

Для чего нужно переопределение моделей - допустим, нам понадобится сохранять дополнительную информацию в придачу к IP. Например, UserAgent.

Мне понадобилось переопределять модели для встраивания UUID.

Optional fields js_after_vote

Перенесу обсуждение сюда, т.к. есть что обмыслить...
Идею с js_before_vote и js_afrter_vote я понял.
Но основной вопрос остается открытым - как тут перехватить сообщения
и вывести их в плагине (например - noty)

Загвоздка в том, что в зависимости от результата действия, должен выводится соответствующий тип сообщения

$message = "Ваш голос учтен";
$type = "success";

или

$message = "Вы не авторизированы";
$type = "error";

                <script type="text/javascript">
                    noty({
                        text: "' . $message . '",
                        type: "' . $type . '",
                        layout: "topRight",
                        timeout: 1500, // delay for closing event. Set false for sticky notifications
                        force: true
                    });
                </script>

У себя я решал через виджет, обрабатывающий Flash сессию
#3 (comment)

Error in backend

Зашел в админку.
Выдало ошибку. В логе винит поведение vote.
Отключил его - ошибки нет.
2015-01-29_21-33-04

Обновить модель после голосования

Вывожу списком статьи через ListView.
Список кешируется. Кеш обновляется, если обновилась модель.

Голосование же идет по другому сценарию.
После факта голосования запись вставляется в таблицу rating.
Затем, после следующей выборки, обновляются поля в самой модели. Это если без кеша.

С кешем у меня эти поля не обновляются, т.к. не произошло обновления самой модели.
Получается, замкнутый круг: кеш не сбросился, т.к. не обновилась модель. Рейтинг не пересчитался, т.к. модель закеширована

Почему бы не объявлять массив моделей, т.к. они есть.

    'modules' => [
        'vote' => [
            'matchingModels' => [ // matching model names with whatever unique integer ID
                'common\models\Page' => 3, // or array with 'id' key
            ],
        ],
    ],

в виджете

                <?php echo Display::widget([
                    'model_name' => $model::className(), // common\models\Page
                    //'model_name' => 'aphorism', // вместо такой записи
                    'target_id' => $model->id, // id of current element
                ]);
                ?>

поведение

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
       return [
            'class' => \chiliec\behaviors\RatingBehavior::className(),
            'model_name' => self::className(), // common\models\Page
        ];

    }

и тогда после вставки голоса в ratiing, имея готовый класс модели, запустить код, который находится в поведении RatingBehavior.

В таком случае, инвалидируется кеш, и список статей будет отображаться верно.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.