<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Zend\Db\Sql\Predicate;

class 
Like implements PredicateInterface
{

    
/**
     * @var string
     */
    
protected $specification '%1$s LIKE %2$s';

    
/**
     * @var string
     */
    
protected $identifier '';

    
/**
     * @var string
     */
    
protected $like '';

    
/**
     * @param string $identifier
     * @param string $like
     */
    
public function __construct($identifier null$like null)
    {
        if (
$identifier) {
            
$this->setIdentifier($identifier);
        }
        if (
$like) {
            
$this->setLike($like);
        }
    }

    
/**
     * @param $identifier
     */
    
public function setIdentifier($identifier)
    {
        
$this->identifier $identifier;
    }

    
/**
     * @return string
     */
    
public function getIdentifier()
    {
        return 
$this->identifier;
    }

    
/**
     * @param $like
     */
    
public function setLike($like)
    {
        
$this->like $like;
    }

    
/**
     * @return string
     */
    
public function getLike()
    {
        return 
$this->like;
    }

    
/**
     * @param $specification
     */
    
public function setSpecification($specification)
    {
        
$this->specification $specification;
    }

    
/**
     * @return string
     */
    
public function getSpecification()
    {
        return 
$this->specification;
    }

    
/**
     * @return array
     */
    
public function getExpressionData()
    {
        return array(
            array(
$this->specification, array($this->identifier$this->like), array(self::TYPE_IDENTIFIERself::TYPE_VALUE))
        );
    }
}
    foreach (
$moduleManager->getLoadedModules(false) as $name => $module) {
                
// Strict-type on ConsoleUsageProviderInterface, or duck-type
                // on the method it defines
                
if (!$module instanceof ConsoleUsageProviderInterface
                    
&& !method_exists($module'getConsoleUsage')
                ) {
                    continue; 
// this module does not provide usage info
                
}

                
// We prepend the usage by the module name (printed in red), so that each module is
                // clearly visible by the user
                
$moduleName sprintf("%s\n%s\n%s\n",
                    
str_repeat('-'$console->getWidth()),
                    
$name,
                    
str_repeat('-'$console->getWidth())
                );

                
$moduleName $console->colorize($moduleNameColorInterface::RED);

                
$usage $module->getConsoleUsage($console);

                
// Normalize what we got from the module or discard
                
if (is_array($usage)) {
                    
array_unshift($usage$moduleName);
                    
$usageInfo[$name] = $usage;
                } elseif (
is_string($usage)) {
                    
$usageInfo[$name] = array($moduleName$usage);
                }
            }
        }

        
/*
         * Handle an application with no usage information
         */
        
if (!count($usageInfo)) {
            
// TODO: implement fetching available console routes from router
            
return '';
        }

        
/*
         * Transform arrays in usage info into columns, otherwise join everything together
         */
        
$result    '';
        
$table     false;
        
$tableCols 0;
        
$tableType 0;
        foreach (
$usageInfo as $moduleName => $usage) {
            if (!
is_string($usage) && !is_array($usage)) {
                throw new 
RuntimeException(sprintf(
                    
'Cannot understand usage info for module "%s"',
                    
$moduleName
                
));
            }

            if (
is_string($usage)) {
                
// It's a plain string - output as is
                
$result .= $usage "\n";
                continue;
            }

            
// It's an array, analyze it
            
foreach ($usage as $a => $b) {
                
/*
                 * 'invocation method' => 'explanation'
                 */
                
if (is_string($a) && is_string($b)) {
                    if ((
$tableCols !== || $tableType != 1) && $table !== false) {
                        
// render last table
                        
$result .= $this->renderTable($table$tableCols$console->getWidth());
                        
$table   false;

                            
// add extra newline for clarity
                        
$result .= "\n";
                    }

                    
// Colorize the command
                    
$a $console->colorize($scriptName ' ' $aColorInterface::GREEN);

                    
$tableCols 2;
                    
$tableType 1;
                    
$table[]   = array($a$b);
                    continue;
                }

                
/*
                 * array('--param', '--explanation')
                 */
                
if (is_array($b)) {
                    if ((
count($b) != $tableCols || $tableType != 2) && $table !== false) {
                        
// render last table
                        
$result .= $this->renderTable($table$tableCols$console->getWidth());
                        
$table   false;

                        
// add extra newline for clarity
                        
$result .= "\n";
                    }

                    
$tableCols count($b);
                    
$tableType 2;
                    
$table[]   = $b;
                    continue;
                }

                
/*
                 * 'A single line of text'
                 */
                
if ($table !== false) {
                    
// render last table
                    
$result .= $this->renderTable($table$tableCols$console->getWidth());
                    
$table   false;

                    
// add extra newline for clarity
                    
$result .= "\n";
                }

                
$tableType 0;
                
$result   .= $b "\n";
            }
        }

        
// Finish last table
        
if ($table !== false) {
            
$result .= $this->renderTable($table$tableCols$console->getWidth());
        }

        return 
$result;
    }

    
/**
     * Render a text table containing the data provided, that will fit inside console window's width.
     *
     * @param  $data
     * @param  $cols
     * @param  $consoleWidth
     * @return string
     */
    
protected function renderTable($data$cols$consoleWidth)
    {
        
$result  '';
        
$padding 2;


        
// If there is only 1 column, just concatenate it
        
if ($cols == 1) {
            foreach (
$data as $row) {
                
$result .= $row[0] . "\n";
            }
            return 
$result;
        }

        
// Get the string wrapper supporting UTF-8 character encoding
        
$strWrapper StringUtils::getWrapper('UTF-8');

        
// Determine max width for each column
        
$maxW = array();
        for (
$x 1$x <= $cols$x += 1) {
            
$maxW[$x] = 0;
            foreach (
$data as $row) {
                
$maxW[$x] = max($maxW[$x], $strWrapper->strlen($row[$x-1]) + $padding 2);
            }
        }

        
/*
         * Check if the sum of x-1 columns fit inside console window width - 10
         * chars. If columns do not fit inside console window, then we'll just
         * concatenate them and output as is.
         */
        
$width 0;
        for (
$x 1$x $cols$x += 1) {
            
$width += $maxW[$x];
        }

        if (
$width >= $consoleWidth 10) {
            foreach (
$data as $row) {
                
$result .= implode("    "$row) . "\n";
            }
            return 
$result;
        }

        
/*
         * Use Zend\Text\Table to render the table.
         * The last column will use the remaining space in console window
         * (minus 1 character to prevent double wrapping at the edge of the
         * screen).
         */
        
$maxW[$cols] = $consoleWidth $width -1;
        
$table       = new Table\Table();
        
$table->setColumnWidths($maxW);
        
$table->setDecorator(new Table\Decorator\Blank());
        
$table->setPadding(2);

        foreach (
$data as $row) {
            
$table->appendRow($row);
        }

        return 
$table->render();
    }

    
/**
     * Report the 404 reason and/or exceptions
     *
     * @param  \Zend\EventManager\EventInterface $e
     * @return string
     */
    
protected function reportNotFoundReason($e)
    {
        if (!
$this->displayNotFoundReason()) {
            return 
'';
        }
        
$exception $e->getParam('exception'false);
        if (!
$exception && !$this->reason) {
            return 
'';
        }

        
$reason    = (isset($this->reason) && !empty($this->reason)) ? $this->reason 'unknown';
        
$reasons   = array(
            
Application::ERROR_CONTROLLER_NOT_FOUND => 'Could not match to a controller',
            
Application::ERROR_CONTROLLER_INVALID   => 'Invalid controller specified',
            
Application::ERROR_ROUTER_NO_MATCH      => 'Invalid arguments or no arguments provided',
            
'unknown'                               => 'Unknown',
        );
        
$report sprintf("\nReason for failure: %s\n"$reasons[$reason]);

        while (
$exception instanceof \Exception) {
            
$report   .= sprintf("Exception: %s\nTrace:\n%s\n"$exception->getMessage(), $exception->getTraceAsString());
            
$exception $exception->getPrevious();
        }
        return 
$report;
    }
}