<?php

/**
 * Add eloquent queries single(), singleOrFail(), singleOrNew()
 */
namespace App\Traits;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ModelNotFoundException;

trait SingleOrFail
{
	private static function bootSingleOrFail(): void
	{
		// When a query should return 1 object, or FAIL if it doesnt
		Builder::macro('singleOrFail',function () {
			$result = $this->get();

			if (($x=$result->count()) === 1)
				return $result->first();

			if ($x === 0)
				throw new ModelNotFoundException('Query brings back 0 record(s) called for singleOrFail()');
			else
				throw new \Exception(sprintf('Query brings back %d record(s) called for singleOrFail()',$x));
		});

		// When a query should return 1 object, or NULL if it doesnt
		Builder::macro('single',function () {
			$result = $this->get();

			if ($result->count() === 1)
				return $result->first();

			return NULL;
		});

		// When a query should return 1 object, or NULL if it doesnt
		Builder::macro('singleOrNew',function ($args) {
			$result = $this->where($args)->get();

			if ($result->count() === 1)
				return $result->first();

			return $this->newModelInstance($args);
		});
	}
}