| 1 | <?php |
| 2 | /* |
| 3 | +--------------------------------------------------------------------+ |
| 4 | | Copyright CiviCRM LLC. All rights reserved. | |
| 5 | | | |
| 6 | | This work is published under the GNU AGPLv3 license with some | |
| 7 | | permitted exceptions and without any warranty. For full license | |
| 8 | | and copyright information, see https://civicrm.org/licensing | |
| 9 | +--------------------------------------------------------------------+ |
| 10 | */ |
| 11 | |
| 12 | /** |
| 13 | * |
| 14 | * @package CRM |
| 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
| 16 | */ |
| 17 | class CRM_Contribute_Form_ContributionCharts extends CRM_Core_Form { |
| 18 | |
| 19 | /** |
| 20 | * Year of chart. |
| 21 | * |
| 22 | * @var int |
| 23 | */ |
| 24 | protected $_year = NULL; |
| 25 | |
| 26 | /** |
| 27 | * The type of chart. |
| 28 | * |
| 29 | * @var string |
| 30 | */ |
| 31 | protected $_chartType = NULL; |
| 32 | |
| 33 | public function preProcess() { |
| 34 | $this->_year = CRM_Utils_Request::retrieve('year', 'Int', $this); |
| 35 | $this->_chartType = CRM_Utils_Request::retrieve('type', 'String', $this); |
| 36 | |
| 37 | $buildChart = FALSE; |
| 38 | |
| 39 | if ($this->_year || $this->_chartType) { |
| 40 | $buildChart = TRUE; |
| 41 | } |
| 42 | $this->assign('buildChart', $buildChart); |
| 43 | $this->postProcess(); |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Build the form object. |
| 48 | */ |
| 49 | public function buildQuickForm() { |
| 50 | //p3 = Three dimensional pie chart. |
| 51 | //bvg = Vertical bar chart |
| 52 | $this->addElement('select', 'chart_type', ts('Chart Style'), [ |
| 53 | 'bvg' => ts('Bar'), |
| 54 | 'p3' => ts('Pie'), |
| 55 | ]); |
| 56 | $defaultValues['chart_type'] = $this->_chartType; |
| 57 | $this->setDefaults($defaultValues); |
| 58 | |
| 59 | //take available years from database to show in drop down |
| 60 | $currentYear = date('Y'); |
| 61 | $years = []; |
| 62 | if (!empty($this->_years)) { |
| 63 | if (!array_key_exists($currentYear, $this->_years)) { |
| 64 | $this->_years[$currentYear] = $currentYear; |
| 65 | krsort($this->_years); |
| 66 | } |
| 67 | foreach ($this->_years as $k => $v) { |
| 68 | $years[substr($k, 0, 4)] = substr($k, 0, 4); |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | $this->addElement('select', 'select_year', ts('Select Year (for monthly breakdown)'), $years); |
| 73 | $this->setDefaults([ |
| 74 | 'select_year' => ($this->_year) ? $this->_year : $currentYear, |
| 75 | ]); |
| 76 | } |
| 77 | |
| 78 | /** |
| 79 | * Process the form after the input has been submitted and validated. |
| 80 | */ |
| 81 | public function postProcess() { |
| 82 | $config = CRM_Core_Config::singleton(); |
| 83 | $chartType = 'bvg'; |
| 84 | if ($this->_chartType) { |
| 85 | $chartType = $this->_chartType; |
| 86 | } |
| 87 | $selectedYear = date('Y'); |
| 88 | if ($this->_year) { |
| 89 | $selectedYear = $this->_year; |
| 90 | } |
| 91 | |
| 92 | //take contribution information monthly |
| 93 | $chartInfoMonthly = CRM_Contribute_BAO_Contribution_Utils::contributionChartMonthly($selectedYear); |
| 94 | |
| 95 | $chartData = $abbrMonthNames = []; |
| 96 | if (is_array($chartInfoMonthly)) { |
| 97 | for ($i = 1; $i <= 12; $i++) { |
| 98 | $abbrMonthNames[$i] = strftime('%b', mktime(0, 0, 0, $i, 10, 1970)); |
| 99 | } |
| 100 | |
| 101 | foreach ($abbrMonthNames as $monthKey => $monthName) { |
| 102 | $val = CRM_Utils_Array::value($monthKey, $chartInfoMonthly['By Month'], 0); |
| 103 | |
| 104 | // don't include zero value month. |
| 105 | if (!$val && ($chartType != 'bvg')) { |
| 106 | continue; |
| 107 | } |
| 108 | |
| 109 | //build the params for chart. |
| 110 | $chartData['by_month']['values'][$monthName] = $val; |
| 111 | } |
| 112 | $chartData['by_month']['legend'] = 'By Month' . ' - ' . $selectedYear; |
| 113 | |
| 114 | // handle onclick event. |
| 115 | $chartData['by_month']['on_click_fun_name'] = 'byMonthOnClick'; |
| 116 | $chartData['by_month']['yname'] = ts('Contribution'); |
| 117 | } |
| 118 | |
| 119 | //take contribution information by yearly |
| 120 | $chartInfoYearly = CRM_Contribute_BAO_Contribution_Utils::contributionChartYearly(); |
| 121 | |
| 122 | //get the years. |
| 123 | $this->_years = $chartInfoYearly['By Year']; |
| 124 | $hasContributions = FALSE; |
| 125 | if (is_array($chartInfoYearly)) { |
| 126 | $hasContributions = TRUE; |
| 127 | $chartData['by_year']['legend'] = 'By Year'; |
| 128 | $chartData['by_year']['values'] = $chartInfoYearly['By Year']; |
| 129 | |
| 130 | // handle onclick event. |
| 131 | $chartData['by_year']['on_click_fun_name'] = 'byYearOnClick'; |
| 132 | $chartData['by_year']['yname'] = ts('Total Amount'); |
| 133 | } |
| 134 | $this->assign('hasContributions', $hasContributions); |
| 135 | |
| 136 | // process the data. |
| 137 | $chartCnt = 1; |
| 138 | |
| 139 | $monthlyChart = $yearlyChart = FALSE; |
| 140 | |
| 141 | foreach ($chartData as $chartKey => & $values) { |
| 142 | $chartValues = CRM_Utils_Array::value('values', $values); |
| 143 | |
| 144 | if (!is_array($chartValues) || empty($chartValues)) { |
| 145 | continue; |
| 146 | } |
| 147 | if ($chartKey == 'by_year') { |
| 148 | $yearlyChart = TRUE; |
| 149 | if (!empty($config->fiscalYearStart) && ($config->fiscalYearStart['M'] !== 1 || $config->fiscalYearStart['d'] !== 1)) { |
| 150 | $values['xLabelAngle'] = 45; |
| 151 | } |
| 152 | else { |
| 153 | $values['xLabelAngle'] = 0; |
| 154 | } |
| 155 | } |
| 156 | if ($chartKey == 'by_month') { |
| 157 | $monthlyChart = TRUE; |
| 158 | } |
| 159 | |
| 160 | $values['divName'] = "chart_{$chartKey}"; |
| 161 | $funName = ($chartType == 'bvg') ? 'barChart' : 'pieChart'; |
| 162 | |
| 163 | // build the chart objects. |
| 164 | $values['object'] = CRM_Utils_Chart::$funName($values); |
| 165 | |
| 166 | //build the urls. |
| 167 | $urlCnt = 0; |
| 168 | foreach ($chartValues as $index => $val) { |
| 169 | $urlParams = NULL; |
| 170 | if ($chartKey == 'by_month') { |
| 171 | $monthPosition = array_search($index, $abbrMonthNames); |
| 172 | $startDate = CRM_Utils_Date::format(['Y' => $selectedYear, 'M' => $monthPosition]); |
| 173 | $endDate = date('Ymd', mktime(0, 0, 0, $monthPosition + 1, 0, $selectedYear)); |
| 174 | $urlParams = "reset=1&force=1&status=1&start={$startDate}&end={$endDate}&test=0"; |
| 175 | } |
| 176 | elseif ($chartKey == 'by_year') { |
| 177 | if (!empty($config->fiscalYearStart) && ($config->fiscalYearStart['M'] != 1 || $config->fiscalYearStart['d'] != 1)) { |
| 178 | $startDate = date('Ymd', mktime(0, 0, 0, $config->fiscalYearStart['M'], $config->fiscalYearStart['d'], substr($index, 0, 4))); |
| 179 | $endDate = date('Ymd', mktime(0, 0, 0, $config->fiscalYearStart['M'], $config->fiscalYearStart['d'], (substr($index, 0, 4)) + 1)); |
| 180 | } |
| 181 | else { |
| 182 | $startDate = CRM_Utils_Date::format(['Y' => substr($index, 0, 4)]); |
| 183 | $endDate = date('Ymd', mktime(0, 0, 0, 13, 0, substr($index, 0, 4))); |
| 184 | } |
| 185 | $urlParams = "reset=1&force=1&status=1&start={$startDate}&end={$endDate}&test=0"; |
| 186 | } |
| 187 | if ($urlParams) { |
| 188 | $values['on_click_urls']["url_" . $urlCnt++] = CRM_Utils_System::url('civicrm/contribute/search', |
| 189 | $urlParams, TRUE, FALSE, FALSE |
| 190 | ); |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | // calculate chart size. |
| 195 | $xSize = 400; |
| 196 | $ySize = 300; |
| 197 | if ($chartType == 'bvg') { |
| 198 | $ySize = 250; |
| 199 | $xSize = 60 * count($chartValues); |
| 200 | |
| 201 | // reduce x size by 100 for by_month |
| 202 | if ($chartKey == 'by_month') { |
| 203 | $xSize -= 100; |
| 204 | } |
| 205 | |
| 206 | //hack to show tooltip. |
| 207 | if ($xSize < 150) { |
| 208 | $xSize = 150; |
| 209 | } |
| 210 | } |
| 211 | $values['size'] = ['xSize' => $xSize, 'ySize' => $ySize]; |
| 212 | } |
| 213 | |
| 214 | // finally assign this chart data to template. |
| 215 | $this->assign('hasYearlyChart', $yearlyChart); |
| 216 | $this->assign('hasByMonthChart', $monthlyChart); |
| 217 | $this->assign('hasChart', empty($chartData) ? FALSE : TRUE); |
| 218 | $this->assign('chartData', json_encode($chartData ?? [])); |
| 219 | } |
| 220 | |
| 221 | } |