| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | // +---------------------------------------------------------------------- | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | // +---------------------------------------------------------------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | // | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | // +---------------------------------------------------------------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | // +---------------------------------------------------------------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | // | Author: yunwuxin <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | // +---------------------------------------------------------------------- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | namespace think\console\command\optimize; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | use think\console\Command; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | use think\console\Input; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | use think\console\input\Argument; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | use think\console\input\Option; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | use think\console\Output; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | class Schema extends Command | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     protected function configure() | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |         $this->setName('optimize:schema') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |             ->addArgument('app', Argument::OPTIONAL, 'app name .') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |             ->addOption('db', null, Option::VALUE_REQUIRED, 'db name .') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |             ->addOption('table', null, Option::VALUE_REQUIRED, 'table name .') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |             ->setDescription('Build database schema cache.'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     protected function execute(Input $input, Output $output) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |         $app = $input->getArgument('app'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         if (empty($app) && !is_dir($this->app->getBasePath() . 'controller')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |             $output->writeln('<error>Miss app name!</error>'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         if ($app) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |             $runtimePath = $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . $app . DIRECTORY_SEPARATOR; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |             $appPath     = $this->app->getBasePath() . $app . DIRECTORY_SEPARATOR; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |             $namespace   = 'app\\' . $app; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |             $runtimePath = $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |             $appPath     = $this->app->getBasePath(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |             $namespace   = 'app'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |         $schemaPath = $runtimePath . 'schema' . DIRECTORY_SEPARATOR; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |         if (!is_dir($schemaPath)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |             mkdir($schemaPath, 0755, true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |         if ($input->hasOption('table')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |             $table = $input->getOption('table'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |             if (false === strpos($table, '.')) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |                 $dbName = $this->app->db->getConfig('database'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |             $tables[] = $table; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         } elseif ($input->hasOption('db')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |             $dbName = $input->getOption('db'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |             $tables = $this->app->db->getConnection()->getTables($dbName); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |             $path = $appPath . 'model'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |             $list = is_dir($path) ? scandir($path) : []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |             foreach ($list as $file) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |                 if (0 === strpos($file, '.')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |                     continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |                 $class = '\\' . $namespace . '\\model\\' . pathinfo($file, PATHINFO_FILENAME); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |                 $this->buildModelSchema($schemaPath, $class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |             $output->writeln('<info>Succeed!</info>'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |             return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         $db = isset($dbName) ? $dbName . '.' : ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |         $this->buildDataBaseSchema($schemaPath, $tables, $db); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         $output->writeln('<info>Succeed!</info>'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |     protected function buildModelSchema(string $path, string $class): void | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         $reflect = new \ReflectionClass($class); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |         if (!$reflect->isAbstract() && $reflect->isSubclassOf('\think\Model')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |             $table   = $class::getTable(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |             $dbName  = $class::getConfig('database'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |             $content = '<?php ' . PHP_EOL . 'return '; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |             $info    = $class::getConnection()->getFields($table); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |             $content .= var_export($info, true) . ';'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |             file_put_contents($path . $dbName . '.' . $table . '.php', $content); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 100 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 101 |  |  |     protected function buildDataBaseSchema(string $path, array $tables, string $db): void | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 102 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 103 |  |  |         if ('' == $db) { | 
            
                                                                        
                            
            
                                    
            
            
                | 104 |  |  |             $dbName = $this->app->db->getConfig('database') . '.'; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 105 |  |  |         } else { | 
            
                                                                        
                            
            
                                    
            
            
                | 106 |  |  |             $dbName = $db; | 
            
                                                                        
                            
            
                                    
            
            
                | 107 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 108 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 109 |  |  |         foreach ($tables as $table) { | 
            
                                                                        
                            
            
                                    
            
            
                | 110 |  |  |             $content = '<?php ' . PHP_EOL . 'return '; | 
            
                                                                        
                            
            
                                    
            
            
                | 111 |  |  |             $info    = $this->app->db->getConnection()->getFields($db . $table); | 
            
                                                                        
                            
            
                                    
            
            
                | 112 |  |  |             $content .= var_export($info, true) . ';'; | 
            
                                                                        
                            
            
                                    
            
            
                | 113 |  |  |             file_put_contents($path . $dbName . $table . '.php', $content); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 116 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 117 |  |  |  |