/** * * * @param int $argc * @param array $argv * * @return void * * @throws \InvalidArgumentException * @throws \RuntimeException if this function is called in a script that is not run at the command line. */ function createController($argc, array $argv) { ////////////////////////////////////////// // START: Environment and Args Validation ////////////////////////////////////////// if (!isPhpRunningInCliMode()) { $err_msg = '`' . __FUNCTION__ . '($argc, array $argv)` should only be called from within' . ' php scripts that should be run via the command line!!!' . PHP_EOL; throw new \RuntimeException($err_msg); } if (is_string($argc) && is_numeric($argc)) { $argc = (int) $argc; } if (!is_int($argc)) { $err_msg = 'The expected value for the first argument to ' . '`' . __FUNCTION__ . '($argc, array $argv)` should be an int.' . ' `' . ucfirst(gettype($argc)) . '` with the value below was supplied:' . PHP_EOL . var_export($argc, true) . PHP_EOL . PHP_EOL . 'Good bye!!!'; throw new \InvalidArgumentException($err_msg); } if (count($argv) < 1) { $err_msg = 'The expected value for the second argument to ' . '`' . __FUNCTION__ . '($argc, array $argv)` should be an array with at least one element. Empty Array was supplied.' . 'This second argument is expected to be the $argv array passed by PHP to the script calling this function.'; throw new \InvalidArgumentException($err_msg); } ////////////////////////////////////////// // END: Environment and Args Validation ////////////////////////////////////////// ////////////////////////////////// ///START: COMMAND PROCESSING ////////////////////////////////// $ds = DIRECTORY_SEPARATOR; if ($argc < 5 || in_array('--help', $argv) || in_array('-help', $argv) || in_array('-h', $argv) || in_array('-?', $argv)) { displayHelp(basename($argv[0])); } else { if ($argc === 5 && (in_array('--controller-name', $argv) || in_array('-c', $argv)) && (in_array('--path-to-src-folder', $argv) || in_array('-p', $argv)) || $argc >= 7 && (in_array('--controller-name', $argv) || in_array('-c', $argv)) && (in_array('--path-to-src-folder', $argv) || in_array('-p', $argv)) && (in_array('--extends-controller', $argv) || in_array('-e', $argv))) { $templates_dir = dirname(__DIR__) . $ds . 'templates' . $ds; $controller_name = getOptVal('--controller-name', $argv); if ($controller_name === false) { $controller_name = getOptVal('-c', $argv); } $studly_controller_name = \Slim3MvcTools\Functions\Str\dashesToStudly(\Slim3MvcTools\Functions\Str\underToStudly($controller_name)); $dashed_controller_name = \Slim3MvcTools\Functions\Str\toDashes($controller_name); if (!isValidClassName($studly_controller_name)) { printError("Invalid controller class name `{$controller_name}` supplied. Goodbye!!"); return; } $src_folder_path = getOptVal('--path-to-src-folder', $argv); if ($src_folder_path === false) { $src_folder_path = getOptVal('-p', $argv); } $src_folder_path = normalizeFolderPathForOs($src_folder_path); if (!file_exists($src_folder_path) || !is_dir($src_folder_path)) { printError("The src folder path `{$src_folder_path}` supplied is a non-existent directory. Goodbye!!"); return; } //////////////////////////////////////////////////////////////////////////// $default_controller_2_extend = '\\Slim3MvcTools\\Controllers\\BaseController'; $controller_2_extend = getOptVal('--extends-controller', $argv); if ($controller_2_extend === false) { $controller_2_extend = getOptVal('-e', $argv); if ($controller_2_extend !== false) { if (!isValidExtendsClassName($controller_2_extend)) { printError("Invalid controller class name `{$controller_2_extend}` for extension supplied. Goodbye!!"); return; } } else { //use default controller class to be extended $controller_2_extend = $default_controller_2_extend; } } else { if (!isValidExtendsClassName($controller_2_extend)) { printError("Invalid controller class name `{$controller_2_extend}` for extension supplied. Goodbye!!"); return; } } //////////////////////////////////////////////////////////////////////////// $namepace_declaration = ''; //omit namespace declaration by default $namepace_4_controller = getOptVal('--namespace-4-controller', $argv); if ($namepace_4_controller === false) { $namepace_4_controller = getOptVal('-n', $argv); if ($namepace_4_controller !== false) { if (!isValidNamespaceName($namepace_4_controller)) { printError("Invalid namespace `{$namepace_4_controller}` supplied. Goodbye!!"); return; } //validation passed $namepace_declaration = "namespace {$namepace_4_controller};"; } else { $namepace_4_controller = ''; } } else { if (!isValidNamespaceName($namepace_4_controller)) { printError("Invalid namespace `{$namepace_4_controller}` supplied. Goodbye!!"); return; } //validation passed $namepace_declaration = "namespace {$namepace_4_controller};"; } //read template controller and substitute __TEMPLTATE_CONTROLLER__ with given controller name \Slim3MvcTools\Functions\Str\underToStudly(dashesToStudly($controller_name_from_cli)) //substitute {{TEMPLTATE_CONTROLLER_VIEW_FOLDER}} with the view folder name \Slim3MvcTools\Functions\Str\toDashes($controller_name_from_cli) //write processed controller file to S3MVC_APP_ROOT_PATH.$ds.'src'.$ds.'controllers'.$ds //make the dir S3MVC_APP_ROOT_PATH.$ds.'src'.$ds.'views'.$ds.\Slim3MvcTools\Functions\Str\toDashes($controller_name_from_cli) //read template controller index view and substitute __TEMPLTATE_CONTROLLER__ with given controller name \Slim3MvcTools\Functions\Str\underToStudly(dashesToStudly($controller_name_from_cli)) //write processed controller file to S3MVC_APP_ROOT_PATH.$ds.'src'.$ds.'views'.$ds.\Slim3MvcTools\Functions\Str\toDashes($controller_name_from_cli) $template_controller_file = $templates_dir . 'controller-class-template.php.tpl'; $dest_controller_class_file_folder = $src_folder_path . 'controllers' . $ds; $dest_controller_class_file = $dest_controller_class_file_folder . "{$studly_controller_name}.php"; if (!file_exists($dest_controller_class_file_folder) && !mkdir($dest_controller_class_file_folder, 0775, true)) { printError("Failed to create `{$dest_controller_class_file_folder}`; the folder supposed to contain the controller named `{$studly_controller_name}`. Goodbye!!"); return; } $template_view_file = $templates_dir . 'index-view-template.php'; $dest_view_file_folder = $src_folder_path . 'views' . $ds . "{$dashed_controller_name}{$ds}"; $dest_view_file = "{$dest_view_file_folder}index.php"; if (!file_exists($dest_view_file_folder) && !mkdir($dest_view_file_folder, 0775, true)) { printError("Failed to create `{$dest_view_file_folder}`; the folder supposed to contain views for the controller named `{$studly_controller_name}`. Goodbye!!"); return; } if (file_exists($dest_controller_class_file)) { printError("Controller class `{$studly_controller_name}` already exists in `{$dest_controller_class_file}`. Goodbye!!"); return; } if (file_exists($dest_view_file)) { printError("View file `{$dest_view_file}` already exists for Controller class `{$studly_controller_name}`. Goodbye!!"); return; } printInfo("Creating Controller Class `{$studly_controller_name}` in `{$dest_controller_class_file}` ...."); //////////////////////////////////////////////////////////////////////////// $replaces = ['__CONTROLLER_2_EXTEND__' => $controller_2_extend, '__TEMPLTATE_CONTROLLER__' => $studly_controller_name, 'namespace __NAMESPACE_2_REPLACE__;' => $namepace_declaration, '{{TEMPLTATE_CONTROLLER_VIEW_FOLDER}}' => $dashed_controller_name, "'__login_success_redirect_controller__'" => "'{$dashed_controller_name}'"]; if (processTemplateFile($template_controller_file, $dest_controller_class_file, $replaces) === false) { printError("Failed transforming template controller `{$template_controller_file}` to `{$dest_controller_class_file}`. Goodbye!!"); } else { printInfo("Successfully created `{$dest_controller_class_file}` ...." . PHP_EOL); } printInfo("Creating index view for `{$studly_controller_name}::actionIndex()` in `{$dest_view_file}` ...."); $replaces['__TEMPLTATE_CONTROLLER__'] = rtrim($namepace_4_controller, '\\') . '\\' . $studly_controller_name; if (processTemplateFile($template_view_file, $dest_view_file, $replaces) === false) { printError("Failed creating index view for `{$studly_controller_name}::actionIndex()` in `{$dest_view_file}`."); printInfo("Deleting `{$dest_controller_class_file}` ...."); if (!unlink($dest_controller_class_file)) { printInfo("Failed to delete `{$dest_controller_class_file}`. Please delete it manually. Goodbye!!"); } else { printInfo("Goodbye!!"); } return; } else { printInfo("Successfully created `{$dest_view_file}` ...." . PHP_EOL); } printInfo("All done!!"); if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { //test if composer is avaliable only if server OS on which this script is being run //is not windows if (isCommandAvailableOnOs('composer')) { passthru('composer dumpautoload'); } else { printInfo("Remember to run `composer dumpautoload` so that composer can pick up the newly created controller class `{$studly_controller_name}` in `{$dest_controller_class_file}`."); } } else { printInfo("Remember to run `composer dumpautoload` so that composer can pick up the newly created controller class `{$studly_controller_name}` in `{$dest_controller_class_file}`."); } //we are done } else { displayHelp(basename($argv[0])); } } ////////////////////////////////// ///END: COMMAND PROCESSING ////////////////////////////////// }
public function testThatIsValidClassNameWorksAsExpected() { $this->assertEquals(true, isValidClassName('SomeClass')); $this->assertEquals(true, isValidClassName('Some1Class')); $this->assertEquals(true, isValidClassName('SomeClass1')); $this->assertEquals(true, isValidClassName('Some_Class')); $this->assertEquals(true, isValidClassName('Some1_Class')); $this->assertEquals(true, isValidClassName('Some_1Class')); $this->assertEquals(true, isValidClassName('Some_Class1')); $this->assertEquals(false, isValidClassName('1SomeClass')); $this->assertEquals(false, isValidClassName('1Some_Class')); $this->assertEquals(false, isValidClassName('Some\\Class\\')); $this->assertEquals(false, isValidClassName('Some-Class')); $this->assertEquals(false, isValidClassName('-SomeClass')); $this->assertEquals(false, isValidClassName('SomeClass-')); /////////////////////////////////////////// //Test \InvalidArgumentException messages /////////////////////////////////////////// $args = array('Integer' => 111, 'Double' => 111.1234, 'Boolean' => true, 'Array' => [], 'Object' => new stdclass(), 'NULL' => null, 'Resource' => tmpfile()); $function_sig_in_err_msg = 'isValidClassName($class_name)'; foreach ($args as $arg_type => $arg) { try { isValidClassName($arg); $msg = '\\InvalidArgumentException should have been thrown in `' . __FILE__ . '`' . ' on line ' . (__LINE__ - 1); static::fail($msg); } catch (\InvalidArgumentException $e) { $msg_substr = "The expected value for the first argument to `{$function_sig_in_err_msg}`" . " should be a String value. `{$arg_type}` with the value below was supplied:"; $this->assertContains($msg_substr, $e->getMessage()); } } // test the callable type try { isValidClassName(function () { echo 'blah'; }); $msg = '\\InvalidArgumentException should have been thrown in `' . __FILE__ . '`' . ' on line ' . (__LINE__ - 1); static::fail($msg); } catch (\InvalidArgumentException $e) { $msg_substr = "The expected value for the first argument to `{$function_sig_in_err_msg}`" . " should be a String value. `Object` with the value below was supplied:"; $this->assertContains($msg_substr, $e->getMessage()); } }