mirror of
https://github.com/salesagility/SuiteCRM.git
synced 2024-12-22 12:28:31 +00:00
73ded274ee
# Conflicts: # .codecov.yml # .travis.yml # composer.lock # include/database/DBManager.php # include/phpmailer/class.phpmailer.php # include/phpmailer/extras/htmlfilter.php # include/tcpdf/fonts/utils/makefont.php # modules/AOD_Index/Lib/Zend/Search/Exception.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Text.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Text/CaseInsensitive.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/TextNum.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/TextNum/CaseInsensitive.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8/CaseInsensitive.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8Num/CaseInsensitive.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/Token.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/LowerCase.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/LowerCaseUtf8.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/ShortWords.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Analysis/TokenFilter/StopWords.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Docx.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Exception.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Document/OpenXml.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Pptx.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Document/Xlsx.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Exception.php # modules/AOD_Index/Lib/Zend/Search/Lucene/FSM.php # modules/AOD_Index/Lib/Zend/Search/Lucene/FSMAction.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Field.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Index/DictionaryLoader.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Index/DocsFilter.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Index/FieldInfo.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Index/Term.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Index/TermInfo.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Index/TermsPriorityQueue.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Interface/MultiSearcher.php # modules/AOD_Index/Lib/Zend/Search/Lucene/LockManager.php # modules/AOD_Index/Lib/Zend/Search/Lucene/MultiSearcher.php # modules/AOD_Index/Lib/Zend/Search/Lucene/PriorityQueue.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/BooleanExpressionRecognizer.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Highlighter/Default.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Empty.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Insignificant.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Preprocessing.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Range.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Term.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Query/Wildcard.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryEntry.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryHit.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryParserContext.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryParserException.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/QueryToken.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Similarity.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Weight.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Search/Weight/Empty.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/Directory.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/Directory/Filesystem.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/File/Filesystem.php # modules/AOD_Index/Lib/Zend/Search/Lucene/Storage/File/Memory.php # modules/Administration/metadata/adminpaneldefs.php # modules/Audit/Audit.php # modules/Calendar/CalendarDisplay.php # modules/Calls/Call.php # modules/Contacts/BusinessCard.php # modules/UpgradeWizard/language/en_us.lang.php # modules/Users/authentication/LDAPAuthenticate/LDAPAuthenticateUser.php # service/v3/SugarWebServiceImplv3.php # service/v4/SugarWebServiceUtilv4.php # tests/unit/phpunit/data/SugarBeanTest.php # themes/SuiteP/css/Dawn/style.css # themes/SuiteP/css/Day/style.css # themes/SuiteP/css/Dusk/style.css # themes/SuiteP/css/Night/style.css
744 lines
30 KiB
PHP
Executable File
744 lines
30 KiB
PHP
Executable File
<?php
|
|
/**
|
|
*
|
|
* SugarCRM Community Edition is a customer relationship management program developed by
|
|
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
|
|
*
|
|
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
|
|
* Copyright (C) 2011 - 2018 SalesAgility Ltd.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU Affero General Public License version 3 as published by the
|
|
* Free Software Foundation with the addition of the following permission added
|
|
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
|
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
|
|
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License along with
|
|
* this program; if not, see http://www.gnu.org/licenses or write to the Free
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301 USA.
|
|
*
|
|
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
|
|
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of this program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU Affero General Public License version 3.
|
|
*
|
|
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
|
* these Appropriate Legal Notices must retain the display of the "Powered by
|
|
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
|
|
* reasonably feasible for technical reasons, the Appropriate Legal Notices must
|
|
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
|
|
*/
|
|
|
|
|
|
|
|
|
|
require_once("include/SugarCharts/SugarChart.php");
|
|
|
|
class JsChart extends SugarChart
|
|
{
|
|
protected $ss;
|
|
public $xmlFile;
|
|
public $jsonFilename;
|
|
public $chartId;
|
|
public $width;
|
|
public $height;
|
|
public $chartType;
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
public function isSupported($chartType)
|
|
{
|
|
$charts = array(
|
|
"stacked group by chart",
|
|
"group by chart",
|
|
"bar chart",
|
|
"horizontal group by chart",
|
|
"horizontal",
|
|
"horizontal bar chart",
|
|
"pie chart",
|
|
"gauge chart",
|
|
"funnel chart 3D",
|
|
"line chart",
|
|
);
|
|
|
|
if (in_array($chartType, $charts)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function tab($str, $depth)
|
|
{
|
|
// $str = preg_replace('/(<\w+>)(.*)(<\/\w+>)/e', "'\\1'.htmlentities(from_html('\\2')).'\\3'", $str);
|
|
return str_repeat("\t", $depth) . $str . "\n";
|
|
}
|
|
|
|
public function display($name, $xmlFile, $width='320', $height='480', $resize=false)
|
|
{
|
|
$this->chartId = $name;
|
|
$this->height = $height;
|
|
$this->width = $width;
|
|
$this->xmlFile = $xmlFile;
|
|
$this->chartType = $this->chart_properties['type'];
|
|
|
|
$style = array();
|
|
$chartConfig = array();
|
|
try {
|
|
$xmlStr = $this->processXML($this->xmlFile);
|
|
$json = $this->buildJson($xmlStr);
|
|
} catch (Exception $e) {
|
|
$GLOBALS['log']->fatal("Unable to return chart data, invalid xml for file {$this->xmlFile}");
|
|
return '';
|
|
}
|
|
$this->saveJsonFile($json);
|
|
$this->ss->assign("chartId", $this->chartId);
|
|
$this->ss->assign("filename", $this->jsonFilename);
|
|
global $mod_strings, $app_strings;
|
|
if (isset($mod_strings['LBL_REPORT_SHOW_CHART'])) {
|
|
$this->ss->assign("showchart", $mod_strings['LBL_REPORT_SHOW_CHART']);
|
|
}
|
|
|
|
$dimensions = $this->getChartDimensions($xmlStr);
|
|
$this->ss->assign("width", $dimensions['width']);
|
|
$this->ss->assign("height", $dimensions['height']);
|
|
$config = $this->getConfigProperties();
|
|
$style['gridLineColor'] = str_replace("0x", "#", $config->gridLines);
|
|
$style['font-family'] = $config->labelFontFamily;
|
|
$style['color'] = str_replace("0x", "#", $config->labelFontColor);
|
|
$this->ss->assign("css", $style);
|
|
foreach ($this->getChartConfigParams($xmlStr) as $key => $value) {
|
|
$chartConfig[$key] = $value;
|
|
}
|
|
$chartConfig['imageExportType'] = $this->image_export_type;
|
|
$this->ss->assign("config", $chartConfig);
|
|
if ($json == "No Data") {
|
|
$this->ss->assign("error", $app_strings['LBL_NO_DATA']);
|
|
}
|
|
|
|
if (!$this->isSupported($this->chartType)) {
|
|
$this->ss->assign("error", "Unsupported Chart Type");
|
|
}
|
|
}
|
|
|
|
|
|
public function getDashletScript($id, $xmlFile="")
|
|
{
|
|
global $sugar_config, $current_user, $current_language;
|
|
$this->id = $id;
|
|
$this->chartId = $id;
|
|
$this->xmlFile = (!$xmlFile) ? sugar_cached("xml/".$current_user->getUserPrivGuid()."_{$this->id}.xml") : $xmlFile;
|
|
|
|
|
|
$style = array();
|
|
$chartConfig = array();
|
|
$this->ss->assign("chartId", $this->chartId);
|
|
$this->ss->assign("filename", str_replace(".xml", ".js", $this->xmlFile));
|
|
$config = $this->getConfigProperties();
|
|
$style['gridLineColor'] = str_replace("0x", "#", $config->gridLines);
|
|
$style['font-family'] = $config->labelFontFamily;
|
|
$style['color'] = str_replace("0x", "#", $config->labelFontColor);
|
|
$this->ss->assign("css", $style);
|
|
$xmlStr = $this->processXML($this->xmlFile);
|
|
foreach ($this->getChartConfigParams($xmlStr) as $key => $value) {
|
|
$chartConfig[$key] = $value;
|
|
}
|
|
|
|
$chartConfig['imageExportType'] = $this->image_export_type;
|
|
$this->ss->assign("config", $chartConfig);
|
|
}
|
|
|
|
public function chartArray($chartsArray)
|
|
{
|
|
$customChartsArray = array();
|
|
$style = array();
|
|
$chartConfig = array();
|
|
foreach ($chartsArray as $id => $data) {
|
|
$customChartsArray[$id] = array();
|
|
$customChartsArray[$id]['chartId'] = $id;
|
|
$customChartsArray[$id]['filename'] = str_replace(".xml", ".js", $data['xmlFile']);
|
|
$customChartsArray[$id]['width'] = $data['width'];
|
|
$customChartsArray[$id]['height'] = $data['height'];
|
|
|
|
$config = $this->getConfigProperties();
|
|
$style['gridLineColor'] = str_replace("0x", "#", $config->gridLines);
|
|
$style['font-family'] = (string)$config->labelFontFamily;
|
|
$style['color'] = str_replace("0x", "#", $config->labelFontColor);
|
|
$customChartsArray[$id]['css'] = $style;
|
|
$xmlStr = $this->processXML($data['xmlFile']);
|
|
$xml = new SimpleXMLElement($xmlStr);
|
|
$params = $this->getChartConfigParams($xmlStr);
|
|
$customChartsArray[$id]['supported'] = ($this->isSupported($xml->properties->type)) ? "true" : "false";
|
|
foreach ($params as $key => $value) {
|
|
$chartConfig[$key] = $value;
|
|
}
|
|
$chartConfig['imageExportType'] = $this->image_export_type;
|
|
$customChartsArray[$id]['chartConfig'] = $chartConfig;
|
|
}
|
|
|
|
return $customChartsArray;
|
|
}
|
|
|
|
public function getChartConfigParams($xmlStr)
|
|
{
|
|
$xml = new SimpleXMLElement($xmlStr);
|
|
|
|
$chartType = $xml->properties->type;
|
|
if ($chartType == "pie chart") {
|
|
return array("pieType" => "basic","tip" => "name","chartType" => "pieChart");
|
|
} elseif ($chartType == "line chart") {
|
|
return array("lineType" => "basic","tip" => "name","chartType" => "lineChart");
|
|
} elseif ($chartType == "funnel chart 3D") {
|
|
return array("funnelType" => "basic","tip" => "name","chartType" => "funnelChart");
|
|
} elseif ($chartType == "gauge chart") {
|
|
return array("gaugeType" => "basic","tip" => "name","chartType" => "gaugeChart");
|
|
} elseif ($chartType == "stacked group by chart") {
|
|
return array("orientation" => "vertical","barType" => "stacked","tip" => "name","chartType" => "barChart");
|
|
} elseif ($chartType == "group by chart") {
|
|
return array("orientation" => "vertical", "barType" => "grouped", "tip" => "title","chartType" => "barChart");
|
|
} elseif ($chartType == "bar chart") {
|
|
return array("orientation" => "vertical", "barType" => "basic", "tip" => "label","chartType" => "barChart");
|
|
} elseif ($chartType == "horizontal group by chart") {
|
|
return array("orientation" => "horizontal", "barType" => "stacked", "tip" => "name","chartType" => "barChart");
|
|
} elseif ($chartType == "horizontal bar chart" || "horizontal") {
|
|
return array("orientation" => "horizontal","barType" => "basic","tip" => "label","chartType" => "barChart");
|
|
} else {
|
|
return array("orientation" => "vertical","barType" => "stacked","tip" => "name","chartType" => "barChart");
|
|
}
|
|
}
|
|
public function getChartDimensions($xmlStr)
|
|
{
|
|
if ($this->getNumNodes($xmlStr) > 9 && $this->chartType != "pie chart") {
|
|
if ($this->chartType == "horizontal group by chart" || $this->chartType == "horizontal bar chart") {
|
|
$height = ($this->getNumNodes($xmlStr) * 60) + 100;
|
|
return array("width"=>$this->width, "height"=>($height));
|
|
} else {
|
|
return array("width"=>($this->width * 2), "height"=>$this->height);
|
|
}
|
|
} else {
|
|
return array("width"=>"100%", "height"=>$this->height);
|
|
}
|
|
}
|
|
|
|
public function checkData($xmlstr)
|
|
{
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
if (count($xml->data->group) > 0) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function getNumNodes($xmlstr)
|
|
{
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
return count($xml->data->group);
|
|
}
|
|
|
|
public function buildProperties($xmlstr)
|
|
{
|
|
$content = $this->tab("\"properties\": [\n", 1);
|
|
$properties = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->properties->children() as $property) {
|
|
$properties[] = $this->tab("\"".$property->getName()."\":"."\"".$this->processSpecialChars($property)."\"", 2);
|
|
}
|
|
$content .= $this->tab("{\n", 1);
|
|
$content .= implode(",\n", $properties)."\n";
|
|
$content .= $this->tab("}\n", 1);
|
|
$content .= $this->tab("],\n", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildLabelsBarChartStacked($xmlstr)
|
|
{
|
|
$content = $this->tab("\"label\": [\n", 1);
|
|
$labels = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->data->group[0]->subgroups->group as $group) {
|
|
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
|
|
}
|
|
$content .= implode(",\n", $labels)."\n";
|
|
$content .= $this->tab("],\n", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildLabelsBarChart($xmlstr)
|
|
{
|
|
|
|
// fix for bug42326: if there is label data that is deeper than that of a normal bar chart, render the labels
|
|
// like a stacked bar chart, this applies when a stacked chart has been converted in templates_chart.php to a bar chart due to it
|
|
// having nothing but single value columns
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
if (count($xml->data->group[0]->subgroups->group) > 0) {
|
|
return $this->buildLabelsBarChartStacked($xmlstr);
|
|
}
|
|
|
|
$content = $this->tab("\"label\": [\n", 1);
|
|
$labels = array();
|
|
|
|
foreach ($xml->data->group as $group) {
|
|
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
|
|
}
|
|
$labelStr = implode(",\n", $labels)."\n";
|
|
$content .= $labelStr;
|
|
$content .= $this->tab("],\n", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildDataBarChartStacked($xmlstr)
|
|
{
|
|
$content = $this->tab("\"values\": [\n", 1);
|
|
$data = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->data->group as $group) {
|
|
$groupcontent = $this->tab("{\n", 1);
|
|
$groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n", 2);
|
|
$groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n", 2);
|
|
$groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n", 2);
|
|
if (!empty($group->id)) {
|
|
$groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n", 2);
|
|
}
|
|
$subgroupValues = array();
|
|
$subgroupValueLabels = array();
|
|
$subgroupLinks = array();
|
|
foreach ($group->subgroups->group as $subgroups) {
|
|
$subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value, 3);
|
|
$subgroupValueLabels[] = $this->tab("\"".$this->processSpecialChars($subgroups->label)."\"", 3);
|
|
$subgroupLinks[] = $this->tab("\"".$subgroups->link."\"", 3);
|
|
}
|
|
$subgroupValuesStr = implode(",\n", $subgroupValues)."\n";
|
|
$subgroupValueLabelsStr = implode(",\n", $subgroupValueLabels)."\n";
|
|
$subgroupLinksStr = implode(",\n", $subgroupLinks)."\n";
|
|
|
|
$groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr, 2);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr, 2);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr, 2);
|
|
$groupcontent .= $this->tab("]\n", 2);
|
|
$groupcontent .= $this->tab("}", 1);
|
|
$data[] = $groupcontent;
|
|
}
|
|
$content .= implode(",\n", $data)."\n";
|
|
$content .= $this->tab("]", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildDataBarChartGrouped($xmlstr)
|
|
{
|
|
$content = $this->tab("\"values\": [\n", 1);
|
|
$data = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->data->group as $group) {
|
|
$groupcontent = $this->tab("{\n", 1);
|
|
$groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n", 2);
|
|
$groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n", 2);
|
|
$groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\",\n", 2);
|
|
if (!empty($group->id)) {
|
|
$groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n", 2);
|
|
}
|
|
$subgroupValues = array();
|
|
$subgroupValueLabels = array();
|
|
$subgroupLinks = array();
|
|
$subgroupTitles = array();
|
|
foreach ($group->subgroups->group as $subgroups) {
|
|
$subgroupValues[] = $this->tab(($subgroups->value == "NULL") ? 0 : $subgroups->value, 3);
|
|
$subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"", 3);
|
|
$subgroupLinks[] = $this->tab("\"".$subgroups->link."\"", 3);
|
|
$subgroupTitles[] = $this->tab("\"".$this->processSpecialChars($subgroups->title)."\"", 3);
|
|
}
|
|
$subgroupValuesStr = implode(",\n", $subgroupValues)."\n";
|
|
$subgroupValueLabelsStr = implode(",\n", $subgroupValueLabels)."\n";
|
|
$subgroupLinksStr = implode(",\n", $subgroupLinks)."\n";
|
|
$subgroupTitlesStr = implode(",\n", $subgroupTitles)."\n";
|
|
|
|
$groupcontent .= $this->tab("\"values\": [\n".$subgroupValuesStr, 2);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr, 2);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr, 2);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"titles\": [\n".$subgroupTitlesStr, 2);
|
|
$groupcontent .= $this->tab("]\n", 2);
|
|
$groupcontent .= $this->tab("}", 1);
|
|
$data[] = $groupcontent;
|
|
}
|
|
$content .= implode(",\n", $data)."\n";
|
|
$content .= $this->tab("]", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildDataBarChart($xmlstr)
|
|
{
|
|
$content = $this->tab("\"values\": [\n", 1);
|
|
$data = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
$groupcontent = "";
|
|
$groupcontentArr = array();
|
|
|
|
foreach ($xml->data->group as $group) {
|
|
$groupcontent = $this->tab("{\n", 1);
|
|
$groupcontent .= $this->tab("\"label\": [\n", 2);
|
|
$groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n", 3);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"values\": [\n", 2);
|
|
$groupcontent .= $this->tab(($group->value == "NULL") ? 0 : $group->value."\n", 3);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
if (!empty($group->id)) {
|
|
$groupcontent .= $this->tab("\"id\": \"{$group->id}\",\n", 2);
|
|
}
|
|
if ($group->label) {
|
|
$groupcontent .= $this->tab("\"valuelabels\": [\n", 2);
|
|
$groupcontent .= $this->tab("\"{$group->label}\"\n", 3);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
}
|
|
$groupcontent .= $this->tab("\"links\": [\n", 2);
|
|
$groupcontent .= $this->tab("\"{$group->link}\"\n", 3);
|
|
$groupcontent .= $this->tab("]\n", 2);
|
|
$groupcontent .= $this->tab("}", 1);
|
|
$groupcontentArr[] = $groupcontent;
|
|
}
|
|
$content .= implode(",\n", $groupcontentArr)."\n";
|
|
$content .= $this->tab("]", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildLabelsPieChart($xmlstr)
|
|
{
|
|
$content = $this->tab("\"label\": [\n", 1);
|
|
$labels = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->data->group as $group) {
|
|
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
|
|
}
|
|
$labelStr = implode(",\n", $labels)."\n";
|
|
$content .= $labelStr;
|
|
$content .= $this->tab("],\n", 1);
|
|
return $content;
|
|
}
|
|
|
|
|
|
public function buildDataPieChart($xmlstr)
|
|
{
|
|
$content = $this->tab("\"values\": [\n", 1);
|
|
$data = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
$groupcontent = "";
|
|
$groupcontentArr = array();
|
|
|
|
foreach ($xml->data->group as $group) {
|
|
$groupcontent = $this->tab("{\n", 1);
|
|
$groupcontent .= $this->tab("\"label\": [\n", 2);
|
|
$groupcontent .= $this->tab("\"".$this->processSpecialChars($group->title)."\"\n", 3);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"values\": [\n", 2);
|
|
$groupcontent .= $this->tab("{$group->value}\n", 3);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"valuelabels\": [\n", 2);
|
|
$groupcontent .= $this->tab("\"{$group->label}\"\n", 3);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"links\": [\n", 2);
|
|
$groupcontent .= $this->tab("\"{$group->link}\"\n", 3);
|
|
$groupcontent .= $this->tab("]\n", 2);
|
|
$groupcontent .= $this->tab("}", 1);
|
|
$groupcontentArr[] = $groupcontent;
|
|
}
|
|
|
|
|
|
$content .= implode(",\n", $groupcontentArr)."\n";
|
|
$content .= $this->tab("\n]", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildLabelsGaugeChart($xmlstr)
|
|
{
|
|
$content = $this->tab("\"label\": [\n", 1);
|
|
$labels = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->data->group as $group) {
|
|
$labels[] = $this->tab("\"".$this->processSpecialChars($group->title)."\"", 2);
|
|
}
|
|
$labelStr = implode(",\n", $labels)."\n";
|
|
$content .= $labelStr;
|
|
$content .= $this->tab("],\n", 1);
|
|
return $content;
|
|
}
|
|
|
|
public function buildDataGaugeChart($xmlstr)
|
|
{
|
|
$content = $this->tab("\"values\": [\n", 1);
|
|
$data = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->data->group as $group) {
|
|
$groupcontent = $this->tab("{\n", 1);
|
|
$groupcontent .= $this->tab("\"label\": \"".$this->processSpecialChars($group->title)."\",\n", 2);
|
|
$groupcontent .= $this->tab("\"gvalue\": \"{$group->value}\",\n", 2);
|
|
$finalComma = ($group->title != "GaugePosition") ? "," : "";
|
|
$groupcontent .= $this->tab("\"gvaluelabel\": \"{$group->label}\"{$finalComma}\n", 2);
|
|
$subgroupTitles = array();
|
|
$subgroupValues = array();
|
|
$subgroupValueLabels = array();
|
|
$subgroupLinks = array();
|
|
|
|
if (is_object($group->subgroups->group)) {
|
|
foreach ($group->subgroups->group as $subgroups) {
|
|
$subgroupTitles[] = $this->tab("\"".$subgroups->title."\"", 3);
|
|
//$subgroupValues[] = $this->tab($subgroups->value,3);
|
|
$subgroupValues[] = $subgroups->value;
|
|
$subgroupValueLabels[] = $this->tab("\"".$subgroups->label."\"", 3);
|
|
$subgroupLinks[] = $this->tab("\"".$subgroups->link."\"", 3);
|
|
}
|
|
$subgroupTitlesStr = implode(",\n", $subgroupTitles)."\n";
|
|
$subgroupValuesStr = implode(",\n", $subgroupValues)."\n";
|
|
$subgroupValueLabelsStr = implode(",\n", $subgroupValueLabels)."\n";
|
|
$subgroupLinksStr = implode(",\n", $subgroupLinks)."\n";
|
|
|
|
//$groupcontent .= $this->tab("\"labels\": [\n".$subgroupTitlesStr,2);
|
|
//$groupcontent .= $this->tab("],\n",2);
|
|
$val = ((int)$subgroupValues[1] == (int)$subgroupValues[0]) ? $this->tab($subgroupValues[1], 3)."\n" : $this->tab($subgroupValues[1] - $subgroupValues[0], 3)."\n";
|
|
|
|
$groupcontent .= $this->tab("\"values\": [\n".$val, 2);
|
|
$groupcontent .= $this->tab("],\n", 2);
|
|
$groupcontent .= $this->tab("\"valuelabels\": [\n".$subgroupValueLabelsStr, 2);
|
|
$groupcontent .= $this->tab("]\n", 2);
|
|
//$groupcontent .= $this->tab("\"links\": [\n".$subgroupLinksStr,2);
|
|
//$groupcontent .= $this->tab("]\n",2);
|
|
}
|
|
|
|
$groupcontent .= $this->tab("}", 1);
|
|
$data[] = $groupcontent;
|
|
}
|
|
|
|
$content .= implode(",\n", $data)."\n";
|
|
|
|
|
|
$content .= $this->tab("]", 1);
|
|
return $content;
|
|
}
|
|
|
|
|
|
public function getConfigProperties()
|
|
{
|
|
$path = SugarThemeRegistry::current()->getImageURL('sugarColors.xml', false);
|
|
|
|
if (!file_exists($path)) {
|
|
$GLOBALS['log']->debug("Cannot open file ($path)");
|
|
}
|
|
$xmlstr = file_get_contents($path);
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
return $xml->charts;
|
|
}
|
|
|
|
public function buildChartColors()
|
|
{
|
|
$content = $this->tab("\"color\": [\n", 1);
|
|
$colorArr = array();
|
|
$xml = $this->getConfigProperties();
|
|
$colors = ($this->chartType == "gauge chart") ? $xml->gaugeChartElementColors->color : $xml->chartElementColors->color;
|
|
foreach ($colors as $color) {
|
|
$colorArr[] = $this->tab("\"".str_replace("0x", "#", $color)."\"", 2);
|
|
}
|
|
$content .= implode(",\n", $colorArr)."\n";
|
|
$content .= $this->tab("],\n", 1);
|
|
|
|
return $content;
|
|
}
|
|
|
|
public function buildJson($xmlstr)
|
|
{
|
|
if ($this->checkData($xmlstr)) {
|
|
$content = "{\n";
|
|
if ($this->chartType == "pie chart" || $this->chartType == "funnel chart 3D") {
|
|
$content .= $this->buildProperties($xmlstr);
|
|
$content .= $this->buildLabelsPieChart($xmlstr);
|
|
$content .= $this->buildChartColors();
|
|
$content .= $this->buildDataPieChart($xmlstr);
|
|
} elseif ($this->chartType == "gauge chart") {
|
|
$content .= $this->buildProperties($xmlstr);
|
|
$content .= $this->buildLabelsGaugeChart($xmlstr);
|
|
$content .= $this->buildChartColors();
|
|
$content .= $this->buildDataGaugeChart($xmlstr);
|
|
} elseif ($this->chartType == "horizontal bar chart" || $this->chartType == "bar chart") {
|
|
$content .= $this->buildProperties($xmlstr);
|
|
$content .= $this->buildLabelsBarChart($xmlstr);
|
|
$content .= $this->buildChartColors();
|
|
$content .= $this->buildDataBarChart($xmlstr);
|
|
} elseif ($this->chartType == "group by chart") {
|
|
$content .= $this->buildProperties($xmlstr);
|
|
$content .= $this->buildLabelsBarChartStacked($xmlstr);
|
|
$content .= $this->buildChartColors();
|
|
$content .= $this->buildDataBarChartGrouped($xmlstr);
|
|
} else {
|
|
$content .= $this->buildProperties($xmlstr);
|
|
$content .= $this->buildLabelsBarChartStacked($xmlstr);
|
|
$content .= $this->buildChartColors();
|
|
$content .= $this->buildDataBarChartStacked($xmlstr);
|
|
}
|
|
$content .= "\n}";
|
|
return $content;
|
|
} else {
|
|
return "No Data";
|
|
}
|
|
}
|
|
|
|
public function buildHTMLLegend($xmlFile)
|
|
{
|
|
$xmlstr = $this->processXML($xmlFile);
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
$this->chartType = $xml->properties->type;
|
|
$html = "<table align=\"left\" cellpadding=\"2\" cellspacing=\"2\">";
|
|
|
|
if (
|
|
$this->chartType == "group by chart"
|
|
|| $this->chartType == "horizontal group by chart"
|
|
|| $this->chartType == 'line chart'
|
|
|| $this->chartType == 'stacked group by chart'
|
|
) {
|
|
$groups = $xml->data->group[0]->subgroups->group;
|
|
$items = (count($xml->data->group[0]->subgroups->group) <= 5) ? 5 : count($xml->data->group[0]->subgroups->group);
|
|
} else {
|
|
if ($this->chartType == "funnel chart 3D") {
|
|
// reverse legend
|
|
$groups = array();
|
|
foreach ($xml->data->group as $group) {
|
|
array_unshift($groups, $group);
|
|
}
|
|
} else {
|
|
$groups = $xml->data->group;
|
|
}
|
|
$items = (count($xml->data->group) <= 5) ? 5 : count($xml->data->group);
|
|
}
|
|
|
|
$rows = ceil($items/5);
|
|
$fullItems = $rows * 5;
|
|
$remainder = ($items < $fullItems) ? $fullItems - $items : 0;
|
|
$i = 0;
|
|
$x = 0;
|
|
|
|
|
|
$colorArr = array();
|
|
$xmlColors = $this->getConfigProperties();
|
|
$colors = ($this->chartType == "gauge chart") ? $xmlColors->gaugeChartElementColors->color : $xmlColors->chartElementColors->color;
|
|
|
|
foreach ($colors as $color) {
|
|
$colorArr[] = str_replace("0x", "#", $color);
|
|
}
|
|
|
|
$isTrClosed = false;
|
|
foreach ($groups as $group) {
|
|
if ($i == 5) {
|
|
$i = 0;
|
|
}
|
|
$html .= ($i == 0) ? "<tr>" : "";
|
|
$html .= "<td width=\"50\">";
|
|
$html .= "<div style=\"background-color:".$colorArr[$x].";\"> </div>";
|
|
$html .= "</td>";
|
|
$html .= "<td>";
|
|
$html .= $group->title;
|
|
$html .= "</td>";
|
|
$html .= ($x+1 == $items) ? "<td colspan=".($remainder*2)."></td>" : "";
|
|
if ($i == 4) {
|
|
$html .= "</tr>";
|
|
$isTrClosed = true;
|
|
} else {
|
|
$isTrClosed = false;
|
|
}
|
|
$x++;
|
|
$i++;
|
|
}
|
|
if ($isTrClosed == false) {
|
|
$html .= '</tr>';
|
|
}
|
|
|
|
$html .= "</table>";
|
|
return $html;
|
|
}
|
|
|
|
public function saveJsonFile($jsonContents)
|
|
{
|
|
$this->jsonFilename = str_replace(".xml", ".js", $this->xmlFile);
|
|
//$jsonContents = $GLOBALS['locale']->translateCharset($jsonContents, 'UTF-8', 'UTF-16LE');
|
|
|
|
// open file
|
|
if (!$fh = sugar_fopen($this->jsonFilename, 'w')) {
|
|
$GLOBALS['log']->debug("Cannot open file ($this->jsonFilename)");
|
|
return;
|
|
}
|
|
|
|
// write the contents to the file
|
|
if (fwrite($fh, $jsonContents) === false) {
|
|
$GLOBALS['log']->debug("Cannot write to file ($this->jsonFilename)");
|
|
return false;
|
|
}
|
|
|
|
$GLOBALS['log']->debug("Success, wrote ($jsonContents) to file ($this->jsonFilename)");
|
|
|
|
fclose($fh);
|
|
return true;
|
|
}
|
|
|
|
public function get_image_cache_file_name($xmlFile, $ext = ".png")
|
|
{
|
|
$filename = str_replace("/xml/", "/images/", str_replace(".xml", $ext, $xmlFile));
|
|
|
|
return $filename;
|
|
}
|
|
|
|
|
|
public function getXMLChartProperties($xmlStr)
|
|
{
|
|
$props = array();
|
|
$xml = new SimpleXMLElement($xmlstr);
|
|
foreach ($xml->properties->children() as $properties) {
|
|
$props[$properties->getName()] = $properties;
|
|
}
|
|
return $props;
|
|
}
|
|
|
|
public function processSpecialChars($str)
|
|
{
|
|
return addslashes(html_entity_decode($str, ENT_QUOTES));
|
|
}
|
|
|
|
public function processXML($xmlFile)
|
|
{
|
|
if (!file_exists($xmlFile)) {
|
|
$GLOBALS['log']->debug("Cannot open file ($xmlFile)");
|
|
}
|
|
|
|
$pattern = array();
|
|
$replacement = array();
|
|
$content = file_get_contents($xmlFile);
|
|
$content = $GLOBALS['locale']->translateCharset($content, 'UTF-16LE', 'UTF-8');
|
|
|
|
/*
|
|
* Fix to Bug 1934 https://suitecrm.com/forum/bug-tracker/1934-unable-to-return-chart-data-invalid-xml-for-file-cache-xml
|
|
*
|
|
* This compensates for changes to PCRE Extension for PHP > 5.5.1
|
|
* Where original Regex expression failed during compilation time using
|
|
* pattern[] = '/\<link\>([a-zA-Z0-9#?&%.;\[\]\/=+_-\s]+)\<\/link\>/e';
|
|
*
|
|
* Replacement regex $pattern applied
|
|
*/
|
|
|
|
$return = preg_replace_callback('/\<link\>([a-zA-Z0-9#?&%.;\[\]\/=+\s\-\_]+)\<\/link\>/', function ($m) {
|
|
return '<link>'.urlencode($m[1]).'</link>';
|
|
}, $content);
|
|
return $return;
|
|
}
|
|
}
|