1<?php
2/*
3 * $Id: 4b57f4d435b61b6501688394f1ff8534d4b7e93f $
4 *
5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 *
17 * This software consists of voluntary contributions made by many individuals
18 * and is licensed under the LGPL. For more information please see
19 * <http://phing.info>.
20 */
21
22require_once 'phing/listener/DefaultLogger.php';
23include_once 'phing/system/util/Properties.php';
24
25/**
26 * Uses CSS class that must be defined in the HTML page
27 * where the Phing output is displayed.
28 *
29 * If used with the -logfile option, the output
30 * will contain the text wrapped in html <span> elements
31 * with those css classes.
32 *
33 * The default classes used for differentiating
34 * the message levels can be changed by editing the
35 * phing/listener/defaults.properties file.
36 *
37 * This file can contain 5 key/value pairs:
38 * HtmlColorLogger.ERROR_CLASS=_your_css_class_name_
39 * HtmlColorLogger.WARNING_CLASS=_your_css_class_name_
40 * HtmlColorLogger.INFO_CLASS=_your_css_class_name_
41 * HtmlColorLogger.VERBOSE_CLASS=_your_css_class_name_
42 * HtmlColorLogger.DEBUG_CLASS=_your_css_class_name_
43 *
44 * This stems from the Ansi Color Logger done by Hans Lellelid:
45 *
46 * @author     Anton Stöckl <anton@stoeckl.de> (Phing HTML Color Logger)
47 * @author     Hans Lellelid <hans@xmpl.org> (Phing Ansi Color Logger)
48 * @author     Magesh Umasankar (Ant)
49 * @package    phing.listener
50 * @version    $Id: 4b57f4d435b61b6501688394f1ff8534d4b7e93f $
51 */
52class HtmlColorLogger extends DefaultLogger {
53
54    const CLASS_ERR     = 'phing_err';
55    const CLASS_VERBOSE = 'phing_verbose';
56    const CLASS_DEBUG   = 'phing_debug';
57    const CLASS_WARN    = 'phing_warn';
58    const CLASS_INFO    = 'phing_info';
59
60    const PREFIX = '<span class="';
61    const SUFFIX = '">';
62    const END_COLOR = '</span>';
63
64    private $errColor;
65    private $warnColor;
66    private $infoColor;
67    private $verboseColor;
68    private $debugColor;
69
70    private $colorsSet = false;
71
72    /**
73     * Construct new HtmlColorLogger
74     * Perform initializations that cannot be done in var declarations.
75     */
76    public function __construct() {
77        parent::__construct();
78        $this->errColor =     self::PREFIX . self::CLASS_ERR     . self::SUFFIX;
79        $this->warnColor =    self::PREFIX . self::CLASS_WARN    . self::SUFFIX;
80        $this->infoColor =    self::PREFIX . self::CLASS_INFO    . self::SUFFIX;
81        $this->verboseColor = self::PREFIX . self::CLASS_VERBOSE . self::SUFFIX;
82        $this->debugColor =   self::PREFIX . self::CLASS_DEBUG   . self::SUFFIX;
83    }
84
85    /**
86     * Set the colors to use from a property file specified in the
87     * special phing property file "phing/listener/defaults.properties".
88     */
89    private final function setColors() {
90
91        $systemColorFile = new PhingFile(Phing::getResourcePath("phing/listener/defaults.properties"));
92
93        try {
94            $prop = new Properties();
95
96            $prop->load($systemColorFile);
97
98            $err     = $prop->getProperty("HtmlColorLogger.ERROR_CLASS");
99            $warn    = $prop->getProperty("HtmlColorLogger.WARNING_CLASS");
100            $info    = $prop->getProperty("HtmlColorLogger.INFO_CLASS");
101            $verbose = $prop->getProperty("HtmlColorLogger.VERBOSE_CLASS");
102            $debug   = $prop->getProperty("HtmlColorLogger.DEBUG_CLASS");
103            if ($err !== null) {
104                $this->errColor = self::PREFIX . $err . self::SUFFIX;
105            }
106            if ($warn !== null) {
107                $this->warnColor = self::PREFIX . $warn . self::SUFFIX;
108            }
109            if ($info !== null) {
110                $this->infoColor = self::PREFIX . $info . self::SUFFIX;
111            }
112            if ($verbose !== null) {
113                $this->verboseColor = self::PREFIX . $verbose . self::SUFFIX;
114            }
115            if ($debug !== null) {
116                $this->debugColor = self::PREFIX . $debug . self::SUFFIX;
117            }
118        } catch (IOException $ioe) {
119            //Ignore exception - we will use the defaults.
120        }
121    }
122
123    /**
124     * @see DefaultLogger#printMessage
125     * @param string $message
126     * @param OutputStream $stream
127     * @param int $priority
128     */
129    protected final function printMessage($message, OutputStream $stream, $priority) {
130        if ($message !== null) {
131
132            if (!$this->colorsSet) {
133                $this->setColors();
134                $this->colorsSet = true;
135            }
136
137            $search = array('<', '>');
138            $replace = array('&lt;', '&gt;');
139            $message = str_replace($search, $replace, $message);
140
141            $search = array("\t", "\n", "\r");
142            $replace = array('&nbsp;&nbsp;&nbsp;', '<br>', '');
143            $message = str_replace($search, $replace, $message);
144
145            if (preg_match('@^( +)([^ ].+)@', $message, $matches)) {
146                $len = strlen($matches[1]);
147                $space = '&nbsp;';
148                for ($i = 1; $i < $len; $i++) {
149                    $space .= '&nbsp;';
150                }
151                $message = $space . $matches[2];
152            }
153
154            switch ($priority) {
155                case Project::MSG_ERR:
156                    $message = $this->errColor . $message . self::END_COLOR;
157                    break;
158                case Project::MSG_WARN:
159                    $message = $this->warnColor . $message . self::END_COLOR;
160                    break;
161                case Project::MSG_INFO:
162                    $message = $this->infoColor . $message . self::END_COLOR;
163                    break;
164                case Project::MSG_VERBOSE:
165                    $message = $this->verboseColor . $message . self::END_COLOR;
166                    break;
167                case Project::MSG_DEBUG:
168                    $message = $this->debugColor . $message . self::END_COLOR;
169                    break;
170            }
171
172            $stream->write($message . '<br/>');
173        }
174    }
175}
176