Initial Commit
This commit is contained in:
6
app/lib/Yiinitializr/CHANGELOG
Normal file
6
app/lib/Yiinitializr/CHANGELOG
Normal file
@@ -0,0 +1,6 @@
|
||||
Yiinitializr Change Log
|
||||
========================
|
||||
|
||||
Thursday 28-March-2013
|
||||
----------------------------
|
||||
Initial release
|
||||
487
app/lib/Yiinitializr/Cli/Console.php
Normal file
487
app/lib/Yiinitializr/Cli/Console.php
Normal file
@@ -0,0 +1,487 @@
|
||||
<?php
|
||||
/**
|
||||
* Console class file.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @author Nofriandi Ramenta <nramenta@gmail.com>
|
||||
* @link http://www.ramirezcobos.com/
|
||||
* @link http://www.2amigos.us/
|
||||
* @link https://github.com/nramenta/clio
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*/
|
||||
namespace Yiinitializr\Cli;
|
||||
/**
|
||||
* Console provides a set of useful functions to work on the terminal
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @package Yiinitializr.Cli
|
||||
* @since 1.0
|
||||
*/
|
||||
class Console
|
||||
{
|
||||
/**
|
||||
* Text foreground colors.
|
||||
*/
|
||||
protected static $FGCOLOR = array(
|
||||
'black' => 30,
|
||||
'red' => 31,
|
||||
'green' => 32,
|
||||
'brown' => 33,
|
||||
'blue' => 34,
|
||||
'purple' => 35,
|
||||
'cyan' => 36,
|
||||
'grey' => 37,
|
||||
'yellow' => 33,
|
||||
);
|
||||
|
||||
/**
|
||||
* Text styling.
|
||||
*/
|
||||
protected static $STYLE = array(
|
||||
'normal' => 0,
|
||||
'bold' => 1,
|
||||
'light' => 1,
|
||||
'underscore' => 4,
|
||||
'underline' => 4,
|
||||
'blink' => 5,
|
||||
'inverse' => 6,
|
||||
'hidden' => 8,
|
||||
'concealed' => 8,
|
||||
);
|
||||
|
||||
/**
|
||||
* Text background color.
|
||||
*/
|
||||
protected static $BGCOLOR = array(
|
||||
'black' => 40,
|
||||
'red' => 41,
|
||||
'green' => 42,
|
||||
'brown' => 43,
|
||||
'yellow' => 43,
|
||||
'blue' => 44,
|
||||
'purple' => 45,
|
||||
'cyan' => 46,
|
||||
'grey' => 47,
|
||||
);
|
||||
|
||||
/**
|
||||
* Color specifier conversion table. Taken from PEAR's Console_Color.
|
||||
*/
|
||||
protected static $CONVERSIONS = array(
|
||||
'%y' => array('yellow', null, null),
|
||||
'%g' => array('green', null, null),
|
||||
'%b' => array('blue', null, null),
|
||||
'%r' => array('red', null, null),
|
||||
'%p' => array('purple', null, null),
|
||||
'%m' => array('purple', null, null),
|
||||
'%c' => array('cyan', null, null),
|
||||
'%w' => array('grey', null, null),
|
||||
'%k' => array('black', null, null),
|
||||
'%n' => array('reset', null, null),
|
||||
'%Y' => array('yellow', 'light', null),
|
||||
'%G' => array('green', 'light', null),
|
||||
'%B' => array('blue', 'light', null),
|
||||
'%R' => array('red', 'light', null),
|
||||
'%P' => array('purple', 'light', null),
|
||||
'%M' => array('purple', 'light', null),
|
||||
'%C' => array('cyan', 'light', null),
|
||||
'%W' => array('grey', 'light', null),
|
||||
'%K' => array('black', 'light', null),
|
||||
'%N' => array('reset', 'light', null),
|
||||
'%3' => array(null, null, 'yellow'),
|
||||
'%2' => array(null, null, 'green'),
|
||||
'%4' => array(null, null, 'blue'),
|
||||
'%1' => array(null, null, 'red'),
|
||||
'%5' => array(null, null, 'purple'),
|
||||
'%6' => array(null, null, 'cyan'),
|
||||
'%7' => array(null, null, 'grey'),
|
||||
'%0' => array(null, null, 'black'),
|
||||
'%F' => array(null, 'blink', null),
|
||||
'%U' => array(null, 'underline', null),
|
||||
'%8' => array(null, 'inverse', null),
|
||||
'%9' => array(null, 'bold', null),
|
||||
'%_' => array(null, 'bold', null),
|
||||
);
|
||||
|
||||
/**
|
||||
* Create ANSI-control codes for text foreground and background colors, and
|
||||
* styling.
|
||||
*
|
||||
* @param string $fgcolor Text foreground color
|
||||
* @param string $style Text style
|
||||
* @param string $bgcolor Text background color
|
||||
*
|
||||
* @return string ANSI-control code
|
||||
*/
|
||||
public static function color($fgcolor, $style, $bgcolor)
|
||||
{
|
||||
$code = array();
|
||||
if ($fgcolor == 'reset') {
|
||||
return "\033[0m";
|
||||
}
|
||||
if (isset(static::$FGCOLOR[$fgcolor])) {
|
||||
$code[] = static::$FGCOLOR[$fgcolor];
|
||||
}
|
||||
if (isset(static::$STYLE[$style])) {
|
||||
$code[] = static::$STYLE[$style];
|
||||
}
|
||||
if (isset(static::$BGCOLOR[$bgcolor])) {
|
||||
$code[] = static::$BGCOLOR[$bgcolor];
|
||||
}
|
||||
if (empty($code)) {
|
||||
$code[] = 0;
|
||||
}
|
||||
return "\033[" . implode(';', $code) . 'm';
|
||||
}
|
||||
|
||||
/**
|
||||
* aken from PEAR's Console_Color:
|
||||
*
|
||||
* Converts colorcodes in the format %y (for yellow) into ansi-control
|
||||
* codes. The conversion table is: ('bold' meaning 'light' on some
|
||||
* terminals). It's almost the same conversion table irssi uses.
|
||||
* <pre>
|
||||
* text text background
|
||||
* ------------------------------------------------
|
||||
* %k %K %0 black dark grey black
|
||||
* %r %R %1 red bold red red
|
||||
* %g %G %2 green bold green green
|
||||
* %y %Y %3 yellow bold yellow yellow
|
||||
* %b %B %4 blue bold blue blue
|
||||
* %m %M %5 magenta bold magenta magenta
|
||||
* %p %P magenta (think: purple)
|
||||
* %c %C %6 cyan bold cyan cyan
|
||||
* %w %W %7 white bold white white
|
||||
*
|
||||
* %F Blinking, Flashing
|
||||
* %U Underline
|
||||
* %8 Reverse
|
||||
* %_,%9 Bold
|
||||
*
|
||||
* %n Resets the color
|
||||
* %% A single %
|
||||
* </pre>
|
||||
* First param is the string to convert, second is an optional flag if
|
||||
* colors should be used. It defaults to true, if set to false, the
|
||||
* colorcodes will just be removed (And %% will be transformed into %)
|
||||
*
|
||||
* @param $text
|
||||
* @param bool $color
|
||||
* @return mixed
|
||||
*/
|
||||
public static function colorize($text, $color = true)
|
||||
{
|
||||
$text = str_replace('%%', '% ', $text);
|
||||
foreach (static::$CONVERSIONS as $key => $value) {
|
||||
list($fgcolor, $style, $bgcolor) = $value;
|
||||
$text = str_replace(
|
||||
$key,
|
||||
$color ? static::color($fgcolor, $style, $bgcolor) : '',
|
||||
$text
|
||||
);
|
||||
}
|
||||
return str_replace('% ', '%', $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips a string from color specifiers.
|
||||
*
|
||||
* @param string $text String to strip
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function decolorize($text)
|
||||
{
|
||||
return static::colorize($text, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips a string of ansi-control codes.
|
||||
*
|
||||
* @param string $text String to strip
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function strip($text)
|
||||
{
|
||||
return preg_replace('/\033\[(\d+)(;\d+)*m/', '', $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets input from STDIN and returns a string right-trimmed for EOLs.
|
||||
*
|
||||
* @param bool $raw If set to true, returns the raw string without trimming
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function stdin($raw = false)
|
||||
{
|
||||
return $raw ? fgets(STDIN) : rtrim(fgets(STDIN), PHP_EOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints text to STDOUT.
|
||||
*
|
||||
* @param string $text
|
||||
* @param bool $raw
|
||||
*
|
||||
* @return int|false Number of bytes printed or false on error
|
||||
*/
|
||||
public static function stdout($text, $raw = false)
|
||||
{
|
||||
if ($raw) {
|
||||
return fwrite(STDOUT, $text);
|
||||
} elseif (extension_loaded('posix') && posix_isatty(STDOUT)) {
|
||||
return fwrite(STDOUT, static::colorize($text));
|
||||
} else {
|
||||
return fwrite(STDOUT, static::decolorize($text));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints text to STDERR.
|
||||
*
|
||||
* @param string $text
|
||||
* @param bool $raw
|
||||
*
|
||||
* @return int|false Number of bytes printed or false on error
|
||||
*/
|
||||
public static function stderr($text, $raw = false)
|
||||
{
|
||||
if ($raw) {
|
||||
return fwrite(STDERR, $text);
|
||||
} elseif (extension_loaded('posix') && posix_isatty(STDERR)) {
|
||||
return fwrite(STDERR, static::colorize($text));
|
||||
} else {
|
||||
return fwrite(STDERR, static::decolorize($text));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints text to STDERR appended with a PHP_EOL.
|
||||
*
|
||||
* @param string $text
|
||||
* @param bool $raw
|
||||
*
|
||||
* @return int|false Number of bytes printed or false on error
|
||||
*/
|
||||
public static function error($text = null, $raw = false)
|
||||
{
|
||||
return static::stderr($text . PHP_EOL, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the user for input. Ends when the user types a PHP_EOL. Optionally
|
||||
* provide a prompt.
|
||||
*
|
||||
* @param string $prompt String prompt (optional)
|
||||
*
|
||||
* @return string User input
|
||||
*/
|
||||
public static function input($prompt = null)
|
||||
{
|
||||
if (isset($prompt)) {
|
||||
static::stdout($prompt);
|
||||
}
|
||||
return static::stdin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints text to STDOUT appended with a PHP_EOL.
|
||||
*
|
||||
* @param string $text
|
||||
* @param bool $raw
|
||||
*
|
||||
* @return int|false Number of bytes printed or false on error
|
||||
*/
|
||||
public static function output($text = null, $raw = false)
|
||||
{
|
||||
return static::stdout($text . PHP_EOL, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompts the user for input
|
||||
*
|
||||
* @param string $text Prompt string
|
||||
* @param array $options Set of options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function prompt($text, $options = array())
|
||||
{
|
||||
$options = $options + array(
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'pattern' => null,
|
||||
'validator' => null,
|
||||
'error' => 'Input unacceptable.',
|
||||
);
|
||||
|
||||
top:
|
||||
if ($options['default']) {
|
||||
$input = static::input("$text [" . $options['default'] . ']: ');
|
||||
} else {
|
||||
$input = static::input("$text: ");
|
||||
}
|
||||
|
||||
if (!strlen($input)) {
|
||||
if (isset($options['default'])) {
|
||||
$input = $options['default'];
|
||||
} elseif ($options['required']) {
|
||||
static::output($options['error']);
|
||||
goto top;
|
||||
}
|
||||
} elseif ($options['pattern'] && !preg_match($options['pattern'], $input)) {
|
||||
static::output($options['error']);
|
||||
goto top;
|
||||
} elseif ($options['validator'] &&
|
||||
!call_user_func_array($options['validator'], array($input, &$error))) {
|
||||
static::output(isset($error) ? $error : $options['error']);
|
||||
goto top;
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the user for a simple yes/no confirmation.
|
||||
*
|
||||
* @param string $text Prompt string
|
||||
*
|
||||
* @return bool Either true or false
|
||||
*/
|
||||
public static function confirm($text)
|
||||
{
|
||||
top:
|
||||
$input = strtolower(static::input("$text [y/n]: "));
|
||||
if (!in_array($input, array('y', 'n'))) goto top;
|
||||
return $input === 'y' ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the user an option to choose from. Giving '?' as an input will show
|
||||
* a list of options to choose from and their explanations.
|
||||
*
|
||||
* @param string $text Prompt string
|
||||
* @param array $options Key-value array of options to choose from
|
||||
*
|
||||
* @return string An option character the user chose
|
||||
*/
|
||||
public static function select($text, $options = array())
|
||||
{
|
||||
top:
|
||||
static::stdout("$text [" . implode(',', array_keys($options)) . ",?]: ");
|
||||
$input = static::stdin();
|
||||
if ($input === '?') {
|
||||
foreach ($options as $key => $value) {
|
||||
echo " $key - $value\n";
|
||||
}
|
||||
echo " ? - Show help\n";
|
||||
goto top;
|
||||
} elseif (!in_array($input, array_keys($options))) goto top;
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a Closure as another process in the background while showing a
|
||||
* status update. The status update can be an indefinite spinner or a string
|
||||
* periodically sent from the background process, depending on whether the
|
||||
* provided Closure object has a $socket parameter or not. Messaging to the
|
||||
* main process is done by socket_* functions. The return value is either
|
||||
* the return value of the background process, or false if the process fork
|
||||
* failed.
|
||||
*
|
||||
* @param callable $callable Closure object
|
||||
* @return bool|int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function work(\Closure $callable)
|
||||
{
|
||||
if (!extension_loaded('pcntl')) {
|
||||
throw new \Exception('pcntl extension required');
|
||||
}
|
||||
|
||||
if (!extension_loaded('sockets')) {
|
||||
throw new \Exception('sockets extension required');
|
||||
}
|
||||
|
||||
$spinner = array('|', '/', '-', '\\');
|
||||
$i = 0; $l = count($spinner);
|
||||
$delay = 100000;
|
||||
|
||||
$func = new \ReflectionFunction($callable);
|
||||
|
||||
$socket = (bool)$func->getNumberOfParameters();
|
||||
|
||||
if ($socket) {
|
||||
$sockets = array();
|
||||
if (socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $sockets) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($pid > 0) {
|
||||
$done = false;
|
||||
$retval = 0;
|
||||
pcntl_signal(SIGCHLD, function() use ($pid, &$done, &$retval) {
|
||||
$child_pid = pcntl_waitpid($pid, $status);
|
||||
if (pcntl_wifexited($status)) {
|
||||
$retval = pcntl_wexitstatus($status);
|
||||
}
|
||||
$done = true;
|
||||
});
|
||||
|
||||
if ($socket) {
|
||||
$text = '';
|
||||
while (!$done) {
|
||||
$r = array($sockets[1]);
|
||||
$w = null;
|
||||
$e = null;
|
||||
if ($status = socket_select($r, $w, $e, 0)) {
|
||||
$data = socket_read($sockets[1], 4096, PHP_NORMAL_READ);
|
||||
if ($data === false) {
|
||||
throw new \Exception(
|
||||
sprintf(
|
||||
'socket write error %s',
|
||||
socket_strerror(socket_last_error($sockets[1]))
|
||||
)
|
||||
);
|
||||
}
|
||||
echo str_repeat(chr(8), strlen($text));
|
||||
$text = rtrim($data, "\n");
|
||||
Console::stdout($text);
|
||||
} else {
|
||||
pcntl_signal_dispatch();
|
||||
}
|
||||
usleep($delay);
|
||||
}
|
||||
echo str_repeat(chr(8), strlen($text));
|
||||
socket_close($sockets[0]);
|
||||
socket_close($sockets[1]);
|
||||
} else {
|
||||
while (!$done) {
|
||||
pcntl_signal_dispatch();
|
||||
echo $spinner[$i];
|
||||
usleep($delay);
|
||||
echo chr(8);
|
||||
$i = $i === $l - 1 ? 0 : $i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $retval;
|
||||
} elseif ($pid === 0) {
|
||||
if ($socket) {
|
||||
call_user_func($callable, $sockets[0]);
|
||||
} else {
|
||||
call_user_func($callable);
|
||||
}
|
||||
exit;
|
||||
} else {
|
||||
// Unable to fork process.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
163
app/lib/Yiinitializr/Cli/Daemon.php
Normal file
163
app/lib/Yiinitializr/Cli/Daemon.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
* Daemon class file.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @author Nofriandi Ramenta <nramenta@gmail.com>
|
||||
* @link http://www.ramirezcobos.com/
|
||||
* @link http://www.2amigos.us/
|
||||
* @link https://github.com/nramenta/clio
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*/
|
||||
namespace Yiinitializr\Cli;
|
||||
/**
|
||||
* Daemon provides helpers for starting and killing daemonized processes
|
||||
*
|
||||
* @author Antonio Ramirez <ramirez.cobos@gmail.com>
|
||||
* @package Yiinitializr.Cli
|
||||
* @since 1.0
|
||||
*/
|
||||
class Daemon
|
||||
{
|
||||
/**
|
||||
* Daemonize a Closure object.
|
||||
* @param array $options Set of options
|
||||
* @param callable $callable Closure object to daemonize
|
||||
* @return bool True on success
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function work(array $options, \Closure $callable)
|
||||
{
|
||||
if (!extension_loaded('pcntl')) {
|
||||
throw new \Exception('pcntl extension required');
|
||||
}
|
||||
|
||||
if (!extension_loaded('posix')) {
|
||||
throw new \Exception('posix extension required');
|
||||
}
|
||||
|
||||
if (!isset($options['pid'])) {
|
||||
throw new \Exception('pid not specified');
|
||||
}
|
||||
|
||||
$options = $options + array(
|
||||
'stdin' => '/dev/null',
|
||||
'stdout' => '/dev/null',
|
||||
'stderr' => 'php://stdout',
|
||||
);
|
||||
|
||||
if (($lock = @fopen($options['pid'], 'c+')) === false) {
|
||||
throw new \Exception('unable to open pid file ' . $options['pid']);
|
||||
}
|
||||
|
||||
if (!flock($lock, LOCK_EX | LOCK_NB)) {
|
||||
throw new \Exception('could not acquire lock for ' . $options['pid']);
|
||||
}
|
||||
|
||||
switch ($pid = pcntl_fork()) {
|
||||
case -1:
|
||||
throw new \Exception('unable to fork');
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
fseek($lock, 0);
|
||||
ftruncate($lock, 0);
|
||||
fwrite($lock ,$pid);
|
||||
fflush($lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (posix_setsid() === -1) {
|
||||
throw new \Exception('failed to setsid');
|
||||
}
|
||||
|
||||
fclose(STDIN);
|
||||
fclose(STDOUT);
|
||||
fclose(STDERR);
|
||||
|
||||
if (!($stdin = fopen($options['stdin'], 'r'))) {
|
||||
throw new \Exception('failed to open STDIN ' . $options['stdin']);
|
||||
}
|
||||
|
||||
if (!($stdout = fopen($options['stdout'], 'w'))) {
|
||||
throw new \Exception('failed to open STDOUT ' . $options['stdout']);
|
||||
}
|
||||
|
||||
if (!($stderr = fopen($options['stderr'], 'w'))) {
|
||||
throw new \Exception('failed to open STDERR ' . $options['stderr']);
|
||||
}
|
||||
|
||||
pcntl_signal(SIGTSTP, SIG_IGN);
|
||||
pcntl_signal(SIGTTOU, SIG_IGN);
|
||||
pcntl_signal(SIGTTIN, SIG_IGN);
|
||||
pcntl_signal(SIGHUP, SIG_IGN);
|
||||
|
||||
call_user_func($callable, $stdin, $stdout, $stderr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a process is running or not
|
||||
* @param $file
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function isRunning($file)
|
||||
{
|
||||
if (!extension_loaded('posix')) {
|
||||
throw new \Exception('posix extension required');
|
||||
}
|
||||
|
||||
if (!is_readable($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($lock = @fopen($file, 'c+')) === false) {
|
||||
throw new \Exception('unable to open pid file ' . $file);
|
||||
}
|
||||
|
||||
if (flock($lock, LOCK_EX | LOCK_NB)) {
|
||||
return false;
|
||||
} else {
|
||||
flock($lock, LOCK_UN);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills a daemon process specified by its PID file.
|
||||
*
|
||||
* @param $file Daemon PID file
|
||||
* @param bool $delete Flag to delete PID file after killing
|
||||
* @return bool True on success, false otherwise
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function kill($file, $delete = false)
|
||||
{
|
||||
if (!extension_loaded('posix')) {
|
||||
throw new \Exception('posix extension required');
|
||||
}
|
||||
|
||||
if (!is_readable($file)) {
|
||||
throw new \Exception('unreadable pid file ' . $file);
|
||||
}
|
||||
|
||||
if (($lock = @fopen($file, 'c+')) === false) {
|
||||
throw new \Exception('unable to open pid file ' . $file);
|
||||
}
|
||||
|
||||
if (flock($lock, LOCK_EX | LOCK_NB)) {
|
||||
flock($lock, LOCK_UN);
|
||||
throw new \Exception('process not running');
|
||||
}
|
||||
|
||||
$pid = fgets($lock);
|
||||
|
||||
if (posix_kill($pid, SIGTERM)) {
|
||||
if ($delete) unlink($file);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
201
app/lib/Yiinitializr/Composer/Callback.php
Normal file
201
app/lib/Yiinitializr/Composer/Callback.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
/**
|
||||
* Yiinitialzr\Composer\Callback provides composer hooks
|
||||
*
|
||||
* Totally inspired by the ComposerCallback of Phundament3 and adapted for its use with Yiinitialzr
|
||||
*
|
||||
* This setup class triggers `./yiic migrate` at post-install and post-update.
|
||||
* For a package the class triggers `./yiic <vendor/<packageName>-<action>` at post-package-install and
|
||||
* post-package-update.
|
||||
*
|
||||
* You can also create new commands to be called within your boilerplate configuration.
|
||||
*
|
||||
* See composer manual (http://getcomposer.org/doc/articles/scripts.md)
|
||||
*
|
||||
* Usage example
|
||||
*
|
||||
* config.php
|
||||
* 'params' => array(
|
||||
* 'composer.callbacks' => array(
|
||||
* 'post-update' => array('yiic', 'migrate'),
|
||||
* 'post-install' => array('yiic', 'migrate'),
|
||||
* 'yiisoft/yii-install' => array('yiic', 'webapp', realpath(dirname(__FILE__))),
|
||||
* ),
|
||||
* ))
|
||||
*
|
||||
* composer.json
|
||||
* "scripts": {
|
||||
* "pre-install-cmd": "Yiinitialzr\\Composer\\Callback::preInstall",
|
||||
* "post-install-cmd": "Yiinitialzr\\Composer\\Callback::postInstall",
|
||||
* "pre-update-cmd": "Yiinitialzr\\Composer\\Callback::preUpdate",
|
||||
* "post-update-cmd": "Yiinitialzr\\Composer\\Callback::postUpdate",
|
||||
* "post-package-install": [
|
||||
* "Yiinitialzr\\Composer\\Callback::postPackageInstall"
|
||||
* ],
|
||||
* "post-package-update": [
|
||||
* "Yiinitialzr\\Composer\\Callback::postPackageUpdate"
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @link http://2amigos.us
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*
|
||||
* Credits to Phundament... Tobias, thanks for introducing me the wonders of composer
|
||||
*
|
||||
* @author Tobias Munk <schmunk@usrbin.de>
|
||||
* @link http://www.phundament.com/
|
||||
* @copyright Copyright © 2012 diemeisterei GmbH
|
||||
* @license http://www.phundament.com/license
|
||||
*/
|
||||
namespace Yiinitializr\Composer;
|
||||
|
||||
use Composer\Script\Event;
|
||||
use Yiinitializr\Helpers\Initializer;
|
||||
use Yiinitializr\Helpers\Config;
|
||||
use Yiinitializr\Cli\Console;
|
||||
|
||||
class Callback
|
||||
{
|
||||
/**
|
||||
* Displays welcome message
|
||||
* @static
|
||||
* @param \Composer\Script\Event $event
|
||||
*/
|
||||
public static function preInstall(Event $event)
|
||||
{
|
||||
Console::output("\n%BYiinitialzr 1.0.1%n\n");
|
||||
Console::output("* download packages specified in composer.json");
|
||||
Console::output("* configures your runtime folders");
|
||||
Console::output("* triggers composer callbacks (yiic commands)\n");
|
||||
|
||||
if (Console::confirm("Start Installation?"))
|
||||
self::runHook('pre-install');
|
||||
else
|
||||
exit("\n%RInstallation aborted%n.\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a post-install callback
|
||||
* @static
|
||||
* @param \Composer\Script\Event $event
|
||||
*/
|
||||
public static function postInstall(Event $event)
|
||||
{
|
||||
self::runHook('post-install');
|
||||
Console::output("\n%GInstallation completed!%n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays updating message
|
||||
*
|
||||
* @static
|
||||
* @param \Composer\Script\Event $event
|
||||
*/
|
||||
public static function preUpdate(Event $event)
|
||||
{
|
||||
Console::output("Updating your application to the latest available packages...");
|
||||
self::runHook('pre-update');
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes post-update message
|
||||
*
|
||||
* @static
|
||||
* @param \Composer\Script\Event $event
|
||||
*/
|
||||
public static function postUpdate(Event $event)
|
||||
{
|
||||
self::runHook('post-update');
|
||||
Console::output("%GUpdate completed.%n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes ./yiic <vendor/<packageName>-<action>
|
||||
*
|
||||
* @static
|
||||
* @param \Composer\Script\Event $event
|
||||
*/
|
||||
public static function postPackageInstall(Event $event)
|
||||
{
|
||||
$installedPackage = $event->getOperation()->getPackage();
|
||||
$hookName = $installedPackage->getPrettyName() . '-install';
|
||||
self::runHook($hookName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes ./yiic <vendor/<packageName>-<action>
|
||||
*
|
||||
* @static
|
||||
* @param \Composer\Script\Event $event
|
||||
*/
|
||||
public static function postPackageUpdate(Event $event)
|
||||
{
|
||||
$installedPackage = $event->getOperation()->getTargetPackage();
|
||||
$commandName = $installedPackage->getPrettyName() . '-update';
|
||||
self::runHook($commandName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs Yii command, if available (defined in config.php)
|
||||
*/
|
||||
private static function runHook($name)
|
||||
{
|
||||
$app = self::getYiiApplication();
|
||||
if ($app === null) return;
|
||||
|
||||
if (isset($app->params['composer.callbacks'][$name]))
|
||||
{
|
||||
$args = $app->params['composer.callbacks'][$name];
|
||||
$app->commandRunner->addCommands(\Yii::getPathOfAlias('system.cli.commands'));
|
||||
$app->commandRunner->run($args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates console application, if Yii is available
|
||||
*/
|
||||
private static function getYiiApplication()
|
||||
{
|
||||
if (!is_file(Config::value('yii.path') . '/yii.php'))
|
||||
{
|
||||
// nothing yet installed, return
|
||||
return null;
|
||||
}
|
||||
|
||||
require_once(Config::value('yii.path') . '/yii.php');
|
||||
|
||||
spl_autoload_register(array('YiiBase', 'autoload'));
|
||||
|
||||
if (\Yii::app() === null)
|
||||
{
|
||||
|
||||
if (!Config::value('envlock'))
|
||||
{
|
||||
$env = Console::prompt('Please, enter your environment -ie. "dev | prod | stage": ', array('default' => 'dev'));
|
||||
Initializer::buildEnvironmentFiles($env);
|
||||
} else
|
||||
{
|
||||
Console::output("\n%Benv.lock%n file found. No environment request required.\n");
|
||||
Console::output("Note: if you wish to re-do enviroment setting merging, please remove the %Benv.lock%n file " .
|
||||
"from the Yiinitializr %Bconfig%n folder.");
|
||||
}
|
||||
|
||||
Initializer::createRuntimeFolders();
|
||||
|
||||
Initializer::createRuntimeFolders('assets');
|
||||
|
||||
if (is_file(Config::value('yiinitializr.config.console')))
|
||||
$app = \Yii::createConsoleApplication(Config::value('yiinitializr.config.console'));
|
||||
else
|
||||
throw new \Exception("'yiinitializr.config.console' setting not found");
|
||||
|
||||
} else
|
||||
{
|
||||
$app = \Yii::app();
|
||||
}
|
||||
return $app;
|
||||
}
|
||||
}
|
||||
416
app/lib/Yiinitializr/Helpers/ArrayX.php
Normal file
416
app/lib/Yiinitializr/Helpers/ArrayX.php
Normal file
@@ -0,0 +1,416 @@
|
||||
<?php
|
||||
/**
|
||||
* ArrayX class file.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @link http://www.ramirezcobos.com/
|
||||
* @link http://www.2amigos.us/
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*/
|
||||
namespace Yiinitializr\Helpers;
|
||||
|
||||
/**
|
||||
* ArrayX provides a set of useful functions
|
||||
*
|
||||
* @author Antonio Ramirez <ramirez.cobos@gmail.com>
|
||||
* @package Yiinitializr.helpers
|
||||
* @since 1.0
|
||||
*/
|
||||
class ArrayX
|
||||
{
|
||||
/**
|
||||
* Get an item from an array using "dot" notation.
|
||||
*
|
||||
* <code>
|
||||
* // Get the $array['user']['name'] value from the array
|
||||
* $name = ArrayX::get($array, 'user.name');
|
||||
*
|
||||
* // Return a default from if the specified item doesn't exist
|
||||
* $name = ArrayX::get($array, 'user.name', 'Taylor');
|
||||
* </code>
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($array, $key, $default = null)
|
||||
{
|
||||
if (is_null($key)) return $array;
|
||||
|
||||
// To retrieve the array item using dot syntax, we'll iterate through
|
||||
// each segment in the key and look for that value. If it exists, we
|
||||
// will return it, otherwise we will set the depth of the array and
|
||||
// look for the next segment.
|
||||
foreach (explode('.', $key) as $segment)
|
||||
{
|
||||
if (!is_array($array) || !array_key_exists($segment, $array))
|
||||
{
|
||||
return self::value($default);
|
||||
}
|
||||
|
||||
$array = $array[$segment];
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item from the given options and returns the value.
|
||||
*
|
||||
* If no key is found, then default value will be returned.
|
||||
*
|
||||
* @param $array
|
||||
* @param $key
|
||||
* @param null $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function pop(&$array, $key, $default = null)
|
||||
{
|
||||
if (is_array($array))
|
||||
{
|
||||
$value = self::get($array, $key, $default);
|
||||
unset($array[$key]);
|
||||
return $value;
|
||||
} else
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an array item to a given value using "dot" notation.
|
||||
*
|
||||
* If no key is given to the method, the entire array will be replaced.
|
||||
*
|
||||
* <code>
|
||||
* // Set the $array['user']['name'] value on the array
|
||||
* ArrayX::set($array, 'user.name', 'Taylor');
|
||||
*
|
||||
* // Set the $array['user']['name']['first'] value on the array
|
||||
* ArrayX::set($array, 'user.name.first', 'Michael');
|
||||
* </code>
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public static function set(&$array, $key, $value)
|
||||
{
|
||||
if (is_null($key)) return $array = $value;
|
||||
|
||||
$keys = explode('.', $key);
|
||||
|
||||
// This loop allows us to dig down into the array to a dynamic depth by
|
||||
// setting the array value for each level that we dig into. Once there
|
||||
// is one key left, we can fall out of the loop and set the value as
|
||||
// we should be at the proper depth.
|
||||
while (count($keys) > 1)
|
||||
{
|
||||
$key = array_shift($keys);
|
||||
|
||||
// If the key doesn't exist at this depth, we will just create an
|
||||
// empty array to hold the next value, allowing us to create the
|
||||
// arrays to hold the final value.
|
||||
if (!isset($array[$key]) || !is_array($array[$key]))
|
||||
$array[$key] = array();
|
||||
|
||||
$array =& $array[$key];
|
||||
}
|
||||
|
||||
$array[array_shift($keys)] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an array item from a given array using "dot" notation.
|
||||
*
|
||||
* <code>
|
||||
* // Remove the $array['user']['name'] item from the array
|
||||
* ArrayX::forget($array, 'user.name');
|
||||
*
|
||||
* // Remove the $array['user']['name']['first'] item from the array
|
||||
* ArrayX::forget($array, 'user.name.first');
|
||||
* </code>
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
public static function forget(&$array, $key)
|
||||
{
|
||||
$keys = explode('.', $key);
|
||||
|
||||
// This loop functions very similarly to the loop in the "set" method.
|
||||
// We will iterate over the keys, setting the array value to the new
|
||||
// depth at each iteration. Once there is only one key left, we will
|
||||
// be at the proper depth in the array.
|
||||
while (count($keys) > 1)
|
||||
{
|
||||
$key = array_shift($keys);
|
||||
|
||||
// Since this method is supposed to remove a value from the array,
|
||||
// if a value higher up in the chain doesn't exist, there is no
|
||||
// need to keep digging into the array, since it is impossible
|
||||
// for the final value to even exist.
|
||||
if (!isset($array[$key]) || !is_array($array[$key]))
|
||||
return;
|
||||
|
||||
$array =& $array[$key];
|
||||
}
|
||||
|
||||
unset($array[array_shift($keys)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first element in an array which passes a given truth test.
|
||||
*
|
||||
* <code>
|
||||
* // Return the first array element that equals "Taylor"
|
||||
* $value = ArrayX::first($array, function($k, $v) {return $v == 'Taylor';});
|
||||
*
|
||||
* // Return a default value if no matching element is found
|
||||
* $value = ArrayX::first($array, function($k, $v) {return $v == 'Taylor'}, 'Default');
|
||||
* </code>
|
||||
*
|
||||
* @param array $array
|
||||
* @param Closure $callback
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function first($array, $callback, $default = null)
|
||||
{
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if (call_user_func($callback, $key, $value)) return $value;
|
||||
}
|
||||
|
||||
return value($default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively remove slashes from array keys and values.
|
||||
*
|
||||
* @param array $array
|
||||
* @return array
|
||||
*/
|
||||
public static function stripSlashes($array)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
$key = stripslashes($key);
|
||||
|
||||
// If the value is an array, we will just recurse back into the
|
||||
// function to keep stripping the slashes out of the array,
|
||||
// otherwise we will set the stripped value.
|
||||
if (is_array($value))
|
||||
{
|
||||
$result[$key] = array_strip_slashes($value);
|
||||
} else
|
||||
{
|
||||
$result[$key] = stripslashes($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide an array into two arrays. One with keys and the other with values.
|
||||
*
|
||||
* @param array $array
|
||||
* @return array
|
||||
*/
|
||||
public static function divide($array)
|
||||
{
|
||||
return array(array_keys($array), array_values($array));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluck an array of values from an array.
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public static function pluck($array, $key)
|
||||
{
|
||||
return array_map(function ($v) use ($key)
|
||||
{
|
||||
return is_object($v) ? $v->$key : $v[$key];
|
||||
|
||||
}, $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subset of the items from the given array.
|
||||
*
|
||||
* @param array $array
|
||||
* @param array $keys
|
||||
* @return array
|
||||
*/
|
||||
public static function only($array, $keys)
|
||||
{
|
||||
return array_intersect_key($array, array_flip((array)$keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the given array except for a specified array of items.
|
||||
*
|
||||
* @param array $array
|
||||
* @param array $keys
|
||||
* @return array
|
||||
*/
|
||||
public static function except($array, $keys)
|
||||
{
|
||||
return array_diff_key($array, array_flip((array)$keys));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the first element of an array.
|
||||
*
|
||||
* This is simply a convenient wrapper around the "reset" method.
|
||||
*
|
||||
* @param array $array
|
||||
* @return mixed
|
||||
*/
|
||||
public static function head($array)
|
||||
{
|
||||
return reset($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two or more arrays into one recursively.
|
||||
* If each array has an element with the same string key value, the latter
|
||||
* will overwrite the former (different from array_merge_recursive).
|
||||
* Recursive merging will be conducted if both arrays have an element of array
|
||||
* type and are having the same key.
|
||||
* For integer-keyed elements, the elements from the latter array will
|
||||
* be appended to the former array.
|
||||
* @param array $a array to be merged to
|
||||
* @param array $b array to be merged from. You can specifiy additional
|
||||
* arrays via third argument, fourth argument etc.
|
||||
* @return array the merged array (the original arrays are not changed.)
|
||||
*/
|
||||
public static function merge($a, $b)
|
||||
{
|
||||
$args = func_get_args();
|
||||
$res = array_shift($args);
|
||||
while (!empty($args))
|
||||
{
|
||||
$next = array_shift($args);
|
||||
foreach ($next as $k => $v)
|
||||
{
|
||||
if (is_integer($k))
|
||||
isset($res[$k]) ? $res[] = $v : $res[$k] = $v;
|
||||
elseif (is_array($v) && isset($res[$k]) && is_array($res[$k]))
|
||||
$res[$k] = self::merge($res[$k], $v); else
|
||||
$res[$k] = $v;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for a given value in an array of arrays, objects and scalar
|
||||
* values. You can optionally specify a field of the nested arrays and
|
||||
* objects to search in.
|
||||
*
|
||||
* Credits to Util.php
|
||||
*
|
||||
* @param array $array The array to search
|
||||
* @param string $search The value to search for
|
||||
* @param bool $field The field to search in, if not specified all fields will be searched
|
||||
* @return bool|mixed|string False on failure or the array key on
|
||||
* @link https://github.com/brandonwamboldt/utilphp/blob/master/util.php
|
||||
*/
|
||||
public static function deepSearch(array $array, $search, $field = FALSE)
|
||||
{
|
||||
// *grumbles* stupid PHP type system
|
||||
$search = (string)$search;
|
||||
|
||||
foreach ($array as $key => $elem)
|
||||
{
|
||||
|
||||
// *grumbles* stupid PHP type system
|
||||
$key = (string)$key;
|
||||
|
||||
if ($field)
|
||||
{
|
||||
if (is_object($elem) && $elem->{$field} === $search)
|
||||
{
|
||||
return $key;
|
||||
} else if (is_array($elem) && $elem[$field] === $search)
|
||||
{
|
||||
return $key;
|
||||
} else if (is_scalar($elem) && $elem === $search)
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (is_object($elem))
|
||||
{
|
||||
$elem = (array)$elem;
|
||||
|
||||
if (in_array($search, $elem))
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
} else if (is_array($elem) && in_array($search, $elem))
|
||||
{
|
||||
return array_search($search, $elem);
|
||||
} else if (is_scalar($elem) && $elem === $search)
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all the elements of arr1 after applying
|
||||
* the callback function to each one.
|
||||
*
|
||||
* Credits to Util.php
|
||||
*
|
||||
* @param array $array an array to run through the callback function
|
||||
* @param $callback Callback function to run for each element in each array
|
||||
* @param bool $on_nonscalar whether or not to call the callback function on nonscalar values (objects, resr, etc)
|
||||
* @return array
|
||||
* @link https://github.com/brandonwamboldt/utilphp/blob/master/util.php
|
||||
*/
|
||||
public static function deepMap(array $array, $callback, $on_nonscalar = FALSE)
|
||||
{
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$args = array($value, $callback, $on_nonscalar);
|
||||
$array[$key] = call_user_func_array(array(__CLASS__, __FUNCTION__), $args);
|
||||
} else if (is_scalar($value) || $on_nonscalar)
|
||||
{
|
||||
$array[$key] = call_user_func($callback, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the given item.
|
||||
*
|
||||
* If the given item is a Closure the result of the Closure will be returned.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function value($value)
|
||||
{
|
||||
return (is_callable($value) and !is_string($value)) ? call_user_func($value) : $value;
|
||||
}
|
||||
}
|
||||
94
app/lib/Yiinitializr/Helpers/Config.php
Normal file
94
app/lib/Yiinitializr/Helpers/Config.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Config class file.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @link http://www.ramirezcobos.com/
|
||||
* @link http://www.2amigos.us/
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*/
|
||||
namespace Yiinitializr\Helpers;
|
||||
|
||||
use Yiinitializr\Helpers\ArrayX;
|
||||
|
||||
/**
|
||||
* Config provides easy access to Yiinitializr configuration file
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @package Yiinitializr.helpers
|
||||
* @since 1.0
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var array the configuration settings
|
||||
*/
|
||||
private static $_settings;
|
||||
|
||||
private static $_config_dir_path;
|
||||
private static $_envlock_file_path;
|
||||
|
||||
/**
|
||||
* Returns a value of the array
|
||||
* @param $value
|
||||
* @return mixed | null if no key is found
|
||||
*/
|
||||
public static function value($value)
|
||||
{
|
||||
return ArrayX::get(self::settings(), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the configuration settings from the file
|
||||
* @return array|mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function settings()
|
||||
{
|
||||
if (null === self::$_settings)
|
||||
{
|
||||
self::$_settings = file_exists(self::getConfigurationDirectoryPath() . '/settings.php')
|
||||
? require_once(self::getConfigurationDirectoryPath() . '/settings.php')
|
||||
: array();
|
||||
self::$_settings['envlock'] = file_exists(self::getEnvironmentLockFilePath());
|
||||
|
||||
}
|
||||
if (empty(self::$_settings))
|
||||
throw new \Exception('Unable to find Yiinitialzr settings file!');
|
||||
|
||||
return self::$_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*/
|
||||
public static function createEnvironmentLockFile($content = '')
|
||||
{
|
||||
umask(0);
|
||||
file_put_contents(self::getEnvironmentLockFilePath(), $content);
|
||||
@chmod(self::getEnvironmentLockFilePath(), 0644);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration directory path
|
||||
* @return string
|
||||
*/
|
||||
public static function getConfigurationDirectoryPath()
|
||||
{
|
||||
if (null === self::$_config_dir_path)
|
||||
self::$_config_dir_path = dirname(__FILE__) . '/../config';
|
||||
return self::$_config_dir_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment lock file path
|
||||
* @return string
|
||||
*/
|
||||
public static function getEnvironmentLockFilePath()
|
||||
{
|
||||
if (null === self::$_envlock_file_path)
|
||||
self::$_envlock_file_path = self::getConfigurationDirectoryPath() . '/env.lock';
|
||||
return self::$_envlock_file_path;
|
||||
}
|
||||
}
|
||||
251
app/lib/Yiinitializr/Helpers/Initializer.php
Normal file
251
app/lib/Yiinitializr/Helpers/Initializer.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/**
|
||||
* Initializer class file.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @link http://www.ramirezcobos.com/
|
||||
* @link http://www.2amigos.us/
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*/
|
||||
namespace Yiinitializr\Helpers;
|
||||
|
||||
use Yiinitializr\Helpers\Config;
|
||||
use Yiinitializr\Helpers\ArrayX;
|
||||
use Yiinitializr\Cli\Console;
|
||||
|
||||
/**
|
||||
* Initializer provides a set of useful functions to initialize a Yii Application development.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @package Yiinitializr.helpers
|
||||
* @since 1.0
|
||||
*/
|
||||
class Initializer
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $root
|
||||
* @param string $configName
|
||||
* @param mixed $mergeWith
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function create($root, $configName = 'main', $mergeWith = array('common', 'env'))
|
||||
{
|
||||
if (($root = realpath($root)) === false)
|
||||
throw new Exception('could not initialize framework.');
|
||||
|
||||
$config = self::config($configName, $mergeWith);
|
||||
|
||||
if (php_sapi_name() !== 'cli') // aren't we in console?
|
||||
$app = \Yii::createWebApplication($config); // create web
|
||||
else
|
||||
{
|
||||
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
|
||||
$app = \Yii::createConsoleApplication($config);
|
||||
$app->commandRunner->addCommands($root . '/cli/commands');
|
||||
$env = @getenv('YII_CONSOLE_COMMANDS');
|
||||
if (!empty($env))
|
||||
$app->commandRunner->addCommands($env);
|
||||
}
|
||||
// return an app
|
||||
return $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $configName config name to load (main, test, etc)
|
||||
* @param null|string $mergeWith
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function config($configName = 'main', $mergeWith = null)
|
||||
{
|
||||
|
||||
$files = array($configName);
|
||||
$directory = Config::value('yiinitializr.app.directories.config.' . $configName);
|
||||
if (null === $directory)
|
||||
throw new \Exception("Unable to find 'yiinitializr.app.directories.config.'{$configName} on the settings.");
|
||||
|
||||
if (null !== $mergeWith)
|
||||
{
|
||||
if (is_array($mergeWith))
|
||||
{
|
||||
foreach($mergeWith as $file)
|
||||
$files[] = $file;
|
||||
}
|
||||
else
|
||||
$files[] = $mergeWith;
|
||||
}
|
||||
|
||||
// do we have any other configuration files to merge with?
|
||||
$mergedSettingFiles = Config::value('yiinitializr.app.files.config.' . $configName);
|
||||
if (null !== $mergedSettingFiles)
|
||||
{
|
||||
if (is_array($mergedSettingFiles))
|
||||
{
|
||||
foreach($mergedSettingFiles as $file)
|
||||
$files[] = $file;
|
||||
}
|
||||
else
|
||||
$files[] = $mergedSettingFiles;
|
||||
}
|
||||
|
||||
$config = self::build($directory, $files);
|
||||
|
||||
$params = isset($config['params'])
|
||||
? $config['params']
|
||||
: array();
|
||||
|
||||
self::setOptions($params);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $directory
|
||||
* @param $files array of configuration files to merge
|
||||
* @return array
|
||||
*/
|
||||
public static function build($directory, $files)
|
||||
{
|
||||
$result = array();
|
||||
if (!is_array($files))
|
||||
$files = array($files);
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$config = file_exists($file) && is_file($file)
|
||||
? require($file)
|
||||
: (is_string($file) && file_exists($directory . '/' . $file . '.php')
|
||||
? require($directory . '/' . $file . '.php')
|
||||
: array());
|
||||
|
||||
if (is_array($config))
|
||||
$result = ArrayX::merge($result, $config);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set php and yii options - some based on the loaded config params
|
||||
* @param array $params The config params being used for the app
|
||||
*/
|
||||
protected static function setOptions(array $params)
|
||||
{
|
||||
// yii config
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', isset($params['yii.debug']) ? $params['yii.debug'] : false);
|
||||
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', isset($params['yii.traceLevel']) ? $params['yii.traceLevel'] : 0);
|
||||
defined('YII_ENABLE_ERROR_HANDLER') or define('YII_ENABLE_ERROR_HANDLER', isset($params['yii.handleErrors']) ? $params['yii.handleErrors'] : true);
|
||||
defined('YII_ENABLE_EXCEPTION_HANDLER') or define('YII_ENABLE_EXCEPTION_HANDLER', YII_ENABLE_ERROR_HANDLER);
|
||||
|
||||
// php config
|
||||
error_reporting(-1);
|
||||
if(isset($params['php.defaultCharset']))
|
||||
ini_set('default_charset', $params['php.defaultCharset']);
|
||||
if(isset($params['php.timezone']))
|
||||
date_default_timezone_set($params['php.timezone']);
|
||||
|
||||
|
||||
date_default_timezone_set($params['php.timezone']);
|
||||
|
||||
if(!class_exists('YiiBase'))
|
||||
require(Config::value('yii.path').'/yii.php');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build environment files
|
||||
* @param $environment
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function buildEnvironmentFiles($environment = 'dev')
|
||||
{
|
||||
self::output("\n%gBuilding environment files.%n");
|
||||
|
||||
umask(0);
|
||||
$directories = Config::value('yiinitializr.app.directories.config');
|
||||
if (null === $directories)
|
||||
throw new \Exception("Unable to find 'yiinitializr.app.directories.config' on the settings.");
|
||||
|
||||
if (!is_array($directories))
|
||||
$directories = array($directories);
|
||||
|
||||
$environment = strlen($environment)
|
||||
? $environment
|
||||
: 'dev';
|
||||
|
||||
foreach ($directories as $directory)
|
||||
{
|
||||
if (file_exists($directory))
|
||||
{
|
||||
$environment_directory = $directory . '/env';
|
||||
if (!file_exists($environment_directory))
|
||||
{
|
||||
mkdir($environment_directory);
|
||||
|
||||
self::output("Your environment directory has been created: %r{$environment_directory}%n.\n");
|
||||
}
|
||||
|
||||
$environment_file = $environment_directory . '/' . $environment . '.php';
|
||||
|
||||
if (!file_exists($environment_file))
|
||||
{
|
||||
file_put_contents($environment_file, "<?php\n/**\n * {$environment}.php\n */\n\nreturn array(\n);");
|
||||
@chmod($environment_file, 0644);
|
||||
|
||||
self::output("%gEnvironment configuration file has been created: %r{$environment_file}%n.\n");
|
||||
}
|
||||
if (!file_exists($directory . '/env.php'))
|
||||
{
|
||||
@copy($environment_file, $directory . '/env.php');
|
||||
|
||||
self::output("Your environment configuration file has been created on {$directory}.\n");
|
||||
} else
|
||||
self::output("'{$directory}/env.php'\n%pfile already exists. No action has been executed.%n");
|
||||
}
|
||||
}
|
||||
Config::createEnvironmentLockFile($environment);
|
||||
self::output("%gEnvironment files creation process finished.%n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name the name of the runtime folder,
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function createRuntimeFolders($name = 'runtime')
|
||||
{
|
||||
self::output("\n%gBuilding runtime '{$name}' folders.%n");
|
||||
umask(0);
|
||||
$directories = Config::value('yiinitializr.app.directories.' . $name);
|
||||
|
||||
if (null === $directories)
|
||||
throw new \Exception("Unable to find 'yiinitializr.app.directories.{$name}' on the settings.");
|
||||
|
||||
if (!is_array($directories))
|
||||
$directories = array($directories);
|
||||
|
||||
foreach ($directories as $directory)
|
||||
{
|
||||
$runtime = $directory . '/' . $name;
|
||||
if (!file_exists($runtime))
|
||||
{
|
||||
@mkdir($runtime, 02777);
|
||||
self::output("Your {$name} folder has been created on {$directory}.");
|
||||
} else
|
||||
self::output("'{$name}' %pfolder already exists. No action has been executed.%n");
|
||||
}
|
||||
self::output("%gRuntime '{$name}' folders creation process finished.%n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs text only to console
|
||||
* @param $message
|
||||
*/
|
||||
protected static function output($message)
|
||||
{
|
||||
if (php_sapi_name() === 'cli')
|
||||
Console::output($message);
|
||||
}
|
||||
}
|
||||
31
app/lib/Yiinitializr/LICENSE
Normal file
31
app/lib/Yiinitializr/LICENSE
Normal file
@@ -0,0 +1,31 @@
|
||||
The Yiinitializr is free software. It is released under the terms of
|
||||
the following BSD License.
|
||||
|
||||
Copyright (c) 2013 by 2amigOS! Consultation Group LLC (http://www.2amigos.us)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of 2amigOS! Consultation Group LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
128
app/lib/Yiinitializr/README.md
Normal file
128
app/lib/Yiinitializr/README.md
Normal file
@@ -0,0 +1,128 @@
|
||||
Yiinitializr
|
||||
============
|
||||
|
||||
Library that will help boost your application installation with ease and also to run Yii applications from its
|
||||
bootstrap files on a much cleaner way that the framework currently proposes. For example:
|
||||
|
||||
```
|
||||
// yii has been installed via composer
|
||||
require('./../app/lib/vendor/yiisoft/yii/framework/yii.php');
|
||||
|
||||
// set alias for namespacing
|
||||
// make sure the path is correct as it can also be installed via composer (see above)
|
||||
Yii::setPathOfAlias('Yiinitializr', './../app/lib/Yiinitializr');
|
||||
|
||||
// use its initializr
|
||||
use Yiinitializr\Helpers\Initializer;
|
||||
|
||||
// tell the Initializer class providing the root, the application config name,
|
||||
// and the files to merge -very useful when working with advanced boilerplates
|
||||
// and different environments
|
||||
Initializer::create('./../app', 'main', array('common', 'env', 'local'))->run();
|
||||
```
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
If you are going to use Yiinitializr to make use of `Yiinitializr\Helpers\Initializr` you can easily install it via
|
||||
`composer`, but if you are going to use it within your application structure in order to configure your application
|
||||
according to your custom needs, then the recommended use is that you [download](https://github.com/2amigos/yiinitializr/archive/master.zip)
|
||||
its source files and place them on a top level folder.
|
||||
|
||||
###Configuration Settings
|
||||
As with Yii, you need to go through a bit of configuration settings if you wish to handle your project structure setup
|
||||
with `composer`. Don't worry, is not going to be too hard, the following is an example configuration file:
|
||||
|
||||
```
|
||||
\\ where am i?
|
||||
$dirname = dirname(__FILE__);
|
||||
\\ where is the application folder?
|
||||
$app = $dirname . '/../../..';
|
||||
\\ where is the root?
|
||||
$root = $app . '/..';
|
||||
|
||||
return array(
|
||||
// yii configurations
|
||||
'yii' => array(
|
||||
// where is the path of the yii framework?
|
||||
// On this example we have installed yii with composer
|
||||
// and as it is used after composer installation, we
|
||||
// can safely point to the vendor folder.
|
||||
'path' => $app . '/lib/vendor/yiisoft/yii/framework'
|
||||
),
|
||||
// yiinitializr specific settings
|
||||
'yiinitializr' => array(
|
||||
// config folders
|
||||
'config' => array(
|
||||
// we just need the console settings
|
||||
// On this example, and due that I used environments
|
||||
// i created a custom console.php app for
|
||||
// Yiinitializr\Composer\Callbak class (see below example)
|
||||
'console' => $dirname . '/console.php'
|
||||
),
|
||||
// application structure settings
|
||||
'app' => array(
|
||||
// where is the root?
|
||||
'root' => $root,
|
||||
// directories setup
|
||||
'directories' => array(
|
||||
// where are the different configuration files settings?
|
||||
'config' => array(
|
||||
// 'key' is the configuration name (see above init example)
|
||||
'main' => $app . '/config',
|
||||
'console' => $app . '/config',
|
||||
'test' => $app . '/config'
|
||||
),
|
||||
// where are my runtime folders?
|
||||
'runtime' => array(
|
||||
// heads up! only the folder location as "/config" will be
|
||||
// appended
|
||||
$app
|
||||
),
|
||||
'assets' => array(
|
||||
// where to write the "assets folders"?
|
||||
$root . '/www'
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
Here is an example of a custom `console.php` settings file when working with environments. As you saw on the previous
|
||||
code, this file on the example was located on the same `Yiinitializr\config` folder:
|
||||
|
||||
```
|
||||
require_once dirname(__FILE__) . '/../Helpers/Initializer.php';
|
||||
require_once dirname(__FILE__) . '/../Helpers/ArrayX.php';
|
||||
|
||||
return Yiinitializr\Helpers\ArrayX::merge(
|
||||
Yiinitializr\Helpers\Initializer::config('console', array('common', 'env', 'local')),
|
||||
array(
|
||||
'params' => array(
|
||||
// here is where the composer magic start.
|
||||
// Thanks! mr Tobias a.k.a Phundament man!
|
||||
'composer.callbacks' => array(
|
||||
'post-update' => array('yiic', 'migrate'),
|
||||
'post-install' => array('yiic', 'migrate'),
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
It works in conjunction with `composer` to install the boilerplate but
|
||||
The minimum requirements by Yiinitializr that you have installed `composer` or have a `composer.phar` on your application
|
||||
root in order to run and ** PHP 5.3+**
|
||||
|
||||
|
||||
###Resources
|
||||
- [Composer](http://getcomposer.org)
|
||||
- [Phundament](http://phundament.com/)
|
||||
- [Download latest ZIPball](https://github.com/2amigos/yiinitializr/archive/master.zip)
|
||||
- [2amigOS Packagist Profile](https://packagist.org/packages/2amigos/)
|
||||
|
||||
> [](http://www.2amigos.us)
|
||||
<i>web development has never been so fun</i>
|
||||
[www.2amigos.us](http://www.2amigos.us)
|
||||
30
app/lib/Yiinitializr/composer.json
Normal file
30
app/lib/Yiinitializr/composer.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "2amigos/yiinitializr",
|
||||
"description": "Yii Web Programming Framework Application initializing library.",
|
||||
"keywords": ["yii", "framework", "application", "boilerplate"],
|
||||
"homepage": "http://yiinitializr.2amigos.us/",
|
||||
"type": "library",
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Antonio Ramirez",
|
||||
"email": "amigo.cobos@gmail.com",
|
||||
"homepage": "http://www.2amigos.us/",
|
||||
"role": "Founder and development"
|
||||
},
|
||||
{
|
||||
"name": "Matt Tabin",
|
||||
"email": "amigo.tabin@gmail.com",
|
||||
"homepage": "http://www.2amigos.us/",
|
||||
"role": "Founder and development"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/2amigos/yiinitializr/issues?state=open",
|
||||
"wiki": "https://github.com/2amigos/yiinitializr",
|
||||
"source": "https://github.com/2amigos/yiinitializr"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
}
|
||||
}
|
||||
30
app/lib/Yiinitializr/config/console.php
Normal file
30
app/lib/Yiinitializr/config/console.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Custom console.php config file.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @link http://www.ramirezcobos.com/
|
||||
* @link http://www.2amigos.us/
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*/
|
||||
/**
|
||||
* Include required classes
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/../Helpers/Initializer.php';
|
||||
require_once dirname(__FILE__) . '/../Helpers/ArrayX.php';
|
||||
|
||||
/**
|
||||
* Return the configuration array appending composer callback methods
|
||||
*/
|
||||
return Yiinitializr\Helpers\ArrayX::merge(
|
||||
Yiinitializr\Helpers\Initializer::config('console', array('common', 'env', 'local')),
|
||||
array(
|
||||
'params' => array(
|
||||
'composer.callbacks' => array(
|
||||
'post-update' => array('yiic', 'migrate'),
|
||||
'post-install' => array('yiic', 'migrate'),
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
40
app/lib/Yiinitializr/config/settings.php
Normal file
40
app/lib/Yiinitializr/config/settings.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* Yiinitializr configuration file.
|
||||
*
|
||||
* @author Antonio Ramirez <amigo.cobos@gmail.com>
|
||||
* @link http://www.ramirezcobos.com/
|
||||
* @link http://www.2amigos.us/
|
||||
* @copyright 2013 2amigOS! Consultation Group LLC
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
||||
*/
|
||||
$dirname = dirname(__FILE__);
|
||||
$app = $dirname . '/../../..';
|
||||
$root = $app . '/..';
|
||||
|
||||
return array(
|
||||
'yii' => array(
|
||||
'path' => $app . '/lib/vendor/yiisoft/yii/framework'
|
||||
),
|
||||
'yiinitializr' => array(
|
||||
'config' => array(
|
||||
'console' => $dirname . '/console.php'
|
||||
),
|
||||
'app' => array(
|
||||
'root' => $root,
|
||||
'directories' => array(
|
||||
'config' => array(
|
||||
'main' => $app . '/config',
|
||||
'console' => $app . '/config',
|
||||
'test' => $app . '/config'
|
||||
),
|
||||
'runtime' => array(
|
||||
$app
|
||||
),
|
||||
'assets' => array(
|
||||
$root . '/www'
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user