<?
function table_checked($table_id,$options=array())
{ ?><form><?
  // обновляем модель таблиц по текущей таблице
  if (!$options['no_update_descr_tables']) create_model_obj_tables(array('use_tkey_table'=>$table_id)) ;
  $cnt_sql_cmd=0 ; $arr_changes=array() ;

  if (isset($_SESSION['descr_obj_tables'][$table_id]))
  { $tname=_DOT($table_id)->table_name ;
    //if ($tname) $table_fields=execSQL("DESCRIBE ".$tname) ; // поля проверяемой таблицы
    //if (_sizeof($table_fields)) foreach($table_fields as $indx=>$rec) $table_fields[$indx]['tkey']=$table_id ;
    //damp_array($table_fields) ;



    if (!$options['show_in_outer_table']) {?><table class=table_checked><?}
    ?><tr class=clss_header><td colspan=2><?echo "Проверка <strong>"._DOT($table_id)->name."'</strong> ($tname)" ; /*damp_array(_DOT($table_id)->list_clss_ext) ; */?></td></tr><?
      /*?><tr class=td_header><td colspan=2><? echo "Проверяем стандартные индексы таблицы"?></td></tr><?*/
      $recs_index=[];
      $index_recs=execSQL('SHOW INDEX from '.$tname,0,1) ;
      if (_sizeof($index_recs)) foreach ($index_recs as $index_rec) { $recs_index[$index_rec['Key_name']]['column_name_array'][]=$index_rec['Column_name']; }
      foreach ($recs_index as $key=>$value) {$recs_index[$key]['used_column']=implode(',',$value['column_name_array']); }
      //recs_index: used_column - импользуемые поля через запятую
//      $recs_index=execSQL('SHOW INDEX from '.$tname,array('use_fname_indx'=>'Key_name')) ;
//      print_2x_arr($recs_index) ;
      if (!$recs_index['PRIMARY'])
      { execSQL_update('delete from '.$tname.' where pkey=0 or pkey is null') ;
        execSQL_update('ALTER TABLE  '.$tname.' ADD PRIMARY KEY (pkey)',$options) ;
        execSQL_update('ALTER TABLE  '.$tname.' CHANGE  pkey  pkey INT( 11 ) NOT NULL AUTO_INCREMENT',$options) ;
        $arr_changes[]='Добавлен первичный ключ pkey' ;
      }
      if (!$recs_index['parent'])  { execSQL_update('ALTER TABLE  '.$tname.' ADD INDEX  parent (  parent )',$options) ; $arr_changes[]='Добавлен индекс для поля parent' ; }
      if (!$recs_index['clss'])    { execSQL_update('ALTER TABLE  '.$tname.' ADD INDEX  clss (  clss )',$options) ;     $arr_changes[]='Добавлен индекс для поля clss' ; }

      // для каждого объекта, который хранится в таблице, проверяем наличие его перечня полей
      $table_fields=execSQL("DESCRIBE ".$tname.' /*проверяем поля таблицы*/') ; // поля проверяемой таблицы
      if (_sizeof(_DOT($table_id)->list_clss_ext)) foreach(_DOT($table_id)->list_clss_ext as $clss=>$clss_info)
      { //print_r($clss_info) ; echo '<br>' ;
        // перед проверкой каждого класса заново загружаем описание таблицы - чтобы исколчить ошибки повторного добавления полей

        $obj_clss=_CLSS($clss);
        $clss_fields=$obj_clss->fields ; // поля проверяемого класса
        $clss_default=$obj_clss->default ; // значения по умолчанию класса
        $clss_index=$obj_clss->index ; // значения по умолчанию класса

        $clss_default['tkey']=$table_id ;
        if($clss_info['main']==$table_id)
          { // формируем перечень полей объекта $clss с учетом  режима хранения объектов или полей класса
            ob_start() ;
            ?><tr class=td_header><td colspan=2><? echo "Проверяем поля для класса <strong>'".$obj_clss->name."'</strong> (clss=".$clss.")&nbsp;" ; ?></td></tr><?
            $title=ob_get_clean() ;

            if (_sizeof($clss_fields))
            { // если текущий класс поддерживает мультиязычность, дополняем указанные поля класса соответствующими мультиязычномы полями
              $lang_clss_fields=$clss_fields ;
              if (isset($clss_info['multilang']) and _sizeof($clss_info['multilang'])) foreach($clss_info['multilang'] as $fname=>$value)
                  if (_sizeof($GLOBALS['lang_arr'])) foreach($GLOBALS['lang_arr'] as $lang_code=>$lang_info) if ($lang_code) $lang_clss_fields[$fname.$lang_info['suff']]=$clss_fields[$fname] ;

              //damp_array($lang_clss_fields) ;
              foreach ($lang_clss_fields as $fname=>$virt_type)
                { $real_type=convert_virt_type_to_db_type($virt_type) ;
                  // сравниваем тип поля
                  if ($table_fields[$fname]['Type']==$real_type) echo "" ;
                     else if (!isset($table_fields[$fname])) // такого поля нет вооще   - - ВЫПОЛНЯЕТСЯ СРАЗУ
                       { ?><tr><td><span class=fname><? echo $fname?></span>: <strong class=red>отсутствует</strong></td>
                               <td><?  execSQL_update("ALTER TABLE `$tname` ADD `$fname` $real_type",$options) ; ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
                           </tr>
                         <?
                         $table_fields[$fname]=array('Field'=>$fname,'Type'=>$real_type) ;
                         $arr_changes[]='Добавлено поле "'.$fname.'" '.$real_type ;
                       }
                      else if (!$options['no_check_type_fields']) // поле есть но тип  не совпадает
                       { ?><tr><td><span class=fname><? echo $fname?></span>: различные типы полей: "<? echo $table_fields[$fname]['Type']." ~ ".$real_type?> "</td>
                               <td><input name="sql_cmd[]" type="checkbox" value="<?echo "ALTER TABLE `$tname` CHANGE $fname $fname $real_type"?>"> Исправить</td>
                           </tr>
                         <?
                         $cnt_sql_cmd++ ;
                       }
                  // сравниваем значение по умолчанию - ВЫПОЛНЯЕТСЯ СРАЗУ
                  $def_value_by_clss=$clss_default[$fname] ;
                  $def_value_by_table=$table_fields[$fname]['Default'] ;
                  if (isset($clss_default[$fname]) and !isset($table_fields[$fname]['Default']))
                  {
                    ?><tr><td><span class=fname><? echo $fname?></span>: в таблице <strong class=red>не задано</strong> значение по умолчанию: "<? echo $def_value_by_clss?>"</td>
                          <td><? // при задании значения пол умолчанию обязательно должен быть флаг  NOT NULL
                                 // при использовании  NOT NULL идет ошибка, если действие применяется к столбцу, в котором уже есть null значения
                                 // выдается ошибка, так как null-значения запрещены
                                 execSQL_update('update '.$tname.' set '.$fname.'="'.$def_value_by_clss.'" where '.$fname.' is null /* задаем значение по умолчанию для существующих строк*/',$options) ;
                                 execSQL_update("ALTER TABLE $tname CHANGE $fname $fname $real_type  DEFAULT  '$def_value_by_clss' /* задаем значение по умолчанию в описании таблицы*/",$options) ;
                                 $arr_changes[]='Изменено значение поля по умолчанию "'.$fname.'": '.$def_value_by_clss ;
                              ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
                      </tr>
                    <?
                  }
                  if (!isset($clss_default[$fname]) and isset($table_fields[$fname]['Default']))
                  { ?><tr><td><span class=fname><? echo $fname?></span>: в базе <strong>задано</strong> значение по умолчанию: "<? echo $def_value_by_table?>"</td>
                          <td><?  execSQL_update("ALTER TABLE `$tname` CHANGE $fname $fname $real_type NULL",$options) ; ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
                      </tr>
                    <?
                    $arr_changes[]='Изменено значение поля по умолчанию "'.$fname.'": NULL' ;
                  }
                  if (isset($clss_default[$fname]) and isset($table_fields[$fname]['Default']) and $clss_default[$fname]!=$table_fields[$fname]['Default'])
                  { ?><tr><td><span class=fname><? echo $fname?></span>: в базе задано значение по умолчанию: "<? echo $def_value_by_table?>" <strong>не соответствует</strong> значению в описании класса: <?echo $def_value_by_clss?></td>
                          <td><? // при задании значения пол умолчанию обязательно должен быть флаг  NOT NULL
                                 // при использовании  NOT NULL идет ошибка, если действие применяется к столбцу, в котором уже есть null значения
                                 // выдается ошибка, так как null-значения запрещены
                                 execSQL_update('update '.$tname.' set '.$fname.'="'.$def_value_by_clss.'" where '.$fname.' is null',$options) ; // сначала заполняем NULL значения
                                 execSQL_update("ALTER TABLE $tname CHANGE $fname $fname $real_type DEFAULT  '$def_value_by_clss'",$options) ;
                                 ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
                      </tr>
                    <?
                    $arr_changes[]='Изменено значение поля по умолчанию "'.$fname.'": '.$def_value_by_clss ;
                  }
                  //if (isset($clss_default[$fname]) and isset($table_fields[$fname]['Default'])) execSQL_update('update '.$tname.' set '.$fname.'="'.$def_value_by_clss.'" where '.$fname.' is null',$options) ;
                }
            }

            if (_sizeof($clss_index))
            {/*?><tr class=td_header><td colspan=2><? echo "Проверяем индексы для класса <strong>'".$obj_clss->name."'</strong> (clss=".$clss.")&nbsp;" ; ?></td></tr><?*/
             foreach($clss_index as $index_name=>$index_fields)
             {
                if (!$recs_index[$index_name]) {
                   ?>
                   <tr>
                        <td><span class=fname>Индекс <? echo $index_name?></span>: <strong class=bg-yellow>отсутствует</strong></td>
                        <td><?  execSQL_update("ALTER TABLE `$tname` ADD INDEX `$index_name` ($index_fields)",$options) ; ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
                   </tr>
                   <?
                   $arr_changes[]='Добавлен индекс для поля "'.$index_fields.'": '.$index_name ;

                } elseif ($recs_index[$index_name]['used_column']!=str_replace(' ','',$index_fields)) {
                   ?>
                   <tr>
                       <td><span class=fname>Индекс <? echo $index_name?></span>: <strong class=bg-yellow>используется для другого поля(полей)</strong></td>
                       <td><?  execSQL_update("DROP INDEX `$index_name` ON `$tname`",$options) ;
                               execSQL_update("ALTER TABLE `$tname` ADD INDEX `$index_name` ($index_fields)",$options) ; ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
                   </tr>
                   <?
                  $arr_changes[]='Удален индекс для поля "'.$index_fields.'": '.$index_name ;
                }
             }
            }
          }
        // если у таблицы есть дочерняя таблица с фотками, проверяем, что у таблицы есть поле _img_name
        /*
        if ($clss=3 and $clss_info['out'])
        { if (!isset($table_fields['_image_name']))
            { ?><tr><?
              echo "<tr><td>"."<span class=fname>_image_name</span>: <strong class=red>отсутствует</strong></td>" ;
              "ALTER TABLE $tname ADD _image_name varchar(255)" ;
              ?><td><input name="sql_cmd[]" type="checkbox" value="1" checked> Исправить</td><?

              ?></tr><?
            }
        }
        */
        // если у тaблицы включен режим parent_enabled (php or sql) проверяем наличие поля "_enabled" - ВЫПОЛНЯЕТСЯ СРАЗУ
      }
       /*?><tr class=td_header><td colspan=2><? echo "Проверяем служебные поля таблицы" ; ?></td></tr><?*/

      // проверяем корректность заполнения поля tkey
      if (!$options['no_check_not_used_field'])
      { $arr_tkey=execSQL_row('select tkey,count(pkey) from '.$tname.' group by tkey') ;
       //echo print_r($arr_tkey,true)."<br>" ;
       if (_sizeof($arr_tkey)>1 or (_sizeof($arr_tkey)==1 and !isset($arr_tkey[$table_id])))
       {   ?><tr><td><span class=fname>tkey</span>: в таблице присутствовали некорректные значения: "<? echo implode(',',array_keys($arr_tkey))?>": <span class="green bold">ИСПРАВЛЕНО</span></td><?
           execSQL_update('update '.$tname.' set tkey='.$table_id,$options) ;
           execSQL_update('ALTER TABLE '.$tname.' CHANGE tkey tkey int(11) NULL DEFAULT '.$table_id,$options) ;
            $arr_changes[]='Исправно значение поля tkey: '.$table_id ;
        }
       }

      /*if ($tname) $table_fields=execSQL("DESCRIBE ".$tname,1) ; // поля проверяемой таблицы
       if (_DOT($table_id)->setting['update_parent_enabled'] and !isset($table_fields['_enabled']))
       {  ?><tr><td><span class=fname>_enabled</span>: <strong class=red>отсутствует</strong></td>
                <td><?  execSQL_update("ALTER TABLE `$tname` ADD _enabled int(1) default 1",$options) ; ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
               </tr>
          <?
       }*/



     // теперь делаем обратную проверку - для каждого из полей объектной таблицы должен существовать хотябы один класс,
     // отвечающий за данное поле
     if (!$options['no_check_not_used_field'])
     { ?><tr class=td_header><td colspan=2><? echo "Ищем неиспользуемые поля" ; ?></td></tr><?
     if ($tname) $table_fields=execSQL("/*Ищем неиспользуемые поля*/ DESCRIBE ".$tname) ; // поля проверяемой таблицы
     if (_sizeof($table_fields)) foreach ($table_fields as $fname=>$finfo)
     {  $cnt=0 ;

       // смотрим описания полей для тех объектов, которые состоят в списке поддерживаемых классов
       //damp_array(_DOT($table_id)->list_clss_ext) ;
       if (_sizeof(_DOT($table_id)->list_clss_ext)) foreach (_DOT($table_id)->list_clss_ext as $clss=>$clss_info) if ($clss_info['main'])
       {  $obj_clss=_CLSS($clss);
          $lang_clss_fields=$obj_clss->fields ;

          if (_sizeof($clss_info['multilang'])) foreach($clss_info['multilang'] as $fname2=>$value)
             if (_sizeof($GLOBALS['lang_arr'])) foreach($GLOBALS['lang_arr'] as $lang_code=>$lang_info)  $lang_clss_fields[$fname2.$lang_info['suff']]=$lang_clss_fields[$fname2] ;

          if (isset($lang_clss_fields[$fname])) $cnt++ ;

       }

       if (!$cnt and $fname!='temp' and $fname!="_enabled" and $fname!="_image_name")
          { ?><tr><td><span class=fname><? echo $fname?></span>: поле не используется.</td>
                  <td><input name="sql_cmd[]" type="checkbox" value="<?echo "ALTER TABLE `$tname` DROP $fname "?>"> Исправить</td>
              </tr>
            <?
            $cnt_sql_cmd++ ;
          }
      }
     }
     //damp_array($table_fields) ;
     /*
     ?><tr class=td_header><td colspan=2><? echo "Проверяем корректность системных полей таблицы" ; ?></td></tr><?
     $table_ids=execSQL_line('select distinct(tkey) from '.$tname) ;
     if (_sizeof($table_ids)>1 or $table_ids[0]!=$table_id)
        { ?><tr><td><span class=fname>tkey</span>: некорректное значение.</td>
                <td><?  execSQL_update("UPDATE ".$tname." SET tkey=".$table_id,$options) ;
                        execSQL_update("ALTER TABLE ".$tname." ADD tkey default ".$table_id,$options) ;
                    ?> <span class="green bold">ИСПРАВЛЕНО</span></td>
            </tr>
          <?
        }
     */
     // если в таблице
     if (!$options['show_in_outer_table']) {?></table><?}

    if (_sizeof($arr_changes))
    { // сохраняем итоговую информацию по таблице в fields_info
      $table_fields=execSQL("DESCRIBE ".$tname.'/*итоговый запрос с учетом изменных полей*/') ; // поля проверяемой таблицы
      update_rec_in_table(TM_DOT,array('fields_info'=>serialize($table_fields)),'pkey='.$table_id) ;
      LOGS()->reg_log('update_db_table',$tname,array('data'=>$arr_changes)) ;
    }


  } else echo "<span>Объектная таблица pkey=$table_id не существует</span><br>" ;

  if (!$options['no_show_button'])
  { if ($cnt_sql_cmd) { ?><button class='button v2' cmd=db/exec_sql_list_cmd>Выполнить выбранные операции</button><? }
    else              { ?><div class=info>Структура полей таблицы в порядке</div><? }
  }
  ?></form><?
  return($cnt_sql_cmd) ;
}
?>
