404

[ Avaa Bypassed ]




Upload:

Command:

elspacio@3.135.219.104: ~ $
<?php

/**
 * Created by Cristian.
 * Date: 11/09/16 12:11 PM.
 */

namespace Reliese\Coders\Model;

use Illuminate\Support\Str;
use Reliese\Meta\Blueprint;
use Illuminate\Support\Fluent;
use Illuminate\Database\Eloquent\SoftDeletes;
use Reliese\Coders\Model\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Reliese\Coders\Model\Relations\ReferenceFactory;

class Model
{
    /**
     * @var \Reliese\Meta\Blueprint
     */
    private $blueprint;

    /**
     * @var \Reliese\Coders\Model\Factory
     */
    private $factory;

    /**
     * @var array
     */
    protected $properties = [];

    /**
     * @var Relation[]
     */
    protected $relations = [];

    /**
     * @var \Reliese\Meta\Blueprint[]
     */
    protected $references = [];

    /**
     * @var array
     */
    protected $hidden = [];

    /**
     * @var array
     */
    protected $fillable = [];

    /**
     * @var array
     */
    protected $casts = [];

    /**
     * @var \Reliese\Coders\Model\Mutator[]
     */
    protected $mutators = [];

    /**
     * @var \Reliese\Coders\Model\Mutation[]
     */
    protected $mutations = [];

    /**
     * @var array
     */
    protected $hints = [];

    /**
     * @var string
     */
    protected $namespace;

    /**
     * @var string
     */
    protected $parentClass;

    /**
     * @var bool
     */
    protected $timestamps = true;

    /**
     * @var string
     */
    protected $CREATED_AT;

    /**
     * @var string
     */
    protected $UPDATED_AT;

    /**
     * @var bool
     */
    protected $softDeletes = false;

    /**
     * @var string
     */
    protected $DELETED_AT;

    /**
     * @var bool
     */
    protected $showConnection = false;

    /**
     * @var string
     */
    protected $connection;

    /**
     * @var \Illuminate\Support\Fluent
     */
    protected $primaryKeys;

    /**
     * @var \Illuminate\Support\Fluent
     */
    protected $primaryKeyColumn;

    /**
     * @var int
     */
    protected $perPage;

    /**
     * @var string
     */
    protected $dateFormat;

    /**
     * @var bool
     */
    protected $loadRelations;

    /**
     * @var bool
     */
    protected $hasCrossDatabaseRelationships = false;

    /**
     * @var string
     */
    protected $tablePrefix = '';

    /**
     * @var string
     */
    protected $relationNameStrategy = '';

    /**
     * @var bool
     */
    protected $definesReturnTypes = false;

    /**
     * ModelClass constructor.
     *
     * @param \Reliese\Meta\Blueprint $blueprint
     * @param \Reliese\Coders\Model\Factory $factory
     * @param \Reliese\Coders\Model\Mutator[] $mutators
     * @param bool $loadRelations
     */
    public function __construct(Blueprint $blueprint, Factory $factory, $mutators = [], $loadRelations = true)
    {
        $this->blueprint = $blueprint;
        $this->factory = $factory;
        $this->loadRelations = $loadRelations;
        $this->mutators = $mutators;
        $this->configure();
        $this->fill();
    }

    protected function configure()
    {
        $this->withNamespace($this->config('namespace'));
        $this->withParentClass($this->config('parent'));

        // Timestamps settings
        $this->withTimestamps($this->config('timestamps.enabled', $this->config('timestamps', true)));
        $this->withCreatedAtField($this->config('timestamps.fields.CREATED_AT', $this->getDefaultCreatedAtField()));
        $this->withUpdatedAtField($this->config('timestamps.fields.UPDATED_AT', $this->getDefaultUpdatedAtField()));

        // Soft deletes settings
        $this->withSoftDeletes($this->config('soft_deletes.enabled', $this->config('soft_deletes', false)));
        $this->withDeletedAtField($this->config('soft_deletes.field', $this->getDefaultDeletedAtField()));

        // Connection settings
        $this->withConnection($this->config('connection', false));
        $this->withConnectionName($this->blueprint->connection());

        // Pagination settings
        $this->withPerPage($this->config('per_page', $this->getDefaultPerPage()));

        // Dates settings
        $this->withDateFormat($this->config('date_format', $this->getDefaultDateFormat()));

        // Table Prefix settings
        $this->withTablePrefix($this->config('table_prefix', $this->getDefaultTablePrefix()));

        // Relation name settings
        $this->withRelationNameStrategy($this->config('relation_name_strategy', $this->getDefaultRelationNameStrategy()));

        $this->definesReturnTypes = $this->config('enable_return_types', false);

        return $this;
    }

    /**
     * Parses the model information.
     */
    protected function fill()
    {
        $this->primaryKeys = $this->blueprint->primaryKey();

        // Process columns
        foreach ($this->blueprint->columns() as $column) {
            $this->parseColumn($column);
        }

        if (! $this->loadRelations) {
            return;
        }

        foreach ($this->blueprint->relations() as $relation) {
            $model = $this->makeRelationModel($relation);
            $belongsTo = new BelongsTo($relation, $this, $model);
            $this->relations[$belongsTo->name()] = $belongsTo;
        }

        foreach ($this->factory->referencing($this) as $related) {
            $factory = new ReferenceFactory($related, $this);
            $references = $factory->make();
            foreach ($references as $reference) {
                $this->relations[$reference->name()] = $reference;
            }
        }
    }

    /**
     * @param \Illuminate\Support\Fluent $column
     */
    protected function parseColumn(Fluent $column)
    {
        // TODO: Check type cast is OK
        $cast = $column->type;

        $propertyName = $this->usesPropertyConstants() ? 'self::'.strtoupper($column->name) : $column->name;

        // Due to some casting problems when converting null to a Carbon instance,
        // we are going to treat Soft Deletes field as string.
        if ($column->name == $this->getDeletedAtField()) {
            $cast = 'string';
        }

        // Track attribute casts, ignoring timestamps
        if ($cast != 'string' && !in_array($propertyName, [$this->CREATED_AT, $this->UPDATED_AT])) {
            $this->casts[$propertyName] = $cast;
        }

        foreach ($this->config('casts', []) as $pattern => $casting) {
            if (Str::is($pattern, $column->name)) {
                $this->casts[$propertyName] = $cast = $casting;
                break;
            }
        }

        if ($this->isHidden($column->name)) {
            $this->hidden[] = $propertyName;
        }

        if ($this->isFillable($column->name)) {
            $this->fillable[] = $propertyName;
        }

        $this->mutate($column->name);

        // Track comment hints
        if (! empty($column->comment)) {
            $this->hints[$column->name] = $column->comment;
        }

        // Track PHP type hints
        $hint = $this->phpTypeHint($cast, $column->nullable);
        $this->properties[$column->name] = $hint;

        if ($column->name == $this->getPrimaryKey()) {
            $this->primaryKeyColumn = $column;
        }
    }

    /**
     * @param string $column
     */
    protected function mutate($column)
    {
        foreach ($this->mutators as $mutator) {
            if ($mutator->applies($column, $this->getBlueprint())) {
                $this->mutations[] = new Mutation(
                    $mutator->getName($column, $this),
                    $mutator->getBody($column, $this)
                );
            }
        }
    }

    /**
     * @param \Illuminate\Support\Fluent $relation
     *
     * @return $this|\Reliese\Coders\Model\Model
     */
    public function makeRelationModel(Fluent $relation)
    {
        list($database, $table) = array_values($relation->on);

        if ($this->blueprint->is($database, $table)) {
            return $this;
        }

        return $this->factory->makeModel($database, $table, false);
    }

    /**
     * @param string $castType
     * @param bool $nullable
     *
     * @todo Make tests
     *
     * @return string
     */
    public function phpTypeHint($castType, $nullable)
    {
        $type = $castType;

        switch ($castType) {
            case 'object':
                $type = '\stdClass';
                break;
            case 'array':
            case 'json':
                $type = 'array';
                break;
            case 'collection':
                $type = '\Illuminate\Support\Collection';
                break;
            case 'datetime':
                $type = '\Carbon\Carbon';
                break;
            case 'binary':
                $type = 'string';
                break;
        }

        if ($nullable) {
            return $type.'|null';
        }

        return $type;
    }

    /**
     * @return string
     */
    public function getSchema()
    {
        return $this->blueprint->schema();
    }

    /**
     * @return string
     */
    public function getTable($andRemovePrefix = false)
    {
        if ($andRemovePrefix) {
            return $this->removeTablePrefix($this->blueprint->table());
        }

        return $this->blueprint->table();
    }

    /**
     * @return string
     */
    public function getQualifiedTable()
    {
        return $this->blueprint->qualifiedTable();
    }

    /**
     * @return string
     */
    public function getTableForQuery()
    {
        return $this->shouldQualifyTableName()
            ? $this->getQualifiedTable()
            : $this->getTable();
    }

    /**
     * @return bool
     */
    public function shouldQualifyTableName()
    {
        return $this->config('qualified_tables', false);
    }

    /**
     * @return bool
     */
    public function shouldPluralizeTableName()
    {
        $pluralize = (bool) $this->config('pluralize', true);

        $overridePluralizeFor = $this->config('override_pluralize_for', []);
        if (count($overridePluralizeFor) > 0) {
            foreach ($overridePluralizeFor as $except) {
                if ($except == $this->getTable()) {
                    return ! $pluralize;
                }
            }
        }

        return $pluralize;
    }

    /**
     * @return bool
     */
    public function shouldLowerCaseTableName()
    {
        return (bool) $this->config('lower_table_name_first', false);
    }

    /**
     * @param \Reliese\Meta\Blueprint[] $references
     */
    public function withReferences($references)
    {
        $this->references = $references;
    }

    /**
     * @param string $namespace
     *
     * @return $this
     */
    public function withNamespace($namespace)
    {
        $this->namespace = $namespace;

        return $this;
    }

    /**
     * @return string
     */
    public function getNamespace()
    {
        return $this->namespace;
    }

    /**
     * @return string
     */
    public function getRelationNameStrategy()
    {
        return $this->relationNameStrategy;
    }

    /**
     * @return string
     */
    public function getBaseNamespace()
    {
        return $this->usesBaseFiles()
            ? $this->getNamespace().'\\Base'
            : $this->getNamespace();
    }

    /**
     * @param string $parent
     *
     * @return $this
     */
    public function withParentClass($parent)
    {
        $this->parentClass = '\\' . ltrim($parent, '\\');

        return $this;
    }

    /**
     * @return string
     */
    public function getParentClass()
    {
        return $this->parentClass;
    }

    /**
     * @return string
     */
    public function getQualifiedUserClassName()
    {
        return '\\'.$this->getNamespace().'\\'.$this->getClassName();
    }

    /**
     * @return string
     */
    public function getClassName()
    {
        // Model names can be manually overridden by users in the config file.
        // If a config entry exists for this table, use that name, rather than generating one.
        $overriddenName = $this->config('model_names.' . $this->getTable());
        if ($overriddenName) {
            return $overriddenName;
        }

        if ($this->shouldLowerCaseTableName()) {
            return Str::studly(Str::lower($this->getRecordName()));
        }

        return Str::studly($this->getRecordName());
    }

    /**
     * @return string
     */
    public function getRecordName()
    {
        if ($this->shouldPluralizeTableName()) {
            return Str::singular($this->removeTablePrefix($this->blueprint->table()));
        }

        return $this->removeTablePrefix($this->blueprint->table());
    }

    /**
     * @param bool $timestampsEnabled
     *
     * @return $this
     */
    public function withTimestamps($timestampsEnabled)
    {
        $this->timestamps = $timestampsEnabled;

        return $this;
    }

    /**
     * @return bool
     */
    public function usesTimestamps()
    {
        return $this->timestamps &&
               $this->blueprint->hasColumn($this->getCreatedAtField()) &&
               $this->blueprint->hasColumn($this->getUpdatedAtField());
    }

    /**
     * @param string $field
     *
     * @return $this
     */
    public function withCreatedAtField($field)
    {
        $this->CREATED_AT = $field;

        return $this;
    }

    /**
     * @return string
     */
    public function getCreatedAtField()
    {
        return $this->CREATED_AT;
    }

    /**
     * @return bool
     */
    public function hasCustomCreatedAtField()
    {
        return $this->usesTimestamps() &&
               $this->getCreatedAtField() != $this->getDefaultCreatedAtField();
    }

    /**
     * @return string
     */
    public function getDefaultCreatedAtField()
    {
        return Eloquent::CREATED_AT;
    }

    /**
     * @param string $field
     *
     * @return $this
     */
    public function withUpdatedAtField($field)
    {
        $this->UPDATED_AT = $field;

        return $this;
    }

    /**
     * @return string
     */
    public function getUpdatedAtField()
    {
        return $this->UPDATED_AT;
    }

    /**
     * @return bool
     */
    public function hasCustomUpdatedAtField()
    {
        return $this->usesTimestamps() &&
               $this->getUpdatedAtField() != $this->getDefaultUpdatedAtField();
    }

    /**
     * @return string
     */
    public function getDefaultUpdatedAtField()
    {
        return Eloquent::UPDATED_AT;
    }

    /**
     * @param bool $softDeletesEnabled
     *
     * @return $this
     */
    public function withSoftDeletes($softDeletesEnabled)
    {
        $this->softDeletes = $softDeletesEnabled;

        return $this;
    }

    /**
     * @return bool
     */
    public function usesSoftDeletes()
    {
        return $this->softDeletes &&
               $this->blueprint->hasColumn($this->getDeletedAtField());
    }

    /**
     * @param string $field
     *
     * @return $this
     */
    public function withDeletedAtField($field)
    {
        $this->DELETED_AT = $field;

        return $this;
    }

    /**
     * @return string
     */
    public function getDeletedAtField()
    {
        return $this->DELETED_AT;
    }

    /**
     * @return bool
     */
    public function hasCustomDeletedAtField()
    {
        return $this->usesSoftDeletes() &&
               $this->getDeletedAtField() != $this->getDefaultDeletedAtField();
    }

    /**
     * @return string
     */
    public function getDefaultDeletedAtField()
    {
        return 'deleted_at';
    }

    /**
     * @return array
     */
    public function getTraits()
    {
        $traits = $this->config('use', []);

        if (! is_array($traits)) {
            throw new \RuntimeException('Config use must be an array of valid traits to append to each model.');
        }

        if ($this->usesSoftDeletes()) {
            $traits = array_merge([SoftDeletes::class], $traits);
        }

        return $traits;
    }

    /**
     * @return bool
     */
    public function needsTableName()
    {
        return false === $this->shouldQualifyTableName() ||
            $this->shouldRemoveTablePrefix() ||
            $this->blueprint->table() != Str::plural($this->getRecordName()) ||
            ! $this->shouldPluralizeTableName();
    }

    /**
     * @return string
     */
    public function shouldRemoveTablePrefix()
    {
        return ! empty($this->tablePrefix);
    }

    /**
     * @param string $tablePrefix
     */
    public function withTablePrefix($tablePrefix)
    {
        $this->tablePrefix = $tablePrefix;
    }

    /**
     * @param string $relationNameStrategy
     */
    public function withRelationNameStrategy($relationNameStrategy)
    {
        $this->relationNameStrategy = $relationNameStrategy;
    }

    /**
     * @param string $table
     */
    public function removeTablePrefix($table)
    {
        if (($this->shouldRemoveTablePrefix()) && (substr($table, 0, strlen($this->tablePrefix)) == $this->tablePrefix)) {
            $table = substr($table, strlen($this->tablePrefix));
        }

        return $table;
    }

    /**
     * @param bool $showConnection
     */
    public function withConnection($showConnection)
    {
        $this->showConnection = $showConnection;
    }

    /**
     * @param string $connection
     */
    public function withConnectionName($connection)
    {
        $this->connection = $connection;
    }

    /**
     * @return bool
     */
    public function shouldShowConnection()
    {
        return (bool) $this->showConnection;
    }

    /**
     * @return string
     */
    public function getConnectionName()
    {
        return $this->connection;
    }

    /**
     * @return bool
     */
    public function hasCustomPrimaryKey()
    {
        return count($this->primaryKeys->columns) == 1 &&
               $this->getPrimaryKey() != $this->getDefaultPrimaryKeyField();
    }

    /**
     * @return string
     */
    public function getDefaultPrimaryKeyField()
    {
        return 'id';
    }

    /**
     * @todo: Improve it
     * @return string
     */
    public function getPrimaryKey()
    {
        if (empty($this->primaryKeys->columns)) {
            return;
        }

        return $this->primaryKeys->columns[0];
    }

    /**
     * @return string
     * @todo: check
     */
    public function getPrimaryKeyType()
    {
        return $this->primaryKeyColumn->type;
    }

    /**
     * @todo: Check whether it is necessary
     * @return bool
     */
    public function hasCustomPrimaryKeyCast()
    {
        return $this->getPrimaryKeyType() != $this->getDefaultPrimaryKeyType();
    }

    /**
     * @return string
     */
    public function getDefaultPrimaryKeyType()
    {
        return 'int';
    }

    /**
     * @return bool
     */
    public function doesNotAutoincrement()
    {
        return ! $this->autoincrement();
    }

    /**
     * @return bool
     */
    public function autoincrement()
    {
        if ($this->primaryKeyColumn) {
            return $this->primaryKeyColumn->autoincrement === true;
        }

        return false;
    }

    /**
     * @param $perPage
     */
    public function withPerPage($perPage)
    {
        $this->perPage = (int) $perPage;
    }

    /**
     * @return int
     */
    public function getPerPage()
    {
        return $this->perPage;
    }

    /**
     * @return bool
     */
    public function hasCustomPerPage()
    {
        return $this->perPage != $this->getDefaultPerPage();
    }

    /**
     * @return int
     */
    public function getDefaultPerPage()
    {
        return 15;
    }

    /**
     * @param string $format
     *
     * @return $this
     */
    public function withDateFormat($format)
    {
        $this->dateFormat = $format;

        return $this;
    }

    /**
     * @return string
     */
    public function getDateFormat()
    {
        return $this->dateFormat;
    }

    /**
     * @return bool
     */
    public function hasCustomDateFormat()
    {
        return $this->dateFormat != $this->getDefaultDateFormat();
    }

    /**
     * @return string
     */
    public function getDefaultDateFormat()
    {
        return 'Y-m-d H:i:s';
    }

    /**
     * @return string
     */
    public function getDefaultTablePrefix()
    {
        return '';
    }

    /**
     * @return string
     */
    public function getDefaultRelationNameStrategy()
    {
        return 'related';
    }

    /**
     * @return bool
     */
    public function hasCasts()
    {
        return ! empty($this->getCasts());
    }

    /**
     * @return array
     */
    public function getCasts()
    {
        if (
            array_key_exists($this->getPrimaryKey(), $this->casts) &&
            $this->autoincrement()
        ) {
            unset($this->casts[$this->getPrimaryKey()]);
        }

        return $this->casts;
    }

    /**
     * @return bool
     */
    public function hasDates()
    {
        return ! empty($this->getDates());
    }

    /**
     * @return array
     */
    public function getDates()
    {
        return array_diff(
            array_filter($this->casts, function (string $cast) {
                return $cast === 'datetime';
            }),
            [$this->CREATED_AT, $this->UPDATED_AT]
        );
    }

    /**
     * @return bool
     */
    public function usesSnakeAttributes()
    {
        return (bool) $this->config('snake_attributes', true);
    }

    /**
     * @return bool
     */
    public function doesNotUseSnakeAttributes()
    {
        return ! $this->usesSnakeAttributes();
    }

    /**
     * @return bool
     */
    public function hasHints()
    {
        return ! empty($this->getHints());
    }

    /**
     * @return array
     */
    public function getHints()
    {
        return $this->hints;
    }

    /**
     * @return array
     */
    public function getProperties()
    {
        return $this->properties;
    }

    /**
     * @param string $name
     *
     * @return bool
     */
    public function hasProperty($name)
    {
        return array_key_exists($name, $this->getProperties());
    }

    /**
     * @return \Reliese\Coders\Model\Relation[]
     */
    public function getRelations()
    {
        return $this->relations;
    }

    /**
     * @return bool
     */
    public function hasRelations()
    {
        return ! empty($this->relations);
    }

    /**
     * @return \Reliese\Coders\Model\Mutation[]
     */
    public function getMutations()
    {
        return $this->mutations;
    }

    /**
     * @param string $column
     *
     * @return bool
     */
    public function isHidden($column)
    {
        $attributes = $this->config('hidden', []);

        if (! is_array($attributes)) {
            throw new \RuntimeException('Config field [hidden] must be an array of attributes to hide from array or json.');
        }

        foreach ($attributes as $pattern) {
            if (Str::is($pattern, $column)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @return bool
     */
    public function hasHidden()
    {
        return ! empty($this->hidden);
    }

    /**
     * @return array
     */
    public function getHidden()
    {
        return $this->hidden;
    }

    /**
     * @param string $column
     *
     * @return bool
     */
    public function isFillable($column)
    {
        $guarded = $this->config('guarded', []);

        if (! is_array($guarded)) {
            throw new \RuntimeException('Config field [guarded] must be an array of attributes to protect from mass assignment.');
        }

        $protected = [
            $this->getCreatedAtField(),
            $this->getUpdatedAtField(),
            $this->getDeletedAtField(),
        ];

        if ($this->primaryKeys->columns) {
            $protected = array_merge($protected, $this->primaryKeys->columns);
        }

        foreach (array_merge($guarded, $protected) as $pattern) {
            if (Str::is($pattern, $column)) {
                return false;
            }
        }

        return true;
    }

    /**
     * @return bool
     */
    public function hasFillable()
    {
        return ! empty($this->fillable);
    }

    /**
     * @return array
     */
    public function getFillable()
    {
        return $this->fillable;
    }

    /**
     * @return \Reliese\Meta\Blueprint
     */
    public function getBlueprint()
    {
        return $this->blueprint;
    }

    /**
     * @param \Illuminate\Support\Fluent $command
     *
     * @return bool
     */
    public function isPrimaryKey(Fluent $command)
    {
        foreach ((array) $this->primaryKeys->columns as $column) {
            if (! in_array($column, $command->columns)) {
                return false;
            }
        }

        return true;
    }

    /**
     * @param \Illuminate\Support\Fluent $command
     *
     * @return bool
     */
    public function isUniqueKey(Fluent $command)
    {
        return $this->blueprint->isUniqueKey($command);
    }

    /**
     * @return bool
     */
    public function usesBaseFiles()
    {
        return $this->config('base_files', false);
    }

    /**
     * @return bool
     */
    public function usesPropertyConstants()
    {
        return $this->config('with_property_constants', false);
    }

    /**
     * @return int
     */
    public function indentWithSpace()
    {
        return (int) $this->config('indent_with_space', 0);
    }

    /**
     * @return bool
     */
    public function usesHints()
    {
        return $this->config('hints', false);
    }

    /**
     * @return bool
     */
    public function doesNotUseBaseFiles()
    {
        return ! $this->usesBaseFiles();
    }

    /**
     * @param string $key
     * @param mixed $default
     *
     * @return mixed
     */
    public function config($key = null, $default = null)
    {
        return $this->factory->config($this->getBlueprint(), $key, $default);
    }

    /**
     * @return bool
     */
    public function fillableInBaseFiles(): bool
    {
        return $this->config('fillable_in_base_files', false);
    }

    /**
     * @return bool
     */
    public function definesReturnTypes()
    {
        return $this->definesReturnTypes;
    }
}

Filemanager

Name Type Size Permission Actions
Relations Folder 0755
Templates Folder 0755
Config.php File 1.2 KB 0644
Factory.php File 17.57 KB 0644
Model.php File 25.79 KB 0644
ModelManager.php File 1.48 KB 0644
Mutation.php File 742 B 0644
Mutator.php File 1.62 KB 0644
Relation.php File 397 B 0644