Skip to content

Instantly share code, notes, and snippets.

@fragoulis
Last active January 16, 2018 06:18
Show Gist options
  • Save fragoulis/6c75b4f28e4f9447242e to your computer and use it in GitHub Desktop.
Save fragoulis/6c75b4f28e4f9447242e to your computer and use it in GitHub Desktop.
Yii very handy console extension for logging timing and progress of an operation with colors and everything :)
<?php
/**
* Copyright 2014 John Fragkoulis
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Console command extensions.
*
* Example #1: Print a mesage
* ```php
* $this->log('my message');
* ```
*
* Example #2: Begin a timely operation
* ```php
* $this->beginTiming('Starting ... ');
* foreach($rows as $row) { ... }
* $this->endTiming();
* ```
*
* Example #3: Begin a timely operation with progress
* ```php
* $this->beginProgress($count, 'Starting ... ');
* foreach($rows as $index => $row) {
* ...
* $this->updateProgress($index);
* }
* $this->endProgress();
* ```
*
* @author John Fragkoulis <john.fragkoulis@gmail.com>
*/
class ConsoleCommand extends CConsoleCommand
{
public $showTimeAtTheEnd = true;
private $_timerStack;
private $_progressTotal;
private $_rate;
private $_wide = 5;
private $_numberFormatter;
# first define colors to use
protected static $foregroundColors = [
'black' => '0;30',
'dark_gray' => '1;30',
'blue' => '0;34',
'light_blue' => '1;34',
'green' => '0;32',
'light_green' => '1;32',
'cyan' => '0;36',
'light_cyan' => '1;36',
'red' => '0;31',
'light_red' => '1;31',
'purple' => '0;35',
'light_purple' => '1;35',
'brown' => '0;33',
'yellow' => '1;33',
'light_gray' => '0;37',
'white' => '1;37',
];
protected static $backgroundColors = [
'black' => '40',
'red' => '41',
'green' => '42',
'yellow' => '43',
'blue' => '44',
'magenta' => '45',
'cyan' => '46',
'light_gray' => '47',
];
/**
* [beforeAction description]
* @param [type] $action [description]
* @param [type] $params [description]
* @return [type] [description]
*/
protected function beforeAction($action, $params)
{
$this->_timerStack = new CStack();
ob_start();
$this->log("\n");
$this->createTimer();
return parent::beforeAction($action, $params);
}
/**
* [afterAction description]
* @param [type] $action [description]
* @param [type] $params [description]
* @return [type] [description]
*/
protected function afterAction($action, $params)
{
if ($this->showTimeAtTheEnd)
echo "\n ** Finished in " . $this->destroyTimer(true) . " **\n";
echo "\n";
flush();
return parent::afterAction($action, $params);
}
/**
* [log description]
* @param [type] $string [description]
* @return [type] [description]
*/
protected function log($string, $foreground = null, $background = null)
{
if (is_object($string) || is_array($string))
$string = CVarDumper::dumpAsString($string);
if ($string == '')
return;
if ($foreground || $background) {
echo $this->color($string, $foreground, $background);
} else {
echo $string;
}
ob_flush();
}
protected function color($string, $foreground_color = null, $background_color = null)
{
$colored_string = '';
// Check if given foreground color found
if (isset(static::$foregroundColors[$foreground_color])) {
$colored_string .= "\033[" . static::$foregroundColors[$foreground_color] . 'm';
}
// Check if given background color found
if (isset(static::$backgroundColors[$background_color])) {
$colored_string .= "\033[" . static::$backgroundColors[$background_color] . 'm';
}
// Add string and end coloring
$colored_string .= $string . "\033[0m";
return $colored_string;
}
/**
* [beginProgress description]
* @param [type] $total [description]
* @param integer $rate [description]
* @param string $message [description]
* @return [type] [description]
*/
public function beginProgress($total, $message='', $rate=100)
{
$this->_progressTotal = $total;
$this->_rate = $rate;
$this->createTimer();
$this->log($message . str_pad('0%', $this->_wide, ' ', STR_PAD_LEFT));
}
/**
* [updateProgress description]
* @param [type] $progress [description]
* @return [type] [description]
*/
public function updateProgress($progress)
{
if ($progress === true || $this->_rate === null || $progress % $this->_rate === 0) {
if ($progress === true)
$progress = $this->_progressTotal;
echo "\033[{$this->_wide}D";
$pc = $this->numberFormatter->formatPercentage((float)($progress / $this->_progressTotal));
$this->log(str_pad($pc, $this->_wide, ' ', STR_PAD_LEFT));
}
}
/**
* [endProgress description]
* @param string $message [description]
* @return [type] [description]
*/
public function endProgress($message='')
{
$this->updateProgress(true);
$time = $this->destroyTimer(true);
$this->log("$message ($time)\n");
}
/**
* [beginTiming description]
* @param [type] $message [description]
* @param integer $rate [description]
* @return [type] [description]
*/
protected function beginTiming($message, $rate = 100)
{
$this->log($message);
$this->createTimer();
}
protected function endTiming($message = 'OK')
{
$time = $this->destroyTimer(true);
$this->log("$message ($time)\n");
}
/**
* [beginTimer description]
* @param boolean $coreTimer [description]
* @return [type] [description]
*/
protected function createTimer()
{
$this->_timerStack->push(microtime(true));
}
/**
* [endTimer description]
* @param [type] $id [description]
* @param boolean $format [description]
* @return [type] [description]
*/
protected function destroyTimer($format = false)
{
$time = $this->_timerStack->pop();
if ($time === null)
throw new CException('The is no timer to return.');
$delta = microtime(true) - $time;
if ($format)
return Yii::app()->numberFormatter->format('#0.00', $delta) . 's';
else
return $delta;
}
public function getNumberFormatter()
{
if ($this->_numberFormatter === null) {
$this->_numberFormatter = Yii::app()->numberFormatter;
}
return $this->_numberFormatter;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment