/** * Clone the Codeigniter repository * * @access public * @param string $repo The git repository url * @param string $location The location where the git repo will be cloned * @param string $tag_or_branch A tag or branch in the git repo to be checked out * @return boolean TRUE/FALSE depending on wheter the repo was cloned or not * @author Aziz Light */ public static function git_clone($repo, $location, $tag_or_branch = "") { if (php_uname('s') === "Windows NT") { $command = 'git clone ' . $repo . ' "' . $location . '" > NUL && echo CLONED || echo ERROR'; } else { $command = 'git clone ' . $repo . ' ' . $location . ' > /dev/null 2>&1 && echo "CLONED" || echo "ERROR"'; } exec($command, $output); if ($output[0] === "CLONED") { if (!empty($tag_or_branch)) { unset($command); if (php_uname('s') === "Windows NT") { $command = 'git checkout ' . $tag_or_branch . ' > NUL && echo CHECKEDOUT || echo ERROR'; } else { $command = 'git checkout ' . $tag_or_branch . ' > /dev/null 2>&1 && echo "CHECKEDOUT" || echo "ERROR"'; } exec($command, $output); if ($output[0] === "ERROR") { ApplicationHelpers::delete_dir($location); return FALSE; } } // delete the .git directory ApplicationHelpers::delete_dir($location . DIRECTORY_SEPARATOR . '.git'); return TRUE; } else { if ($output[0] == "ERROR") { return FALSE; } } }
/** * The brains of the command * * @access public * @return void * @author Aziz Light **/ public function run() { $codeigniter_sample_project_path = BASE_PATH . DIRECTORY_SEPARATOR . 'codeigniter'; if (is_dir($codeigniter_sample_project_path)) { ApplicationHelpers::delete_dir($codeigniter_sample_project_path); } fwrite(STDOUT, 'Bootstrapping Fire...' . PHP_EOL); if (GithubHelpers::git_clone($this->get_github_repo_link(), $codeigniter_sample_project_path) === FALSE) { throw new RuntimeException("Unable to clone the sample CodeIgniter project from Github"); } else { if (php_uname("s") === "Windows NT") { $message = "\tFire Bootstrapped" . PHP_EOL; } else { $message = "\t" . ApplicationHelpers::colorize('Fire', 'green') . ' Bootstrapped' . PHP_EOL; } fwrite(STDOUT, $message); } }
/** * Parse the args list retrieved from the command line * * @param array $args Argument list * @return array Parsed argument list * @access private * @author Aziz Light */ private static function parse($args) { $parsed_args = array(); // remove the script name from the commands list. array_shift($args); if (!empty($args) && in_array($args[0], self::$valid_tasks)) { $parsed_args['command'] = $args[0]; array_shift($args); } else { if (!empty($args)) { $args[0] = self::check_and_get_command_alias($args[0]); if (empty($args[0])) { throw new InvalidArgumentException("Invalid task", INVALID_TASK_EXCEPTION); } else { # FIXME: Try to remove the duplication here. # NOTE: This is a good case for a goto: :-{) $parsed_args['command'] = $args[0]; array_shift($args); } } else { throw new InvalidArgumentException("Invalid task", INVALID_TASK_EXCEPTION); } } if (!empty($args) && array_key_exists($parsed_args['command'], self::$valid_subjects) && in_array($args[0], self::$valid_subjects[$parsed_args['command']])) { $parsed_args['subject'] = $args[0]; array_shift($args); } else { if (self::has_subjects($parsed_args['command'])) { if ($parsed_args['command'] !== 'migrate' && (empty($args) || !in_array($args[0], self::$valid_subjects[$parsed_args['command']]))) { throw new InvalidArgumentException("Invalid subject", INVALID_SUBJECT_EXCEPTION); } } } // The bootstrap command is the only one that is called without any additional args if (self::has_a_name($parsed_args['command'])) { if (empty($args)) { throw new InvalidArgumentException("Missing name", MISSING_NAME_EXCEPTION); } $unparsed_name = array_shift($args); // NOTE: I have to use this $tmp variable in order to avoid getting a "Stict Standards" notice by php $tmp = explode(DIRECTORY_SEPARATOR, $unparsed_name); $parsed_args['name'] = array_pop($tmp); $parsed_args['subdirectories'] = join(DIRECTORY_SEPARATOR, $tmp); if (Inflector::is_plural($parsed_args['name']) && $parsed_args['command'] === 'generate' && in_array($parsed_args['subject'], array('model', 'scaffold'), TRUE)) { $message = 'Fire thinks that your model name is plural.' . PHP_EOL; $message .= 'If that\'s the case then you\'re probably doing it wrong...' . PHP_EOL; $message .= 'Read the section on generating models or scaffolds in' . PHP_EOL; $message .= 'the README for more info on the subject.' . PHP_EOL . PHP_EOL; fwrite(STDOUT, $message); } if ($parsed_args['command'] != 'new_project') { $parsed_args['filename'] = ApplicationHelpers::underscorify($parsed_args['name']) . ".php"; } } if (!empty($args)) { if ($parsed_args['command'] === 'generate') { if (in_array($parsed_args['subject'], array('model', 'migration', 'scaffold'))) { $parsed_args['extra'] = self::parse_table_columns($args); } else { $parsed_args['extra'] = $args; } } else { throw new InvalidArgumentException('Too many arguments'); } } return $parsed_args; }
/** * Create the Migrate controller that * will be used to migrate the database * * @access private * @return void * @author Aziz Light **/ private function create_migration_controller() { $controller = $this->location . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . $this->controller_name . '.php'; if (is_file($controller)) { throw new RuntimeException('The ' . $this->controller_name . ' controller aleardy exists!'); } else { $template_name = "migration_controller"; $args = array('class_name' => ApplicationHelpers::camelize($this->controller_name)); if ($this->run_from_web === FALSE) { $args['extra'] = ' $this->input->is_cli_request() or exit("Execute via command line: php index.php migrate");'; } else { $args['extra'] = PHP_EOL; } $template = new TemplateScanner($template_name, $args); $controller_contents = $template->parse(); if (!file_put_contents($controller, $controller_contents)) { throw new RuntimeException('Could not create migration controller...' . PHP_EOL); } return TRUE; } }
/** * Installs WebFire * * @access private * @return void * @author Aziz Light **/ private function install() { if ($this->is_webfire_installed()) { throw new RuntimeException('WebFire seems to be installed already!'); } if (!$this->create_directories()) { throw new RuntimeException('Unable to create WebFire directories'); } $application_folder = explode(DIRECTORY_SEPARATOR, $this->location); $application_folder = array_pop($application_folder); foreach ($this->files as $file) { $source = BASE_PATH . DIRECTORY_SEPARATOR . 'WebFire' . DIRECTORY_SEPARATOR . 'application' . DIRECTORY_SEPARATOR . $file; $destination = $this->location . DIRECTORY_SEPARATOR . $file; $relative_location = $application_folder . DIRECTORY_SEPARATOR . $file; $subject = ''; $message = ''; if (preg_match('/templates/', $file) === 1) { $subject = 'template'; } else { $subject = explode('/', $file); $subject = array_shift($subject); $subject = rtrim($subject, 's'); } if (copy($source, $destination)) { $message = "\tCreated {$subject}: "; if (php_uname("s") !== "Windows NT") { $message = ApplicationHelpers::colorize($message, 'green'); } $message .= $relative_location; } else { $message = "\tFailed to create {$subject}: "; if (php_uname("s") !== "Windows NT") { $message = ApplicationHelpers::colorize($message, 'red'); } $message .= $relative_location; } fwrite(STDOUT, $message . PHP_EOL); unset($source, $destination, $relative_location, $subject); } foreach ($this->assets as $asset) { $source = BASE_PATH . DIRECTORY_SEPARATOR . 'WebFire' . DIRECTORY_SEPARATOR . $asset; $location = explode(DIRECTORY_SEPARATOR, $this->location); array_pop($location); $location = join(DIRECTORY_SEPARATOR, $location); $destination = $location . DIRECTORY_SEPARATOR . $asset; $subject = ''; $message = ''; if (copy($source, $destination)) { $message = "\tCreated asset: "; if (php_uname("s") !== "Windows NT") { $message = ApplicationHelpers::colorize($message, 'green'); } $message .= $asset; } else { $message = "\tFailed to create asset: "; if (php_uname("s") !== "Windows NT") { $message = ApplicationHelpers::colorize($message, 'red'); } $message .= $asset; } fwrite(STDOUT, $message . PHP_EOL); unset($source, $location, $destination, $subject, $message); } }
/** * Parse the args list retrieved from the command line * * @param array $args Argument list * @return array Parsed argument list * @access private * @author Aziz Light */ private static function parse($args) { $parsed_args = array(); // remove the script name from the commands list. array_shift($args); if (!empty($args) && in_array($args[0], self::$valid_tasks)) { $parsed_args['command'] = $args[0]; array_shift($args); } else { if (!empty($args)) { $args[0] = self::check_and_get_command_alias($args[0]); if (empty($args[0])) { throw new InvalidArgumentException("Invalid task", INVALID_TASK_EXCEPTION); } else { # FIXME: Try to remove the duplication here. # NOTE: This is a good case for a goto: :-{) $parsed_args['command'] = $args[0]; array_shift($args); } } else { throw new InvalidArgumentException("Invalid task", INVALID_TASK_EXCEPTION); } } if (!empty($args) && array_key_exists($parsed_args['command'], self::$valid_subjects) && in_array($args[0], self::$valid_subjects[$parsed_args['command']])) { $parsed_args['subject'] = $args[0]; array_shift($args); } else { if (self::has_subjects($parsed_args['command'])) { if ($parsed_args['command'] !== 'migrate' && !in_array($args[0], self::$valid_subjects[$parsed_args['command']])) { throw new InvalidArgumentException("Invalid subject", INVALID_SUBJECT_EXCEPTION); } } } // The bootstrap command is the only one that is called without any additional args if (self::has_a_name($parsed_args['command'])) { if (empty($args)) { throw new InvalidArgumentException("Missing name", MISSING_NAME_EXCEPTION); } $unparsed_name = array_shift($args); // NOTE: I have to use this $tmp variable in order to avoid getting a "Stict Standards" notice by php $tmp = explode(DIRECTORY_SEPARATOR, $unparsed_name); $parsed_args['name'] = end($tmp); if ($parsed_args['command'] != 'new_project') { $parsed_args['filename'] = ApplicationHelpers::underscorify($unparsed_name) . ".php"; } } if (!empty($args)) { if ($parsed_args['command'] === 'generate') { if (in_array($parsed_args['subject'], array('model', 'migration'))) { $parsed_args['extra'] = self::parse_table_columns($args); } else { $parsed_args['extra'] = $args; } } else { throw new InvalidArgumentException('Too many arguments'); } } return $parsed_args; }
/** * Create a migration file * * @access private * @return void * @author Aziz Light **/ private function migration() { $location = $this->args['location'] . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR; if (!is_dir($location)) { mkdir($location); } $backtrace = debug_backtrace(); $calling_function = $backtrace[1]['function']; if ($calling_function === "model") { $args = array('class_name' => 'Migration_Add_' . Inflector::pluralize($this->args['name']), 'table_name' => Inflector::pluralize(strtolower($this->args['name'])), 'filename' => 'add_' . Inflector::pluralize(ApplicationHelpers::underscorify($this->args['name'])) . '.php', 'application_folder' => $this->args['application_folder'], 'parent_class' => $this->args['parent_migration'], 'extra' => $this->extra); $template_name = 'migration'; } else { $args = array('class_name' => 'Migration_' . $this->args['name'], 'table_name' => $this->get_table_name_out_of_migration_name(), 'filename' => $this->args['filename'], 'application_folder' => $this->args['application_folder'], 'parent_class' => $this->args['parent_migration'], 'extra' => $this->extra); $template_name = 'empty_migration'; } $template = new TemplateScanner($template_name, $args); $migration = $template->parse(); $migration_number = MigrationHelpers::get_migration_number($this->args['location']); $filename = $location . $migration_number . '_' . $args['filename']; $potential_duplicate_migration_filename = MigrationHelpers::decrement_migration_number($migration_number) . '_' . $args['filename']; $potential_duplicate_migration = $location . $potential_duplicate_migration_filename; $message = "\t"; if (file_exists($potential_duplicate_migration)) { $message .= 'Migration already exists : '; if (php_uname("s") !== "Windows NT") { $message = ApplicationHelpers::colorize($message, 'light_blue'); } $message .= $this->args['application_folder'] . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . $potential_duplicate_migration_filename; } else { if (file_put_contents($filename, $migration) && MigrationHelpers::add_migration_number_to_config_file($this->args['location'], $migration_number)) { $message .= 'Created Migration: '; if (php_uname("s") !== "Windows NT") { $message = ApplicationHelpers::colorize($message, 'green'); } $message .= $this->args['application_folder'] . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . $migration_number . '_' . $args['filename']; } else { $message .= 'Unable to create migration: '; if (php_uname("s") !== "Windows NT") { $message = ApplicationHelpers::colorize($message, 'red'); } $message .= $this->args['application_folder'] . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . $migration_number . '_' . $this->args['filename']; } } fwrite(STDOUT, $message . PHP_EOL); return; }
/** * The brains of the command * * @access public * @return void * @author Aziz Light **/ public function run() { if ($this->is_fire_bootstrapped() && $this->force_clone === FALSE) { if ($this->copy_codeigniter_sample_project($this->location, BASE_PATH . DIRECTORY_SEPARATOR . 'codeigniter')) { if (php_uname("s") !== "Windows NT") { $message = "\t" . ApplicationHelpers::colorize('CodeIgniter project created', 'green') . ' ' . $this->name . PHP_EOL; } else { $message = "\tCodeIgniter project created " . $this->name . PHP_EOL; } fwrite(STDOUT, $message); } else { throw new RuntimeException("Unable to create a new CodeIgniter Project"); } } else { fwrite(STDOUT, 'Cloning CodeIgniter...' . PHP_EOL); // First let's download CodeIgniter if (GithubHelpers::git_clone($this->repo, $this->location, $this->tag_or_branch) === FALSE) { throw new RuntimeException("Unable to clone CodeIgniter from Github"); } else { if (php_uname("s") !== "Windows NT") { $message = "\t" . ApplicationHelpers::colorize('CodeIgniter project created', 'green') . ' ' . $this->name . PHP_EOL; } else { $message = "\tCodeIgniter project created " . $this->name . PHP_EOL; } fwrite(STDOUT, $message); } } }