<commit_before><?php

namespace nineinchnick\nfy\controllers;

use nineinchnick\nfy\components\Queue;
use nineinchnick\nfy\components\QueueInterface;
use nineinchnick\nfy\Module;
use Yii;
use yii\web\ForbiddenHttpException;
use yii\web\NotFoundHttpException;
use yii\helpers\Url;
use nineinchnick\nfy\components;
use nineinchnick\nfy\models;
use yii\web\User;

/**
 * The default controller providing a basic queue managment interface and poll action.
 * @author <NAME> <<EMAIL>>
 */
class QueueController extends \yii\web\Controller
{
    public function filters()
    {
        return [
            'accessControl',
        ];
    }

    public function accessRules()
    {
        return [
            ['allow', 'actions' => ['index'], 'users' => ['@'], 'roles' => ['nfy.queue.read']],
            ['allow', 'actions' => ['messages', 'message', 'subscribe', 'unsubscribe'], 'users' => ['@']],
            ['allow', 'actions' => ['poll'], 'users' => ['@']],
            ['deny', 'users' => ['*']],
        ];
    }

    /**
     * Displays a list of queues and their subscriptions.
     */
    public function actionIndex()
    {
        /** @var User */
        $user = Yii::$app->user;
        $subscribedOnly = $user->can('nfy.queue.read.subscribed');
        $queues = [];
        foreach ($this->module->queues as $queueId) {
            /** @var Queue */
            $queue = Yii::$app->get($queueId);
            if (!($queue instanceof components\QueueInterface)
                || ($subscribedOnly
                    && !$queue->isSubscribed($user->getId()))
            ) {
                continue;
            }
            $queues[$queueId] = $queue;
        }

        return $this->render('index', [
            'queues' => $queues,
            'subscribedOnly' => $subscribedOnly,
        ]);
    }

    /**
     * Subscribe current user to selected queue.
     * @param string $queue_name
     * @return string|\yii\web\Response
     */
    public function actionSubscribe($queue_name)
    {
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.queue.subscribe']);

        $form = new models\SubscriptionForm();
        if (isset($_POST['SubscriptionForm'])) {
            $form->attributes = $_POST['SubscriptionForm'];
            if ($form->validate()) {
                $queue->subscribe(Yii::$app->user->getId(), $form->label, $form->categories, $form->exceptions);

                return $this->redirect(['index']);
            }
        }

        return $this->render('subscription', [
            'queue' => $queue,
            'model' => $form,
        ]);
    }

    /**
     * Unsubscribe current user from selected queue.
     * @param string $queue_name
     * @return \yii\web\Response
     */
    public function actionUnsubscribe($queue_name)
    {
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.queue.unsubscribe']);
        $queue->unsubscribe(Yii::$app->user->getId());

        return $this->redirect(['index']);
    }

    /**
     * Displays and send messages in the specified queue.
     * @param string $queue_name
     * @param string $subscriber_id
     * @return string|\yii\web\Response
     */
    public function actionMessages($queue_name, $subscriber_id = null)
    {
        if (($subscriber_id = trim($subscriber_id)) === '') {
            $subscriber_id = null;
        }
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.message.read', 'nfy.message.create']);
        $this->verifySubscriber($queue, $subscriber_id);

        $formModel = new models\MessageForm();
        if ($authItems['nfy.message.create'] && isset($_POST['MessageForm'])) {
            $formModel->attributes = $_POST['MessageForm'];
            if ($formModel->validate()) {
                $queue->send($formModel->content, $formModel->category);

                return $this->redirect([
                    'messages',
                    'queue_name' => $queue_name,
                    'subscriber_id' => $subscriber_id,
                ]);
            }
        }

        $dataProvider = null;
        if ($authItems['nfy.message.read']) {
            $dataProvider = new \yii\data\ArrayDataProvider([
                'allModels' => $queue->peek($subscriber_id, 200, [
                    components\Message::AVAILABLE,
                    components\Message::RESERVED,
                    components\Message::DELETED,
                ]),
                'sort' => [
                    'attributes' => ['id'],
                    'defaultOrder' => ['id' => SORT_DESC],
                ],
            ]);
            // reverse display order to simulate a chat window, where latest message is right above the message form
            $dataProvider->setModels(array_reverse($dataProvider->getModels()));
        }

        return $this->render('messages', [
            'queue' => $queue,
            'queue_name' => $queue_name,
            'dataProvider' => $dataProvider,
            'model' => $formModel,
            'authItems' => $authItems,
        ]);
    }

    /**
     * Marks all messages or specified message as read.
     * @param $queue_name
     * @param mixed $message_id
     * @param mixed $subscriber_id
     * @return \yii\web\Response
     */
    public function actionMark($queue_name, $message_id = null, $subscriber_id = null)
    {
        if (($subscriber_id = trim($subscriber_id)) === '') {
            $subscriber_id = null;
        }
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.message.read']);
        $this->verifySubscriber($queue, $subscriber_id);

        if ($authItems['nfy.message.read']) {
            if ($message_id === null) {
                $queue->receive($subscriber_id);
            } else {
                $queue->delete($message_id);
            }
        }
        return $this->redirect(Yii::$app->user->returnUrl);
    }

    /**
     * Fetches details of a single message, allows to release or delete it or sends a new message.
     * @param string $queue_name
     * @param string $subscriber_id
     * @param string $message_id
     * @return string|\yii\web\Response
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     */
    public function actionMessage($queue_name, $subscriber_id = null, $message_id = null)
    {
        if (($subscriber_id = trim($subscriber_id)) === '') {
            $subscriber_id = null;
        }
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.message.read', 'nfy.message.create']);
        $this->verifySubscriber($queue, $subscriber_id);

        if ($queue instanceof components\DbQueue) {
            $query = models\DbMessage::find()->withQueue($queue->id);
            if ($subscriber_id !== null) {
                $query->withSubscriber($subscriber_id);
            }

            $dbMessage = $query->andWhere([<commit_msg>slightly improve queue mark action<commit_after><?php

namespace nineinchnick\nfy\controllers;

use nineinchnick\nfy\components\Queue;
use nineinchnick\nfy\components\QueueInterface;
use nineinchnick\nfy\Module;
use Yii;
use yii\web\ForbiddenHttpException;
use yii\web\NotFoundHttpException;
use yii\helpers\Url;
use nineinchnick\nfy\components;
use nineinchnick\nfy\models;
use yii\web\User;

/**
 * The default controller providing a basic queue managment interface and poll action.
 * @author <NAME> <<EMAIL>>
 */
class QueueController extends \yii\web\Controller
{
    public function filters()
    {
        return [
            'accessControl',
        ];
    }

    public function accessRules()
    {
        return [
            ['allow', 'actions' => ['index'], 'users' => ['@'], 'roles' => ['nfy.queue.read']],
            ['allow', 'actions' => ['messages', 'message', 'subscribe', 'unsubscribe'], 'users' => ['@']],
            ['allow', 'actions' => ['poll'], 'users' => ['@']],
            ['deny', 'users' => ['*']],
        ];
    }

    /**
     * Displays a list of queues and their subscriptions.
     */
    public function actionIndex()
    {
        /** @var User */
        $user = Yii::$app->user;
        $subscribedOnly = $user->can('nfy.queue.read.subscribed');
        $queues = [];
        foreach ($this->module->queues as $queueId) {
            /** @var Queue */
            $queue = Yii::$app->get($queueId);
            if (!($queue instanceof components\QueueInterface)
                || ($subscribedOnly
                    && !$queue->isSubscribed($user->getId()))
            ) {
                continue;
            }
            $queues[$queueId] = $queue;
        }

        return $this->render('index', [
            'queues' => $queues,
            'subscribedOnly' => $subscribedOnly,
        ]);
    }

    /**
     * Subscribe current user to selected queue.
     * @param string $queue_name
     * @return string|\yii\web\Response
     */
    public function actionSubscribe($queue_name)
    {
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.queue.subscribe']);

        $form = new models\SubscriptionForm();
        if (isset($_POST['SubscriptionForm'])) {
            $form->attributes = $_POST['SubscriptionForm'];
            if ($form->validate()) {
                $queue->subscribe(Yii::$app->user->getId(), $form->label, $form->categories, $form->exceptions);

                return $this->redirect(['index']);
            }
        }

        return $this->render('subscription', [
            'queue' => $queue,
            'model' => $form,
        ]);
    }

    /**
     * Unsubscribe current user from selected queue.
     * @param string $queue_name
     * @return \yii\web\Response
     */
    public function actionUnsubscribe($queue_name)
    {
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.queue.unsubscribe']);
        $queue->unsubscribe(Yii::$app->user->getId());

        return $this->redirect(['index']);
    }

    /**
     * Displays and send messages in the specified queue.
     * @param string $queue_name
     * @param string $subscriber_id
     * @return string|\yii\web\Response
     */
    public function actionMessages($queue_name, $subscriber_id = null)
    {
        if (($subscriber_id = trim($subscriber_id)) === '') {
            $subscriber_id = null;
        }
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.message.read', 'nfy.message.create']);
        $this->verifySubscriber($queue, $subscriber_id);

        $formModel = new models\MessageForm();
        if ($authItems['nfy.message.create'] && isset($_POST['MessageForm'])) {
            $formModel->attributes = $_POST['MessageForm'];
            if ($formModel->validate()) {
                $queue->send($formModel->content, $formModel->category);

                return $this->redirect([
                    'messages',
                    'queue_name' => $queue_name,
                    'subscriber_id' => $subscriber_id,
                ]);
            }
        }

        $dataProvider = null;
        if ($authItems['nfy.message.read']) {
            $dataProvider = new \yii\data\ArrayDataProvider([
                'allModels' => $queue->peek($subscriber_id, 200, [
                    components\Message::AVAILABLE,
                    components\Message::RESERVED,
                    components\Message::DELETED,
                ]),
                'sort' => [
                    'attributes' => ['id'],
                    'defaultOrder' => ['id' => SORT_DESC],
                ],
            ]);
            // reverse display order to simulate a chat window, where latest message is right above the message form
            $dataProvider->setModels(array_reverse($dataProvider->getModels()));
        }

        return $this->render('messages', [
            'queue' => $queue,
            'queue_name' => $queue_name,
            'dataProvider' => $dataProvider,
            'model' => $formModel,
            'authItems' => $authItems,
        ]);
    }

    /**
     * Marks all messages or specified message as read.
     * @param $queue_name
     * @param mixed $message_id
     * @param mixed $subscriber_id
     * @param string $returnUrl
     * @return \yii\web\Response
     */
    public function actionMark($queue_name, $message_id = null, $subscriber_id = null, $returnUrl = null)
    {
        if (($subscriber_id = trim($subscriber_id)) === '') {
            $subscriber_id = null;
        }
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.message.read']);
        $this->verifySubscriber($queue, $subscriber_id);

        if ($authItems['nfy.message.read']) {
            if ($message_id === null) {
                $queue->receive($subscriber_id);
            } else {
                $queue->delete($message_id);
            }
        }
        return $this->redirect($returnUrl !== null ? $returnUrl : Yii::$app->user->returnUrl);
    }

    /**
     * Fetches details of a single message, allows to release or delete it or sends a new message.
     * @param string $queue_name
     * @param string $subscriber_id
     * @param string $message_id
     * @return string|\yii\web\Response
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     */
    public function actionMessage($queue_name, $subscriber_id = null, $message_id = null)
    {
        if (($subscriber_id = trim($subscriber_id)) === '') {
            $subscriber_id = null;
        }
        /** @var QueueInterface $queue */
        list($queue, $authItems) = $this->loadQueue($queue_name, ['nfy.message.read', 'nfy.message.create']);
        $this->verifySubscriber($queue, $subscriber_id);

        if ($queue instanceof components\DbQueue) {
            $query = models\DbMessage::find()->withQueue($queue->id);
            if ($subscriber_id !== null) {
                $query->withSubscriber($subscriber_id);
            }

            $dbMessage = $query->andWhere([
{'fraction_non_alphanumeric': 0.15478600851776864, 'fraction_numerical': 0.0004189066536340152, 'mean_word_length': 2.082418764794491, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 155, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7635842', 'n_tokens_mistral': 4107, 'n_tokens_neox': 4043, 'n_words': 803}