| Conditions | 44 |
| Paths | 68 |
| Total Lines | 338 |
| Code Lines | 142 |
| Lines | 17 |
| Ratio | 5.03 % |
| Changes | 9 | ||
| Bugs | 1 | Features | 3 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 94 | public function classes($class_data, $class_name, $table_name = NULL, array $db_relations = NULL) |
||
| 95 | { |
||
| 96 | // Сюда соберем код для генерации классов ActiveRecord |
||
| 97 | $class_eval = ''; |
||
| 98 | |||
| 99 | $func_eval = ''; |
||
| 100 | |||
| 101 | // Префикс для функций обращения к классам БД |
||
| 102 | if (!defined('__ARQ_Prefix__')) define('__ARQ_Prefix__', '_'); |
||
| 103 | |||
| 104 | // Сформируем имя функции для "вызова" класса |
||
| 105 | $func_name = __ARQ_Prefix__ . $class_name; |
||
| 106 | |||
| 107 | // If table name prefix is set |
||
| 108 | if (isset(self::$prefix{0})) { |
||
| 109 | // Remove prefix from class name |
||
| 110 | $class_name = str_replace(self::$prefix, '', $class_name); |
||
| 111 | } |
||
| 112 | |||
| 113 | // Если такой класс не был описан вручную до этого |
||
| 114 | if (!class_exists($class_name, false) && !in_array($class_name, $this->created_classes)) { |
||
| 115 | // Создадим коллекцию созданных классов |
||
| 116 | $this->created_classes[] = $class_name; |
||
| 117 | |||
| 118 | // Определим реальную таблицу БД |
||
| 119 | $table_name = isset($table_name) ? $table_name : self::$prefix . $class_name; |
||
| 120 | |||
| 121 | // Флаг того что этот класс относительный |
||
| 122 | $relational_class = $table_name != $class_name; |
||
| 123 | |||
| 124 | // Добавим обдасть имен |
||
| 125 | //$class_eval .= 'namespace Samson\ActiveRecord {'; |
||
| 126 | |||
| 127 | // Заполним комманду создания класса |
||
| 128 | $class_eval .= "\n" . '/**'; |
||
| 129 | |||
| 130 | // Для относительных классов выведем специальный заголовок |
||
| 131 | if ($relational_class) $class_eval .= "\n" . ' * ОТНОСИТЕЛЬНЫЙ Класс для работы с таблицей БД "' . $table_name . '" через "' . $class_name . '"'; |
||
| 132 | else $class_eval .= "\n" . ' * Класс для работы с таблицей БД "' . $table_name . '"'; |
||
| 133 | $class_eval .= "\n" . ' * @package SamsonActiveRecord'; |
||
| 134 | $class_eval .= "\n" . ' * @author Vitaly Iegorov <[email protected]>'; |
||
| 135 | $class_eval .= "\n" . ' * @author Nikita Kotenko <[email protected]>'; |
||
| 136 | $class_eval .= "\n" . ' * @version 2.0'; |
||
| 137 | $class_eval .= "\n" . ' */'; |
||
| 138 | $class_eval .= "\n" . 'class ' . $class_name . ' extends \samson\activerecord\dbRecord {'; |
||
| 139 | |||
| 140 | // Запишем реальное имя таблицы в БД |
||
| 141 | $class_eval .= "\n\t" . '/** Настоящее имя таблицы в БД к которой привязан данный класс */'; |
||
| 142 | $class_eval .= "\n\t" . 'public static $_table_name = "' . $table_name . '";'; |
||
| 143 | |||
| 144 | $class_eval .= "\n\t" . '/** Внутрення группировка таблицы */'; |
||
| 145 | $class_eval .= "\n\t" . 'public static $_own_group = array();'; |
||
| 146 | |||
| 147 | // Коллекция уникальных переменных |
||
| 148 | $unique_var = array(); |
||
| 149 | |||
| 150 | // Коллекция ключей переменных |
||
| 151 | $index_var = array(); |
||
| 152 | |||
| 153 | // Коллекция типов переменных |
||
| 154 | $var_types = array(); |
||
| 155 | |||
| 156 | // Primary field name |
||
| 157 | $primary_field = ''; |
||
| 158 | |||
| 159 | // Переберем данные описывающие структуру таблицы, её колонки |
||
| 160 | foreach ($class_data as & $column) { |
||
| 161 | // Если это главный ключ таблицы запишем его в специальную переменную |
||
| 162 | if ($column['Key'] == 'PRI' && $primary_field == '') { |
||
| 163 | $class_eval .= "\n\t" . '/** Название ключевого поля таблицы */'; |
||
| 164 | $class_eval .= "\n\t" . 'public static $_primary = "' . $column['Field'] . '";'; |
||
| 165 | $primary_field = $column['Field']; |
||
| 166 | } // Уникальные поля |
||
| 167 | else if ($column['Key'] == 'UNI') $unique_var[] = $column['Field']; |
||
| 168 | // Ключевые поля |
||
| 169 | else if ($column['Key'] == 'MUL') $index_var[] = $column['Field']; |
||
| 170 | |||
| 171 | // Запишем тип переменной |
||
| 172 | $var_types[$column['Field']] = $column['Type']; |
||
| 173 | } |
||
| 174 | |||
| 175 | // Коллекция определенных переменных |
||
| 176 | $defined_vars = array(); |
||
| 177 | |||
| 178 | // Комманда на выборку полей |
||
| 179 | $sql_select = array(); |
||
| 180 | |||
| 181 | // Счетчик не английских переменных |
||
| 182 | $utf8_fields_count = 1; |
||
| 183 | |||
| 184 | // Переменные |
||
| 185 | $vars_eval = ''; |
||
| 186 | |||
| 187 | // Переберем данные описывающие структуру таблицы, её колонки |
||
| 188 | foreach ($class_data as & $column) { |
||
| 189 | // Получим реальное имя колонки в таблице БД |
||
| 190 | $field = (isset($column['Column'])) ? $column['Column'] : $column['Field']; |
||
| 191 | |||
| 192 | // Получим виртуальное имя колонки если оно задано |
||
| 193 | $f_name = $column['Field']; |
||
| 194 | |||
| 195 | // Если переменную с такими именем мы еще не создавали |
||
| 196 | if (!in_array($field, $defined_vars)) { |
||
| 197 | // Сформируем SQL комманду для "правильной" выборки данных из БД |
||
| 198 | $sql_select[] = $table_name . '.' . $field; |
||
| 199 | |||
| 200 | // Если это русская переменная или содержащая не правильное имя переменной то мы называем её по своему |
||
| 201 | if (preg_match('/([^a-zA-Z_\s0-9]|[\-])+/ui', $field)) { |
||
| 202 | // Сгенерируем имя поля |
||
| 203 | $f_name = 'Field_' . ($utf8_fields_count++); |
||
| 204 | |||
| 205 | // Создадим переменную класса |
||
| 206 | $vars_eval .= "\n\t" . '/** ' . $field . ' */'; |
||
| 207 | } // Если это не настоящие имя поля - укажем настоящее |
||
| 208 | else if ($table_name != $class_name) $vars_eval .= "\n\t" . '/** ' . $column['Field'] . ' */'; |
||
| 209 | |||
| 210 | // Создадим саму переменную класса |
||
| 211 | $value = $column['Null'] !== 'NO' ? ' = null' : ' = ""'; |
||
| 212 | |||
| 213 | // TODO: refactor |
||
| 214 | switch (gettype($column['Default'])) { |
||
| 215 | case 'string': |
||
| 216 | switch ($column['Default']) { |
||
| 217 | case 'CURRENT_TIMESTAMP': $value = ''; break; |
||
| 218 | case '': $value = ' = ""'; break; |
||
| 219 | View Code Duplication | default: $value = $column['Default'] !== null ? ' = "'.$column['Default'].'"' : $value; |
|
| 220 | } |
||
| 221 | break; |
||
| 222 | View Code Duplication | case 'number': $value = $column['Default'] !== null ? ' = '.$column['Default'] : $value; |
|
| 223 | } |
||
| 224 | |||
| 225 | $vars_eval .= "\n\t" . 'public $' . $f_name . $value . ';'; |
||
| 226 | |||
| 227 | // Добавим имя переменной |
||
| 228 | $defined_vars[$f_name] = $field; |
||
| 229 | } // Создадим специальную переменную с пометкой о дубликате и ссылкой на него |
||
| 230 | else e('Ошибка: В таблице ##, найден дубликат колонки ##-##', D_SAMSON_ACTIVERECORD_DEBUG, array($class_name, $field, $f_name)); |
||
| 231 | } |
||
| 232 | |||
| 233 | // Пропишем поля записи |
||
| 234 | $class_eval .= "\n\t" . '/** Коллекция полей класса и имен колонок в таблице БД */'; |
||
| 235 | $class_eval .= "\n\t" . 'public static $_attributes = array('; |
||
| 236 | View Code Duplication | foreach ($defined_vars as $name => $db_name) $class_eval .= "\n\t\t" . '"' . $name . '"=>"' . $db_name . '",'; |
|
| 237 | $class_eval .= "\n\t" . ');'; |
||
| 238 | |||
| 239 | // Пропишем колонки таблицы |
||
| 240 | $class_eval .= "\n\t" . '/** Коллекция РЕАЛЬНЫХ имен колонок в таблице БД */'; |
||
| 241 | $class_eval .= "\n\t" . 'public static $_table_attributes = array('; |
||
| 242 | View Code Duplication | foreach ($defined_vars as $name => $db_name) $class_eval .= "\n\t\t" . '"' . $name . '"=>"' . $db_name . '",'; |
|
| 243 | $class_eval .= "\n\t" . ');'; |
||
| 244 | |||
| 245 | // Сформируем SQL комманду для "правильной" выборки данных из БД |
||
| 246 | $class_eval .= "\n\t" . '/** Коллекция параметров SQL комманды для запроса к таблице */'; |
||
| 247 | $class_eval .= "\n\t" . 'public static $_sql_from = array('; |
||
| 248 | $class_eval .= "\n\t\t" . '"this" => "`' . $table_name . '`",'; |
||
| 249 | |||
| 250 | // Выборка полей для запроса |
||
| 251 | $select_eval = "\n\t" . '/** Часть SQL-комманды на выборку полей класса для запроса к таблице БД */'; |
||
| 252 | $select_eval .= "\n\t" . 'public static $_sql_select = array('; |
||
| 253 | $select_eval .= "\n\t\t" . '"this" => "' . implode(',' . "\n", $sql_select) . '",'; |
||
| 254 | |||
| 255 | // Коллекция связей имен полей связанных таблиц |
||
| 256 | $relation_eval = "\n\t" . '/** Коллекция имен полей связанных таблиц для запроса к таблице БД */'; |
||
| 257 | $relation_eval .= "\n\t" . 'public static $_relations = array('; |
||
| 258 | |||
| 259 | // Коллекция типов связей имен полей связанных таблиц |
||
| 260 | $reltype_eval = "\n\t" . '/** Коллекция типов связанных таблиц для запроса к таблице БД */'; |
||
| 261 | $reltype_eval .= "\n\t" . 'public static $_relation_type = array('; |
||
| 262 | |||
| 263 | // Коллекция типов связей имен полей связанных таблиц |
||
| 264 | $relalias_eval = "\n\t" . '/** Коллекция алиасов связанных таблиц для запроса к таблице БД */'; |
||
| 265 | $relalias_eval .= "\n\t" . 'public static $_relation_alias = array('; |
||
| 266 | |||
| 267 | // Коллекция имен полей для мапинга |
||
| 268 | $map_vars = array(); |
||
| 269 | foreach ($defined_vars as $name => $db_name) $map_vars[$name] = $table_name . '.' . $db_name; |
||
| 270 | |||
| 271 | // Permanent relation is specified |
||
| 272 | if (isset($db_relations[$table_name])) { |
||
| 273 | // Iterate table permanent relations |
||
| 274 | foreach ($db_relations[$table_name] as $r_table => $i) { |
||
| 275 | // Check child table |
||
| 276 | if (!isset(self::$tables[$i->child])) { |
||
| 277 | e('Cannot create relation beetween ## and ## - Table ## does not exists', E_SAMSON_ACTIVERECORD_ERROR, array($i->parent, $i->child)); |
||
| 278 | continue; |
||
| 279 | } |
||
| 280 | |||
| 281 | // Parent table name |
||
| 282 | $r_table_name = isset($i->alias{0}) ? $i->alias : $i->child; |
||
| 283 | |||
| 284 | // If relation alias is defined |
||
| 285 | if (isset($i->alias{0})) $class_eval .= "\n\t\t" . '"' . $i->alias . '"=>" LEFT JOIN `' . $i->child . '` AS ' . $i->alias; |
||
| 286 | else $class_eval .= "\n\t\t" . '"' . $i->child . '"=>" LEFT JOIN `' . $i->child . '`'; |
||
| 287 | |||
| 288 | // Parent table name |
||
| 289 | $ptable = $i->parent; |
||
| 290 | |||
| 291 | // If parent field not specified - use parent table primary field |
||
| 292 | View Code Duplication | if (!isset($i->parent_field)) $pfield = $primary_field; |
|
| 293 | // Correctly determine parent field name |
||
| 294 | else { |
||
| 295 | // Define if parent field name has table name in it |
||
| 296 | $tableinpf = strpos($i->parent_field, '.'); |
||
| 297 | |||
| 298 | // Get parent table field name |
||
| 299 | $pfield = $tableinpf !== false ? substr($i->parent_field, $tableinpf + 1) : $i->parent_field; |
||
| 300 | |||
| 301 | // Parent table field |
||
| 302 | $ptable = $tableinpf !== false ? substr($i->parent_field, 0, $tableinpf) : $i->parent; |
||
| 303 | } |
||
| 304 | |||
| 305 | // If no "." symbol in parent field name append parent table name |
||
| 306 | $pf = '`' . $ptable . '`.`' . $pfield . '`'; |
||
| 307 | |||
| 308 | // If child field not specified |
||
| 309 | if (!isset($i->child_field{0})) $cf = '`' . $i->child . '`.`' . $pfield . '`'; |
||
| 310 | // If no "." symbol in child field name append child table name |
||
| 311 | View Code Duplication | else $cf = strpos($i->child_field, '.') === false ? '`' . (isset($i->alias{0}) ? $i->alias : $i->child) . '`.' . $i->child_field : $i->child_field; |
|
| 312 | |||
| 313 | // And joining field |
||
| 314 | $class_eval .= ' ON ' . $pf . ' = ' . $cf . '",'; |
||
| 315 | |||
| 316 | // Установим тип связи |
||
| 317 | $reltype_eval .= "\n\t\t" . '"' . $r_table_name . '"=>' . $i->type . ','; |
||
| 318 | |||
| 319 | $relation_eval .= "\n\t\t" . '"' . $r_table_name . '" => array('; |
||
| 320 | |||
| 321 | $relalias_eval .= "\n\t\t" . '"' . $r_table_name . '" => "' . $i->child . '",'; |
||
| 322 | |||
| 323 | // Array for select block |
||
| 324 | $select_eval_array = array(); |
||
| 325 | |||
| 326 | // Переберем поля связанной таблицы |
||
| 327 | foreach (self::$tables[$i->child] as $column_data) { |
||
| 328 | // Имя поля связанной таблицы |
||
| 329 | $r_field_name = $r_table_name . '_' . $column_data['Field']; |
||
| 330 | |||
| 331 | // Имя поля связанной таблицы |
||
| 332 | $r_real_name = $r_table_name . '.' . $column_data['Field']; |
||
| 333 | |||
| 334 | // Добавим связь в мап |
||
| 335 | $map_vars[$r_field_name] = $r_real_name; |
||
| 336 | |||
| 337 | // Сформируем значение массива |
||
| 338 | $relation_eval .= "\n\t\t\t" . '"' . $column_data['Field'] . '" => "' . $r_field_name . '",'; |
||
| 339 | |||
| 340 | // Часть SQL-комманды |
||
| 341 | $select_eval_array[] = "\n\t\t\t" . $r_real_name . ' as ' . $r_field_name . ''; |
||
| 342 | } |
||
| 343 | |||
| 344 | // Сформируем массив имен полей для связи |
||
| 345 | $select_eval .= "\n\t\t" . '"' . $r_table_name . '" => "' . implode(',', $select_eval_array) . '",'; |
||
| 346 | |||
| 347 | // Закроем коллекцию связей |
||
| 348 | $relation_eval .= "\n\t\t" . '),'; |
||
| 349 | } |
||
| 350 | } |
||
| 351 | |||
| 352 | // Закроем |
||
| 353 | $class_eval .= "\n\t" . ');'; |
||
| 354 | |||
| 355 | // Закроем |
||
| 356 | $select_eval .= "\n\t" . ');'; |
||
| 357 | |||
| 358 | // Закроем |
||
| 359 | $relation_eval .= "\n\t" . ');'; |
||
| 360 | |||
| 361 | $reltype_eval .= "\n\t" . ');'; |
||
| 362 | |||
| 363 | $relalias_eval .= "\n\t" . ');'; |
||
| 364 | |||
| 365 | // Слепим все вместе |
||
| 366 | $class_eval .= $relation_eval . $relalias_eval . $reltype_eval . $select_eval; |
||
| 367 | |||
| 368 | // Пропишем типы полей записи |
||
| 369 | $class_eval .= "\n\t" . '/** Коллекция типов полей записи в таблице БД */'; |
||
| 370 | $class_eval .= "\n\t" . 'public static $_types = array('; |
||
| 371 | foreach ($var_types as $name => $type) $class_eval .= "\n\t\t" . '"' . $name . '"=>"' . $type . '",'; |
||
| 372 | $class_eval .= "\n\t" . ');'; |
||
| 373 | |||
| 374 | // Пропишем ключевые поля записи |
||
| 375 | $class_eval .= "\n\t" . '/** Коллекция имен ключей записи в таблице БД */'; |
||
| 376 | $class_eval .= "\n\t" . 'public static $_indeces = array('; |
||
| 377 | foreach ($index_var as $name) $class_eval .= "\n\t\t" . '"' . $name . '",'; |
||
| 378 | $class_eval .= "\n\t" . ');'; |
||
| 379 | |||
| 380 | // Пропишем уникальные поля записи |
||
| 381 | $class_eval .= "\n\t" . '/** Коллекция имен уникальных полей записи в таблице БД */'; |
||
| 382 | $class_eval .= "\n\t" . 'public static $_unique = array('; |
||
| 383 | foreach ($unique_var as $name) $class_eval .= "\n\t\t" . '"' . $name . '",'; |
||
| 384 | $class_eval .= "\n\t" . ');'; |
||
| 385 | |||
| 386 | // Пропишем поля записи |
||
| 387 | $class_eval .= "\n\t" . '/** Коллекция связей между именами полей класса и именами колонок в таблице БД */'; |
||
| 388 | $class_eval .= "\n\t" . 'public static $_map = array('; |
||
| 389 | foreach ($map_vars as $name => $db_name) $class_eval .= "\n\t\t" . '"' . $name . '"=>"' . $db_name . '",'; |
||
| 390 | $class_eval .= "\n\t" . ');'; |
||
| 391 | |||
| 392 | // Запишем имена всех полей класса как метаданные |
||
| 393 | $class_eval .= $vars_eval; |
||
| 394 | |||
| 395 | // Заполним конструктор класса для установки схемы |
||
| 396 | //$class_eval .= "\n\t".'/** Создать экземпляр класса '.$class_name.' */'; |
||
| 397 | //$class_eval .= "\n\t".'public function __construct( $id = NULL, $class_name = NULL ){ if( !isset($class_name)) $class_name = "'.$class_name.'" ; parent::__construct( $id, $class_name ); }'; |
||
| 398 | |||
| 399 | // Геттер для получения переменных класса по другому названию |
||
| 400 | //$class_eval .= "\n\t".'/** Попытаться получить переменную класса '.$class_name.' */'; |
||
| 401 | //$class_eval .= "\n\t".'public function __get( $name ){ if( isset( self::$_attributes[ $name ]) ){ $f = self::$_attributes[ $name ]; return $this->$f; } else return parent::__get( $name );}'; |
||
| 402 | |||
| 403 | // Сеттер для установки переменных класса по другому названию |
||
| 404 | //$class_eval .= "\n\t".'/** Попытаться получить переменную класса '.$class_name.' */'; |
||
| 405 | //$class_eval .= "\n\t".'public function __set( $name, $value ){ if( isset( self::$_attributes[ $name ]) ){ $f = self::$_attributes[ $name ]; return $this->$f = $value; } else return parent::__set( $name, $value );}'; |
||
| 406 | |||
| 407 | // Закончим описание класса |
||
| 408 | $class_eval .= "\n}"; |
||
| 409 | |||
| 410 | // Создадим подгруппу для хранения экземпляров данного класса |
||
| 411 | $class_eval .= "\n" . 'dbRecord::$instances["' . $class_name . '"] = array();'; |
||
| 412 | |||
| 413 | // Закончим описание области имен |
||
| 414 | //$class_eval .= "\n}"; |
||
| 415 | |||
| 416 | // Если мы еще не объявляли функцию для данного класса |
||
| 417 | if (!function_exists($func_name)) { |
||
| 418 | // Создадим специальную функцию для динамических запросов к АктивРекорду |
||
| 419 | //$class_eval .= "\n".'namespace {'; |
||
| 420 | $func_eval .= "\n" . '/** ' . "\n" . ' * @return dbQuery ' . "\n" . ' */'; |
||
| 421 | $func_eval .= "\n" . 'function ' . $func_name . '(){ return new \samson\activerecord\dbQuery("' . $class_name . '"); }' . "\n" . "\n"; |
||
| 422 | //$class_eval .= "\n}"; |
||
| 423 | } |
||
| 424 | } |
||
| 425 | |||
| 426 | // Установим переменную для оптимизации |
||
| 427 | //$this->classes .= $class_eval; |
||
| 428 | |||
| 429 | // Вернем строку с описанием классов для таблиц БД |
||
| 430 | return array($class_eval, $func_eval); |
||
| 431 | } |
||
| 432 | |||
| 676 |
Classes in PHP are usually named in CamelCase.
In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. The whole name starts with a capital letter as well.
Thus the name database provider becomes
DatabaseProvider.