Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/cakephp/migrations/src/Util/ColumnParser.php
<?php
namespace Migrations\Util;

use
Cake\Collection\Collection;
use
Cake\Utility\Hash;
use
ReflectionClass;

/**
 * Utility class used to parse arguments passed to a ``bake migration`` class
 */
class ColumnParser
{

   
/**
     * Regex used to parse the column definition passed through the shell
     *
     * @var string
     */
   
protected $regexpParseColumn = '/
        ^
        (\w+)
        (?::(\w+\??
            (?:\[
                (?:[0-9]|[1-9][0-9]+)
                (?:,(?:[0-9]|[1-9][0-9]+))?
            \])?
        ))?
        (?::(\w+))?
        (?::(\w+))?
        $
        /x'
;

   
/**
     * Regex used to parse the field type and length
     *
     * @var string
     */
   
protected $regexpParseField = '/(\w+\??)\[([0-9,]+)\]/';

   
/**
     * Parses a list of arguments into an array of fields
     *
     * @param array $arguments A list of arguments being parsed
     * @return array
     */
   
public function parseFields($arguments)
    {
       
$fields = [];
       
$arguments = $this->validArguments($arguments);
        foreach (
$arguments as $field) {
           
preg_match($this->regexpParseColumn, $field, $matches);
           
$field = $matches[1];
           
$type = Hash::get($matches, 2);
           
$indexType = Hash::get($matches, 3);

           
$typeIsPk = in_array($type, ['primary', 'primary_key']);
           
$isPrimaryKey = false;
            if (
$typeIsPk || in_array($indexType, ['primary', 'primary_key'])) {
               
$isPrimaryKey = true;

                if (
$typeIsPk) {
                   
$type = 'primary';
                }
            }
           
$nullable = (bool)strpos($type, '?');
           
$type = $nullable ? str_replace('?', '', $type) : $type;

            list(
$type, $length) = $this->getTypeAndLength($field, $type);
           
$fields[$field] = [
               
'columnType' => $type,
               
'options' => [
                   
'null' => $nullable,
                   
'default' => null,
                ],
            ];

            if (
$length !== null) {
                if (
is_array($length)) {
                    list(
$fields[$field]['options']['precision'], $fields[$field]['options']['scale']) = $length;
                } else {
                   
$fields[$field]['options']['limit'] = $length;
                }
            }

            if (
$isPrimaryKey === true && $type === 'integer') {
               
$fields[$field]['options']['autoIncrement'] = true;
            }
        }

        return
$fields;
    }

   
/**
     * Parses a list of arguments into an array of indexes
     *
     * @param array $arguments A list of arguments being parsed
     * @return array
     */
   
public function parseIndexes($arguments)
    {
       
$indexes = [];
       
$arguments = $this->validArguments($arguments);
        foreach (
$arguments as $field) {
           
preg_match($this->regexpParseColumn, $field, $matches);
           
$field = $matches[1];
           
$type = Hash::get($matches, 2);
           
$indexType = Hash::get($matches, 3);
           
$indexName = Hash::get($matches, 4);

            if (
               
in_array($type, ['primary', 'primary_key']) ||
               
in_array($indexType, ['primary', 'primary_key']) ||
               
$indexType === null
           
) {
                continue;
            }

           
$indexUnique = false;
            if (
$indexType === 'unique') {
               
$indexUnique = true;
            }

           
$indexName = $this->getIndexName($field, $indexType, $indexName, $indexUnique);

            if (empty(
$indexes[$indexName])) {
               
$indexes[$indexName] = [
                   
'columns' => [],
                   
'options' => [
                       
'unique' => $indexUnique,
                       
'name' => $indexName,
                    ],
                ];
            }

           
$indexes[$indexName]['columns'][] = $field;
        }

        return
$indexes;
    }

   
/**
     * Parses a list of arguments into an array of fields composing the primary key
     * of the table
     *
     * @param array $arguments A list of arguments being parsed
     * @return array
     */
   
public function parsePrimaryKey($arguments)
    {
       
$primaryKey = [];
       
$arguments = $this->validArguments($arguments);
        foreach (
$arguments as $field) {
           
preg_match($this->regexpParseColumn, $field, $matches);
           
$field = $matches[1];
           
$type = Hash::get($matches, 2);
           
$indexType = Hash::get($matches, 3);

            if (
in_array($type, ['primary', 'primary_key']) || in_array($indexType, ['primary', 'primary_key'])) {
               
$primaryKey[] = $field;
            }
        }

        return
$primaryKey;
    }

   
/**
     * Returns a list of only valid arguments
     *
     * @param array $arguments A list of arguments
     * @return array
     */
   
public function validArguments($arguments)
    {
       
$collection = new Collection($arguments);

        return
$collection->filter(function ($value, $field) {
            return
preg_match($this->regexpParseColumn, $field);
        })->
toArray();
    }

   
/**
     * Get the type and length of a field based on the field and the type passed
     *
     * @param string $field Name of field
     * @param string $type User-specified type
     * @return array First value is the field type, second value is the field length. If no length
     * can be extracted, null is returned for the second value
     */
   
public function getTypeAndLength($field, $type)
    {
        if (
preg_match($this->regexpParseField, $type, $matches)) {
            if (
strpos($matches[2], ',') !== false) {
               
$matches[2] = explode(',', $matches[2]);
            }

            return [
$matches[1], $matches[2]];
        }

       
$fieldType = $this->getType($field, $type);
       
$length = $this->getLength($fieldType);

        return [
$fieldType, $length];
    }

   
/**
     * Retrieves a type that should be used for a specific field
     *
     * @param string $field Name of field
     * @param string $type User-specified type
     * @return string
     */
   
public function getType($field, $type)
    {
       
$reflector = new ReflectionClass('Phinx\Db\Adapter\AdapterInterface');
       
$collection = new Collection($reflector->getConstants());

       
$validTypes = $collection->filter(function ($value, $constant) {
            return
substr($constant, 0, strlen('PHINX_TYPE_')) === 'PHINX_TYPE_';
        })->
toArray();
       
$fieldType = $type;
        if (
$type === null || !in_array($type, $validTypes)) {
            if (
$type === 'primary') {
               
$fieldType = 'integer';
            } elseif (
$field === 'id') {
               
$fieldType = 'integer';
            } elseif (
in_array($field, ['created', 'modified', 'updated']) || substr($field, -3) === '_at') {
               
$fieldType = 'datetime';
            } elseif (
in_array($field, ['latitude', 'longitude'])) {
               
$fieldType = 'decimal';
            } else {
               
$fieldType = 'string';
            }
        }

        return
$fieldType;
    }

   
/**
     * Returns the default length to be used for a given fie
     *
     * @param string $type User-specified type
     * @return int
     */
   
public function getLength($type)
    {
       
$length = null;
        if (
$type === 'string') {
           
$length = 255;
        } elseif (
$type === 'integer') {
           
$length = 11;
        } elseif (
$type === 'biginteger') {
           
$length = 20;
        } elseif (
$type === 'decimal') {
           
$length = [10, 6];
        }

        return
$length;
    }

   
/**
     * Returns the default length to be used for a given fie
     *
     * @param string $field Name of field
     * @param string $indexType Type of index
     * @param string $indexName Name of index
     * @param bool $indexUnique Whether this is a unique index or not
     * @return string
     */
   
public function getIndexName($field, $indexType, $indexName, $indexUnique)
    {
        if (empty(
$indexName)) {
           
$indexName = strtoupper('BY_' . $field);
            if (
$indexType === 'primary') {
               
$indexName = 'PRIMARY';
            } elseif (
$indexUnique) {
               
$indexName = strtoupper('UNIQUE_' . $field);
            }
        }

        return
$indexName;
    }
}