<commit_before><?php

namespace Fenos\Notifynder\Builder;

use ArrayAccess;
use Carbon\Carbon;
use Fenos\Notifynder\Contracts\NotifynderCategory;
use Fenos\Notifynder\Exceptions\EntityNotIterableException;
use Fenos\Notifynder\Exceptions\IterableIsEmptyException;
use Fenos\Notifynder\Exceptions\NotificationBuilderException;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Database\Eloquent\Model;
use Traversable;
use Closure;

/**
 * Class NotifynderBuilder.
 *
 * The builder is a main factor of Notifynder, it make sure
 * that the notification is decorated and validated before
 * are passed to the Sender Classes. It also helps you to
 * create multi notifications with the same simple and easy syntax.
 */
class NotifynderBuilder implements ArrayAccess
{
    use BuilderRules;

    /**
     * @var string notification to store
     */
    public $date;

    /**
     * Builder data.
     *
     * @var array
     */
    protected $notifications = [];

    /**
     * @var Repository
     */
    protected $config;

    /**
     * @var NotifynderCategory
     */
    private $notifynderCategory;

    /**
     * @param NotifynderCategory $notifynderCategory
     */
    public function __construct(NotifynderCategory $notifynderCategory)
    {
        $this->notifynderCategory = $notifynderCategory;
    }

    /**
     * Set who will send the notification.
     *
     * @return $this
     */
    public function from()
    {
        $from = func_get_args();

        $this->setEntityAction($from, 'from');

        return $this;
    }

    /**
     * Set who will receive the notification.
     *
     * @return $this
     */
    public function to()
    {
        $from = func_get_args();

        $this->setEntityAction($from, 'to');

        return $this;
    }

    /**
     * Set the url of the notification.
     *
     * @param $url
     * @return $this
     */
    public function url($url)
    {
        $this->isString($url);

        $this->setBuilderData('url', $url);

        return $this;
    }

    /**
     * Set expire time.
     *
     * @param $datetime
     * @return $this
     */
    public function expire($datetime)
    {
        $this->isCarbon($datetime);
        $this->setBuilderData('expire_time', $datetime);

        return $this;
    }

    /**
     * Set Category and covert it, to the id
     * if name of it given.
     *
     * @param $category
     * @return $this
     */
    public function category($category)
    {
        if (! is_numeric($category)) {
            $category = $this->notifynderCategory
                            ->findByName($category)->id;
        }

        $this->setBuilderData('category_id', $category);

        return $this;
    }

    /**
     * Set extra value.
     *
     * @param $extra
     * @return $this
     */
    public function extra(array $extra = [])
    {
        $this->isReadyArrToFormatInJson($extra);

        $jsonExtraValues = json_encode($extra);

        $this->setBuilderData('extra', $jsonExtraValues);

        return $this;
    }

    /**
     * Build the array with the builder inside
     * a Closure, it has more flexibility for<commit_msg>#105 add `setField()` method to the builder to allow setting custom additional fields<commit_after><?php

namespace Fenos\Notifynder\Builder;

use ArrayAccess;
use Carbon\Carbon;
use Fenos\Notifynder\Contracts\NotifynderCategory;
use Fenos\Notifynder\Exceptions\EntityNotIterableException;
use Fenos\Notifynder\Exceptions\IterableIsEmptyException;
use Fenos\Notifynder\Exceptions\NotificationBuilderException;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Database\Eloquent\Model;
use Traversable;
use Closure;

/**
 * Class NotifynderBuilder.
 *
 * The builder is a main factor of Notifynder, it make sure
 * that the notification is decorated and validated before
 * are passed to the Sender Classes. It also helps you to
 * create multi notifications with the same simple and easy syntax.
 */
class NotifynderBuilder implements ArrayAccess
{
    use BuilderRules;

    /**
     * @var string notification to store
     */
    public $date;

    /**
     * Builder data.
     *
     * @var array
     */
    protected $notifications = [];

    /**
     * @var Repository
     */
    protected $config;

    /**
     * @var NotifynderCategory
     */
    private $notifynderCategory;

    /**
     * @param NotifynderCategory $notifynderCategory
     */
    public function __construct(NotifynderCategory $notifynderCategory)
    {
        $this->notifynderCategory = $notifynderCategory;
    }

    /**
     * Set who will send the notification.
     *
     * @return $this
     */
    public function from()
    {
        $from = func_get_args();

        $this->setEntityAction($from, 'from');

        return $this;
    }

    /**
     * Set who will receive the notification.
     *
     * @return $this
     */
    public function to()
    {
        $from = func_get_args();

        $this->setEntityAction($from, 'to');

        return $this;
    }

    /**
     * Set the url of the notification.
     *
     * @param $url
     * @return $this
     */
    public function url($url)
    {
        $this->isString($url);

        $this->setBuilderData('url', $url);

        return $this;
    }

    /**
     * Set expire time.
     *
     * @param $datetime
     * @return $this
     */
    public function expire($datetime)
    {
        $this->isCarbon($datetime);
        $this->setBuilderData('expire_time', $datetime);

        return $this;
    }

    /**
     * Set Category and covert it, to the id
     * if name of it given.
     *
     * @param $category
     * @return $this
     */
    public function category($category)
    {
        if (! is_numeric($category)) {
            $category = $this->notifynderCategory
                            ->findByName($category)->id;
        }

        $this->setBuilderData('category_id', $category);

        return $this;
    }

    /**
     * Set extra value.
     *
     * @param $extra
     * @return $this
     */
    public function extra(array $extra = [])
    {
        $this->isReadyArrToFormatInJson($extra);

        $jsonExtraValues = json_encode($extra);

        $this->setBuilderData('extra', $jsonExtraValues);

        return $this;
    }

    /**
     * Set additional fields value.
     *
     * @param $key
     * @param $value
     * @return $this
     */
    public function setField($key, $value)
    {
        $this->setBuilderData($key, $value);

        return $this;
    }

    /**
     * Build the array with the builder inside
     * a Closure, it has more flexibility for
{'fraction_non_alphanumeric': 0.11509490810485086, 'fraction_numerical': 0.00045194335643266047, 'mean_word_length': 2.1614285714285715, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 30, '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': '5315653', 'n_tokens_mistral': 1956, 'n_tokens_neox': 1958, 'n_words': 487}