Current File : /pages/54/47/d0016649/home/htdocs/ob_maxi/wp-content/plugins/digimember/system/model/data/base.php
<?php

abstract class ncore_BaseData extends ncore_Model
{
    public function __construct( ncore_ApiCore $api, $file='', $dir='' )
    {
        parent::__construct( $api, $file, $dir );

        if ($this->networkModeForced())
        {
            $this->in_network_mode = true;
        }
    }

    public function sqlLockedDateInfo( $table_prefix='auto' )
    {
        $table_name = $table_prefix === 'auto'
                    ? $this->sqlTableName()
                    : $table_prefix.$this->unprefixedTableName();

        $lock_date_columns = array();

        $meta = $this->sqlTableMeta();

        foreach ($meta['columns'] as $column => $type)
        {
            $is_lock_date = $type === 'lock_date';
            if ($is_lock_date) {
                $lock_date_columns[] = $column;
            }
        }

        return array( $table_name, $lock_date_columns );
    }

    public function isId( $txt )
    {
        if (is_numeric($txt) && $txt > 0) {
            return true;
        }

        return false;
    }

    public function setup()
    {
        $table_name = $this->sqlTableName();
        $meta = $this->_getSqlTableMeta();

        /** @var ncore_SqlInstallerLib $installer */
        $installer = $this->api->load->library( 'sql_installer' );

        $db = $this->db();

        $installer->setup( $db, $table_name, $meta );

        $this->onSetup();
    }

    public function teardown()
    {
        $table_name = $this->sqlTableName();

        /** @var ncore_SqlInstallerLib $installer */
        $installer = $this->api->load->library( 'sql_installer' );

        $db = $this->db();

        $installer->teardown( $db, $table_name );
    }

    public function sqlTableExists()
    {
        $table_name = $this->sqlTableName();

        $query = $this->db()->query("SHOW TABLES LIKE '$table_name'");

        $table_exists = (bool) $query;

        return $table_exists;
    }

    public function resolveToId( $object_or_id )
    {
        return is_numeric( $object_or_id )
               ? $object_or_id
               : ncore_retrieve( $object_or_id, 'id', false );
    }

    public function resolveToObj( $object_or_id )
    {
        return is_numeric( $object_or_id ) || is_string( $object_or_id )
               ? $this->get( $object_or_id )
               : $object_or_id;
    }

    public function resolveToObjCached( $object_or_id )
    {
        return is_numeric( $object_or_id ) || is_string( $object_or_id )
               ? $this->getCached( $object_or_id )
               : $object_or_id;
    }

    public function create( $data )
    {
        $this->onBeforeUpdate( $new_id=0, $data );

        $this->packSerializedData( $data );

        $data = $this->sanitizeData( __FUNCTION__, $data );

        $default_values = $this->defaultValues();
        foreach ($default_values as $column => $value)
        {
            if (!isset( $data[$column] ) )
            {
                $data[$column] = $value;
            }
        }

        $tableName = $this->sqlTableName();

        $sql_col = "";
        $sql_val = "";


        foreach ($data as $column => $value)
        {
            if ($sql_col)
            {
                $sql_col .= ',';
                $sql_val .= ',';
            }

            $column_esc = $this->colEscape( $column );
            $value_esc = $this->valEscape( $value );

            $sql_col .= $column_esc;
            $sql_val .= $value_esc;
        }

        $sql = "INSERT INTO `$tableName` ($sql_col) VALUES ($sql_val)";

        $this->db()->query( $sql );

        $new_id = $this->db()->insertId();

        $this->deleteVoidSubTableEntries();

        $this->onUpdate( $new_id, $data );

        if ($this->callOnUpdateDiff()) {
            $new_object = $this->get( $new_id );
            $this->onUpdateDiff( $new_object, null );
        }

        return $new_id;
    }

    public function defaultValue( $key, $fallback='' )
    {
        $values = $this->defaultValues();

        return ncore_retrieve( $values, $key, $fallback );
    }

    public function emptyObject()
    {
        $values = $this->defaultValues();

        $obj = (object) $values;

        $this->buildObject( $obj );

        return $obj;
    }

    protected function onBeforeUpdate( $obj_or_id, &$data )
    {
    }

    protected function onBeforeCopy( &$data )
    {
    }

    protected function callOnUpdateDiff() {
        return false;
    }

    protected function onUpdateDiff( $new_object, $old_object ) {
    }

    protected function onSetup()
    {
    }


    public function update( $obj_or_id, $data, $where = array() )
    {
        $this->onBeforeUpdate( $obj_or_id, $data );

        $id = $this->resolveToId( $obj_or_id );

        $this->packSerializedData( $data, $id );

        $tableName = $this->sqlTableName();

        $data = $this->sanitizeData( __FUNCTION__, $data );

        if (empty($data)) {
            return false;
        }

        $old_object = null;
        if ($this->callOnUpdateDiff()) {
            $old_object = $this->get( $id );
        }

        $sql_set = "";

        foreach ($data as $column => $value)
        {
            if ($sql_set)
            {
                $sql_set .= ',';
            }

            $column_esc = $this->colEscape( $column );
            $value_esc = $this->valEscape( $value );

            $sql_set .= "$column_esc = $value_esc";
        }

        if (is_object($obj_or_id))
        {
            foreach ($data as $column => $value)
            {
                $obj_or_id->$column = $value;
            }
        }

        $where['id'] = $id;
        $sql_where = $this->renderWhere( $where );

        $sql = "UPDATE `$tableName` SET $sql_set";

        if ($sql_where)
        {
            $sql .= " WHERE $sql_where";
        }

        $this->db()->query( $sql );

        $modified = $this->db()->modified();

        $must_update_modification_date = $modified && $this->hasModified();

        if ($must_update_modification_date)
        {
            $now = ncore_dbDate();
            $id_esc = $this->valEscape( $id );
            $sql = "UPDATE `$tableName` SET modified='$now' WHERE id = $id_esc";
            $this->db()->query( $sql );
        }

        if ($modified)
        {
            $this->onUpdate( $id, $data );
        }


        $this->deleteVoidSubTableEntries();

        if ($modified && $this->callOnUpdateDiff()) {
            $new_object = $this->get( $id );
            $this->onUpdateDiff( $new_object, $old_object );
        }

        return (bool) $modified;
    }

    public function delete( $obj_or_id )
    {
        $id = $this->resolveToId( $obj_or_id );

        $tableName = $this->sqlTableName();

        $id = $this->db()->escape( $id );

        $sql = "DELETE FROM `$tableName` WHERE id = '$id'";

        $this->db()->query( $sql );

        $modified = $this->db()->modified();

        $this->deleteVoidSubTableEntries();

        return (bool) $modified;
    }

    public function deleteWhere( $where )
    {
        $count = 0;
        $all = $this->getAll( $where );

        foreach ($all  as $one)
        {
            $modified = $this->delete( $one->id );
            if ($modified) {
                $count++;
            }
        }

        return $count;
    }


    public function copy( $id, $set_columns = array() )
    {
        $obj = $this->get( $id );
        $data = (array) $obj;

        $columns_to_unset = $this->notCopiedColumns();
        foreach ($columns_to_unset as $key) {
            unset( $data[ $key ] );
        }
        unset( $data['id'] );

        $name_column = $this->nameColumn();
        $name = ncore_retrieve( $data, $name_column );

        if ($name)
        {
            $data[$name_column] = $this->copyName( $name );
        }

        foreach ($set_columns as $key => $value)
        {
            $data[ $key ] = $value;
        }

        $this->onBeforeCopy( $data );

        $new_id = $this->create( $data );

        $sub_models = $this->subModelsToCopy();
        foreach ($sub_models as $model_name => $id_name)
        {
            /** @var ncore_BaseData $model */
            $model = $this->api->load->model( "data/$model_name" );

            $where = array( $id_name => $id );
            $set_columns = array( $id_name => $new_id );;

            $all = $model->getAll( $where );
            foreach ($all as $one)
            {
                $model->copy( $one->id, $set_columns );
            }
        }

        return $new_id;
    }

    public function get( $id )
    {
        $where = array( 'id' => $id );

        return $this->getWhere( $where );
    }

    public function getCached( $id )
    {
        $cache_key = $this->in_network_mode
                   ? "n-$id"
                   : "x-$id";

        $obj =& $this->cache[ $cache_key ];

        if (!isset( $obj ) || !empty($_GET['reload']))
        {
            $obj = $this->get( $id );
        }

        return $obj;
    }

    public function getWhere( $where, $order_by='' )
    {
        $list = $this->getAll( $where, $limit='0,1', $order_by );

        return $list
             ? $list[0]
             : false;
    }

    public function getCount( $where=array() )
    {
        $tableName = $this->sqlTableName();

        $sql = "SELECT COUNT(1) AS count FROM `$tableName`";

        $sql_where = $this->renderWhere( $where );

        if ($sql_where)
        {
            $sql .= " WHERE $sql_where";
        }

        $list = $this->db()->query( $sql );

        $count = $list[0]->count;

        return $count;

    }

    public function getAll( $where=array(), $limit=false, $order_by='' )
    {
        $tableName = $this->sqlTableName();

        $columns = $this->sqlColumns();

        $sql = "SELECT $columns FROM `$tableName`";

        $sql_where = $this->renderWhere( $where );

        if ($sql_where)
        {
            $sql .= " WHERE $sql_where";
        }

        if ($order_by)
        {
            $order_by .= ', ';
        }
        $order_by .= $this->defaultOrder();

        if ($order_by)
        {
            $sql .= " ORDER BY $order_by";
        }

        if ($limit)
        {
            list( $first, $count ) = explode( ',', $limit);
            $first = intval( $first );
            $count = intval( $count );
            $sql .= " LIMIT $first,$count";
        }

        return $this->getBySql( $sql );
    }

    public function asArray( $value_column, $key_column='id', $where = array() )
    {
        $limit = '';
        $order_by = "$value_column ASC";

        $all = $this->getAll( $where, $limit, $order_by );

        $array = array();
        foreach ($all as $one)
        {
            $key = $one->$key_column;
            $val = $one->$value_column;

            $array[ $key ] = $val;
        }

        return $array;
    }

    public function getByColumn( $column, $value )
    {
        $order_by = 'id ASC';

        $where = array( $column => $value );

        return $this->getWhere( $where, $order_by );
    }

    public function moveToTrash( $id )
    {
        if ($this->hasTrash())
        {
            $data = array( 'deleted' => ncore_dbDate() );
            $modified = $this->update( $id, $data );
        }
        else
        {
            $modified = $this->delete( $id );
        }

        return $modified;
    }

    public function retoreFromTrash( $id )
    {
        if ($this->hasTrash())
        {
            $data = array( 'deleted' => null );
            $where = array( 'deleted !=' => null );
            $modified = $this->update( $id, $data, $where );
        }
        else
        {
            $modified = false;
        }

        return $modified;
    }

    public function status( $row )
    {
        $is_deleted = (bool) ncore_retrieve( $row, 'deleted' );

        return $is_deleted
             ? 'deleted'
             : 'created';
    }

    public function statusLabels()
    {
        $labels = array(
            'created' => _ncore('created'),
        );

        if ($this->hasTrash())
        {
            $labels['deleted'] = _ncore('deleted');
        }

        return $labels;
    }

    public function search( $column, $search_for, $compare='like' )
    {
        $column = ncore_WashText( $column );

        $where = $compare == 'equal'
               ? array( $column => $search_for)
               : array( "$column like" => '%'.$search_for.'%' );

        $matches = $this->getAll( $where, '', "$column ASC" );

        return $matches;
    }

    public function pushNetworkMode() {

        if ($this->networkModeForced()) {
            $this->in_network_mode = true;
            return;
        }

        $this->network_modes[] = $this->in_network_mode;
        $this->in_network_mode = true;
    }

    public function popNetworkMode() {

        if ($this->networkModeForced()) {
            $this->in_network_mode = true;
            return;
        }

        if ($this->network_modes)
        {
            $previous = array_pop( $this->network_modes );
            $this->in_network_mode = $previous;
        }
    }

    public function getDeleted( $min_age_in_days )
    {
        if (!$this->hasTrash())
        {
            return array();
        }

        $min_age_in_days = ncore_washInt( $min_age_in_days );

        $table_name = $this->sqlTableName();

        $columns = $this->sqlColumns();

        $now = ncore_dbDate();

        $sql = "SELECT $columns FROM `$table_name` WHERE deleted < '$now' - INTERVAL $min_age_in_days DAY";

        return $this->getBySql( $sql );
    }


    public function dataType()
    {
        return NCORE_MODEL_DATA_TYPE_PLUGIN;
    }

    public function unprefixedTableName() {

        $basename = $this->sqlBaseTableName();

        $pluginname = $this->isUniqueInBlog()
                    ? 'digimember'
                    : $this->api->pluginName();

        $tablename = $pluginname . '_' . $basename;

        return $tablename;

    }

    //
    // protected
    //

    protected function sqlTableName()
    {
        $prefix = $this->in_network_mode
                ? $this->db()->networkTableNamePrefix()
                : $this->db()->tableNamePrefix();

        $tablename = $prefix . $this->unprefixedTableName();

        return $tablename;
    }


    protected function db()
    {
        global $ncore_db;
        if (!isset($ncore_db))
        {
            /** @var ncore_DbLib $ncore_db */
            $ncore_db = $this->api->load->library( 'db' );
        }

        return $ncore_db;
    }

    protected function networkModeForced()
    {
        return false;
    }

    protected function isUniqueInBlog() {

        return false;
    }

    protected function sqlExtraColumns()
    {
        return array();
    }

    protected function defaultOrder()
    {
        return 'id ASC';
    }

    protected function defaultValues()
    {
        $values['created'] = ncore_dbDate();

        if ($this->hasModified())
        {
            $values['modified'] = $values['created'];
        }

        return $values;
    }

    protected function buildObject( $object )
    {
        $object->table = $this->sqlBaseTableName();

        $object->status = $this->status( $object );

        $this->unpackSeriazedData( $object );
    }

    protected function serializedDataMeta() {
        return array(
            // 'data_serialized' => 'prefix_',
        );
    }

    protected function serializedColumns() {
        return array(
            // column_name without _serialized suffix
        );
    }

    protected function nameColumn()
    {
        return 'name';
    }

    protected function copyNameTemplate()
    {
        return _ncore( 'Copy of [NAME]' );
    }

    protected function notCopiedColumns()
    {
        return array( 'created', 'published', 'deleted', 'modified' );
    }


    protected function subModelsToCopy()
    {
        $models = array();

        return $models;
    }


    protected function hasTrash()
    {
        return false;
    }

    protected function hasModified()
    {
        return false;
    }

    protected function onWhere( &$where, $compound )
    {
        if ($this->hasTrash())
        {
            $this->maybeAddDeletedColToWhere( $where, $compound );
        }
    }

    abstract protected function sqlBaseTableName();
    abstract protected function sqlTableMeta();

    protected function subTableMetas()
    {
        return array(

        );
    }

    protected function protectedColumns( /** @noinspection PhpUnusedParameterInspection */ $method )
    {
        $columns = array( 'id', 'created', 'modified' );
//        switch ($method)
//        {
//            case 'create':
//                break;
//            case 'update':
//                break;
//        }
        return $columns;
    }

    protected function existingColumns()
    {
        $system_columns = array( 'id', 'created', 'modified', 'deleted'  );

        $meta = $this->sqlTableMeta();

        $columns = array_keys( $meta['columns'] );

        $columns = array_merge( $system_columns, $columns);

        foreach ($this->serializedColumns() as $col)
        {
            $columns[] = $col . '_serialized';
        }

        foreach ($this->serializedDataMeta() as $col => $prefix) {
            $columns[] = $col;
        }

        return $columns;
    }

    protected function onBeforeSave( &$data )
    {
    }

    protected function onUpdate( $id, $data )
    {
    }

    protected function renderWhere( $where, $compound='AND' )
    {
        $this->onWhere( $where, $compound );

        $sql_where = '';

        foreach ($where as $key_operator => $value)
        {
            if ($sql_where)
            {
                $sql_where .= " $compound ";
            }

            $is_or_condition = strtolower($key_operator) == 'or';
            if ($is_or_condition)
            {
                $sql_where .= '(' . $this->renderWhere( $value, 'OR' ) . ')';
                continue;
            }

            list( $key, $operator ) = $this->explodeKeyAndOperator( $key_operator );

            $is_sql = $operator === 'sql';
            if ($is_sql)
            {
                $sql_where .= "($value)";
                continue;
            }


            $is_null = !isset( $value ) || $value === 'NULL';

            $key = $this->colEscape( $key );
            $value = $this->valEscape( $value, $operator );

            if ($is_null)
            {
                $negate = $operator == '!=';
                $sql_where .= $negate
                            ? "($key IS NOT NULL)"
                            : "($key IS NULL)";
            }
            else
            {
                $sql_where .= "$key $operator $value";
            }
        }

        return $sql_where;
    }

    protected function getBySql( $sql )
    {
        $list = $this->db()->query( $sql  );

        foreach ($list as $one)
        {
            $this->buildObject( $one );
        }

        return $list;
    }

    //
    // private
    //
    private $cache = array();
    private $in_network_mode = false;
    private $network_modes = array();

    private function _sqlTableName( $basename )
    {
        $prefix = $this->db()->tableNamePrefix();

        $pluginname = $this->api->pluginName();

        $tablename = $prefix . $pluginname . '_' . $basename;

        return $tablename;
    }

    private function colEscape( $column )
    {
        return '`' . $this->db()->escape( $column ) . '`';
    }

    private function valEscape( $value, $operator = '=' )
    {
        if (!isset($value) || $value === 'NULL')
        {
            return 'NULL';
        }

        $is_in = $operator == 'in';
        if ($is_in)
        {
            if (!is_array($value))
            {
                $value = explode( ',', $value );
            }
            $sql = '';
            foreach ($value as $one)
            {
                if ($sql)
                {
                    $sql .= ',';
                }

                $sql .= "'" . $this->db()->escape( $one ) . "'";
            }

            if (!$sql)
            {
                return '(NULL)';
            }

            return "($sql)";
        }


        $is_now_date = strlen($value) >= 5
                    && is_string($value)
                    && $value[0] == 'N'
                    && substr( $value, 0, 5 ) == 'NOW()';

        if ($is_now_date)
        {
            $now = ncore_dbDate();
            $rest = substr( $value, 5 );
            if (!$rest)
            {
                $rest='';
            }
            return "'$now'$rest";
        }

        $is_like = $operator == 'like';
        if ($is_like)
        {
            $has_wildcard = strpos( $value, '%' ) !== false;
            if (!$has_wildcard)
            {
                $value = '%'.$value.'%';
            }
        }

        return "'" . $this->db()->escape( $value ) . "'";
    }

    private function explodeKeyAndOperator( $key_operator )
    {
        $tokens = explode( ' ', $key_operator );
        $key = ncore_retrieve( $tokens, 0 );
        $operator = ncore_retrieve( $tokens, 1, '=' );

        $key = trim( $key );
        $operator = trim( strtolower($operator) );

        return array( $key, $operator );
    }

    private function sqlColumns()
    {
        $sql_columns = '*';

        $columns = $this->sqlExtraColumns();

        foreach ($columns as $name => $sql )
        {
            $sql_columns .= ", ($sql) AS `$name`";
        }

        return $sql_columns;
    }

    private function _getSqlTableMeta()
    {
        $meta = $this->sqlTableMeta();

        if ($this->hasTrash())
        {
            $meta['columns']['deleted'] = 'lock_date';
        }
        if ($this->hasModified())
        {
            $meta['columns']['modified'] = 'datetime';
        }

        foreach ($this->serializedColumns() as $col)
        {
            $meta['columns'][ $col.'_serialized' ] = 'text';
        }

        foreach ($this->serializedDataMeta() as $col => $prefix) {
            $meta['columns'][ $col ] = 'text';
        }

        return $meta;
    }

    private function maybeAddDeletedColToWhere( &$where, $compound )
    {
        $is_and = strtoupper( trim($compound) ) == 'AND';

        if (!$is_and)
        {
            return;
        }

        foreach ($where as $key => $value)
        {
            $have_deleted = $key == 'deleted'
                                 || ncore_stringStartsWith( $key, 'deleted ' );
            if ($have_deleted)
            {
                return;
            }
        }

        $where[ 'deleted'] = null;
    }


    private function sanitizeData( $method, $data )
    {
        $existing_columns = $this->existingColumns();

        $protected_columns = $this->protectedColumns( $method );

        foreach ($data as $column => $value)
        {
            $is_protected = in_array( $column, $protected_columns );

            $is_existing = in_array( $column, $existing_columns );

            $is_valid = $is_existing && !$is_protected;

            if (!$is_valid)
            {
                unset( $data[ $column ]);
            }
        }

        $this->onBeforeSave( $data );

        return $data;
    }

    private function deleteVoidSubTableEntries()
    {
        $metas = $this->subTableMetas();
        if (!$metas)
        {
            return;
        }

        /** @var ncore_SqlInstallerLib $installer */
        $installer = $this->api->load->library( 'sql_installer' );

        $db = $this->db();

        $metas = $this->subTableMetas();

        $main_table = $this->sqlTableName();

        foreach ($metas as $table => $id_column)
        {
            $sub_table = $this->_sqlTableName( $table );
            $installer->deleteSubTableEntry( $db, $main_table, $sub_table, $id_column );

            /** @var ncore_BaseData $model */
            $model = $this->api->load->model( "data/$table" );
            $model->deleteVoidSubTableEntries();
        }
    }

    private function copyName( $name )
    {
        $template = $this->copyNameTemplate();

        $pattern = str_replace( '[NAME]', '(.*?)', $template );

        $is_copied = preg_match( "|^$pattern\$|", $name, $matches );

        if ($is_copied)
        {
            $name = $matches[1];

            $has_number = preg_match( '|^(.*) \(([0-9]*)\)$|', $name, $matches );
            if ($has_number)
            {
                $name   = $matches[1];
                $number = $matches[2];
                $number++;
            }
            else
            {
                $number = 2;
            }
        }
        else
        {
            $number = 1;
        }

        $name_column = $this->nameColumn();

        $new_name = '';
        $tries = 100;
        while ($tries--)
        {
            $new_base_name = $number >= 2
                           ? "$name ($number)"
                           : $name;

            $new_name = str_replace( '[NAME]', $new_base_name, $template );

            $where = array( $name_column => $new_name );

            $is_used = (bool) $this->getWhere( $where );
            if (!$is_used)
            {
                break;
            }

            $number++;
        }

        return $new_name;

    }

    protected function sanitizeSerializedData( /** @noinspection PhpUnusedParameterInspection */ $column, $array )
    {
        return $array;
    }

    private function packSerializedData( &$data, $id = false ) {

        foreach ($this->serializedColumns() as $column)
        {
            $have_data = isset( $data[$column] );
            if (!$have_data) {
                continue;
            }

            $array = $data[$column]
                   ? $data[$column]
                   : array();

            $array = $this->sanitizeSerializedData( $column, $array );

            $value_serialized = empty($array)
                              ? ''
                              : serialize( $array );
            unset($data[$column]);
            $data[ $column . '_serialized' ] = $value_serialized;
        }

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

        $must_load_seralized_data = (bool) $id;

        $obj = $must_load_seralized_data
              ? $this->get( $id )
              : false;

        foreach ($this->serializedDataMeta() as $column => $prefix)
        {
            $have_data = isset( $data[$column] );
            if (!$have_data) {
                continue;
            }

            $data_serialized = ncore_retrieve( $data, $column );

            if (!$data_serialized && $obj) {
                $data_serialized = ncore_retrieve( $obj, $column );
            }

            $array = $data_serialized
                    ? unserialize( $data_serialized )
                    : array();


            foreach ($data as $key => $value) {
                $is_seralized = ncore_stringStartsWith( $key, $prefix );
                if ($is_seralized) {
                    $array[ $key ] = $value;
                    unset( $data[ $key ] );
                }
            }

            $array = $this->sanitizeSerializedData( $column, $array );

            $data[ $column ] = serialize( $array );
        }
    }

    private function unpackSeriazedData( $object ) {


        foreach ($this->serializedColumns() as $col)
        {
            $value_serialized = ncore_retrieveAndUnset( $object, $col . '_serialized' );

            $value = $value_serialized
                   ? @unserialize( $value_serialized )
                   : null;

            $object->$col = $value;
        }

        foreach ($this->serializedDataMeta() as $column => $prefix)
        {
            $data_serialized = ncore_retrieve( $object, $column );
            if (!$data_serialized) {
                continue;
            }

            $array = unserialize( $data_serialized );
            foreach ($array as $key => $value) {

                if (!isset($object->$key)) {
                    $object->$key = $value;
                }

            }
        }
    }

    public function updateTableIfNeeded() {
        global $wpdb;
        $table_schema = $wpdb->dbname;
        $table_name = $this->sqlTableName();
        $tableData = $this->sqlTableMeta();
        foreach ($tableData['columns'] as $columnName => $columnData) {
            $row = false;
            $row = $wpdb->get_results(  "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = '".$table_schema."' AND table_name = '".$table_name."' AND column_name = '".$columnName."'"  );
            if ( is_array($row) && count($row) < 1 ) {
                $initCore = $this->api->init();
                $initCore->forceUpgrade();
                return true;
            }
        }
        return false;
    }
}