├── .gitignore ├── .idea ├── db_craft.iml ├── git_toolbox_blame.xml ├── git_toolbox_prj.xml ├── modules.xml ├── php.xml ├── phpspec.xml ├── vcs.xml └── workspace.xml ├── README.md ├── composer.json ├── composer.lock ├── rector.php ├── src ├── Commands │ ├── GetMigrationCommand.php │ └── GetSeedCommand.php ├── Config.php ├── Libraries │ ├── FileHandler.php │ ├── MigrationGenerator.php │ └── SeederGenerator.php └── Templates │ ├── migration.txt │ └── seeder.txt ├── test_performance.php └── vendor ├── autoload.php └── composer ├── ClassLoader.php ├── InstalledVersions.php ├── LICENSE ├── autoload_classmap.php ├── autoload_namespaces.php ├── autoload_psr4.php ├── autoload_real.php ├── autoload_static.php ├── installed.json ├── installed.php └── platform_check.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | 3 | ./.idea/ -------------------------------------------------------------------------------- /.idea/db_craft.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/git_toolbox_blame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/git_toolbox_prj.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/php.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 38 | 40 | -------------------------------------------------------------------------------- /.idea/phpspec.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 38 | 39 | $PROJECT_DIR$/composer.json 40 | 41 | 42 | 43 | 44 | 45 | 50 | 52 | { 53 | "lastFilter": { 54 | "state": "OPEN", 55 | "assignee": "robinNcode" 56 | } 57 | } 58 | 59 | 82 | 83 | { 84 | "selectedUrlAndAccountId": { 85 | "url": "https://github.com/robinNcode/db_craft.git", 86 | "accountId": "210695b1-0b05-48e6-9bf3-53a64b7a6a77" 87 | } 88 | } 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | { 99 | "associatedIndex": 3 100 | } 101 | 102 | 103 | 106 | 120 | 121 | 122 | 123 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 1727801203503 133 | 145 | 146 | 153 | 154 | 161 | 162 | 169 | 172 | 173 | 175 | 176 | 185 | 186 | 187 | 188 | 189 | 191 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DB-Craft 2 | 3 | DB-Craft is a package for CodeIgniter 4 that provides convenient commands to generate migration and seeder files from a connected database. 4 | 5 | - Automatic Migration Generation: DB-Craft provides a simple command-line interface to generate migration files automatically based on the connected database. This feature allows developers to keep track of database schema changes and easily apply them to different environments. 6 | 7 | - Table-Specific Migrations: Developers can also generate migration files for specific tables, providing granular control over database changes. This flexibility allows for efficient database management and versioning. 8 | 9 | - Seeding Support: DB-Craft includes functionality to generate seeders, enabling developers to populate their database with initial data. This feature is especially useful for setting up sample data or populating reference tables. 10 | 11 | ## Installation 12 | 13 | You can install the DB-Craft package via Composer by running the following command: 14 | 15 | ``` 16 | composer require robinncode/db_craft 17 | ``` 18 | ## Dependencies 19 | 20 | DB-Craft has the following dependencies: 21 | 22 | - PHP: ^7.0.* || ^8.0.* 23 | - CodeIgniter/Framework: ^4.0.* 24 | 25 | 26 | ## Usage 27 | 28 | DB-Craft comes with the following commands: 29 | 30 | ### Generate Migration Files 31 | 32 | To generate all migration files from the connected database, run the following command: 33 | 34 | ``` 35 | php spark get:migration 36 | ``` 37 | 38 | To generate migration files for a specific table, run the following command: 39 | 40 | ``` 41 | php spark get:migration table_name 42 | ``` 43 | 44 | Replace `table_name` with the name of the specific table for which you want to generate migration files. 45 | 46 | ### Generate Seeder Files 47 | 48 | To generate all seeder files from the connected database, run the following command: 49 | 50 | ``` 51 | php spark get:seed 52 | ``` 53 | 54 | To generate seeder files for a specific table with table data, run the following command: 55 | 56 | ``` 57 | php spark get:seed table_name 58 | ``` 59 | 60 | Replace `table_name` with the name of the specific table for which you want to generate seeder files. 61 | 62 | ## License 63 | 64 | DB-Craft is open-source software licensed under the [MIT license](https://opensource.org/licenses/MIT). 65 | 66 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "robinncode/db_craft", 3 | "description": "DB Craft is a CodeIgniter4 Seeder, Migration Generator. \n\n Automatic Migration Generation: DB-Craft provides a simple command-line interface to generate migration files automatically based on the connected database. This feature allows developers to keep track of database schema changes and easily apply them to different environments.\n\n Table-Specific Migrations: Developers can also generate migration files for specific tables, providing granular control over database changes. This flexibility allows for efficient database management and versioning.\n\n Seeding Support: DB-Craft includes functionality to generate seeders, enabling developers to populate their database with initial data. This feature is especially useful for setting up sample data or populating reference tables.", 4 | "type": "library", 5 | "version": "1.2.1", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Mohammad Shahin Mia Robin", 10 | "email": "msmrobin518@gmail.com" 11 | } 12 | ], 13 | "config": { 14 | "optimize-autoloader": true, 15 | "sort-packages": true 16 | }, 17 | "autoload": { 18 | "psr-4": { 19 | "Robinncode\\DbCraft\\": "src/" 20 | } 21 | }, 22 | "minimum-stability": "stable", 23 | "require": { 24 | "php": ">= 7.2" 25 | }, 26 | "prefer-stable": true, 27 | "keywords": [ 28 | "Codeigniter4", 29 | "Migration", 30 | "Seeder", 31 | "Connected Database", 32 | "PHP", 33 | "CLI Tool" 34 | ], 35 | "homepage": "https://github.com/robinNcode/db_craft", 36 | "repository": "https://github.com/robinNcode/db_craft.git", 37 | "support": { 38 | "documentation": "https://github.com/robinNcode/db_craft/blob/master/README.md", 39 | "email": "msmrobin518@gmail.com", 40 | "issues": "https://github.com/robinNcode/db_craft/issues" 41 | }, 42 | "require-dev": { 43 | "laravel/pint": "^1.22", 44 | "rector/rector": "^2.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "be1c31a1566b04d68083ddd82a41c62c", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "laravel/pint", 12 | "version": "v1.22.1", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/laravel/pint.git", 16 | "reference": "941d1927c5ca420c22710e98420287169c7bcaf7" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/laravel/pint/zipball/941d1927c5ca420c22710e98420287169c7bcaf7", 21 | "reference": "941d1927c5ca420c22710e98420287169c7bcaf7", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "ext-json": "*", 26 | "ext-mbstring": "*", 27 | "ext-tokenizer": "*", 28 | "ext-xml": "*", 29 | "php": "^8.2.0" 30 | }, 31 | "require-dev": { 32 | "friendsofphp/php-cs-fixer": "^3.75.0", 33 | "illuminate/view": "^11.44.7", 34 | "larastan/larastan": "^3.4.0", 35 | "laravel-zero/framework": "^11.36.1", 36 | "mockery/mockery": "^1.6.12", 37 | "nunomaduro/termwind": "^2.3.1", 38 | "pestphp/pest": "^2.36.0" 39 | }, 40 | "bin": [ 41 | "builds/pint" 42 | ], 43 | "type": "project", 44 | "autoload": { 45 | "psr-4": { 46 | "App\\": "app/", 47 | "Database\\Seeders\\": "database/seeders/", 48 | "Database\\Factories\\": "database/factories/" 49 | } 50 | }, 51 | "notification-url": "https://packagist.org/downloads/", 52 | "license": [ 53 | "MIT" 54 | ], 55 | "authors": [ 56 | { 57 | "name": "Nuno Maduro", 58 | "email": "enunomaduro@gmail.com" 59 | } 60 | ], 61 | "description": "An opinionated code formatter for PHP.", 62 | "homepage": "https://laravel.com", 63 | "keywords": [ 64 | "format", 65 | "formatter", 66 | "lint", 67 | "linter", 68 | "php" 69 | ], 70 | "support": { 71 | "issues": "https://github.com/laravel/pint/issues", 72 | "source": "https://github.com/laravel/pint" 73 | }, 74 | "time": "2025-05-08T08:38:12+00:00" 75 | }, 76 | { 77 | "name": "phpstan/phpstan", 78 | "version": "2.1.17", 79 | "source": { 80 | "type": "git", 81 | "url": "https://github.com/phpstan/phpstan.git", 82 | "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053" 83 | }, 84 | "dist": { 85 | "type": "zip", 86 | "url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053", 87 | "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053", 88 | "shasum": "" 89 | }, 90 | "require": { 91 | "php": "^7.4|^8.0" 92 | }, 93 | "conflict": { 94 | "phpstan/phpstan-shim": "*" 95 | }, 96 | "bin": [ 97 | "phpstan", 98 | "phpstan.phar" 99 | ], 100 | "type": "library", 101 | "autoload": { 102 | "files": [ 103 | "bootstrap.php" 104 | ] 105 | }, 106 | "notification-url": "https://packagist.org/downloads/", 107 | "license": [ 108 | "MIT" 109 | ], 110 | "description": "PHPStan - PHP Static Analysis Tool", 111 | "keywords": [ 112 | "dev", 113 | "static analysis" 114 | ], 115 | "support": { 116 | "docs": "https://phpstan.org/user-guide/getting-started", 117 | "forum": "https://github.com/phpstan/phpstan/discussions", 118 | "issues": "https://github.com/phpstan/phpstan/issues", 119 | "security": "https://github.com/phpstan/phpstan/security/policy", 120 | "source": "https://github.com/phpstan/phpstan-src" 121 | }, 122 | "funding": [ 123 | { 124 | "url": "https://github.com/ondrejmirtes", 125 | "type": "github" 126 | }, 127 | { 128 | "url": "https://github.com/phpstan", 129 | "type": "github" 130 | } 131 | ], 132 | "time": "2025-05-21T20:55:28+00:00" 133 | }, 134 | { 135 | "name": "rector/rector", 136 | "version": "2.0.16", 137 | "source": { 138 | "type": "git", 139 | "url": "https://github.com/rectorphp/rector.git", 140 | "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2" 141 | }, 142 | "dist": { 143 | "type": "zip", 144 | "url": "https://api.github.com/repos/rectorphp/rector/zipball/f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", 145 | "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", 146 | "shasum": "" 147 | }, 148 | "require": { 149 | "php": "^7.4|^8.0", 150 | "phpstan/phpstan": "^2.1.14" 151 | }, 152 | "conflict": { 153 | "rector/rector-doctrine": "*", 154 | "rector/rector-downgrade-php": "*", 155 | "rector/rector-phpunit": "*", 156 | "rector/rector-symfony": "*" 157 | }, 158 | "suggest": { 159 | "ext-dom": "To manipulate phpunit.xml via the custom-rule command" 160 | }, 161 | "bin": [ 162 | "bin/rector" 163 | ], 164 | "type": "library", 165 | "autoload": { 166 | "files": [ 167 | "bootstrap.php" 168 | ] 169 | }, 170 | "notification-url": "https://packagist.org/downloads/", 171 | "license": [ 172 | "MIT" 173 | ], 174 | "description": "Instant Upgrade and Automated Refactoring of any PHP code", 175 | "keywords": [ 176 | "automation", 177 | "dev", 178 | "migration", 179 | "refactoring" 180 | ], 181 | "support": { 182 | "issues": "https://github.com/rectorphp/rector/issues", 183 | "source": "https://github.com/rectorphp/rector/tree/2.0.16" 184 | }, 185 | "funding": [ 186 | { 187 | "url": "https://github.com/tomasvotruba", 188 | "type": "github" 189 | } 190 | ], 191 | "time": "2025-05-12T16:37:16+00:00" 192 | } 193 | ], 194 | "aliases": [], 195 | "minimum-stability": "stable", 196 | "stability-flags": [], 197 | "prefer-stable": true, 198 | "prefer-lowest": false, 199 | "platform": { 200 | "php": ">= 7.2" 201 | }, 202 | "platform-dev": [], 203 | "plugin-api-version": "2.6.0" 204 | } 205 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | withPaths([ 11 | __DIR__.'/src', 12 | ]) 13 | // uncomment to reach your current PHP version 14 | ->withPhpSets() 15 | ->withTypeCoverageLevel(0) 16 | ->withDeadCodeLevel(0) 17 | ->withCodeQualityLevel(0); 18 | } catch (InvalidConfigurationException $e) { 19 | return throw new RuntimeException( 20 | 'Rector configuration error: '.$e->getMessage(), 21 | $e->getCode(), 22 | $e 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/Commands/GetMigrationCommand.php: -------------------------------------------------------------------------------- 1 | generateAllMigration(); 24 | } else { 25 | $migration->generateSingleMigration($table); 26 | 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Commands/GetSeedCommand.php: -------------------------------------------------------------------------------- 1 | generateSeeders($table_name); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Config.php: -------------------------------------------------------------------------------- 1 | config = new Config; 15 | } 16 | 17 | /** 18 | * Convert table name to file class name 19 | */ 20 | public function tableToSeederClassName($input): string 21 | { 22 | $parts = explode('_', $input); 23 | $className = ''; 24 | 25 | foreach ($parts as $part) { 26 | $className .= ucfirst($part); 27 | } 28 | 29 | $className .= 'Seeder'; 30 | 31 | return $className; 32 | } 33 | 34 | /** 35 | * Table to migration class name 36 | */ 37 | public function tableToMigrationClassName($input): string 38 | { 39 | $parts = explode('_', $input); 40 | $className = 'Create'; 41 | 42 | foreach ($parts as $part) { 43 | $className .= ucfirst($part); 44 | } 45 | 46 | $className .= 'Table'; 47 | 48 | return $className; 49 | } 50 | 51 | public function renderTemplate(string $template, array $data): string 52 | { 53 | $templateDir = realpath(__DIR__.'/../Templates/').'/'; 54 | $skeleton = file_get_contents($templateDir.$template.'.txt'); 55 | 56 | return str_replace(array_keys($data), array_values($data), $skeleton); 57 | } 58 | 59 | public function writeTable(string $table, string $attributes, string $keys) 60 | { 61 | helper('inflector'); 62 | $fileName = date('Y-m-d-His').'_create_'.$table.'_table.php'; 63 | $targetDir = APPPATH.'Database/Migrations/'; 64 | $filePath = $targetDir.$fileName; 65 | 66 | $replace = ['{migrate}', '{fields}', '{keys}', '{table}']; 67 | 68 | $with = [$attributes, $keys, $table]; 69 | 70 | $data = [ 71 | '{name}' => $this->tableToMigrationClassName($table), 72 | '{created_at}' => PRETTIFY_DATETIME, 73 | '{attributes}' => $attributes, 74 | '{keys}' => $keys, 75 | '{table}' => $table, 76 | ]; 77 | 78 | $finalFile = $this->renderTemplate('migration', $data); 79 | 80 | CLI::write($fileName.' file is creating...', 'yellow'); 81 | if (file_put_contents($filePath, $finalFile)) { 82 | CLI::write($fileName.' file created!', 'green'); 83 | } else { 84 | CLI::error($fileName.' failed to create file!'); 85 | } 86 | } 87 | 88 | public function checkFileExist(string $path): bool 89 | { 90 | if (is_file($path)) { 91 | $permission = CLI::prompt('File already exists.Overwrite? ', ['yes', 'no'], 'required|in_list[yes,no]'); 92 | if ($permission == 'no') { 93 | CLI::error('Task Cancelled.'); 94 | exit(1); 95 | } 96 | } 97 | 98 | return true; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Libraries/MigrationGenerator.php: -------------------------------------------------------------------------------- 1 | db = Database::connect($group); 32 | $this->db->initialize(); 33 | } catch (Throwable $exception) { 34 | CLI::error($exception->getMessage()); 35 | exit(); 36 | } 37 | } 38 | 39 | /** 40 | * Generating all migration... 41 | */ 42 | public function generateAllMigration(): void 43 | { 44 | $tables = $this->getTableNames(); 45 | foreach ($tables as $table) { 46 | $tableInfo = $this->getTableInfos($table); 47 | 48 | if ($table === self::MIGRATION_TABLE) { 49 | continue; 50 | } 51 | 52 | $file = new FileHandler; 53 | $file->writeTable($table, $tableInfo['attributes'], $tableInfo['keys']); 54 | } 55 | } 56 | 57 | /** 58 | * Generate migration for a single table ... 59 | */ 60 | public function generateSingleMigration($table): void 61 | { 62 | $tableInfo = $this->getTableInfos($table); 63 | 64 | $file = new FileHandler; 65 | $file->writeTable($table, $tableInfo['attributes'], $tableInfo['keys']); 66 | } 67 | 68 | /** 69 | * Return a list of All tables 70 | * Name from a specific database group 71 | * or default on 72 | */ 73 | public function getTableNames(): array 74 | { 75 | $tables = $this->db->listTables() ?? []; 76 | 77 | if (empty($tables)) { 78 | CLI::error('No table found in database!'); 79 | exit(1); 80 | } 81 | 82 | return $tables; 83 | } 84 | 85 | /** 86 | * return a list of all fields and 87 | * key generated from a table 88 | */ 89 | public function getTableInfos(string $table): array 90 | { 91 | $fields = $this->generateField($table); 92 | 93 | $indexes = $this->generateKeys($table); 94 | 95 | $relations = $this->generateForeignKeys($table); 96 | 97 | return [ 98 | 'attributes' => $fields, 99 | 'keys' => $indexes."\n".$relations, 100 | ]; 101 | } 102 | 103 | /** 104 | * Glue an array into a single string 105 | * 106 | * @author MsM Robin 107 | */ 108 | protected function getGluedString(array $arr, bool $is_assoc = false): string 109 | { 110 | // array consist of one element 111 | if (count($arr) == 1) { 112 | return "'".array_shift($arr)."'"; 113 | } else { 114 | $str = ''; 115 | if (! $is_assoc) { 116 | foreach ($arr as $item) { 117 | if (strlen($item) > 0) { 118 | $str .= "'$item', "; 119 | } 120 | } 121 | } else { 122 | foreach ($arr as $index => $item) { 123 | if (strlen($item) > 0) { 124 | $str .= "'$index' => '$item',"; 125 | } 126 | } 127 | } 128 | 129 | return '[ '.rtrim($str, ', ').']'; 130 | } 131 | } 132 | 133 | /** 134 | * Generate Field array from a table 135 | */ 136 | protected function generateField(string $table): ?string 137 | { 138 | $query = $this->db->query("DESCRIBE $table")->getResult(); 139 | $fieldString = ''; 140 | 141 | foreach ($query as $field) { 142 | 143 | // Check if the field has a default value of 'current_timestamp()' or other custom default value 144 | if ($field->Default === 'current_timestamp()' || $this->isCustomDefaultValue($field->Default)) { 145 | $fieldString .= "\n\t\t'$field->Field $field->Type NULL DEFAULT current_timestamp()',"; 146 | 147 | continue; 148 | } 149 | 150 | $singleField = "\n\t\t'$field->Field' => ["; 151 | // Type 152 | if (preg_match('/^([a-z]+)/', $field->Type, $matches) > 0) { 153 | $singleField .= "\n\t\t\t'type' => '".strtoupper($matches[1])."',"; 154 | } 155 | 156 | // Constraint 157 | if (preg_match('/\((.+)\)/', $field->Type, $matches) > 0) { 158 | // integer , varchar 159 | if (is_numeric($matches[1])) { 160 | $singleField .= "\n\t\t\t'constraint' => ".$matches[1].','; 161 | } 162 | // float , double 163 | elseif (preg_match('/[\d]+\s?,[\d]+\s?/', $matches[1]) > 0) { 164 | $singleField .= "\n\t\t\t'constraint' => '".$matches[1]."',"; 165 | } 166 | // Enum Fields 167 | else { 168 | $values = explode(',', str_replace("'", '', $matches[1])); 169 | 170 | if (count($values) == 1) { 171 | $singleField .= "\n\t\t\t'constraint' => [".$this->getGluedString($values).'],'; 172 | } else { 173 | $singleField .= "\n\t\t\t'constraint' => ".$this->getGluedString($values).','; 174 | } 175 | } 176 | } 177 | 178 | // if field needs null 179 | $singleField .= "\n\t\t\t'null' => ".(($field->Null == 'YES') ? 'true,' : 'false,'); 180 | // unsigned 181 | if (strpos($field->Type, 'unsigned') !== false) { 182 | $singleField .= "\n\t\t\t'unsigned' => true,"; 183 | } 184 | 185 | // autoincrement 186 | if (strpos($field->Extra, 'auto_increment') !== false) { 187 | $singleField .= "\n\t\t\t'auto_increment' => true,"; 188 | } 189 | 190 | $singleField .= "\n\t\t],"; 191 | $fieldString .= $singleField; 192 | } 193 | 194 | return $fieldString; 195 | } 196 | 197 | /** 198 | * Check if the given default value is a custom default value 199 | */ 200 | protected function isCustomDefaultValue(?string $defaultValue): bool 201 | { 202 | // Implementing custom logic to check for other custom default values here 203 | // For example, you can check if the default value contains 'current_timestamp()' or not ... 204 | if ($defaultValue === null) { 205 | return false; 206 | } 207 | 208 | return strpos($defaultValue, 'current_timestamp()') !== false; 209 | } 210 | 211 | /** 212 | * To generate keys from a table ... 213 | */ 214 | protected function generateKeys(string $table): ?string 215 | { 216 | $index = $this->db->getIndexData($table); 217 | 218 | $keys = []; 219 | $keys['primary'] = ''; 220 | $keys['foreign'] = ''; 221 | $keys['unique'] = ''; 222 | 223 | foreach ($index as $key) { 224 | switch ($key->type) { 225 | case 'PRIMARY': 226 | $keys['primary'] = "\n\t\t\$this->forge->addPrimaryKey(". 227 | $this->getGluedString($key->fields).');'; 228 | break; 229 | 230 | case 'UNIQUE': 231 | $keys['unique'] .= "\n\t\t\$this->forge->addUniqueKey(". 232 | $this->getGluedString($key->fields).');'; 233 | break; 234 | 235 | default: 236 | $keys['foreign'] .= "\n\t\t\$this->forge->addKey(". 237 | $this->getGluedString($key->fields).');'; 238 | break; 239 | 240 | } 241 | } 242 | 243 | return implode("\n", $keys); 244 | } 245 | 246 | protected function generateForeignKeys(string $table): ?string 247 | { 248 | $keys = $this->db->getForeignKeyData($table); 249 | $keyArray = []; 250 | foreach ($keys as $key) { 251 | $columnName = $key->column_name[0]; 252 | $foreignColumnName = $key->foreign_column_name[0]; 253 | $foreignTableName = $key->foreign_table_name; 254 | $onDelete = $key->on_delete; 255 | $onUpdate = $key->on_update; 256 | 257 | $keyArray[] = "\n\t\t\$this->forge->addForeignKey('$columnName','$foreignTableName','$foreignColumnName','$onDelete','$onUpdate');"; 258 | } 259 | 260 | return implode('', array_unique($keyArray)); 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /src/Libraries/SeederGenerator.php: -------------------------------------------------------------------------------- 1 | db = db_connect(); 24 | $this->file = new FileHandler; 25 | } 26 | 27 | /** 28 | * Generate Seeder files based on database tables. 29 | * 30 | * @return void 31 | */ 32 | public function generateSeeders(?string $table_name = null) 33 | { 34 | $tables = $this->getTables($table_name); 35 | 36 | if (empty($tables)) { 37 | CLI::write('No table found. Check your database connection', 'red'); 38 | 39 | return; 40 | } 41 | 42 | foreach ($tables as $table) { 43 | $this->createSeederFileWithChunks($table); 44 | } 45 | } 46 | 47 | /** 48 | * Process table data in chunks, and add progress tracking. 49 | */ 50 | protected function createSeederFileWithChunks(string $table): void 51 | { 52 | $totalRows = $this->getTableRowCount($table); 53 | $chunkSize = self::CHUNK_SIZE; 54 | 55 | if ($totalRows === 0) { 56 | CLI::write("Table '$table' is empty. Skipping...", 'yellow'); 57 | 58 | return; 59 | } elseif ($totalRows < $chunkSize) { 60 | $chunkSize = $totalRows; 61 | } 62 | 63 | $totalChunks = (int) ceil($totalRows / $chunkSize); 64 | $className = $this->file->tableToSeederClassName($table); 65 | $filePath = APPPATH.'Database/Seeds/'.$className.'.php'; 66 | 67 | // Initialize header and footer templates 68 | $headerTemplate = $this->getSeederHeaderTemplate($className, $table); 69 | $footerTemplate = $this->getSeederFooterTemplate($table); 70 | 71 | // Write header to file 72 | file_put_contents($filePath, $headerTemplate); 73 | 74 | // Generate seeder content in chunks 75 | for ($chunk = 0; $chunk < $totalChunks; $chunk++) { 76 | $offset = $chunk * $chunkSize; 77 | $rows = $this->getTableDataChunk($table, $offset, $chunkSize); 78 | $chunkContent = ''; 79 | 80 | foreach ($rows as $row) { 81 | $chunkContent .= ' ['; 82 | foreach ($row as $column => $value) { 83 | $chunkContent .= "'$column' => ".var_export($value, true).','; 84 | } 85 | $chunkContent .= "],\n"; 86 | } 87 | 88 | // Append chunk data to the seeder file 89 | file_put_contents($filePath, $chunkContent, FILE_APPEND | LOCK_EX); 90 | 91 | // Display progress 92 | $progress = (($chunk + 1) * $chunkSize) / $totalRows * 100; 93 | CLI::write(sprintf('Progress: %.2f%% (%d/%d rows)', $progress, min(($chunk + 1) * $chunkSize, $totalRows), $totalRows), 'yellow'); 94 | } 95 | 96 | // Write footer to finalize the file 97 | file_put_contents($filePath, $footerTemplate, FILE_APPEND | LOCK_EX); 98 | 99 | // Success message for each file generated 100 | CLI::write("Seeder file for table '$table' generated successfully!", 'green'); 101 | } 102 | 103 | /** 104 | * Returns the header template with placeholders replaced. 105 | */ 106 | protected function getSeederHeaderTemplate(string $className, string $table): string 107 | { 108 | $currentTime = date('Y-m-d H:i:s'); 109 | 110 | return <<db->disableForeignKeyChecks(); 134 | 135 | // Table Data 136 | \$$table = [ 137 | EOT; 138 | } 139 | 140 | /** 141 | * Returns the footer template with placeholders replaced. 142 | */ 143 | protected function getSeederFooterTemplate(string $table): string 144 | { 145 | return <<db->table('$table')->truncate(); 150 | 151 | // Insert data into the table 152 | try { 153 | \$this->db->table('$table')->insertBatch(\$$table); 154 | } catch (ReflectionException \$e) { 155 | throw new ReflectionException(\$e->getMessage()); 156 | } 157 | 158 | // Enable foreign key checks 159 | \$this->db->enableForeignKeyChecks(); 160 | } 161 | } 162 | EOT; 163 | } 164 | 165 | /** 166 | * Get total row count for the table. 167 | */ 168 | protected function getTableRowCount(string $table): int 169 | { 170 | return $this->db->table($table)->countAllResults(); 171 | } 172 | 173 | /** 174 | * Retrieves a chunk of data from the specified table. 175 | */ 176 | protected function getTableDataChunk(string $table, int $offset, int $limit): array 177 | { 178 | return $this->db->table($table) 179 | ->limit($limit, $offset) 180 | ->get() 181 | ->getResultArray(); 182 | } 183 | 184 | /** 185 | * Get the list of tables or a specific table. 186 | * 187 | * @param string|null $table_name 188 | */ 189 | protected function getTables($table_name = null): array 190 | { 191 | $tables = $this->allTables(); 192 | 193 | if (empty($table_name)) { 194 | return $tables; 195 | } elseif (in_array($table_name, $tables)) { 196 | return [$table_name]; 197 | } else { 198 | CLI::write("Table '$table_name' not found. Check your table name", 'red'); 199 | 200 | return []; 201 | } 202 | } 203 | 204 | /** 205 | * Fetch all tables from the database. 206 | */ 207 | protected function allTables(): array 208 | { 209 | $tables = []; 210 | $result = $this->db->listTables(); 211 | foreach ($result as $row) { 212 | if ($row !== self::MIGRATION_TABLE) { 213 | $tables[] = $row; 214 | } 215 | } 216 | 217 | return $tables; 218 | } 219 | 220 | /** 221 | * Getting table data ... 222 | */ 223 | protected function getTableData($table): array 224 | { 225 | $query = $this->db->table($table)->get(); 226 | 227 | return $query->getResultArray(); 228 | } 229 | 230 | /** 231 | * Generating seeder files ... 232 | */ 233 | protected function generateSeederFile($table, $data): string 234 | { 235 | $className = $this->file->tableToSeederClassName($table); 236 | // Generate the Seeder file content based on the $table and $data 237 | // You can customize the Seeder file content generation according to your needs 238 | 239 | $seederFileContent = '$'.$table." = [\n"; 240 | foreach ($data as $row) { 241 | $seederFileContent .= ' ['; 242 | foreach ($row as $column => $value) { 243 | $seederFileContent .= "'$column' => ".var_export($value, true).','; 244 | } 245 | $seederFileContent .= "],\n"; 246 | } 247 | $seederFileContent .= " ];\n"; 248 | 249 | $data = [ 250 | '{name}' => $className, 251 | '{created_at}' => PRETTIFY_DATETIME, 252 | '{seeder}' => $seederFileContent, 253 | '{table}' => $table, 254 | ]; 255 | 256 | return $this->file->renderTemplate('seeder', $data); 257 | } 258 | 259 | /** 260 | * Saving the seeder file ... 261 | * 262 | * @return void 263 | */ 264 | protected function saveSeederFile($table, $seederFileContent) 265 | { 266 | // Save the Seeder file to app/Database/Seeds folder 267 | $fileName = $this->file->tableToSeederClassName($table); 268 | $path = APPPATH.'Database/Seeds/'.$fileName.'.php'; 269 | 270 | if (! file_exists($path)) { 271 | helper('filesystem'); 272 | write_file($path, $seederFileContent); 273 | CLI::write($table.' Seeder file generated!', 'yellow'); 274 | } else { 275 | CLI::write($table.' Seeder file already exists!', 'red'); 276 | } 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /src/Templates/migration.txt: -------------------------------------------------------------------------------- 1 | db->disableForeignKeyChecks(); 20 | 21 | $this->forge->addField([ 22 | {attributes} 23 | ]); 24 | 25 | // table keys ... 26 | {keys} 27 | 28 | // Create Table ... 29 | $this->forge->createTable('{table}'); 30 | 31 | //enable foreign key check ... 32 | $this->db->enableForeignKeyChecks(); 33 | } 34 | 35 | //-------------------------------------------------------------------- 36 | 37 | public function down() 38 | { 39 | // disable foreign key check ... 40 | $this->db->disableForeignKeyChecks(); 41 | 42 | // Drop Table ... 43 | $this->forge->dropTable('{table}'); 44 | 45 | //enable foreign key check ... 46 | $this->db->enableForeignKeyChecks(); 47 | } 48 | } -------------------------------------------------------------------------------- /src/Templates/seeder.txt: -------------------------------------------------------------------------------- 1 | db->disableForeignKeyChecks(); 24 | 25 | // Table Data ... 26 | {seeder} 27 | 28 | // Cleaning up the table before seeding ... 29 | $this->db->table('{table}')->truncate(); 30 | 31 | //Using Query Builder Class ... 32 | try { 33 | $this->db->table('{table}')->insertBatch(${table}); 34 | } catch (ReflectionException $e) { 35 | throw new ReflectionException($e->getMessage()); 36 | } 37 | 38 | //enable foreign key check ... 39 | $this->db->enableForeignKeyChecks(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test_performance.php: -------------------------------------------------------------------------------- 1 | 7 | * Jordi Boggiano 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Composer\Autoload; 14 | 15 | /** 16 | * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. 17 | * 18 | * $loader = new \Composer\Autoload\ClassLoader(); 19 | * 20 | * // register classes with namespaces 21 | * $loader->add('Symfony\Component', __DIR__.'/component'); 22 | * $loader->add('Symfony', __DIR__.'/framework'); 23 | * 24 | * // activate the autoloader 25 | * $loader->register(); 26 | * 27 | * // to enable searching the include path (eg. for PEAR packages) 28 | * $loader->setUseIncludePath(true); 29 | * 30 | * In this example, if you try to use a class in the Symfony\Component 31 | * namespace or one of its children (Symfony\Component\Console for instance), 32 | * the autoloader will first look for the class under the component/ 33 | * directory, and it will then fallback to the framework/ directory if not 34 | * found before giving up. 35 | * 36 | * This class is loosely based on the Symfony UniversalClassLoader. 37 | * 38 | * @author Fabien Potencier 39 | * @author Jordi Boggiano 40 | * @see https://www.php-fig.org/psr/psr-0/ 41 | * @see https://www.php-fig.org/psr/psr-4/ 42 | */ 43 | class ClassLoader 44 | { 45 | /** @var \Closure(string):void */ 46 | private static $includeFile; 47 | 48 | /** @var string|null */ 49 | private $vendorDir; 50 | 51 | // PSR-4 52 | /** 53 | * @var array> 54 | */ 55 | private $prefixLengthsPsr4 = array(); 56 | /** 57 | * @var array> 58 | */ 59 | private $prefixDirsPsr4 = array(); 60 | /** 61 | * @var list 62 | */ 63 | private $fallbackDirsPsr4 = array(); 64 | 65 | // PSR-0 66 | /** 67 | * List of PSR-0 prefixes 68 | * 69 | * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) 70 | * 71 | * @var array>> 72 | */ 73 | private $prefixesPsr0 = array(); 74 | /** 75 | * @var list 76 | */ 77 | private $fallbackDirsPsr0 = array(); 78 | 79 | /** @var bool */ 80 | private $useIncludePath = false; 81 | 82 | /** 83 | * @var array 84 | */ 85 | private $classMap = array(); 86 | 87 | /** @var bool */ 88 | private $classMapAuthoritative = false; 89 | 90 | /** 91 | * @var array 92 | */ 93 | private $missingClasses = array(); 94 | 95 | /** @var string|null */ 96 | private $apcuPrefix; 97 | 98 | /** 99 | * @var array 100 | */ 101 | private static $registeredLoaders = array(); 102 | 103 | /** 104 | * @param string|null $vendorDir 105 | */ 106 | public function __construct($vendorDir = null) 107 | { 108 | $this->vendorDir = $vendorDir; 109 | self::initializeIncludeClosure(); 110 | } 111 | 112 | /** 113 | * @return array> 114 | */ 115 | public function getPrefixes() 116 | { 117 | if (!empty($this->prefixesPsr0)) { 118 | return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); 119 | } 120 | 121 | return array(); 122 | } 123 | 124 | /** 125 | * @return array> 126 | */ 127 | public function getPrefixesPsr4() 128 | { 129 | return $this->prefixDirsPsr4; 130 | } 131 | 132 | /** 133 | * @return list 134 | */ 135 | public function getFallbackDirs() 136 | { 137 | return $this->fallbackDirsPsr0; 138 | } 139 | 140 | /** 141 | * @return list 142 | */ 143 | public function getFallbackDirsPsr4() 144 | { 145 | return $this->fallbackDirsPsr4; 146 | } 147 | 148 | /** 149 | * @return array Array of classname => path 150 | */ 151 | public function getClassMap() 152 | { 153 | return $this->classMap; 154 | } 155 | 156 | /** 157 | * @param array $classMap Class to filename map 158 | * 159 | * @return void 160 | */ 161 | public function addClassMap(array $classMap) 162 | { 163 | if ($this->classMap) { 164 | $this->classMap = array_merge($this->classMap, $classMap); 165 | } else { 166 | $this->classMap = $classMap; 167 | } 168 | } 169 | 170 | /** 171 | * Registers a set of PSR-0 directories for a given prefix, either 172 | * appending or prepending to the ones previously set for this prefix. 173 | * 174 | * @param string $prefix The prefix 175 | * @param list|string $paths The PSR-0 root directories 176 | * @param bool $prepend Whether to prepend the directories 177 | * 178 | * @return void 179 | */ 180 | public function add($prefix, $paths, $prepend = false) 181 | { 182 | $paths = (array) $paths; 183 | if (!$prefix) { 184 | if ($prepend) { 185 | $this->fallbackDirsPsr0 = array_merge( 186 | $paths, 187 | $this->fallbackDirsPsr0 188 | ); 189 | } else { 190 | $this->fallbackDirsPsr0 = array_merge( 191 | $this->fallbackDirsPsr0, 192 | $paths 193 | ); 194 | } 195 | 196 | return; 197 | } 198 | 199 | $first = $prefix[0]; 200 | if (!isset($this->prefixesPsr0[$first][$prefix])) { 201 | $this->prefixesPsr0[$first][$prefix] = $paths; 202 | 203 | return; 204 | } 205 | if ($prepend) { 206 | $this->prefixesPsr0[$first][$prefix] = array_merge( 207 | $paths, 208 | $this->prefixesPsr0[$first][$prefix] 209 | ); 210 | } else { 211 | $this->prefixesPsr0[$first][$prefix] = array_merge( 212 | $this->prefixesPsr0[$first][$prefix], 213 | $paths 214 | ); 215 | } 216 | } 217 | 218 | /** 219 | * Registers a set of PSR-4 directories for a given namespace, either 220 | * appending or prepending to the ones previously set for this namespace. 221 | * 222 | * @param string $prefix The prefix/namespace, with trailing '\\' 223 | * @param list|string $paths The PSR-4 base directories 224 | * @param bool $prepend Whether to prepend the directories 225 | * 226 | * @throws \InvalidArgumentException 227 | * 228 | * @return void 229 | */ 230 | public function addPsr4($prefix, $paths, $prepend = false) 231 | { 232 | $paths = (array) $paths; 233 | if (!$prefix) { 234 | // Register directories for the root namespace. 235 | if ($prepend) { 236 | $this->fallbackDirsPsr4 = array_merge( 237 | $paths, 238 | $this->fallbackDirsPsr4 239 | ); 240 | } else { 241 | $this->fallbackDirsPsr4 = array_merge( 242 | $this->fallbackDirsPsr4, 243 | $paths 244 | ); 245 | } 246 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) { 247 | // Register directories for a new namespace. 248 | $length = strlen($prefix); 249 | if ('\\' !== $prefix[$length - 1]) { 250 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 251 | } 252 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 253 | $this->prefixDirsPsr4[$prefix] = $paths; 254 | } elseif ($prepend) { 255 | // Prepend directories for an already registered namespace. 256 | $this->prefixDirsPsr4[$prefix] = array_merge( 257 | $paths, 258 | $this->prefixDirsPsr4[$prefix] 259 | ); 260 | } else { 261 | // Append directories for an already registered namespace. 262 | $this->prefixDirsPsr4[$prefix] = array_merge( 263 | $this->prefixDirsPsr4[$prefix], 264 | $paths 265 | ); 266 | } 267 | } 268 | 269 | /** 270 | * Registers a set of PSR-0 directories for a given prefix, 271 | * replacing any others previously set for this prefix. 272 | * 273 | * @param string $prefix The prefix 274 | * @param list|string $paths The PSR-0 base directories 275 | * 276 | * @return void 277 | */ 278 | public function set($prefix, $paths) 279 | { 280 | if (!$prefix) { 281 | $this->fallbackDirsPsr0 = (array) $paths; 282 | } else { 283 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; 284 | } 285 | } 286 | 287 | /** 288 | * Registers a set of PSR-4 directories for a given namespace, 289 | * replacing any others previously set for this namespace. 290 | * 291 | * @param string $prefix The prefix/namespace, with trailing '\\' 292 | * @param list|string $paths The PSR-4 base directories 293 | * 294 | * @throws \InvalidArgumentException 295 | * 296 | * @return void 297 | */ 298 | public function setPsr4($prefix, $paths) 299 | { 300 | if (!$prefix) { 301 | $this->fallbackDirsPsr4 = (array) $paths; 302 | } else { 303 | $length = strlen($prefix); 304 | if ('\\' !== $prefix[$length - 1]) { 305 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 306 | } 307 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 308 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 309 | } 310 | } 311 | 312 | /** 313 | * Turns on searching the include path for class files. 314 | * 315 | * @param bool $useIncludePath 316 | * 317 | * @return void 318 | */ 319 | public function setUseIncludePath($useIncludePath) 320 | { 321 | $this->useIncludePath = $useIncludePath; 322 | } 323 | 324 | /** 325 | * Can be used to check if the autoloader uses the include path to check 326 | * for classes. 327 | * 328 | * @return bool 329 | */ 330 | public function getUseIncludePath() 331 | { 332 | return $this->useIncludePath; 333 | } 334 | 335 | /** 336 | * Turns off searching the prefix and fallback directories for classes 337 | * that have not been registered with the class map. 338 | * 339 | * @param bool $classMapAuthoritative 340 | * 341 | * @return void 342 | */ 343 | public function setClassMapAuthoritative($classMapAuthoritative) 344 | { 345 | $this->classMapAuthoritative = $classMapAuthoritative; 346 | } 347 | 348 | /** 349 | * Should class lookup fail if not found in the current class map? 350 | * 351 | * @return bool 352 | */ 353 | public function isClassMapAuthoritative() 354 | { 355 | return $this->classMapAuthoritative; 356 | } 357 | 358 | /** 359 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled. 360 | * 361 | * @param string|null $apcuPrefix 362 | * 363 | * @return void 364 | */ 365 | public function setApcuPrefix($apcuPrefix) 366 | { 367 | $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; 368 | } 369 | 370 | /** 371 | * The APCu prefix in use, or null if APCu caching is not enabled. 372 | * 373 | * @return string|null 374 | */ 375 | public function getApcuPrefix() 376 | { 377 | return $this->apcuPrefix; 378 | } 379 | 380 | /** 381 | * Registers this instance as an autoloader. 382 | * 383 | * @param bool $prepend Whether to prepend the autoloader or not 384 | * 385 | * @return void 386 | */ 387 | public function register($prepend = false) 388 | { 389 | spl_autoload_register(array($this, 'loadClass'), true, $prepend); 390 | 391 | if (null === $this->vendorDir) { 392 | return; 393 | } 394 | 395 | if ($prepend) { 396 | self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; 397 | } else { 398 | unset(self::$registeredLoaders[$this->vendorDir]); 399 | self::$registeredLoaders[$this->vendorDir] = $this; 400 | } 401 | } 402 | 403 | /** 404 | * Unregisters this instance as an autoloader. 405 | * 406 | * @return void 407 | */ 408 | public function unregister() 409 | { 410 | spl_autoload_unregister(array($this, 'loadClass')); 411 | 412 | if (null !== $this->vendorDir) { 413 | unset(self::$registeredLoaders[$this->vendorDir]); 414 | } 415 | } 416 | 417 | /** 418 | * Loads the given class or interface. 419 | * 420 | * @param string $class The name of the class 421 | * @return true|null True if loaded, null otherwise 422 | */ 423 | public function loadClass($class) 424 | { 425 | if ($file = $this->findFile($class)) { 426 | $includeFile = self::$includeFile; 427 | $includeFile($file); 428 | 429 | return true; 430 | } 431 | 432 | return null; 433 | } 434 | 435 | /** 436 | * Finds the path to the file where the class is defined. 437 | * 438 | * @param string $class The name of the class 439 | * 440 | * @return string|false The path if found, false otherwise 441 | */ 442 | public function findFile($class) 443 | { 444 | // class map lookup 445 | if (isset($this->classMap[$class])) { 446 | return $this->classMap[$class]; 447 | } 448 | if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 449 | return false; 450 | } 451 | if (null !== $this->apcuPrefix) { 452 | $file = apcu_fetch($this->apcuPrefix.$class, $hit); 453 | if ($hit) { 454 | return $file; 455 | } 456 | } 457 | 458 | $file = $this->findFileWithExtension($class, '.php'); 459 | 460 | // Search for Hack files if we are running on HHVM 461 | if (false === $file && defined('HHVM_VERSION')) { 462 | $file = $this->findFileWithExtension($class, '.hh'); 463 | } 464 | 465 | if (null !== $this->apcuPrefix) { 466 | apcu_add($this->apcuPrefix.$class, $file); 467 | } 468 | 469 | if (false === $file) { 470 | // Remember that this class does not exist. 471 | $this->missingClasses[$class] = true; 472 | } 473 | 474 | return $file; 475 | } 476 | 477 | /** 478 | * Returns the currently registered loaders keyed by their corresponding vendor directories. 479 | * 480 | * @return array 481 | */ 482 | public static function getRegisteredLoaders() 483 | { 484 | return self::$registeredLoaders; 485 | } 486 | 487 | /** 488 | * @param string $class 489 | * @param string $ext 490 | * @return string|false 491 | */ 492 | private function findFileWithExtension($class, $ext) 493 | { 494 | // PSR-4 lookup 495 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; 496 | 497 | $first = $class[0]; 498 | if (isset($this->prefixLengthsPsr4[$first])) { 499 | $subPath = $class; 500 | while (false !== $lastPos = strrpos($subPath, '\\')) { 501 | $subPath = substr($subPath, 0, $lastPos); 502 | $search = $subPath . '\\'; 503 | if (isset($this->prefixDirsPsr4[$search])) { 504 | $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); 505 | foreach ($this->prefixDirsPsr4[$search] as $dir) { 506 | if (file_exists($file = $dir . $pathEnd)) { 507 | return $file; 508 | } 509 | } 510 | } 511 | } 512 | } 513 | 514 | // PSR-4 fallback dirs 515 | foreach ($this->fallbackDirsPsr4 as $dir) { 516 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { 517 | return $file; 518 | } 519 | } 520 | 521 | // PSR-0 lookup 522 | if (false !== $pos = strrpos($class, '\\')) { 523 | // namespaced class name 524 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) 525 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); 526 | } else { 527 | // PEAR-like class name 528 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; 529 | } 530 | 531 | if (isset($this->prefixesPsr0[$first])) { 532 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { 533 | if (0 === strpos($class, $prefix)) { 534 | foreach ($dirs as $dir) { 535 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 536 | return $file; 537 | } 538 | } 539 | } 540 | } 541 | } 542 | 543 | // PSR-0 fallback dirs 544 | foreach ($this->fallbackDirsPsr0 as $dir) { 545 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 546 | return $file; 547 | } 548 | } 549 | 550 | // PSR-0 include paths. 551 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { 552 | return $file; 553 | } 554 | 555 | return false; 556 | } 557 | 558 | /** 559 | * @return void 560 | */ 561 | private static function initializeIncludeClosure() 562 | { 563 | if (self::$includeFile !== null) { 564 | return; 565 | } 566 | 567 | /** 568 | * Scope isolated include. 569 | * 570 | * Prevents access to $this/self from included files. 571 | * 572 | * @param string $file 573 | * @return void 574 | */ 575 | self::$includeFile = \Closure::bind(static function($file) { 576 | include $file; 577 | }, null, null); 578 | } 579 | } 580 | -------------------------------------------------------------------------------- /vendor/composer/InstalledVersions.php: -------------------------------------------------------------------------------- 1 | 7 | * Jordi Boggiano 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Composer; 14 | 15 | use Composer\Autoload\ClassLoader; 16 | use Composer\Semver\VersionParser; 17 | 18 | /** 19 | * This class is copied in every Composer installed project and available to all 20 | * 21 | * See also https://getcomposer.org/doc/07-runtime.md#installed-versions 22 | * 23 | * To require its presence, you can require `composer-runtime-api ^2.0` 24 | * 25 | * @final 26 | */ 27 | class InstalledVersions 28 | { 29 | /** 30 | * @var mixed[]|null 31 | * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null 32 | */ 33 | private static $installed; 34 | 35 | /** 36 | * @var bool|null 37 | */ 38 | private static $canGetVendors; 39 | 40 | /** 41 | * @var array[] 42 | * @psalm-var array}> 43 | */ 44 | private static $installedByVendor = array(); 45 | 46 | /** 47 | * Returns a list of all package names which are present, either by being installed, replaced or provided 48 | * 49 | * @return string[] 50 | * @psalm-return list 51 | */ 52 | public static function getInstalledPackages() 53 | { 54 | $packages = array(); 55 | foreach (self::getInstalled() as $installed) { 56 | $packages[] = array_keys($installed['versions']); 57 | } 58 | 59 | if (1 === \count($packages)) { 60 | return $packages[0]; 61 | } 62 | 63 | return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); 64 | } 65 | 66 | /** 67 | * Returns a list of all package names with a specific type e.g. 'library' 68 | * 69 | * @param string $type 70 | * @return string[] 71 | * @psalm-return list 72 | */ 73 | public static function getInstalledPackagesByType($type) 74 | { 75 | $packagesByType = array(); 76 | 77 | foreach (self::getInstalled() as $installed) { 78 | foreach ($installed['versions'] as $name => $package) { 79 | if (isset($package['type']) && $package['type'] === $type) { 80 | $packagesByType[] = $name; 81 | } 82 | } 83 | } 84 | 85 | return $packagesByType; 86 | } 87 | 88 | /** 89 | * Checks whether the given package is installed 90 | * 91 | * This also returns true if the package name is provided or replaced by another package 92 | * 93 | * @param string $packageName 94 | * @param bool $includeDevRequirements 95 | * @return bool 96 | */ 97 | public static function isInstalled($packageName, $includeDevRequirements = true) 98 | { 99 | foreach (self::getInstalled() as $installed) { 100 | if (isset($installed['versions'][$packageName])) { 101 | return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; 102 | } 103 | } 104 | 105 | return false; 106 | } 107 | 108 | /** 109 | * Checks whether the given package satisfies a version constraint 110 | * 111 | * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: 112 | * 113 | * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') 114 | * 115 | * @param VersionParser $parser Install composer/semver to have access to this class and functionality 116 | * @param string $packageName 117 | * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package 118 | * @return bool 119 | */ 120 | public static function satisfies(VersionParser $parser, $packageName, $constraint) 121 | { 122 | $constraint = $parser->parseConstraints((string) $constraint); 123 | $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); 124 | 125 | return $provided->matches($constraint); 126 | } 127 | 128 | /** 129 | * Returns a version constraint representing all the range(s) which are installed for a given package 130 | * 131 | * It is easier to use this via isInstalled() with the $constraint argument if you need to check 132 | * whether a given version of a package is installed, and not just whether it exists 133 | * 134 | * @param string $packageName 135 | * @return string Version constraint usable with composer/semver 136 | */ 137 | public static function getVersionRanges($packageName) 138 | { 139 | foreach (self::getInstalled() as $installed) { 140 | if (!isset($installed['versions'][$packageName])) { 141 | continue; 142 | } 143 | 144 | $ranges = array(); 145 | if (isset($installed['versions'][$packageName]['pretty_version'])) { 146 | $ranges[] = $installed['versions'][$packageName]['pretty_version']; 147 | } 148 | if (array_key_exists('aliases', $installed['versions'][$packageName])) { 149 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); 150 | } 151 | if (array_key_exists('replaced', $installed['versions'][$packageName])) { 152 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); 153 | } 154 | if (array_key_exists('provided', $installed['versions'][$packageName])) { 155 | $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); 156 | } 157 | 158 | return implode(' || ', $ranges); 159 | } 160 | 161 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 162 | } 163 | 164 | /** 165 | * @param string $packageName 166 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present 167 | */ 168 | public static function getVersion($packageName) 169 | { 170 | foreach (self::getInstalled() as $installed) { 171 | if (!isset($installed['versions'][$packageName])) { 172 | continue; 173 | } 174 | 175 | if (!isset($installed['versions'][$packageName]['version'])) { 176 | return null; 177 | } 178 | 179 | return $installed['versions'][$packageName]['version']; 180 | } 181 | 182 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 183 | } 184 | 185 | /** 186 | * @param string $packageName 187 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present 188 | */ 189 | public static function getPrettyVersion($packageName) 190 | { 191 | foreach (self::getInstalled() as $installed) { 192 | if (!isset($installed['versions'][$packageName])) { 193 | continue; 194 | } 195 | 196 | if (!isset($installed['versions'][$packageName]['pretty_version'])) { 197 | return null; 198 | } 199 | 200 | return $installed['versions'][$packageName]['pretty_version']; 201 | } 202 | 203 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 204 | } 205 | 206 | /** 207 | * @param string $packageName 208 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference 209 | */ 210 | public static function getReference($packageName) 211 | { 212 | foreach (self::getInstalled() as $installed) { 213 | if (!isset($installed['versions'][$packageName])) { 214 | continue; 215 | } 216 | 217 | if (!isset($installed['versions'][$packageName]['reference'])) { 218 | return null; 219 | } 220 | 221 | return $installed['versions'][$packageName]['reference']; 222 | } 223 | 224 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 225 | } 226 | 227 | /** 228 | * @param string $packageName 229 | * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. 230 | */ 231 | public static function getInstallPath($packageName) 232 | { 233 | foreach (self::getInstalled() as $installed) { 234 | if (!isset($installed['versions'][$packageName])) { 235 | continue; 236 | } 237 | 238 | return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; 239 | } 240 | 241 | throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); 242 | } 243 | 244 | /** 245 | * @return array 246 | * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} 247 | */ 248 | public static function getRootPackage() 249 | { 250 | $installed = self::getInstalled(); 251 | 252 | return $installed[0]['root']; 253 | } 254 | 255 | /** 256 | * Returns the raw installed.php data for custom implementations 257 | * 258 | * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. 259 | * @return array[] 260 | * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} 261 | */ 262 | public static function getRawData() 263 | { 264 | @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); 265 | 266 | if (null === self::$installed) { 267 | // only require the installed.php file if this file is loaded from its dumped location, 268 | // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 269 | if (substr(__DIR__, -8, 1) !== 'C') { 270 | self::$installed = include __DIR__ . '/installed.php'; 271 | } else { 272 | self::$installed = array(); 273 | } 274 | } 275 | 276 | return self::$installed; 277 | } 278 | 279 | /** 280 | * Returns the raw data of all installed.php which are currently loaded for custom implementations 281 | * 282 | * @return array[] 283 | * @psalm-return list}> 284 | */ 285 | public static function getAllRawData() 286 | { 287 | return self::getInstalled(); 288 | } 289 | 290 | /** 291 | * Lets you reload the static array from another file 292 | * 293 | * This is only useful for complex integrations in which a project needs to use 294 | * this class but then also needs to execute another project's autoloader in process, 295 | * and wants to ensure both projects have access to their version of installed.php. 296 | * 297 | * A typical case would be PHPUnit, where it would need to make sure it reads all 298 | * the data it needs from this class, then call reload() with 299 | * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure 300 | * the project in which it runs can then also use this class safely, without 301 | * interference between PHPUnit's dependencies and the project's dependencies. 302 | * 303 | * @param array[] $data A vendor/composer/installed.php data set 304 | * @return void 305 | * 306 | * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data 307 | */ 308 | public static function reload($data) 309 | { 310 | self::$installed = $data; 311 | self::$installedByVendor = array(); 312 | } 313 | 314 | /** 315 | * @return array[] 316 | * @psalm-return list}> 317 | */ 318 | private static function getInstalled() 319 | { 320 | if (null === self::$canGetVendors) { 321 | self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); 322 | } 323 | 324 | $installed = array(); 325 | 326 | if (self::$canGetVendors) { 327 | foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { 328 | if (isset(self::$installedByVendor[$vendorDir])) { 329 | $installed[] = self::$installedByVendor[$vendorDir]; 330 | } elseif (is_file($vendorDir.'/composer/installed.php')) { 331 | /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ 332 | $required = require $vendorDir.'/composer/installed.php'; 333 | $installed[] = self::$installedByVendor[$vendorDir] = $required; 334 | if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { 335 | self::$installed = $installed[count($installed) - 1]; 336 | } 337 | } 338 | } 339 | } 340 | 341 | if (null === self::$installed) { 342 | // only require the installed.php file if this file is loaded from its dumped location, 343 | // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 344 | if (substr(__DIR__, -8, 1) !== 'C') { 345 | /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ 346 | $required = require __DIR__ . '/installed.php'; 347 | self::$installed = $required; 348 | } else { 349 | self::$installed = array(); 350 | } 351 | } 352 | 353 | if (self::$installed !== array()) { 354 | $installed[] = self::$installed; 355 | } 356 | 357 | return $installed; 358 | } 359 | } 360 | -------------------------------------------------------------------------------- /vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /vendor/composer/autoload_classmap.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/composer/InstalledVersions.php', 10 | 'Robinncode\\DbCraft\\Commands\\GetMigrationCommand' => $baseDir . '/src/Commands/GetMigrationCommand.php', 11 | 'Robinncode\\DbCraft\\Commands\\GetSeedCommand' => $baseDir . '/src/Commands/GetSeedCommand.php', 12 | 'Robinncode\\DbCraft\\Config' => $baseDir . '/src/Config.php', 13 | 'Robinncode\\DbCraft\\Libraries\\FileHandler' => $baseDir . '/src/Libraries/FileHandler.php', 14 | 'Robinncode\\DbCraft\\Libraries\\MigrationGenerator' => $baseDir . '/src/Libraries/MigrationGenerator.php', 15 | 'Robinncode\\DbCraft\\Libraries\\SeederGenerator' => $baseDir . '/src/Libraries/SeederGenerator.php', 16 | ); 17 | -------------------------------------------------------------------------------- /vendor/composer/autoload_namespaces.php: -------------------------------------------------------------------------------- 1 | array($baseDir . '/src'), 10 | 'Database\\Seeders\\' => array($vendorDir . '/laravel/pint/database/seeders'), 11 | 'Database\\Factories\\' => array($vendorDir . '/laravel/pint/database/factories'), 12 | 'App\\' => array($vendorDir . '/laravel/pint/app'), 13 | ); 14 | -------------------------------------------------------------------------------- /vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | register(true); 35 | 36 | $filesToLoad = \Composer\Autoload\ComposerStaticInite82b8245945cb29db431af3b6cd28e27::$files; 37 | $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { 38 | if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { 39 | $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; 40 | 41 | require $file; 42 | } 43 | }, null, null); 44 | foreach ($filesToLoad as $fileIdentifier => $file) { 45 | $requireFile($fileIdentifier, $file); 46 | } 47 | 48 | return $loader; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/..' . '/phpstan/phpstan/bootstrap.php', 11 | '38143a9afc50997d55e4815db8489d1c' => __DIR__ . '/..' . '/rector/rector/bootstrap.php', 12 | ); 13 | 14 | public static $prefixLengthsPsr4 = array ( 15 | 'R' => 16 | array ( 17 | 'Robinncode\\DbCraft\\' => 19, 18 | ), 19 | 'D' => 20 | array ( 21 | 'Database\\Seeders\\' => 17, 22 | 'Database\\Factories\\' => 19, 23 | ), 24 | 'A' => 25 | array ( 26 | 'App\\' => 4, 27 | ), 28 | ); 29 | 30 | public static $prefixDirsPsr4 = array ( 31 | 'Robinncode\\DbCraft\\' => 32 | array ( 33 | 0 => __DIR__ . '/../..' . '/src', 34 | ), 35 | 'Database\\Seeders\\' => 36 | array ( 37 | 0 => __DIR__ . '/..' . '/laravel/pint/database/seeders', 38 | ), 39 | 'Database\\Factories\\' => 40 | array ( 41 | 0 => __DIR__ . '/..' . '/laravel/pint/database/factories', 42 | ), 43 | 'App\\' => 44 | array ( 45 | 0 => __DIR__ . '/..' . '/laravel/pint/app', 46 | ), 47 | ); 48 | 49 | public static $classMap = array ( 50 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 51 | 'Robinncode\\DbCraft\\Commands\\GetMigrationCommand' => __DIR__ . '/../..' . '/src/Commands/GetMigrationCommand.php', 52 | 'Robinncode\\DbCraft\\Commands\\GetSeedCommand' => __DIR__ . '/../..' . '/src/Commands/GetSeedCommand.php', 53 | 'Robinncode\\DbCraft\\Config' => __DIR__ . '/../..' . '/src/Config.php', 54 | 'Robinncode\\DbCraft\\Libraries\\FileHandler' => __DIR__ . '/../..' . '/src/Libraries/FileHandler.php', 55 | 'Robinncode\\DbCraft\\Libraries\\MigrationGenerator' => __DIR__ . '/../..' . '/src/Libraries/MigrationGenerator.php', 56 | 'Robinncode\\DbCraft\\Libraries\\SeederGenerator' => __DIR__ . '/../..' . '/src/Libraries/SeederGenerator.php', 57 | ); 58 | 59 | public static function getInitializer(ClassLoader $loader) 60 | { 61 | return \Closure::bind(function () use ($loader) { 62 | $loader->prefixLengthsPsr4 = ComposerStaticInite82b8245945cb29db431af3b6cd28e27::$prefixLengthsPsr4; 63 | $loader->prefixDirsPsr4 = ComposerStaticInite82b8245945cb29db431af3b6cd28e27::$prefixDirsPsr4; 64 | $loader->classMap = ComposerStaticInite82b8245945cb29db431af3b6cd28e27::$classMap; 65 | 66 | }, null, ClassLoader::class); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /vendor/composer/installed.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "laravel/pint", 5 | "version": "v1.22.1", 6 | "version_normalized": "1.22.1.0", 7 | "source": { 8 | "type": "git", 9 | "url": "https://github.com/laravel/pint.git", 10 | "reference": "941d1927c5ca420c22710e98420287169c7bcaf7" 11 | }, 12 | "dist": { 13 | "type": "zip", 14 | "url": "https://api.github.com/repos/laravel/pint/zipball/941d1927c5ca420c22710e98420287169c7bcaf7", 15 | "reference": "941d1927c5ca420c22710e98420287169c7bcaf7", 16 | "shasum": "" 17 | }, 18 | "require": { 19 | "ext-json": "*", 20 | "ext-mbstring": "*", 21 | "ext-tokenizer": "*", 22 | "ext-xml": "*", 23 | "php": "^8.2.0" 24 | }, 25 | "require-dev": { 26 | "friendsofphp/php-cs-fixer": "^3.75.0", 27 | "illuminate/view": "^11.44.7", 28 | "larastan/larastan": "^3.4.0", 29 | "laravel-zero/framework": "^11.36.1", 30 | "mockery/mockery": "^1.6.12", 31 | "nunomaduro/termwind": "^2.3.1", 32 | "pestphp/pest": "^2.36.0" 33 | }, 34 | "time": "2025-05-08T08:38:12+00:00", 35 | "bin": [ 36 | "builds/pint" 37 | ], 38 | "type": "project", 39 | "installation-source": "dist", 40 | "autoload": { 41 | "psr-4": { 42 | "App\\": "app/", 43 | "Database\\Seeders\\": "database/seeders/", 44 | "Database\\Factories\\": "database/factories/" 45 | } 46 | }, 47 | "notification-url": "https://packagist.org/downloads/", 48 | "license": [ 49 | "MIT" 50 | ], 51 | "authors": [ 52 | { 53 | "name": "Nuno Maduro", 54 | "email": "enunomaduro@gmail.com" 55 | } 56 | ], 57 | "description": "An opinionated code formatter for PHP.", 58 | "homepage": "https://laravel.com", 59 | "keywords": [ 60 | "format", 61 | "formatter", 62 | "lint", 63 | "linter", 64 | "php" 65 | ], 66 | "support": { 67 | "issues": "https://github.com/laravel/pint/issues", 68 | "source": "https://github.com/laravel/pint" 69 | }, 70 | "install-path": "../laravel/pint" 71 | }, 72 | { 73 | "name": "phpstan/phpstan", 74 | "version": "2.1.17", 75 | "version_normalized": "2.1.17.0", 76 | "source": { 77 | "type": "git", 78 | "url": "https://github.com/phpstan/phpstan.git", 79 | "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053" 80 | }, 81 | "dist": { 82 | "type": "zip", 83 | "url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053", 84 | "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053", 85 | "shasum": "" 86 | }, 87 | "require": { 88 | "php": "^7.4|^8.0" 89 | }, 90 | "conflict": { 91 | "phpstan/phpstan-shim": "*" 92 | }, 93 | "time": "2025-05-21T20:55:28+00:00", 94 | "bin": [ 95 | "phpstan", 96 | "phpstan.phar" 97 | ], 98 | "type": "library", 99 | "installation-source": "dist", 100 | "autoload": { 101 | "files": [ 102 | "bootstrap.php" 103 | ] 104 | }, 105 | "notification-url": "https://packagist.org/downloads/", 106 | "license": [ 107 | "MIT" 108 | ], 109 | "description": "PHPStan - PHP Static Analysis Tool", 110 | "keywords": [ 111 | "dev", 112 | "static analysis" 113 | ], 114 | "support": { 115 | "docs": "https://phpstan.org/user-guide/getting-started", 116 | "forum": "https://github.com/phpstan/phpstan/discussions", 117 | "issues": "https://github.com/phpstan/phpstan/issues", 118 | "security": "https://github.com/phpstan/phpstan/security/policy", 119 | "source": "https://github.com/phpstan/phpstan-src" 120 | }, 121 | "funding": [ 122 | { 123 | "url": "https://github.com/ondrejmirtes", 124 | "type": "github" 125 | }, 126 | { 127 | "url": "https://github.com/phpstan", 128 | "type": "github" 129 | } 130 | ], 131 | "install-path": "../phpstan/phpstan" 132 | }, 133 | { 134 | "name": "rector/rector", 135 | "version": "2.0.16", 136 | "version_normalized": "2.0.16.0", 137 | "source": { 138 | "type": "git", 139 | "url": "https://github.com/rectorphp/rector.git", 140 | "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2" 141 | }, 142 | "dist": { 143 | "type": "zip", 144 | "url": "https://api.github.com/repos/rectorphp/rector/zipball/f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", 145 | "reference": "f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2", 146 | "shasum": "" 147 | }, 148 | "require": { 149 | "php": "^7.4|^8.0", 150 | "phpstan/phpstan": "^2.1.14" 151 | }, 152 | "conflict": { 153 | "rector/rector-doctrine": "*", 154 | "rector/rector-downgrade-php": "*", 155 | "rector/rector-phpunit": "*", 156 | "rector/rector-symfony": "*" 157 | }, 158 | "suggest": { 159 | "ext-dom": "To manipulate phpunit.xml via the custom-rule command" 160 | }, 161 | "time": "2025-05-12T16:37:16+00:00", 162 | "bin": [ 163 | "bin/rector" 164 | ], 165 | "type": "library", 166 | "installation-source": "dist", 167 | "autoload": { 168 | "files": [ 169 | "bootstrap.php" 170 | ] 171 | }, 172 | "notification-url": "https://packagist.org/downloads/", 173 | "license": [ 174 | "MIT" 175 | ], 176 | "description": "Instant Upgrade and Automated Refactoring of any PHP code", 177 | "keywords": [ 178 | "automation", 179 | "dev", 180 | "migration", 181 | "refactoring" 182 | ], 183 | "support": { 184 | "issues": "https://github.com/rectorphp/rector/issues", 185 | "source": "https://github.com/rectorphp/rector/tree/2.0.16" 186 | }, 187 | "funding": [ 188 | { 189 | "url": "https://github.com/tomasvotruba", 190 | "type": "github" 191 | } 192 | ], 193 | "install-path": "../rector/rector" 194 | } 195 | ], 196 | "dev": true, 197 | "dev-package-names": [ 198 | "laravel/pint", 199 | "phpstan/phpstan", 200 | "rector/rector" 201 | ] 202 | } 203 | -------------------------------------------------------------------------------- /vendor/composer/installed.php: -------------------------------------------------------------------------------- 1 | array( 3 | 'name' => 'robinncode/db_craft', 4 | 'pretty_version' => '1.2.1', 5 | 'version' => '1.2.1.0', 6 | 'reference' => null, 7 | 'type' => 'library', 8 | 'install_path' => __DIR__ . '/../../', 9 | 'aliases' => array(), 10 | 'dev' => true, 11 | ), 12 | 'versions' => array( 13 | 'laravel/pint' => array( 14 | 'pretty_version' => 'v1.22.1', 15 | 'version' => '1.22.1.0', 16 | 'reference' => '941d1927c5ca420c22710e98420287169c7bcaf7', 17 | 'type' => 'project', 18 | 'install_path' => __DIR__ . '/../laravel/pint', 19 | 'aliases' => array(), 20 | 'dev_requirement' => true, 21 | ), 22 | 'phpstan/phpstan' => array( 23 | 'pretty_version' => '2.1.17', 24 | 'version' => '2.1.17.0', 25 | 'reference' => '89b5ef665716fa2a52ecd2633f21007a6a349053', 26 | 'type' => 'library', 27 | 'install_path' => __DIR__ . '/../phpstan/phpstan', 28 | 'aliases' => array(), 29 | 'dev_requirement' => true, 30 | ), 31 | 'rector/rector' => array( 32 | 'pretty_version' => '2.0.16', 33 | 'version' => '2.0.16.0', 34 | 'reference' => 'f1366d1f8c7490541c8f7af6e5c7cef7cca1b5a2', 35 | 'type' => 'library', 36 | 'install_path' => __DIR__ . '/../rector/rector', 37 | 'aliases' => array(), 38 | 'dev_requirement' => true, 39 | ), 40 | 'robinncode/db_craft' => array( 41 | 'pretty_version' => '1.2.1', 42 | 'version' => '1.2.1.0', 43 | 'reference' => null, 44 | 'type' => 'library', 45 | 'install_path' => __DIR__ . '/../../', 46 | 'aliases' => array(), 47 | 'dev_requirement' => false, 48 | ), 49 | ), 50 | ); 51 | -------------------------------------------------------------------------------- /vendor/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 70200)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | --------------------------------------------------------------------------------