コード例 #1
0
/**
 * 
 * Creates a controller object or returns a Respond object containing a not found page.
 *  
 * The controller class must be \Slim3MvcTools\Controllers\BaseController or one of its sub-classes
 * 
 * @param \Interop\Container\ContainerInterface $container
 * @param string $controller_name_from_url
 * @param string $action_name_from_url
 * @param \Psr\Http\Message\ServerRequestInterface $request
 * @param \Psr\Http\Message\ResponseInterface $response
 * 
 * @return \Slim3MvcTools\Controllers\BaseController|\Psr\Http\Message\ResponseInterface 
 *          an instance of \Slim3MvcTools\Controllers\BaseController or its sub-class or
 *          an instance \Psr\Http\Message\ResponseInterface containing the not found 
 *          page.
 */
function s3MVC_CreateController(\Interop\Container\ContainerInterface $container, $controller_name_from_url, $action_name_from_url, \Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response)
{
    $has_logger = $container->has('logger') && $container->get('logger') instanceof \Psr\Log\LoggerInterface;
    $notFoundHandlerClass = '\\Slim3MvcTools\\Controllers\\HttpNotFoundController';
    // default handler
    $container->has('notFoundHandlerClass') && ($notFoundHandlerClass = $container->get('notFoundHandlerClass'));
    $has_logger && ($logger = $container->get('logger'));
    $controller_class_name = \Slim3MvcTools\Functions\Str\dashesToStudly($controller_name_from_url);
    $regex_4_valid_class_name = '/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/';
    if (!preg_match($regex_4_valid_class_name, preg_quote($controller_class_name, '/'))) {
        //A valid php class name starts with a letter or underscore, followed by
        //any number of letters, numbers, or underscores.
        //Make sure the controller name is a valid string usable as a class name
        //in php as defined in http://php.net/manual/en/language.oop5.basic.php
        //trigger 404 not found
        $has_logger && $logger->notice("`" . __FILE__ . "` on line " . __LINE__ . ": Bad controller name `{$controller_class_name}`");
        $notFoundHandler = new $notFoundHandlerClass($container, $controller_name_from_url, $action_name_from_url, $request, $response);
        $notFoundHandler->preAction();
        $action_result = $notFoundHandler->actionHttpNotFound();
        //invoke the not found handler
        $notFoundHandler->postAction();
        return $action_result;
    }
    if (!class_exists($controller_class_name)) {
        if ($container->has('namespaces_for_controllers')) {
            $namespaces_4_controllers = $container->get('namespaces_for_controllers');
            //try to prepend name space
            foreach ($namespaces_4_controllers as $namespace_4_controllers) {
                if (class_exists($namespace_4_controllers . $controller_class_name)) {
                    $controller_class_name = $namespace_4_controllers . $controller_class_name;
                    break;
                }
            }
        }
        //class still doesn't exist
        if (!class_exists($controller_class_name)) {
            //404 Not Found: Controller class not found.
            $has_logger && $logger->notice("`" . __FILE__ . "` on line " . __LINE__ . ": Class `{$controller_class_name}` does not exist.");
            $notFoundHandler = new $notFoundHandlerClass($container, $controller_name_from_url, $action_name_from_url, $request, $response);
            $notFoundHandler->preAction();
            $action_result = $notFoundHandler->actionHttpNotFound();
            //invoke the not found handler
            $notFoundHandler->postAction();
            return $action_result;
        }
    }
    //Create the controller object
    return new $controller_class_name($container, $controller_name_from_url, $action_name_from_url, $request, $response);
}
/**
 * 
 * 
 * @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
    //////////////////////////////////
}