<commit_before><?php
namespace Minds\Core\Boost;

use Minds\Interfaces\BoostHandlerInterface;
use Minds\Core;
use Minds\Core\Data;
use Minds\Entities;
use Minds\Helpers;

use MongoDB\BSON;

/**
 * Newsfeed Boost handler
 * @todo Proper DI
 */
class Network implements BoostHandlerInterface
{
    protected $handler = 'newsfeed';
    protected $mongo;
    protected $db;


    public function __construct($options = [], Data\Interfaces\ClientInterface $mongo = null, Data\Call $db = null)
    {
        $this->mongo = $mongo ?: Data\Client::build('MongoDB');
        $this->db = $db ?: new Data\Call('entities_by_time');
    }

    /**
     * Boost an entity
     * @param  object/int $entity - the entity to boost
     * @param  int        $impressions
     * @return boolean
     */
    public function boost($boost, $impressions = 0)
    {

        $documentId = $this->mongo->insert("boost", [
          'guid' => $boost->getGuid(),
          'owner_guid' => $boost->getOwner()->guid,
          'impressions' => $boost->getImpressions(),
          'state' => 'review',
          'type' => $this->handler,
          'priority' => $boost->getPriorityRate(),
          'categories' => $boost->getCategories(),
          'createdAt' => new BSON\UTCDateTime(time()),
          'approvedAt' => null,
        ]);

        if ($documentId) {
            return (string) $documentId;
        }

        return $boost->getGuid();
    }

     /**
     * Return boosts for review
     * @param  int    $limit
     * @param  string $offset
     * @return array
     */
    public function getReviewQueue($limit, $offset = "")
    {
        $query = [ 'state'=>'review', 'type'=> $this->handler ];
        if ($offset) {
            $query['_id'] = [ '$gt' => $offset ];
        }
        $queue = $this->mongo->find("boost", $query, [
            'limit' => $limit,
            'sort' => [ 'priority' => -1, '_id' => 1 ],
        ]);
        if (!$queue) {
            return false;
        }

        $guids = [];
        $end = "";
        foreach ($queue as $data) {
            $_id = (string) $data['_id'];
            $guids[$_id] = (string) $data['guid'];
            $end = $data['guid'];
            //$this->mongo->remove("boost", ['_id' => $_id]);
        }

        if (!$guids) {
            return false;
        }

        $prepared = new Core\Data\Cassandra\Prepared\Custom();
        $collection = \Cassandra\Type::collection(\Cassandra\Type::text())
            ->create(... array_values($guids));
        $prepared->query("SELECT * from entities_by_time WHERE key= ? AND column1 IN ? LIMIT ?",
          [ "boost:$this->handler", $collection, count($guids) ]);

        $cql = Core\Di\Di::_()->get('Database\Cassandra\Cql');
        $data = $cql->request($prepared);

        $boosts = [];
        foreach ($data as $row) {
            $boost = (new Entities\Boost\Network())
              ->loadFromArray(json_decode($row['value'], true));
            //double check
            if (isset($guids[$boost->getId()])) {
                $boosts[] = $boost;
            }
        }
        return $boosts;
    }

    /**
     * Return the review count
     * @return int
     */
    public function getReviewQueueCount()
    {
        $query = ['state' => 'review', 'type' => $this->handler];
        $count = $this->mongo->count("boost", $query);
        return $count;
    }

    /**
     * Get our own submitted Boosts
     * @param  int    $limit
     * @param  string $offset
     * @return array
     */
    public function getOutbox($limit, $offset = "")
    {
        $db = new Data\Call('entities_by_time');
        $data = $db->getRow("boost:$this->handler:requested:" . Core\Session::getLoggedinUser()->guid, [
          'limit'=>$limit,
          'offset'=>$offset,
          'reversed'=>true
        ]);

        $boosts = [];
        foreach ($data as $guid => $raw_data) {
            //$raw_data['guid']
            $boosts[] = (new Entities\Boost\Network())
              ->loadFromArray(json_decode($raw_data, true));
        }
        return $boosts;
    }

    /**
     * Gets a single boost entity
     * @param  mixed $guid
     * @return object
     */
    public function getBoostEntity($guid)
    {
        $db = new Data\Call('entities_by_time');
        $data = $db->getRow("boost:$this->handler", ['limit'=>1, 'offset'=>$guid]);
        if (key($data) != $guid) {
            return false;
        }

        $boost = (new Entities\Boost\Network($db))
          ->loadFromArray(json_decode($data[$guid], true));
        return $boost;
    }

    /**
     * Accept a boost
     * @param  mixed $_id
     * @param  int   $impressions Optional. Defaults to 0.
     * @return boolean
     */
    public function accept($boost, $impressions = 0)
    {
        $accept = $this->mongo->update("boost", ['_id' => $boost->getId()], ['state'=>'approved', 'rating'=>$boost->getRating(), 'approvedAt' => new BSON\UTCDateTime(time()) ]);
        $boost->setState('approved');
        if ($accept) {
            //remove from review
            //$db->removeAttributes("boost:newsfeed:review", array($guid));
            //clear the counter for boost_impressions
            //Helpers\Counters::clear($guid, "boost_impressions");

            Core\Events\Dispatcher::trigger('notification', 'boost', [
                'to'=> [ $boost->getOwner()->guid ],
                'entity' => $boost->getEntity(),
                'from'=> 100000000000000519,
                'title' => $boost->getEntity()->title,
                'notification_view' => 'boost_accepted',
                'params' => ['impressions' => $boost->getBid()],
                'impressions' => $boost->getBid()
              ]);
            $boost->save();
        }
        return $accept;
    }<commit_msg>(fix): use correct timestamp with mongodb save<commit_after><?php
namespace Minds\Core\Boost;

use Minds\Interfaces\BoostHandlerInterface;
use Minds\Core;
use Minds\Core\Data;
use Minds\Entities;
use Minds\Helpers;

use MongoDB\BSON;

/**
 * Newsfeed Boost handler
 * @todo Proper DI
 */
class Network implements BoostHandlerInterface
{
    protected $handler = 'newsfeed';
    protected $mongo;
    protected $db;


    public function __construct($options = [], Data\Interfaces\ClientInterface $mongo = null, Data\Call $db = null)
    {
        $this->mongo = $mongo ?: Data\Client::build('MongoDB');
        $this->db = $db ?: new Data\Call('entities_by_time');
    }

    /**
     * Boost an entity
     * @param  object/int $entity - the entity to boost
     * @param  int        $impressions
     * @return boolean
     */
    public function boost($boost, $impressions = 0)
    {

        $documentId = $this->mongo->insert("boost", [
          'guid' => $boost->getGuid(),
          'owner_guid' => $boost->getOwner()->guid,
          'impressions' => $boost->getImpressions(),
          'state' => 'review',
          'type' => $this->handler,
          'priority' => $boost->getPriorityRate(),
          'categories' => $boost->getCategories(),
          'createdAt' => new BSON\UTCDateTime(time() * 1000),
          'approvedAt' => null,
        ]);

        if ($documentId) {
            return (string) $documentId;
        }

        return $boost->getGuid();
    }

     /**
     * Return boosts for review
     * @param  int    $limit
     * @param  string $offset
     * @return array
     */
    public function getReviewQueue($limit, $offset = "")
    {
        $query = [ 'state'=>'review', 'type'=> $this->handler ];
        if ($offset) {
            $query['_id'] = [ '$gt' => $offset ];
        }
        $queue = $this->mongo->find("boost", $query, [
            'limit' => $limit,
            'sort' => [ 'priority' => -1, '_id' => 1 ],
        ]);
        if (!$queue) {
            return false;
        }

        $guids = [];
        $end = "";
        foreach ($queue as $data) {
            $_id = (string) $data['_id'];
            $guids[$_id] = (string) $data['guid'];
            $end = $data['guid'];
            //$this->mongo->remove("boost", ['_id' => $_id]);
        }

        if (!$guids) {
            return false;
        }

        $prepared = new Core\Data\Cassandra\Prepared\Custom();
        $collection = \Cassandra\Type::collection(\Cassandra\Type::text())
            ->create(... array_values($guids));
        $prepared->query("SELECT * from entities_by_time WHERE key= ? AND column1 IN ? LIMIT ?",
          [ "boost:$this->handler", $collection, count($guids) ]);

        $cql = Core\Di\Di::_()->get('Database\Cassandra\Cql');
        $data = $cql->request($prepared);

        $boosts = [];
        foreach ($data as $row) {
            $boost = (new Entities\Boost\Network())
              ->loadFromArray(json_decode($row['value'], true));
            //double check
            if (isset($guids[$boost->getId()])) {
                $boosts[] = $boost;
            }
        }
        return $boosts;
    }

    /**
     * Return the review count
     * @return int
     */
    public function getReviewQueueCount()
    {
        $query = ['state' => 'review', 'type' => $this->handler];
        $count = $this->mongo->count("boost", $query);
        return $count;
    }

    /**
     * Get our own submitted Boosts
     * @param  int    $limit
     * @param  string $offset
     * @return array
     */
    public function getOutbox($limit, $offset = "")
    {
        $db = new Data\Call('entities_by_time');
        $data = $db->getRow("boost:$this->handler:requested:" . Core\Session::getLoggedinUser()->guid, [
          'limit'=>$limit,
          'offset'=>$offset,
          'reversed'=>true
        ]);

        $boosts = [];
        foreach ($data as $guid => $raw_data) {
            //$raw_data['guid']
            $boosts[] = (new Entities\Boost\Network())
              ->loadFromArray(json_decode($raw_data, true));
        }
        return $boosts;
    }

    /**
     * Gets a single boost entity
     * @param  mixed $guid
     * @return object
     */
    public function getBoostEntity($guid)
    {
        $db = new Data\Call('entities_by_time');
        $data = $db->getRow("boost:$this->handler", ['limit'=>1, 'offset'=>$guid]);
        if (key($data) != $guid) {
            return false;
        }

        $boost = (new Entities\Boost\Network($db))
          ->loadFromArray(json_decode($data[$guid], true));
        return $boost;
    }

    /**
     * Accept a boost
     * @param  mixed $_id
     * @param  int   $impressions Optional. Defaults to 0.
     * @return boolean
     */
    public function accept($boost, $impressions = 0)
    {
        $accept = $this->mongo->update("boost", ['_id' => $boost->getId()], ['state'=>'approved', 'rating'=>$boost->getRating(), 'approvedAt' => new BSON\UTCDateTime(time() * 1000) ]);
        $boost->setState('approved');
        if ($accept) {
            //remove from review
            //$db->removeAttributes("boost:newsfeed:review", array($guid));
            //clear the counter for boost_impressions
            //Helpers\Counters::clear($guid, "boost_impressions");

            Core\Events\Dispatcher::trigger('notification', 'boost', [
                'to'=> [ $boost->getOwner()->guid ],
                'entity' => $boost->getEntity(),
                'from'=> 100000000000000519,
                'title' => $boost->getEntity()->title,
                'notification_view' => 'boost_accepted',
                'params' => ['impressions' => $boost->getBid()],
                'impressions' => $boost->getBid()
              ]);
            $boost->save();
        }
        return $accept;
    }
{'fraction_non_alphanumeric': 0.17513541397988136, 'fraction_numerical': 0.0049866735448370735, 'mean_word_length': 1.9756971092350986, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 173, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, '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': '5592742', 'n_tokens_mistral': 3580, 'n_tokens_neox': 3473, 'n_words': 712}