Skip to content

Instantly share code, notes, and snippets.

@ManojKiranA
Forked from saniyathossain/TagTrait.php
Created July 30, 2020 03:45
Show Gist options
  • Save ManojKiranA/a773d897b398b79f26d81b28a031d8e5 to your computer and use it in GitHub Desktop.
Save ManojKiranA/a773d897b398b79f26d81b28a031d8e5 to your computer and use it in GitHub Desktop.
Trait for A Virtual Field to Laravel Model Collection
<?php
namespace App\Eloquents\Traits;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;
use ReflectionClass;
/**
* Generates prefixed column along with padded specific model attribute (e.g. model table primary key attribute)
* & use it as Laravel accessor along with Eloquent Model Data. Also generates SQL expressions and Laravel model
* scope for running query (e.g. filter) by tag behaving like a physical database column. The value is a string
* which has 3 parts: a prefix, a separator and a database field attribute (padded).
*
* For Example, if App\Http\Controllers\App\NexusController class uses this trait with default settings then the
* tag would be: 'NEX-0001'. Here 'Nex' is prefix, '-' is separator and '0001' is database primary key (padded).
*/
trait TagTrait
{
/**
* @var string
*/
public $tagPrefix;
/**
* @var integer
*/
public $tagPrefixLength = 3;
/**
* @var string
*/
public $tagSeparator = '-';
/**
* @var string\integer
*/
public $tagSuffixPadString = 0;
/**
* @var integer
*/
public $tagSuffixPadLength = 4;
/**
* @var integer
*/
public $tagSuffixPadType = STR_PAD_LEFT;
/**
* @var string
*/
public $tagTemplate = '%s%s%s';
/**
* @var string
*/
public $tagSqlExpressionTemplate = 'concat("%s%s", %s(%s, %s, "%s"))';
/**
* Get caller class shortname
* (e.g. \App\Http\Controllers\App\NexusController to NexusController)
*
* @return string
*/
public function getClassShortName(): string
{
return (new ReflectionClass($this))->getShortName();
}
/**
* Get tag prefix, can be considered as shortcode of tag
* if not default set then generate from caller class shortname
* (e.g. \App\Http\Controllers\App\NexusController to NEX)
*
* @return string
*/
public function getTagPrefix(): string
{
return !empty($this->tagPrefix) ?
$this->tagPrefix :
Str::upper(
Str::limit($this->getClassShortName(), $this->tagPrefixLength, null)
);
}
/**
* @return string
*/
public function getTagSuffixColumn(): string
{
return $this->getKeyName();
}
/**
* @return string
*/
public function getTagSuffixQualifiedColumn(): string
{
return $this->getQualifiedKeyName();
}
/**
* @return string
*/
public function getTagSuffix(): string
{
return $this->attributes[$this->getTagSuffixColumn()];
}
/**
* Get tag attribute
*
* @return string
*/
public function getTagAttribute(): string
{
return sprintf(
$this->tagTemplate,
$this->getTagPrefix(),
$this->tagSeparator,
str_pad(
$this->getTagSuffix(),
$this->tagSuffixPadLength,
$this->tagSuffixPadString,
$this->tagSuffixPadType
)
);
}
/**
* @return string
*/
public function tagSqlPadType(): string
{
return $this->tagSuffixPadType == STR_PAD_LEFT ? 'lpad' : 'rpad';
}
/**
* @return string
*/
public function tagSqlExpression(): string
{
return sprintf(
$this->tagSqlExpressionTemplate,
$this->getTagPrefix(),
$this->tagSeparator,
$this->tagSqlPadType(),
$this->getTagSuffixQualifiedColumn(),
$this->tagSuffixPadLength,
$this->tagSuffixPadString,
);
}
/**
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param string $type
* @param string \ array $value
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSearchTag(Builder $builder, $type, $value)
{
$type = !in_array($type, ['=', 'like', '!=', '<>', 'in', 'not in']) ? '=' : $type;
$bind = in_array($type, ['in', 'not in']) ?
sprintf('(%s)', implode(',', array_fill(0, count($value), '?'))) : '?';
return $builder->whereRaw(
sprintf('%s %s %s', $this->tagSqlExpression(), $type, $bind), compact('value')
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment