1<?php 2/** 3 * Helper class for the charter plugin, provides methods for rendering charts 4 * using the pChart library. 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Gina Häußge <osd@foosel.net> 8 */ 9 10// must be run within Dokuwiki 11if (!defined('DOKU_INC')) die(); 12 13if (!defined('DOKU_LF')) define('DOKU_LF', "\n"); 14if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t"); 15if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 16 17require_once(DOKU_PLUGIN.'charter/lib/pchart/pData.class.php'); 18require_once(DOKU_PLUGIN.'charter/lib/pchart/pChart.class.php'); 19 20class helper_plugin_charter extends DokuWiki_Plugin { // DokuWiki_Helper_Plugin 21 22 function getInfo() { 23 return array ( 24 'author' => 'Gina Haeussge', 25 'email' => 'osd@foosel.net', 26 'date' => @file_get_contents(DOKU_PLUGIN.'charter/VERSION'), 27 'name' => 'Charter Plugin (helper component)', 28 'desc' => 'Renders customized charts using the pChart library', 29 'url' => 'http://foosel.org/snippets/dokuwiki/charter', 30 ); 31 } 32 33 function getMethods() { 34 $result = array (); 35 $result[] = array ( 36 'name' => 'setFlags', 37 'desc' => 'sets the flags to use', 38 'params' => array( 39 'flags' => 'array', 40 ), 41 ); 42 $result[] = array ( 43 'name' => 'setData', 44 'desc' => 'sets the data to use', 45 'params' => array ( 46 'data' => 'array', 47 ), 48 ); 49 $result[] = array ( 50 'name' => 'render', 51 'desc' => 'renders the chart into the given file', 52 'params' => array ( 53 'filename' => 'string', 54 ), 55 'return' => array ( 56 'success' => 'boolean' 57 ), 58 ); 59 return $result; 60 } 61 62 /** Flags */ 63 var $flags; 64 65 /** Chart data */ 66 var $data; 67 68 /** Valid flags */ 69 var $validFlags = array( 70 'size', // size of the image, format 'width'x'height' 71 'align', // alignment of image, valid values are 'left', 'right' and 'center' 72 'type', // type of graph to generate, for valid values see below 73 'title', // title of the graph 74 75 'bgcolor', // background color 76 'legendColor', // background color of the legend 77 'graphColor', // background color of the graph area 78 'titleColor', // color of the title 79 'scaleColor', // color of the scale 80 'shadowColor', // color of the shadow 81 82 'bggradient', // background gradient, format '#RRGGBB@shades' 83 'graphGradient', // graph area gradient, format '#RRGGBB@shades' 84 85 'XAxisName', // name of X-axis 86 'YAxisName', // name of Y-axis 87 'XAxisFormat', // format of X-axis 88 'YAxisFormat', // format of Y-axis 89 'XAxisUnit', // unit of X-axis 90 'YAxisUnit', // unit of Y-axis 91 92 'fontTitle', // font for title, format 'fontfile@size' 93 'fontDefault', // font for everything else, format 'formatfile@size' 94 'fontLegend', // font for legend entries 95 96 'labelSerie', // serie to use for labels 97 'legendEntries', // entries for the legend 98 'graphLabels', // special labels to be shown in the graph, comma-separated list of 99 // Serie-No.|X-Value|Description values 100 101 'dots', // size of circles which plot the given data points, defaults to false (= not plotted) 102 'legend', // whether to show the legend, defaults to true 103 'shadow', // whether to use shadows, defaults to false 104 'grid', // whether to show the grid, defaults to true 105 'alpha', // alpha value to use for bargraphs, filled linegraphs or filled cubic curves, defaults to 50 106 'ticks', // whether to show ticks on scale 107 'decimals', // amount of decimals to display on scale 108 109 'thresholds', // values at which to draw thresholds 110 'palette', // color palette to use 111 112 'pieLabels', // whether to show labels in the pie chart, defaults to true 113 'piePercentages', // whether to show calculated percentages in pie chart, default to false 114 'pieExploded', // whether to draw pie graph in exploded state 115 ); 116 117 /** Valid chart types */ 118 var $validTypes = array( 119 'line', 120 'lineFilled', 121 'cubic', 122 'cubicFilled', 123 'bar', 124 'barStacked', 125 'barOverlayed', 126 'pie', 127 'pie3d', 128 ); 129 130 /** Default values for flags */ 131 var $flagDefaults = array(); 132 133 /** 134 * Plugin constructor, initializes default settings and prepares 135 * default flags. 136 * 137 * @author Gina Haeussge <osd@foosel.net> 138 */ 139 function helper_plugin_charter() { 140 $this->flagDefaults = array( 141 'size' => array( 142 'width' => 600, 143 'height' => 300, 144 ), 145 'align' => 'left', 146 'type' => 'line', 147 'fontDefault' => array( 148 'name' => DOKU_PLUGIN.'charter/lib/fonts/Vera.ttf', 149 'size' => 8, 150 ), 151 'fontLegend' => array( 152 'name' => DOKU_PLUGIN.'charter/lib/fonts/Vera.ttf', 153 'size' => 8, 154 ), 155 'fontTitle' => array( 156 'name' => DOKU_PLUGIN.'charter/lib/fonts/VeraBd.ttf', 157 'size' => 10, 158 ), 159 'legend' => true, 160 'grid' => true, 161 'alpha' => 50, 162 'dots' => false, 163 'shadow' => false, 164 'ticks' => true, 165 'decimals' => 0, 166 167 'bgcolor' => array(250, 250, 250), 168 'graphColor' => array(255, 255, 255), 169 'legendColor' => array(250, 250, 250), 170 'titleColor' => array(0, 0, 0), 171 'scaleColor' => array(150, 150, 150), 172 'shadowColor' => array(200, 200, 200), 173 174 'pieLabels' => false, 175 'piePercentages' => true, 176 'pieExploded' => false, 177 ); 178 } 179 180 /** 181 * Sets the flags from the given array. While doing so also validates and 182 * postprocesses them, making sure to fall back to usable default values 183 * where necessary. 184 * 185 * @param flags flags to set 186 * 187 * @author Gina Häußge <osd@foosel.net> 188 */ 189 function setFlags($flags = array()) { 190 foreach ($flags as $key => $val) { 191 if (!in_array($key, $this->validFlags)) 192 unset($flags[$key]); 193 194 if (($key == 'fontTitle') || ($key == 'fontDefault') || ($key == 'fontLegend')) { 195 // validate fontdefinitions 196 list($fontname, $fontsize) = explode('@', $val, 2); 197 $flags[$key] = array( 198 'name' => DOKU_PLUGIN.'charter/lib/fonts/' . $fontname, 199 'size' => $fontsize, 200 ); 201 if (!file_exists($flags[$key]['name'])) 202 unset($flags[$key]); 203 } else if ($key == 'size') { 204 // validate and process size 205 list($w, $h) = $this->_trimArray(explode('x', $val, 2)); 206 $flags[$key] = array( 207 'width' => $w, 208 'height' => $h, 209 ); 210 211 if ($w < 0 || $h < 0) 212 unset($flags[$key]); 213 } else if ($key == 'align') { 214 // validate and process alignment 215 if (!in_array($val, array('left', 'right', 'center'))) 216 unset($flags[$key]); 217 } else if ($key == 'grid' || $key == 'legend' || $key == 'shadow' || $key == 'ticks' || $key == 'pieLabels' || $key == 'piePercentages' || $key == 'pieExploded') { 218 // validate and process boolean settings 219 if ($val == 'true' || $val == '1' || $val == 'on') 220 $flags[$key] = true; 221 else if ($val == 'false' || $val == '0' || $val == 'off') 222 $flags[$key] = false; 223 else 224 unset($flags[$key]); 225 } else if ($key == 'legendEntries' || $key == 'thresholds') { 226 // process legend entries and thresholds 227 $flags[$key] = $this->_trimArray(explode(',', $flags[$key])); 228 } else if ($key == 'type') { 229 // validate graph type 230 if (!in_array($val, $this->validTypes)) 231 unset($flags[$key]); 232 } else if ($key == 'alpha') { 233 // validate alpha setting 234 if (!is_numeric($val) || $val < 0 || $val > 100) 235 unset($flags[$key]); 236 } else if ($key == 'dots' || $key == 'decimals') { 237 // validate dot and decimals setting 238 if (!is_numeric($val) || $val < 0) 239 unset($flags[$key]); 240 } else if ($key == 'bgcolor' || $key == 'legendColor' || $key == 'graphColor' || $key == 'titleColor' || $key == 'scaleColor' || $key == 'shadowColor') { 241 // validate and process color definitions 242 $flags[$key] = $this->_parseRGB($val); 243 if (!$flags[$key]) 244 unset($flags[$key]); 245 } else if ($key == 'palette') { 246 // validate and process palette settings 247 $flags[$key] = DOKU_PLUGIN.'charter/lib/palettes/' . $val . '.txt'; 248 if (!file_exists($flags[$key])) 249 unset($flags[$key]); 250 } else if ($key == 'graphLabels') { 251 // validate and process graph labels 252 $flags[$key] = $this->_trimArray(explode(',', $flags[$key])); 253 for ($i = 0; $i < count($flags[$key]); $i++) { 254 $flags[$key][$i] = $this->_trimArray(explode('|', $flags[$key][$i])); 255 if (count($flags[$key][$i]) != 3) { 256 unset($flags[$key]); 257 break; 258 } 259 if (!is_numeric($flags[$key][$i][0]) || $flags[$key][$i][0] < 0) { 260 unset($flags[$key]); 261 break; 262 } 263 } 264 } else if ($key == 'XAxisFormat' || $key == 'YAxisFormat') { 265 // validate axis format settings 266 if (!in_array($val, array('number', 'time', 'date', 'metric', 'currency'))) 267 unset($flags[$key]); 268 } else if ($key == 'bggradient' || $key == 'graphGradient') { 269 // validate and process background and graph gradients 270 list($color, $shades) = $this->_trimArray(explode('@', $val, 2)); 271 $rgb = $this->_parseRGB($color); 272 if (!$rgb || !is_numeric($shades) || $shades < 0) 273 unset($flags[$key]); 274 275 $flags[$key] = array( 276 'color' => $rgb, 277 'shades' => $shades, 278 ); 279 } 280 } 281 282 foreach ($this->flagDefaults as $key => $val) { 283 if (!isset($flags[$key])) 284 $flags[$key] = $val; 285 } 286 287 $this->flags = $flags; 288 } 289 290 /** 291 * Sets the data to use. 292 * 293 * @param data the data 294 * 295 * @author Gina Häußge <osd@foosel.net> 296 */ 297 function setData($data = array()) { 298 $this->data = $data; 299 } 300 301 /** 302 * Renders the graph into given file. 303 * 304 * @param filename the file to render to 305 * @return true on success, false on failure 306 * 307 * @author Gina Häußge <osd@foosel.net> 308 */ 309 function render($filename) { 310 if (!$filename) 311 return false; 312 313 // parse input data 314 $csv = $this->_parseCsv($this->data); 315 if (!$csv) 316 return false; 317 318 // create pData instance 319 $pdata = $this->_createGraphData($csv); 320 if (!$pdata) 321 return false; 322 323 // prepare pChart instance based on graph type 324 switch ($this->flags['type']) { 325 case 'line': 326 case 'lineFilled': 327 case 'cubic': 328 case 'cubicFilled': 329 case 'bar': 330 case 'barStacked': 331 case 'barOverlayed': 332 default: 333 $chart = $this->_createLineGraph($pdata); 334 break; 335 case 'pie': 336 case 'pie3d': 337 case 'pieExploded': 338 $chart = $this->_createPieGraph($pdata); 339 break; 340 } 341 if (!$chart) 342 return false; 343 344 // render graph into file 345 if (!$chart->Render($filename)) 346 return false; 347 348 return true; 349 } 350 351 /** 352 * Creates a pData instance from flags and data. 353 * 354 * @param csv 2d array containing the data series 355 * @return object pData object containing both data and data descriptions to use 356 * 357 * @author Gina Häußge <osd@foosel.net> 358 */ 359 function _createGraphData($csv) { 360 $pdata = new pData(); 361 362 // set axis names 363 if (isset($this->flags['XAxisName'])) 364 $pdata->SetXAxisName($this->flags['XAxisName']); 365 if (isset($this->flags['YAxisName'])) 366 $pdata->SetYAxisName($this->flags['YAxisName']); 367 368 // set axis units 369 if (isset($this->flags['XAxisUnit'])) 370 $pdata->SetXAxisUnit($this->flags['XAxisUnit']); 371 if (isset($this->flags['YAxisUnit'])) 372 $pdata->SetYAxisUnit($this->flags['YAxisUnit']); 373 374 // set axis formats 375 if (isset($this->flags['XAxisFormat'])) 376 $pdata->SetXAxisFormat($this->flags['XAxisFormat']); 377 if (isset($this->flags['YAxisFormat'])) 378 $pdata->SetYAxisFormat($this->flags['YAxisFormat']); 379 380 // add series to graph data 381 $serie = 1; 382 foreach ($csv as $row) { 383 $pdata->AddPoint($row, 'Serie' . $serie); 384 if (isset($this->flags['legendEntries'][$serie-1])) 385 $pdata->SetSerieName($this->flags['legendEntries'][$serie-1], 'Serie' . $serie); 386 $serie++; 387 } 388 $pdata->AddAllSeries(); 389 390 // if label serie is defined, mark it as such 391 if (isset($this->flags['labelSerie'])) { 392 $labelSerie = 'Serie' . $this->flags['labelSerie']; 393 $pdata->RemoveSerie($labelSerie); 394 $pdata->SetAbsciseLabelSerie($labelSerie); 395 } 396 397 return $pdata; 398 } 399 400 /** 401 * Creates the pChart instance used to render the line/curve/bar graph. 402 * 403 * @param pdata the pData instance containing the data to plot 404 * @return object a renderable pChart object 405 * 406 * @author Gina Häußge <osd@foosel.net> 407 */ 408 function _createLineGraph($pdata) { 409 $pchart = new pChart($this->flags['size']['width'], $this->flags['size']['height']); 410 $pchart->drawBackground($this->flags['bgcolor'][0], $this->flags['bgcolor'][1], $this->flags['bgcolor'][2]); 411 412 // draw background gradient 413 if (isset($this->flags['bggradient'])) 414 $pchart->drawGraphAreaGradient($this->flags['bggradient']['color'][0], $this->flags['bggradient']['color'][1], $this->flags['bggradient']['color'][2], $this->flags['bggradient']['shades'], TARGET_BACKGROUND); 415 416 // set palette 417 if (isset($this->flags['palette'])) 418 $pchart->loadColorPalette($this->flags['palette']); 419 420 // get legend size 421 $pchart->setFontProperties($this->flags['fontLegend']['name'], $this->flags['fontLegend']['size']); 422 $legendSize = array(0, 0); 423 if ($this->flags['legend']) 424 $legendSize = $pchart->getLegendBoxSize($pdata->GetDataDescription()); 425 426 // draw graph area 427 $pchart->setFontProperties($this->flags['fontDefault']['name'], $this->flags['fontDefault']['size']); 428 $pchart->setGraphArea(50, 30, $this->flags['size']['width'] - $legendSize[0] - 40, $this->flags['size']['height'] - 50); 429 $pchart->drawGraphArea($this->flags['graphColor'][0], $this->flags['graphColor'][1], $this->flags['graphColor'][2], true); 430 431 // draw graph area gradient 432 if (isset($this->flags['graphGradient'])) 433 $pchart->drawGraphAreaGradient($this->flags['graphGradient']['color'][0], $this->flags['graphGradient']['color'][1], $this->flags['graphGradient']['color'][2], $this->flags['graphGradient']['shades']); 434 435 // draw legend 436 if ($this->flags['legend']) { 437 $pchart->setFontProperties($this->flags['fontLegend']['name'], $this->flags['fontLegend']['size']); 438 $pchart->drawLegend($this->flags['size']['width'] - $legendSize[0] - 15, 30, $pdata->GetDataDescription(), $this->flags['legendColor'][0], $this->flags['legendColor'][1], $this->flags['legendColor'][2]); 439 $pchart->setFontProperties($this->flags['fontDefault']['name'], $this->flags['fontDefault']['size']); 440 } 441 442 // draw scale 443 switch ($this->flags['type']) { 444 case 'bar': 445 case 'barOverlayed': 446 $pchart->drawScale($pdata->GetData(), $pdata->GetDataDescription(), SCALE_START0, $this->flags['scaleColor'][0], $this->flags['scaleColor'][1], $this->flags['scaleColor'][2], $this->flags['ticks'], 0, $this->flags['decimals'], true); 447 break; 448 case 'barStacked': 449 $pchart->drawScale($pdata->GetData(), $pdata->GetDataDescription(), SCALE_ADDALLSTART0, $this->flags['scaleColor'][0], $this->flags['scaleColor'][1], $this->flags['scaleColor'][2], $this->flags['ticks'], 0, $this->flags['decimals'], true); 450 break; 451 default: 452 $pchart->drawScale($pdata->GetData(), $pdata->GetDataDescription(), SCALE_START0, $this->flags['scaleColor'][0], $this->flags['scaleColor'][1], $this->flags['scaleColor'][2], $this->flags['ticks'], 0, $this->flags['decimals'], false); 453 break; 454 } 455 456 // draw grid 457 if ($this->flags['grid']) 458 $pchart->drawGrid(4, true, 230, 230, 230, $this->flags['alpha']); 459 460 // draw thresholds 461 if (isset($this->flags['thresholds'])) { 462 foreach ($this->flags['thresholds'] as $threshold) { 463 $pchart->drawTreshold($threshold, 143, 55, 72, true, true); 464 } 465 } 466 467 // draw graph 468 if ($this->flags['shadow'] && in_array($this->flags['type'], array('line', 'lineFilled', 'cubic', 'cubicFilled'))) 469 $pchart->setShadowProperties(3,3,$this->flags['shadowColor'][0],$this->flags['shadowColor'][1],$this->flags['shadowColor'][2],30,4); 470 if ($this->flags['dots']) 471 $pchart->drawPlotGraph($pdata->GetData(), $pdata->GetDataDescription(), $this->flags['dots']); 472 switch ($this->flags['type']) { 473 case 'line': 474 $pchart->drawLineGraph($pdata->GetData(), $pdata->GetDataDescription()); 475 break; 476 case 'lineFilled': 477 $pchart->drawFilledLineGraph($pdata->GetData(), $pdata->GetDataDescription(), $this->flags['alpha']); 478 break; 479 case 'cubic': 480 $pchart->drawCubicCurve($pdata->GetData(), $pdata->GetDataDescription()); 481 break; 482 case 'cubicFilled': 483 $pchart->drawFilledCubicCurve($pdata->GetData(), $pdata->GetDataDescription(), 0.1, $this->flags['alpha']); 484 break; 485 case 'bar': 486 $pchart->drawBarGraph($pdata->GetData(), $pdata->GetDataDescription(), $this->flags['shadow'], $this->flags['alpha']); 487 break; 488 case 'barStacked': 489 $pchart->drawStackedBarGraph($pdata->GetData(), $pdata->GetDataDescription(), $this->flags['alpha']); 490 break; 491 case 'barOverlayed': 492 $pchart->drawOverlayBarGraph($pdata->GetData(), $pdata->GetDataDescription(), $this->flags['alpha']); 493 break; 494 } 495 $pchart->clearShadow(); 496 497 // draw graph labels 498 if (isset($this->flags['graphLabels'])) { 499 $pchart->setFontProperties($this->flags['fontLegend']['name'], $this->flags['fontLegend']['size']); 500 foreach($this->flags['graphLabels'] as $label) { 501 $pchart->setLabel($pdata->GetData(), $pdata->GetDataDescription(), 'Serie' . $label[0], $label[1], $label[2]); 502 } 503 } 504 505 // draw title 506 if (isset($this->flags['title'])) { 507 $pchart->setFontProperties($this->flags['fontTitle']['name'], $this->flags['fontTitle']['size']); 508 $pchart->drawTitle(50, 20, $this->flags['title'], $this->flags['titleColor'][0], $this->flags['titleColor'][1], $this->flags['titleColor'][2], $this->flags['size']['width'] - $legendSize[0] - 40); 509 } 510 511 return $pchart; 512 } 513 514 /** 515 * Creates the pChart instance used to render the pie graph. 516 * 517 * @param pdata the pData instance containing the data to plot 518 * @return object a renderable pChart object 519 * 520 * @author Gina Häußge <osd@foosel.net> 521 */ 522 function _createPieGraph($pdata) { 523 $pchart = new pChart($this->flags['size']['width'], $this->flags['size']['height']); 524 $pchart->drawBackground($this->flags['bgcolor'][0], $this->flags['bgcolor'][1], $this->flags['bgcolor'][2]); 525 526 // set palette 527 if (isset($this->flags['palette'])) 528 $pchart->loadColorPalette($this->flags['palette']); 529 530 // get legend size 531 $pchart->setFontProperties($this->flags['fontLegend']['name'], $this->flags['fontLegend']['size']); 532 $legendSize = array(0, 0); 533 if ($this->flags['legend']) 534 $legendSize = $pchart->getPieLegendBoxSize($pdata->GetData(), $pdata->GetDataDescription()); 535 536 // calculate center positiong and radius of pie chart 537 $center = array( 538 (int)(($this->flags['size']['width'] - $legendSize[0] - 20) / 2), 539 (int)($this->flags['size']['height'] / 2), 540 ); 541 $radius = min($center[0], $center[1]) - 40; 542 if ($this->flags['pieExploded']) 543 $radius -= 10; 544 545 // draw legend 546 $pchart->setFontProperties($this->flags['fontDefault']['name'], $this->flags['fontDefault']['size']); 547 if ($this->flags['legend']) { 548 $pchart->setFontProperties($this->flags['fontLegend']['name'], $this->flags['fontLegend']['size']); 549 $pchart->drawPieLegend($this->flags['size']['width'] - $legendSize[0] - 15, 30, $pdata->GetData(), $pdata->GetDataDescription(), $this->flags['legendColor'][0], $this->flags['legendColor'][1], $this->flags['legendColor'][2]); 550 $pchart->setFontProperties($this->flags['fontDefault']['name'], $this->flags['fontDefault']['size']); 551 } 552 553 // draw graph 554 $labeltype = PIE_NO_LABEL; 555 if ($this->flags['pieLabels'] && $this->flags['piePercentages']) 556 $labeltype = PIE_PERCENTAGE_LABEL; 557 else if ($this->flags['pieLabels']) 558 $labeltype = PIE_LABELS; 559 else if ($this->flags['piePercentages']) 560 $labeltype = PIE_PERCENTAGE; 561 if ($this->flags['shadow']) 562 $pchart->setShadowProperties(3,3,$this->flags['shadowColor'][0],$this->flags['shadowColor'][1],$this->flags['shadowColor'][2], 30, 4); 563 switch ($this->flags['type']) { 564 case 'pie': 565 if ($this->flags['pieExploded']) { 566 $pchart->drawFlatPieGraphWithShadow($pdata->GetData(), $pdata->GetDataDescription(), $center[0], $center[1], $radius, $labeltype, 10, $this->flags['decimals']); 567 } else { 568 $pchart->drawBasicPieGraph($pdata->GetData(), $pdata->GetDataDescription(), $center[0], $center[1], $radius, $labeltype, 255, 255, 255, $this->flags['decimals']); 569 } 570 break; 571 case 'pie3d': 572 $pchart->drawPieGraph($pdata->GetData(), $pdata->GetDataDescription(), $center[0], $center[1], $radius, $labeltype, true, 60, 20, (($this->flags['pieExploded']) ? 10 : 0), $this->flags['decimals']); 573 break; 574 } 575 $pchart->clearShadow(); 576 577 // draw title 578 if (isset($this->flags['title'])) { 579 $pchart->setFontProperties($this->flags['fontTitle']['name'], $this->flags['fontTitle']['size']); 580 $pchart->drawTitle(50, 20, $this->flags['title'], $this->flags['titleColor'][0], $this->flags['titleColor'][1], $this->flags['titleColor'][2], $this->flags['size']['width'] - $legendSize[0] - 40); 581 $pchart->setFontProperties($this->flags['fontLegend']['name'], $this->flags['fontLegend']['size']); 582 } 583 584 return $pchart; 585 } 586 587 /** 588 * Parses the given CSV string or line array into a 589 * two-dimensional array. Very simplistic approach which 590 * does not support quoted strings and such, but should 591 * be sufficient for basic graph data. 592 * 593 * @param data the data to parse 594 * @return array two-dimensional array containing the parsed data 595 * 596 * @author Gina Häußge <osd@foosel.net> 597 */ 598 function _parseCsv($data) { 599 if (!is_array($data)) 600 $data = explode("\n", $data); 601 602 $output = array(); 603 foreach($data as $row) { 604 $values = $this->_trimArray(explode(',', $row)); 605 array_push($output, $values); 606 } 607 608 return $output; 609 } 610 611 /** 612 * Trims all items in a given array. 613 * 614 * @param a the array to trim 615 * @return array trimmed array 616 * 617 * @author Gina Häußge <osd@foosel.net> 618 */ 619 function _trimArray($a) { 620 if (!is_array($a)) 621 return $a; 622 623 for ($i = 0; $i < count($a); $i++) { 624 $a[$i] = trim($a[$i]); 625 } 626 627 return $a; 628 } 629 630 /** 631 * Parses a given HTML RGB color into three 8 bit sized 632 * integers representing the color. 633 * 634 * Leading # is optional. Both six and three character wide 635 * color definitions are supported. 636 * 637 * @param input a string containing a RGB color 638 * @param array 3d array containing integer representations of red, green and blue 639 * 640 * @author Gina Häußge <osd@foosel.net> 641 */ 642 function _parseRGB($input) { 643 if ($input[0] == '#') 644 $input = substr($input, 1); 645 646 if (strlen($input) == 6) { 647 // #RRGGBB 648 $r = hexdec(substr($input, 0, 2)); 649 $g = hexdec(substr($input, 2, 2)); 650 $b = hexdec(substr($input, 4, 2)); 651 } else if (strlen($input) == 3) { 652 // #RGB 653 $r = hexdec($input[0]); 654 $g = hexdec($input[1]); 655 $b = hexdec($input[2]); 656 657 $r = $r * 16 + $r; 658 $g = $g * 16 + $g; 659 $b = $b * 16 + $b; 660 } else { 661 return false; 662 } 663 664 return array($r, $g, $b); 665 } 666 667}