From 7af18d10dc23084ae8390241c2e9951d530248f7 Mon Sep 17 00:00:00 2001 From: Chris Buechler Date: Tue, 25 Jan 2011 05:20:28 -0500 Subject: archive some more dead packages --- config/archive/dspam/conf.default/config.xml | 1020 +++++++ config/archive/dspam/pear/Image/Canvas.php | 733 +++++ config/archive/dspam/pear/Image/Canvas/Color.php | 182 ++ .../archive/dspam/pear/Image/Canvas/Fonts/README | 12 + .../dspam/pear/Image/Canvas/Fonts/fontmap.txt | 25 + config/archive/dspam/pear/Image/Canvas/GD.php | 1693 +++++++++++ config/archive/dspam/pear/Image/Canvas/GD/JPG.php | 119 + config/archive/dspam/pear/Image/Canvas/GD/PNG.php | 125 + .../archive/dspam/pear/Image/Canvas/ImageMap.php | 354 +++ config/archive/dspam/pear/Image/Canvas/PDF.php | 1007 +++++++ config/archive/dspam/pear/Image/Canvas/SVG.php | 918 ++++++ config/archive/dspam/pear/Image/Canvas/Tool.php | 217 ++ config/archive/dspam/pear/Image/Canvas/WithMap.php | 278 ++ config/archive/dspam/pear/Image/Color.php | 719 +++++ config/archive/dspam/pear/Image/Graph.php | 851 ++++++ config/archive/dspam/pear/Image/Graph/Axis.php | 1690 +++++++++++ .../dspam/pear/Image/Graph/Axis/Category.php | 437 +++ .../dspam/pear/Image/Graph/Axis/Logarithmic.php | 152 + .../dspam/pear/Image/Graph/Axis/Marker/Area.php | 156 ++ .../dspam/pear/Image/Graph/Axis/Marker/Line.php | 124 + .../archive/dspam/pear/Image/Graph/Axis/Radar.php | 204 ++ config/archive/dspam/pear/Image/Graph/Common.php | 313 +++ config/archive/dspam/pear/Image/Graph/Config.php | 30 + .../archive/dspam/pear/Image/Graph/Constants.php | 225 ++ .../dspam/pear/Image/Graph/DataPreprocessor.php | 74 + .../pear/Image/Graph/DataPreprocessor/Array.php | 103 + .../pear/Image/Graph/DataPreprocessor/Currency.php | 66 + .../pear/Image/Graph/DataPreprocessor/Date.php | 90 + .../Image/Graph/DataPreprocessor/Formatted.php | 90 + .../pear/Image/Graph/DataPreprocessor/Function.php | 92 + .../Image/Graph/DataPreprocessor/NumberText.php | 89 + .../Image/Graph/DataPreprocessor/RomanNumerals.php | 79 + .../Image/Graph/DataPreprocessor/Sequential.php | 67 + .../dspam/pear/Image/Graph/DataSelector.php | 67 + .../Image/Graph/DataSelector/EveryNthPoint.php | 97 + .../pear/Image/Graph/DataSelector/NoZeros.php | 68 + .../dspam/pear/Image/Graph/DataSelector/Values.php | 90 + config/archive/dspam/pear/Image/Graph/Dataset.php | 483 ++++ .../dspam/pear/Image/Graph/Dataset/Function.php | 147 + .../dspam/pear/Image/Graph/Dataset/Random.php | 77 + .../dspam/pear/Image/Graph/Dataset/Sequential.php | 114 + .../dspam/pear/Image/Graph/Dataset/Trivial.php | 260 ++ .../pear/Image/Graph/Dataset/VectorFunction.php | 185 ++ config/archive/dspam/pear/Image/Graph/Element.php | 763 +++++ .../dspam/pear/Image/Graph/Figure/Circle.php | 64 + .../dspam/pear/Image/Graph/Figure/Ellipse.php | 97 + .../dspam/pear/Image/Graph/Figure/Polygon.php | 94 + .../dspam/pear/Image/Graph/Figure/Rectangle.php | 96 + config/archive/dspam/pear/Image/Graph/Fill.php | 63 + .../archive/dspam/pear/Image/Graph/Fill/Array.php | 137 + .../dspam/pear/Image/Graph/Fill/Gradient.php | 149 + .../archive/dspam/pear/Image/Graph/Fill/Image.php | 97 + config/archive/dspam/pear/Image/Graph/Font.php | 158 ++ config/archive/dspam/pear/Image/Graph/Grid.php | 175 ++ .../archive/dspam/pear/Image/Graph/Grid/Bars.php | 117 + .../archive/dspam/pear/Image/Graph/Grid/Lines.php | 114 + .../archive/dspam/pear/Image/Graph/Grid/Polar.php | 111 + .../pear/Image/Graph/Images/Icons/pinpoint.png | Bin 0 -> 452 bytes .../pear/Image/Graph/Images/Icons/pinpointr.png | Bin 0 -> 437 bytes .../dspam/pear/Image/Graph/Images/Maps/README | 17 + config/archive/dspam/pear/Image/Graph/Layout.php | 219 ++ .../dspam/pear/Image/Graph/Layout/Horizontal.php | 186 ++ .../dspam/pear/Image/Graph/Layout/Matrix.php | 201 ++ .../dspam/pear/Image/Graph/Layout/Vertical.php | 108 + config/archive/dspam/pear/Image/Graph/Legend.php | 385 +++ .../archive/dspam/pear/Image/Graph/Line/Array.php | 129 + .../archive/dspam/pear/Image/Graph/Line/Dashed.php | 76 + .../archive/dspam/pear/Image/Graph/Line/Dotted.php | 67 + .../dspam/pear/Image/Graph/Line/Formatted.php | 90 + .../archive/dspam/pear/Image/Graph/Line/Solid.php | 105 + config/archive/dspam/pear/Image/Graph/Logo.php | 153 + config/archive/dspam/pear/Image/Graph/Marker.php | 123 + .../dspam/pear/Image/Graph/Marker/Array.php | 105 + .../dspam/pear/Image/Graph/Marker/Asterisk.php | 109 + .../dspam/pear/Image/Graph/Marker/Average.php | 91 + .../archive/dspam/pear/Image/Graph/Marker/Box.php | 76 + .../dspam/pear/Image/Graph/Marker/Bubble.php | 91 + .../dspam/pear/Image/Graph/Marker/Circle.php | 96 + .../dspam/pear/Image/Graph/Marker/Cross.php | 114 + .../dspam/pear/Image/Graph/Marker/Diamond.php | 73 + .../archive/dspam/pear/Image/Graph/Marker/Icon.php | 133 + .../dspam/pear/Image/Graph/Marker/Pinpoint.php | 65 + .../archive/dspam/pear/Image/Graph/Marker/Plus.php | 98 + .../dspam/pear/Image/Graph/Marker/Pointing.php | 140 + .../pear/Image/Graph/Marker/Pointing/Angular.php | 105 + .../pear/Image/Graph/Marker/Pointing/Radial.php | 91 + .../pear/Image/Graph/Marker/ReversePinpoint.php | 65 + .../archive/dspam/pear/Image/Graph/Marker/Star.php | 88 + .../dspam/pear/Image/Graph/Marker/Triangle.php | 75 + .../dspam/pear/Image/Graph/Marker/Value.php | 214 ++ config/archive/dspam/pear/Image/Graph/Plot.php | 824 ++++++ .../archive/dspam/pear/Image/Graph/Plot/Area.php | 194 ++ .../archive/dspam/pear/Image/Graph/Plot/Band.php | 205 ++ config/archive/dspam/pear/Image/Graph/Plot/Bar.php | 307 ++ .../dspam/pear/Image/Graph/Plot/BoxWhisker.php | 298 ++ .../dspam/pear/Image/Graph/Plot/CandleStick.php | 251 ++ config/archive/dspam/pear/Image/Graph/Plot/Dot.php | 99 + .../dspam/pear/Image/Graph/Plot/Fit/Line.php | 118 + .../dspam/pear/Image/Graph/Plot/Impulse.php | 204 ++ .../archive/dspam/pear/Image/Graph/Plot/Line.php | 171 ++ config/archive/dspam/pear/Image/Graph/Plot/Odo.php | 719 +++++ config/archive/dspam/pear/Image/Graph/Plot/Pie.php | 623 +++++ .../archive/dspam/pear/Image/Graph/Plot/Radar.php | 118 + .../dspam/pear/Image/Graph/Plot/Smoothed/Area.php | 145 + .../pear/Image/Graph/Plot/Smoothed/Bezier.php | 173 ++ .../dspam/pear/Image/Graph/Plot/Smoothed/Line.php | 172 ++ .../dspam/pear/Image/Graph/Plot/Smoothed/Radar.php | 142 + .../archive/dspam/pear/Image/Graph/Plot/Step.php | 200 ++ config/archive/dspam/pear/Image/Graph/Plotarea.php | 1145 ++++++++ .../dspam/pear/Image/Graph/Plotarea/Element.php | 87 + .../dspam/pear/Image/Graph/Plotarea/Map.php | 304 ++ .../dspam/pear/Image/Graph/Plotarea/Radar.php | 243 ++ config/archive/dspam/pear/Image/Graph/Simple.php | 121 + config/archive/dspam/pear/Image/Graph/Title.php | 194 ++ config/archive/dspam/pear/Image/Graph/Tool.php | 291 ++ config/archive/dspam/pkg/000.mysql.sh | 68 + config/archive/dspam/pkg/010.clamav-clamd.sh | 56 + config/archive/dspam/pkg/020.clamav-freshclam.sh | 33 + config/archive/dspam/pkg/030.p3scan.sh | 60 + config/archive/dspam/pkg/clamd.conf | 299 ++ config/archive/dspam/pkg/default.prefs.sample | 43 + config/archive/dspam/pkg/dspam-config.inc | 42 + config/archive/dspam/pkg/dspam-guifunc.inc | 2606 +++++++++++++++++ config/archive/dspam/pkg/dspam-pkgfunc.inc | 548 ++++ config/archive/dspam/pkg/dspam-utilfunc.inc | 458 +++ config/archive/dspam/pkg/dspam.inc | 360 +++ config/archive/dspam/pkg/dspam.xml | 342 +++ config/archive/dspam/pkg/dspam_alerts.xml | 147 + config/archive/dspam/pkg/freshclam.conf | 110 + config/archive/dspam/pkg/p3scan-pf-emer.xml | 127 + config/archive/dspam/pkg/p3scan-pf-msg.xml | 198 ++ config/archive/dspam/pkg/p3scan-pf-spam.xml | 119 + config/archive/dspam/pkg/p3scan-pf-vir.xml | 162 ++ config/archive/dspam/pkg/p3scan-pf.xml | 211 ++ config/archive/dspam/pkg/p3scan.inc | 277 ++ config/archive/dspam/pkg/verdana.ttf | Bin 0 -> 139640 bytes config/archive/dspam/www/dspam-admin-graph.php | 201 ++ config/archive/dspam/www/dspam-admin-prefs.php | 249 ++ config/archive/dspam/www/dspam-admin-stats.php | 123 + config/archive/dspam/www/dspam-admin.php | 207 ++ config/archive/dspam/www/dspam-analysis-graph.php | 137 + config/archive/dspam/www/dspam-analysis.php | 147 + config/archive/dspam/www/dspam-hfragment.php | 90 + config/archive/dspam/www/dspam-history.php | 172 ++ config/archive/dspam/www/dspam-perf.php | 222 ++ config/archive/dspam/www/dspam-prefs.php | 234 ++ config/archive/dspam/www/dspam-quarantine.php | 178 ++ config/archive/dspam/www/dspam-settings-algo.php | 204 ++ config/archive/dspam/www/dspam-settings-bmta.php | 202 ++ config/archive/dspam/www/dspam-settings-feat.php | 203 ++ config/archive/dspam/www/dspam-settings-header.php | 197 ++ config/archive/dspam/www/dspam-settings-overr.php | 197 ++ config/archive/dspam/www/dspam-settings-prefs.php | 197 ++ config/archive/dspam/www/dspam-settings-spwd.php | 197 ++ config/archive/dspam/www/dspam-settings-tuser.php | 195 ++ config/archive/dspam/www/dspam-settings.php | 2955 ++++++++++++++++++++ config/archive/dspam/www/dspam-train.php | 284 ++ config/archive/dspam/www/dspam-viewmsg.php | 158 ++ config/archive/dspam/www/dspam.php | 264 ++ config/archive/dspam/www/themes/metallic/dspam.css | 115 + .../archive/dspam/www/wizards/dspam-lda-proxy.png | Bin 0 -> 20556 bytes .../archive/dspam/www/wizards/dspam-pop-proxy.png | Bin 0 -> 18247 bytes .../archive/dspam/www/wizards/dspam-smtp-relay.png | Bin 0 -> 30404 bytes config/archive/dspam/www/wizards/dspam_wizard.xml | 1848 ++++++++++++ config/archive/p3scan-pf/p3scan-pf-emer.xml | 131 + config/archive/p3scan-pf/p3scan-pf-msg.xml | 202 ++ config/archive/p3scan-pf/p3scan-pf-spam.xml | 122 + config/archive/p3scan-pf/p3scan-pf-transex.xml | 124 + config/archive/p3scan-pf/p3scan-pf-vir.xml | 166 ++ config/archive/p3scan-pf/p3scan-pf.inc | 395 +++ config/archive/p3scan-pf/p3scan-pf.xml | 218 ++ config/archive/p3scan.inc | 63 + config/archive/p3scan.mail | 15 + config/archive/p3scan.xml | 73 + config/archive/upclient.xml | 126 + 175 files changed, 44270 insertions(+) create mode 100644 config/archive/dspam/conf.default/config.xml create mode 100644 config/archive/dspam/pear/Image/Canvas.php create mode 100644 config/archive/dspam/pear/Image/Canvas/Color.php create mode 100644 config/archive/dspam/pear/Image/Canvas/Fonts/README create mode 100644 config/archive/dspam/pear/Image/Canvas/Fonts/fontmap.txt create mode 100644 config/archive/dspam/pear/Image/Canvas/GD.php create mode 100644 config/archive/dspam/pear/Image/Canvas/GD/JPG.php create mode 100644 config/archive/dspam/pear/Image/Canvas/GD/PNG.php create mode 100644 config/archive/dspam/pear/Image/Canvas/ImageMap.php create mode 100644 config/archive/dspam/pear/Image/Canvas/PDF.php create mode 100644 config/archive/dspam/pear/Image/Canvas/SVG.php create mode 100644 config/archive/dspam/pear/Image/Canvas/Tool.php create mode 100644 config/archive/dspam/pear/Image/Canvas/WithMap.php create mode 100644 config/archive/dspam/pear/Image/Color.php create mode 100644 config/archive/dspam/pear/Image/Graph.php create mode 100644 config/archive/dspam/pear/Image/Graph/Axis.php create mode 100644 config/archive/dspam/pear/Image/Graph/Axis/Category.php create mode 100644 config/archive/dspam/pear/Image/Graph/Axis/Logarithmic.php create mode 100644 config/archive/dspam/pear/Image/Graph/Axis/Marker/Area.php create mode 100644 config/archive/dspam/pear/Image/Graph/Axis/Marker/Line.php create mode 100644 config/archive/dspam/pear/Image/Graph/Axis/Radar.php create mode 100644 config/archive/dspam/pear/Image/Graph/Common.php create mode 100644 config/archive/dspam/pear/Image/Graph/Config.php create mode 100644 config/archive/dspam/pear/Image/Graph/Constants.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/Array.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/Currency.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/Date.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/Formatted.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/Function.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/NumberText.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/RomanNumerals.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataPreprocessor/Sequential.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataSelector.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataSelector/EveryNthPoint.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataSelector/NoZeros.php create mode 100644 config/archive/dspam/pear/Image/Graph/DataSelector/Values.php create mode 100644 config/archive/dspam/pear/Image/Graph/Dataset.php create mode 100644 config/archive/dspam/pear/Image/Graph/Dataset/Function.php create mode 100644 config/archive/dspam/pear/Image/Graph/Dataset/Random.php create mode 100644 config/archive/dspam/pear/Image/Graph/Dataset/Sequential.php create mode 100644 config/archive/dspam/pear/Image/Graph/Dataset/Trivial.php create mode 100644 config/archive/dspam/pear/Image/Graph/Dataset/VectorFunction.php create mode 100644 config/archive/dspam/pear/Image/Graph/Element.php create mode 100644 config/archive/dspam/pear/Image/Graph/Figure/Circle.php create mode 100644 config/archive/dspam/pear/Image/Graph/Figure/Ellipse.php create mode 100644 config/archive/dspam/pear/Image/Graph/Figure/Polygon.php create mode 100644 config/archive/dspam/pear/Image/Graph/Figure/Rectangle.php create mode 100644 config/archive/dspam/pear/Image/Graph/Fill.php create mode 100644 config/archive/dspam/pear/Image/Graph/Fill/Array.php create mode 100644 config/archive/dspam/pear/Image/Graph/Fill/Gradient.php create mode 100644 config/archive/dspam/pear/Image/Graph/Fill/Image.php create mode 100644 config/archive/dspam/pear/Image/Graph/Font.php create mode 100644 config/archive/dspam/pear/Image/Graph/Grid.php create mode 100644 config/archive/dspam/pear/Image/Graph/Grid/Bars.php create mode 100644 config/archive/dspam/pear/Image/Graph/Grid/Lines.php create mode 100644 config/archive/dspam/pear/Image/Graph/Grid/Polar.php create mode 100644 config/archive/dspam/pear/Image/Graph/Images/Icons/pinpoint.png create mode 100644 config/archive/dspam/pear/Image/Graph/Images/Icons/pinpointr.png create mode 100644 config/archive/dspam/pear/Image/Graph/Images/Maps/README create mode 100644 config/archive/dspam/pear/Image/Graph/Layout.php create mode 100644 config/archive/dspam/pear/Image/Graph/Layout/Horizontal.php create mode 100644 config/archive/dspam/pear/Image/Graph/Layout/Matrix.php create mode 100644 config/archive/dspam/pear/Image/Graph/Layout/Vertical.php create mode 100644 config/archive/dspam/pear/Image/Graph/Legend.php create mode 100644 config/archive/dspam/pear/Image/Graph/Line/Array.php create mode 100644 config/archive/dspam/pear/Image/Graph/Line/Dashed.php create mode 100644 config/archive/dspam/pear/Image/Graph/Line/Dotted.php create mode 100644 config/archive/dspam/pear/Image/Graph/Line/Formatted.php create mode 100644 config/archive/dspam/pear/Image/Graph/Line/Solid.php create mode 100644 config/archive/dspam/pear/Image/Graph/Logo.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Array.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Asterisk.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Average.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Box.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Bubble.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Circle.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Cross.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Diamond.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Icon.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Pinpoint.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Plus.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Pointing.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Pointing/Angular.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Pointing/Radial.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/ReversePinpoint.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Star.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Triangle.php create mode 100644 config/archive/dspam/pear/Image/Graph/Marker/Value.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Area.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Band.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Bar.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/BoxWhisker.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/CandleStick.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Dot.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Fit/Line.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Impulse.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Line.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Odo.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Pie.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Radar.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Area.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Line.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plot/Step.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plotarea.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plotarea/Element.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plotarea/Map.php create mode 100644 config/archive/dspam/pear/Image/Graph/Plotarea/Radar.php create mode 100644 config/archive/dspam/pear/Image/Graph/Simple.php create mode 100644 config/archive/dspam/pear/Image/Graph/Title.php create mode 100644 config/archive/dspam/pear/Image/Graph/Tool.php create mode 100644 config/archive/dspam/pkg/000.mysql.sh create mode 100644 config/archive/dspam/pkg/010.clamav-clamd.sh create mode 100644 config/archive/dspam/pkg/020.clamav-freshclam.sh create mode 100644 config/archive/dspam/pkg/030.p3scan.sh create mode 100644 config/archive/dspam/pkg/clamd.conf create mode 100644 config/archive/dspam/pkg/default.prefs.sample create mode 100644 config/archive/dspam/pkg/dspam-config.inc create mode 100644 config/archive/dspam/pkg/dspam-guifunc.inc create mode 100644 config/archive/dspam/pkg/dspam-pkgfunc.inc create mode 100644 config/archive/dspam/pkg/dspam-utilfunc.inc create mode 100644 config/archive/dspam/pkg/dspam.inc create mode 100644 config/archive/dspam/pkg/dspam.xml create mode 100644 config/archive/dspam/pkg/dspam_alerts.xml create mode 100644 config/archive/dspam/pkg/freshclam.conf create mode 100644 config/archive/dspam/pkg/p3scan-pf-emer.xml create mode 100644 config/archive/dspam/pkg/p3scan-pf-msg.xml create mode 100644 config/archive/dspam/pkg/p3scan-pf-spam.xml create mode 100644 config/archive/dspam/pkg/p3scan-pf-vir.xml create mode 100644 config/archive/dspam/pkg/p3scan-pf.xml create mode 100644 config/archive/dspam/pkg/p3scan.inc create mode 100644 config/archive/dspam/pkg/verdana.ttf create mode 100644 config/archive/dspam/www/dspam-admin-graph.php create mode 100644 config/archive/dspam/www/dspam-admin-prefs.php create mode 100644 config/archive/dspam/www/dspam-admin-stats.php create mode 100644 config/archive/dspam/www/dspam-admin.php create mode 100644 config/archive/dspam/www/dspam-analysis-graph.php create mode 100644 config/archive/dspam/www/dspam-analysis.php create mode 100644 config/archive/dspam/www/dspam-hfragment.php create mode 100644 config/archive/dspam/www/dspam-history.php create mode 100644 config/archive/dspam/www/dspam-perf.php create mode 100644 config/archive/dspam/www/dspam-prefs.php create mode 100644 config/archive/dspam/www/dspam-quarantine.php create mode 100644 config/archive/dspam/www/dspam-settings-algo.php create mode 100644 config/archive/dspam/www/dspam-settings-bmta.php create mode 100644 config/archive/dspam/www/dspam-settings-feat.php create mode 100644 config/archive/dspam/www/dspam-settings-header.php create mode 100644 config/archive/dspam/www/dspam-settings-overr.php create mode 100644 config/archive/dspam/www/dspam-settings-prefs.php create mode 100644 config/archive/dspam/www/dspam-settings-spwd.php create mode 100644 config/archive/dspam/www/dspam-settings-tuser.php create mode 100644 config/archive/dspam/www/dspam-settings.php create mode 100644 config/archive/dspam/www/dspam-train.php create mode 100644 config/archive/dspam/www/dspam-viewmsg.php create mode 100644 config/archive/dspam/www/dspam.php create mode 100644 config/archive/dspam/www/themes/metallic/dspam.css create mode 100644 config/archive/dspam/www/wizards/dspam-lda-proxy.png create mode 100644 config/archive/dspam/www/wizards/dspam-pop-proxy.png create mode 100644 config/archive/dspam/www/wizards/dspam-smtp-relay.png create mode 100644 config/archive/dspam/www/wizards/dspam_wizard.xml create mode 100644 config/archive/p3scan-pf/p3scan-pf-emer.xml create mode 100644 config/archive/p3scan-pf/p3scan-pf-msg.xml create mode 100644 config/archive/p3scan-pf/p3scan-pf-spam.xml create mode 100644 config/archive/p3scan-pf/p3scan-pf-transex.xml create mode 100644 config/archive/p3scan-pf/p3scan-pf-vir.xml create mode 100644 config/archive/p3scan-pf/p3scan-pf.inc create mode 100644 config/archive/p3scan-pf/p3scan-pf.xml create mode 100644 config/archive/p3scan.inc create mode 100644 config/archive/p3scan.mail create mode 100644 config/archive/p3scan.xml create mode 100644 config/archive/upclient.xml (limited to 'config/archive') diff --git a/config/archive/dspam/conf.default/config.xml b/config/archive/dspam/conf.default/config.xml new file mode 100644 index 00000000..4b33662e --- /dev/null +++ b/config/archive/dspam/conf.default/config.xml @@ -0,0 +1,1020 @@ + + + + 2.1 + + nione + + + normal + nione + local + + + Etc/UTC + 300 + pool.ntp.org + + admins + System Administrators + system + ANY + index.php + + + dspam_users + DSPAM Users + user + dspam.php + + dspam.php + wizard.php + system_usermanager.php + license.php + pkg.php + pkg_edit.php + index.php + dspam_alerts.xml + dspam.xml + dspam-perf.php + dspam-prefs.php + dspam-train.php + dspam-quarantine.php + dspam-viewmsg.php + dspam-hfragment.php + dspam-history.php + dspam-analysis-graph.php + dspam-analysis.php + ifstats.php + xmlrpc.php + preload.php + functions.inc.php + javascript.inc.php + sajax.class.php + + + + dspam_admins + DSPAM Administrators + user + dspam.php + + dspam.php + dspam_wizard.xml + wizard.php + system_usermanager.php + license.php + pkg.php + pkg_edit.php + index.php + status_services.php + dspam-admin-prefs.php + dspam_alerts.xml + dspam.xml + dspam-perf.php + dspam-prefs.php + dspam-train.php + dspam-admin-stats.php + dspam-admin-graph.php + dspam-admin.php + dspam-quarantine.php + dspam-viewmsg.php + dspam-hfragment.php + dspam-history.php + dspam-analysis-graph.php + dspam-analysis.php + dspam-settings-algo.php + dspam-settings-bmta.php + dspam-settings-feat.php + dspam-settings-prefs.php + dspam-settings-header.php + dspam-settings-overr.php + dspam-settings-spwd.php + dspam-settings-tuser.php + dspam-settings.php + p3scan-pf-emer.xml + p3scan-pf.xml + p3scan-pf-msg.xml + p3scan-pf-spam.xml + p3scan-pf-vir.xml + p3scan-pf-transex.xml + ifstats.php + xmlrpc.php + preload.php + functions.inc.php + javascript.inc.php + sajax.class.php + + + + admin + System Administrator + system + admins + $1$pHZLmGLm$rtBJza55tMwVbJNkr0qCz/ + + lockwc + Lock webConfigurator + Indicates whether this user will lock access to the webConfigurator for other users. + + + lock-ipages + Lock individual pages + Indicates whether this user will lock individual HTML pages after having accessed a particular page(the lock will be freed if the user leaves or saves the page form). + + + hasshell + Has shell access + Indicates whether this user is able to login for example via SSH. + + + isroot + Is root user + This user is associated with the UNIX root user (you should associate this privilege only with one single user). + + + + dspamadm + DSPAM Administrator + user + dspam_admins + $1$utl.fBcK$ZDnGqMSm2fJHi8vxQ6EfT1 + + + http + + + + + + + + + + + sis0 + 192.168.1.1 + 24 + + + 100 + Mb + + + + sis1 + + dhcp + + + + + + + + + 100 + Mb + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dyndns + + + + + + + + + + + 192.168.1.100 + 192.168.1.199 + + + + + + + + + + + + + + + + + + + + + + + + + + public + + + + + + + + + + + + + + + + + + + + + + + + + + + pass + Default LAN -> any + lan + + lan + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mysql + + /tmp/mysql.sock + + dspam + dspam + dspam + 10 + yes + yes + + + + + mail + yes + 192.168.1.6 + 24 + localhost + smtp + error + + + + + root + root desc + + + mail + mail desc + + + mailnull + mailnull desc + + + smmsp + smmsp desc + + + daemon + daemon desc + + + + + teft + yes + + chained + feat desc + + + whitelist + whitelist desc + + + graham + naive desc + + + burton + naive desc + + graham + yes + + "spamAction=quarantine" + desc + + + "signatureLocation=message" + 'message' or 'headers' + + + "showFactors=on" + desc + + + trainingMode + tmode desc + + + spamAction spamSubject + desc + + + statisticalSedation + desc + + + enableBNR + desc + + + enableWhitelist + desc + + + signatureLocation + desc + + + showFactors + desc + + + optIn optOut + desc + + + whitelistThreshold + desc + + + + + 1 + yes + support + + + + 14 + 90 + 90 + 30 + 15 + 15 + + + + 127.0.0.1 + yes + yes + out + yes + yes + 307200 + yes + + + + yes + 3310 + 127.0.0.1 + accept + + + + 24 + 32 + /var/run/dspam/dspam.pid + standard + --deliver=innocent -d %u + abysseleven.abyssworld.de + /var/run/dspam/dspam.sock + + + + dspam + http://dspam.nuclearelephant.com/ + + DSPAM is a scalable and open-source content-based spam filter designed for multi-user enterprise systems. + On a properly configured system, many users experience results between 99.5% - 99.95%, or one error for + every 200 to 2000 messages. DSPAM supports many different MTAs and can also be deployed as a stand-alone + SMTP appliance. + + http://www.abyssworld.de/packages/config/dspam.xml + http://www.abyssworld.de/packages/All/ + dspam-devel-3.6.4.20060315.1518.tbz + 3.6.6 + ALPHA + me@daniel.stefan.haischt.name + + dspam + + + + p3scan-pf + A transparent POP3-Proxy with virus-scanning- and spam-scanning-capabilities. + http://www.undergroundsecurity.com/p3scan/ + Security + 0.1 + ALPHA + fernando@netfilter.com.br + http://www.pfsense.com/packages/All/ + p3scan-pf-2.3.2.tbz + http://www.pfsense.org/packages/config/p3scan-pf/p3scan-pf.xml + p3scan-pf.xml + + + mysql + http://www.mysql.com/ + + MySQL RDBMS. + + http://www.abyssworld.de/packages/config/mysql.xml + http://www.abyssworld.de/packages/All/ + mysql-server-5.0.21.tbz + 5.0.21 + ALPHA + me@daniel.stefan.haischt.name + + mysql + + + + clamav + http://www.clamav.net/ + + Clam Antivirus. + + http://www.abyssworld.de/packages/config/clamav.xml + http://www.abyssworld.de/packages/All/ + clamav-devel-20060503_1.tbz + 20060503_1 + ALPHA + me@daniel.stefan.haischt.name + + clamav + + + + sshterm + + This is a package of the SSHTools SSHTerm Java Applet. SSHTools is a + suite of Java SSH applications providing a Java SSH API, + SSH Terminal, SSH secured VNC client, SFTP client and SSH Daemon. + + http://sourceforge.net/projects/sshtools/ + Security + 0.1 + ALPHA + me@daniel.stefan.haischt.name + http://www.pfsense.com/packages/All/ + sshtools-0.2.2.tbz + http://www.pfsense.org/packages/config/sshterm/sshterm.xml + sshterm.xml + + + POP3 Proxy +
Services
+ p3scan-pf.xml + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + A transparent POP3-Proxy with virus-scanning capabilities +
+ + DSPAM +
Services
+ dspam.inc + /dspam.php +
+ + DSPAM Wizard +
Services
+ dspam.inc + /wizard.php?xml=dspam_wizard.xml +
+ + Shell +
Diagnostics
+ sshterm.xml + /diag_shell.php +
+ + dspam + DSPAM content-based spam filter + dspam.sh + dspam + + + clamd + Clam AntiVirus Scanner + 010.clamav-clamd.sh + clamd + + + Deamon that receives new AntiVirus signatures + freshclam + 020.clamav-freshclam.sh + freshclam + + + mysql + MySQL RDBMS + 000.mysql.sh + mysqld_safe + + + p3scan-pf + + p3scan is a pop3 antivirus proxy that can be used completely transparently with any pop3 mail client. + + 030.p3scan.sh + p3scan + +
+ + + 0 + * + * + * + * + root + /usr/bin/nice -n20 newsyslog + + + 1,31 + 0-5 + * + * + * + root + /usr/bin/nice -n20 adjkerntz -a + + + 1 + * + 1 + * + * + root + /usr/bin/nice -n20 /etc/rc.update_bogons.sh + + + */60 + * + * + * + * + root + /usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 sshlockout + + + 1 + 1 + * + * + * + root + /usr/bin/nice -n20 /etc/rc.dyndns.update + + + */5 + * + * + * + * + root + /usr/bin/nice -n20 /etc/ping_hosts.sh + + +
diff --git a/config/archive/dspam/pear/Image/Canvas.php b/config/archive/dspam/pear/Image/Canvas.php new file mode 100644 index 00000000..e669807a --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas.php @@ -0,0 +1,733 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Specfies the path to the system location of font files. + * + * Remember trailing slash! + * + * This is set by default on Windows systems to %SystemRoot%\Fonts\ + */ +if (!defined('IMAGE_CANVAS_SYSTEM_FONT_PATH')) { + if (isset($_SERVER['SystemRoot'])) { + define('IMAGE_CANVAS_SYSTEM_FONT_PATH', $_SERVER['SystemRoot'] . '/Fonts/'); + } else { + /** + * @ignore + */ + define('IMAGE_CANVAS_SYSTEM_FONT_PATH', ''); + } +} + +/** + * Class for handling different output formats + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + * @abstract + */ +class Image_Canvas +{ + + /** + * The leftmost pixel of the element on the canvas + * @var int + * @access private + */ + var $_left = 0; + + /** + * The topmost pixel of the element on the canvas + * @var int + * @access private + */ + var $_top = 0; + + /** + * The width of the graph + * @var int + * @access private + */ + var $_width = 0; + + /** + * The height of the graph + * @var int + * @access private + */ + var $_height = 0; + + /** + * Polygon vertex placeholder + * @var array + * @access private + */ + var $_polygon = array(); + + /** + * The thickness of the line(s) + * @var int + * @access private + */ + var $_thickness = 1; + + /** + * The line style + * @var mixed + * @access private + */ + var $_lineStyle = 'transparent'; + + /** + * The fill style + * @var mixed + * @access private + */ + var $_fillStyle = 'transparent'; + + /** + * The font options + * @var array + * @access private + */ + var $_font = array(); + + /** + * The default font + * @var array + * @access private + */ + var $_defaultFont = array('name' => 'Courier New', 'color' => 'black', 'size' => 9); + + /** + * Create the canvas. + * + * Parameters available: + * + * 'width' The width of the graph on the canvas + * + * 'height' The height of the graph on the canvas + * + * 'left' The left offset of the graph on the canvas + * + * 'top' The top offset of the graph on the canvas + * + * @param array $params Parameter array + * @abstract + */ + function Image_Canvas($params) + { + if (isset($params['left'])) { + $this->_left = $params['left']; + } + + if (isset($params['top'])) { + $this->_top = $params['top']; + } + + if (isset($params['width'])) { + $this->_width = $params['width']; + } + + if (isset($params['height'])) { + $this->_height = $params['height']; + } + + $this->setDefaultFont($this->_defaultFont); + } + + /** + * Get the x-point from the relative to absolute coordinates + * + * @param float $x The relative x-coordinate (in percentage of total width) + * @return float The x-coordinate as applied to the canvas + * @access private + */ + function _getX($x) + { + return floor($this->_left + $x); + } + + /** + * Get the y-point from the relative to absolute coordinates + * + * @param float $y The relative y-coordinate (in percentage of total width) + * @return float The y-coordinate as applied to the canvas + * @access private + */ + function _getY($y) + { + return floor($this->_top + $y); + } + + /** + * Get the width of the canvas + * + * @return int The width + */ + function getWidth() + { + return $this->_width; + } + + /** + * Get the height of the canvas + * + * @return int The height + */ + function getHeight() + { + return $this->_height; + } + + /** + * Sets the thickness of the line(s) to be drawn + * + * @param int $thickness The actual thickness (in pixels) + */ + function setLineThickness($thickness) + { + $this->_thickness = $thickness; + } + + /** + * Sets the color of the line(s) to be drawn + * + * @param mixed $color The color of the line + */ + function setLineColor($color) + { + $this->_lineStyle = $color; + } + + /** + * Sets the style of the filling of drawn objects. + * + * This method gives simple access to setFillColor(), setFillImage() and + * setGradientFill() + * + * @param mixed $fill The fill style + */ + function setFill($fill) + { + if (is_array($fill)) { + $this->setGradientFill($fill); + } elseif (file_exists($fill)) { + $this->setFillImage($fill); + } else { + $this->setFillColor($fill); + } + } + + /** + * Sets the color of the filling of drawn objects + * + * @param mixed $color The fill color + */ + function setFillColor($color) + { + $this->_fillStyle = $color; + } + + /** + * Sets an image that should be used for filling + * + * @param string $filename The filename of the image to fill with + */ + function setFillImage($filename) + { + } + + /** + * Sets a gradient fill + * + * @param array $gradient Gradient fill options + */ + function setGradientFill($gradient) + { + $this->_fillStyle = $gradient; + } + + /** + * Sets the font options. + * + * The $font array may have the following entries: + * + * 'name' The name of the font. This name must either be supported + * natively by the canvas or mapped to a font using the font-mapping scheme + * + * 'size' Size in pixels + * + * 'angle' The angle with which to write the text + * + * @param array $fontOptions The font options. + */ + function setFont($fontOptions) + { + $this->_font = $fontOptions; + + if (!isset($this->_font['color'])) { + $this->_font['color'] = 'black'; + } + + if (!(isset($this->_font['angle'])) || ($this->_font['angle'] === false)) { + $this->_font['angle'] = 0; + } + + if (isset($this->_font['angle'])) { + if ((($this->_font['angle'] > 45) && ($this->_font['angle'] < 135)) || + (($this->_font['angle'] > 225) && ($this->_font['angle'] < 315)) + ) { + $this->_font['vertical'] = true; + } + } + + if ((!isset($this->_font['file'])) && (isset($this->_font['name']))) { + include_once 'Image/Canvas/Tool.php'; + $this->_font['file'] = Image_Canvas_Tool::fontMap($this->_font['name']); + } + } + + /** + * Sets the default font options. + * + * The $font array may have the following entries: + * + * 'name' The name of the font. This name must either be supported + * natively by the canvas or mapped to a font using the font-mapping scheme + * + * 'size' Size in pixels + * + * 'angle' The angle with which to write the text + * + * @param array $fontOptions The font options. + */ + function setDefaultFont($fontOptions) + { + $this->setFont($fontOptions); + $this->_defaultFont = $this->_font; + } + + /** + * Resets the canvas. + * + * Includes fillstyle, linestyle, thickness and polygon + * + * @access private + */ + function _reset() + { + $this->_lineStyle = false; + $this->_fillStyle = false; + $this->_thickness = 1; + $this->_polygon = array(); + $this->_font = $this->_defaultFont; + } + + /** + * Reset the canvas. + * + * Includes fillstyle, linestyle, thickness and polygon + */ + function reset() + { + $this->_reset(); + } + + /** + * Draw a line end + * + * Parameter array: + * 'x': int X point + * 'y': int Y point + * 'end': string The end type of the end + * 'angle': int [optional] The angle with which to draw the end + * @param array $params Parameter array + */ + function drawEnd($params) + { + } + + /** + * Draw a line + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'end0': string [optional] The end type of end0 (the start) + * 'end1': string [optional] The end type of end1 (the end) + * 'size0': int [optional] The size of end0 + * 'size1': int [optional] The size of end1 + * 'color': mixed [optional] The line color + * @param array $params Parameter array + */ + function line($params) + { + $x0 = $this->_getX($params['x0']); + $y0 = $this->_getY($params['y0']); + $x1 = $this->_getX($params['x1']); + $y1 = $this->_getY($params['y1']); + if (isset($params['end0'])) { + $angle = Image_Canvas_Tool::getAngle($x1, $y1, $x0, $y0); + $this->drawEnd( + array( + 'end' => $params['end0'], + 'x' => $params['x0'], + 'y' => $params['y0'], + 'angle' => $angle, + 'color' => (isset($params['color0']) ? $params['color0'] : false), + 'size' => $params['size0'] + ) + ); + } + if (isset($params['end1'])) { + $angle = Image_Canvas_Tool::getAngle($x0, $y0, $x1, $y1); + //print "
"; var_dump($params, $angle); print "
"; + $this->drawEnd( + array( + 'end' => $params['end1'], + 'x' => $params['x1'], + 'y' => $params['y1'], + 'angle' => $angle, + 'color' => (isset($params['color1']) ? $params['color1'] : false), + 'size' => $params['size1'] + ) + ); + } + $this->_reset(); + } + + /** + * Adds vertex to a polygon + * + * Parameter array: + * 'x': int X point + * 'y': int Y point + * 'url': string [optional] URL to link the vertex to (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * 'alt': string [optional] Alternative text to show in the image map (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * 'target': string [optional] The link target on the image map (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * 'mapsize': int [optional] The size of the "map", i.e. the size of the hot spot (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * @param array $params Parameter array + */ + function addVertex($params) + { + $params['X'] = $this->_getX($params['x']); + $params['Y'] = $this->_getY($params['y']); + $this->_polygon[] = $params; + } + + /** + * Adds "splined" vertex to a polygon + * + * Parameter array: + * 'x': int X point + * 'y': int Y point + * 'p1x': int X Control point 1 + * 'p1y': int Y Control point 1 + * 'p2x': int X Control point 2 + * 'p2y': int Y Control point 2 + * 'url': string [optional] URL to link the vertex to (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * 'alt': string [optional] Alternative text to show in the image map (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * 'target': string [optional] The link target on the image map (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * 'mapsize': int [optional] The size of the "map", i.e. the size of the hot spot (must be used with 'map_vertices' in polygon() on a canvas that support image maps) + * @param array $params Parameter array + */ + function addSpline($params) + { + $params['X'] = $this->_getX($params['x']); + $params['Y'] = $this->_getY($params['y']); + $params['P1X'] = $this->_getX($params['p1x']); + $params['P1Y'] = $this->_getY($params['p1y']); + $params['P2X'] = $this->_getX($params['p2x']); + $params['P2Y'] = $this->_getY($params['p2y']); + $this->_polygon[] = $params; + } + + /** + * Draws a polygon + * + * Parameter array: + * 'connect': bool [optional] Specifies whether the start point should be + * connected to the endpoint (closed polygon) or not (connected line) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function polygon($params) + { + $this->_reset(); + } + + /** + * Draw a rectangle + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function rectangle($params) + { + $this->_reset(); + } + + /** + * Draw an ellipse + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function ellipse($params) + { + $this->_reset(); + } + + /** + * Draw a pie slice + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'v1': int The starting angle (in degrees) + * 'v2': int The end angle (in degrees) + * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut) + * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function pieslice($params) + { + $this->_reset(); + } + + /** + * Get the width of a text, + * + * @param string $text The text to get the width of + * @return int The width of the text + */ + function textWidth($text) + { + } + + /** + * Get the height of a text, + * + * @param string $text The text to get the height of + * @return int The height of the text + */ + function textHeight($text) + { + } + + /** + * Writes text + * + * Parameter array: + * 'x': int X-point of text + * 'y': int Y-point of text + * 'text': string The text to add + * 'alignment': array [optional] Alignment + * 'color': mixed [optional] The color of the text + */ + function addText($params) + { + $this->_reset(); + } + + /** + * Overlay image + * + * Parameter array: + * 'x': int X-point of overlayed image + * 'y': int Y-point of overlayed image + * 'filename': string The filename of the image to overlay + * 'width': int [optional] The width of the overlayed image (resizing if possible) + * 'height': int [optional] The height of the overlayed image (resizing if possible) + * 'alignment': array [optional] Alignment + */ + function image($params) + { + } + + /** + * Set clipping to occur + * + * Parameter array: + * + * 'x0': int X point of Upper-left corner + * 'y0': int X point of Upper-left corner + * 'x1': int X point of lower-right corner + * 'y1': int Y point of lower-right corner + */ + function setClipping($params = false) + { + } + + /** + * Start a group. + * + * What this does, depends on the canvas/format. + * + * @param string $name The name of the group + */ + function startGroup($name = false) + { + } + + /** + * End the "current" group. + * + * What this does, depends on the canvas/format. + */ + function endGroup() + { + } + + /** + * Output the result of the canvas to the browser + * + * @param array $params Parameter array, the contents and meaning depends on the actual Canvas + * @abstract + */ + function show($params = false) + { + if ($params === false) { + header('Expires: Tue, 2 Jul 1974 17:41:00 GMT'); // Date in the past + header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified + header('Cache-Control: no-cache, must-revalidate'); // HTTP/1.1 + header('Pragma: no-cache'); + } + } + + /** + * Save the result of the canvas to a file + * + * Parameter array: + * 'filename': string The file to output to + * @param array $params Parameter array, the contents and meaning depends on the actual Canvas + * @abstract + */ + function save($params = false) + { + } + + /** + * Get a canvas specific HTML tag. + * + * This method implicitly saves the canvas to the filename in the + * filesystem path specified and parses it as URL specified by URL path + * + * Parameter array: + * 'filename': string + * 'filepath': string Path to the file on the file system. Remember the final slash + * 'urlpath': string Path to the file available through an URL. Remember the final slash + */ + function toHtml($params) + { + $this->save(array('filename' => $params['filepath'] . $params['filename'])); + } + + /** + * Canvas factory method. + * + * Supported canvass are: + * + * 'png': output in PNG format (using GD) + * + * 'jpg': output in JPEG format (using GD) + * + * 'pdf': output in PDF format (using PDFlib) + * + * 'svg': output in SVG format + * + * 'imagemap': output as a html image map + * + * An example of usage: + * + * + * 800, 'height' => 600, 'antialias' => 'native') + * ); + * ?> + * + * + * @param string $canvas The canvas type + * @param array $params The parameters for the canvas constructor + * @return Image_Canvas The newly created canvas + * @static + */ + function &factory($canvas, $params) + { + $canvas = strtoupper($canvas); + + if (($canvas == 'PNG') || ($canvas == 'GD')) { + $canvas = 'GD_PNG'; + } + if (($canvas == 'JPG') || ($canvas == 'JPEG')) { + $canvas = 'GD_JPG'; + } + + if ($canvas == 'IMAGEMAP') { + $canvas = 'ImageMap'; + } + + $class = 'Image_Canvas_'. $canvas; + include_once 'Image/Canvas/'. str_replace('_', '/', $canvas) . '.php'; + + $obj =& new $class($params); + return $obj; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/Color.php b/config/archive/dspam/pear/Image/Canvas/Color.php new file mode 100644 index 00000000..0ac78553 --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/Color.php @@ -0,0 +1,182 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id$ + +/** +* Class for color-handling +* +* @author Stefan Neufeind +* @package Image_Canvas +* @category images +* @license The PHP License, version 2.02 +*/ + +/** +* Color class to be extended; from package PEAR::Image_Color +*/ +require_once 'Image/Color.php'; + +/** +* Class for color-handling +* +* This is used to extend the functionality of the current PEAR::Image_Color v0.4. +* I hope to be allowed to incorporate some of the improvements in a new Image_Color release. +* +* @author Stefan Neufeind +* @package Image_Canvas +* @access public +*/ +class Image_Canvas_Color extends Image_Color +{ + /** + * Allocates a color in the given image. + * + * Userdefined color specifications get translated into + * an array of rgb values. + * + * @param resource GD-resource + * @param mixed any color representation supported by color2RGB() + * @return resource Image color handle + * @see color2RGB() + * @access public + * @static + */ + function allocateColor(&$img, $color) + { + $color = Image_Canvas_Color::color2RGB($color); + + if (($color[3] == 255) || (!function_exists("imagecolorallocatealpha"))) { + return imagecolorallocate($img, $color[0], $color[1], $color[2]); + } else { + return imagecolorallocatealpha($img, $color[0], $color[1], $color[2], 127-round(($color[3]*127)/255)); + } + } + + /** + * Convert any color-representation into an array of 4 ints (RGBA). + * + * Userdefined color specifications get translated into + * an array of rgb values. + * + * @param mixed any color representation supported by Image_Canvas_Color::color2RGB() + * @return array Array of 4 ints (RGBA-representation) + * @access public + * @static + */ + function color2RGB($color) + { + if (is_array($color)) { + if (!is_numeric($color[0])) { + return null; // error + } + if (count($color) == 3) { // assume RGB-color + + // 255 = alpha-value; full opaque + return array((int) $color[0], + (int) $color[1], + (int) $color[2], + 255); + } + if (count($color) == 4) { // assume RGBA-color + + // 255 = alpha-value; full opaque + return array((int) $color[0], + (int) $color[1], + (int) $color[2], + (int) $color[3]); + } + return null; // error + } elseif (is_string($color)) { + $alphaPos = strpos($color, '@'); + if ($alphaPos === false) { + $alpha = 255; + } else { + $alphaFloat = (float) substr($color, $alphaPos+1); + // restrict to range 0..1 + $alphaFloat = max(min($alphaFloat, 1), 0); + $alpha = (int) round((float) 255 * $alphaFloat); + $color = substr($color, 0, $alphaPos); + } + if ($color[0] == '#') { // hex-color given, e.g. #FFB4B4 + $tempColor = parent::hex2rgb($color); + return array((int) $tempColor[0], + (int) $tempColor[1], + (int) $tempColor[2], + $alpha); + } + if (strpos($color,'%') !== false) { + $tempColor = parent::percentageColor2RGB($color); + return array((int) $tempColor[0], + (int) $tempColor[1], + (int) $tempColor[2], + $alpha); + } else { + $tempColor = parent::namedColor2RGB($color); + return array((int) $tempColor[0], + (int) $tempColor[1], + (int) $tempColor[2], + $alpha); + } + } else { + return null; // error + } + } + + /** + * getRange + * Given a degree, you can get the range of colors between one color and + * another color. + * + * @access public + * @param string How much each 'step' between the colors we should take. + * @return array Returns an array of all the colors, one element for each color. + */ + function getRange ($degrees) + { + $tempColors = parent::getRange($degrees); + + // now add alpha-channel information + $steps = count($tempColors); + for($counter=0;$counter<$steps;$counter++) { + $tempColors[$counter] = parent::hex2rgb($tempColors[$counter]); + unset($tempColors[$counter]['hex']); + $tempColors[$counter][3] = (int) round( + (((float) $this->color1[3]*($steps-$counter))+ + ((float) $this->color2[3]*($counter)) + ) / $steps + ); + } + + return $tempColors; + } + + /** + * Internal method to correctly set the colors. + * + * @param mixed color 1 + * @param mixed color 2 + * @access private + */ + function _setColors ( $col1, $col2 ) + { + $this->color1 = Image_Canvas_Color::color2RGB($col1); + $this->color2 = Image_Canvas_Color::color2RGB($col2); + } +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/Fonts/README b/config/archive/dspam/pear/Image/Canvas/Fonts/README new file mode 100644 index 00000000..0a836147 --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/Fonts/README @@ -0,0 +1,12 @@ +This is where the font files are located. + +Font files can be found at: + +MS CoreFonts + http://corefonts.sourceforge.net/ + +Divide By Zero (most are cartoonish) + http://fonts.tom7.com/ + +MING FDB Fonts + http://ming.sf.net/ \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/Fonts/fontmap.txt b/config/archive/dspam/pear/Image/Canvas/Fonts/fontmap.txt new file mode 100644 index 00000000..ccec67dd --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/Fonts/fontmap.txt @@ -0,0 +1,25 @@ +Arial,arial.ttf +Arial Bold,arialbd.ttf +Arial Bold Italic,arialbi.ttf +Arial Italic,ariali.ttf +Courier New,cour.ttf +Courier New Bold,courbd.ttf +Courier New Bold Italic,courbi.ttf +Courier New Italic,couri.ttf +Garamond,gara.ttf +Garamond Bold,garabd.ttf +Garamond Italic,garait.ttf +Gothic,gothic.ttf +Gothic Bold,gothicb.ttf +Gothic Bold Italic,gothicbi.ttf +Gothic Italic,gothici.ttf +Sans Serif,micross.ttf +Reference Sans Serif,refsan.ttf +Times New Roman,times.ttf +Times New Roman Bold,timesbd.ttf +Times New Roman Bold Italic,timesbi.ttf +Times New Roman Italic,timesi.ttf +Verdana,verdana.ttf +Verdana Bold,verdanab.ttf +Verdana Bold Italic,verdanaz.ttf +Verdana Italic,verdanai.ttf \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/GD.php b/config/archive/dspam/pear/Image/Canvas/GD.php new file mode 100644 index 00000000..40132899 --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/GD.php @@ -0,0 +1,1693 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Include file Image/Canvas.php + */ +require_once 'Image/Canvas/WithMap.php'; + +/** + * Include file Image/Canvas/Color.php + */ +require_once 'Image/Canvas/Color.php'; + +/** + * Canvas class to output using PHP GD support. + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + * @abstract + */ +class Image_Canvas_GD extends Image_Canvas_WithMap +{ + + /** + * The canvas of the graph + * @var resource + * @access private + */ + var $_canvas; + + /** + * The canvas to use for tiled filling + * @var resource + * @access private + */ + var $_tileImage = null; + + /** + * Is version GD2 installed? + * @var bool + * @access private + */ + var $_gd2 = true; + + /** + * Antialiasing? + * + * Possible values 'off', 'driver' and 'native' + * + * @var string + * @access private + */ + var $_antialias = 'off'; + + var $_alpha = false; + + var $_clipping = array(); + + /** + * Create the GD canvas. + * + * Parameters available: + * + * 'width' The width of the graph on the canvas + * + * 'height' The height of the graph on the canvas + * + * 'left' The left offset of the graph on the canvas + * + * 'top' The top offset of the graph on the canvas + * + * 'antialias' = 'native' enables native GD antialiasing - this + * method has no severe impact on performance (approx +5%). Requires PHP + * 4.3.2 (with bundled GD2) + * + * 'antialias' = {true|'driver'} Image_Graph implemented method. This method + * has a severe impact on performance, drawing an antialiased line this + * way is about XX times slower, with an overall performance impact of + * about +40%. The justification for this method is that if native support + * is not available this can be used, it is also a future feature that this + * method for antialiasing will support line styles. + * + * Use antialiased for best results with a line/area chart having just a few + * datapoints. Native antialiasing does not provide a good appearance with + * short lines, as for example with smoothed charts. Antialiasing does not + * (currently) work with linestyles, neither native nor driver method! + * + * 'noalpha' = true If alpha blending is to be disabled + * + * 'filename' An image to open, on which the graph is created on + * + * 'gd' A GD resource to add the image to, use this option to continue + * working on an already existing GD resource. Make sure this is passed 'by- + * reference' (using &) + * + * 'usemap' Initialize an image map + * + * 'gd' and 'filename' are mutually exclusive with 'gd' as preference + * + * 'width' and 'height' are required unless 'filename' or 'gd' are + * specified, in which case the width and height are taken as the actual + * image width/height. If the latter is the case and 'left' and/or 'top' was + * also specified, the actual 'width'/'height' are altered so that the graph + * fits inside the canvas (i.e 'height' = actual height - top, etc.) + * + * @param array $param Parameter array + */ + function Image_Canvas_GD($param) + { + include_once 'Image/Canvas/Color.php'; + + parent::Image_Canvas_WithMap($param); + + $this->_gd2 = ($this->_version() == 2); + $this->_font = array('font' => 1, 'color' => 'black'); + + if ((isset($param['gd'])) && (is_resource($param['gd']))) { + $this->_canvas =& $param['gd']; + } elseif (isset($param['filename'])) { + $this->_canvas =& $this->_getGD($param['filename']); + } else { + if ($this->_gd2) { + $this->_canvas = ImageCreateTrueColor( + $this->_width, + $this->_height + ); + if ((!isset($param['noalpha'])) || ($param['noalpha'] !== true)) { + ImageAlphaBlending($this->_canvas, true); + $this->_alpha = true; + } + } else { + $this->_canvas = ImageCreate($this->_width, $this->_height); + } + } + + if (isset($param['antialias'])) { + $this->_antialias = $param['antialias']; + } + + if ($this->_antialias === true) { + $this->_antialias = 'driver'; + } + + if (($this->_gd2) && ($this->_antialias === 'native')) { + ImageAntialias($this->_canvas, true); + } + } + + /** + * Get an GD image resource from a file + * + * @param string $filename + * @return mixed The GD image resource + * @access private + */ + function &_getGD($filename) + { + $info = getimagesize($filename); + + $result = null; + switch($info[2]) { + case IMG_PNG: + $result =& ImageCreateFromPNG($filename); + break; + + case IMG_JPG: + $result =& ImageCreateFromJPEG($filename); + break; + + case IMG_GIF: + $result =& ImageCreateFromGIF($filename); + break; + } + return $result; + } + + /** + * Get the color index for the RGB color + * + * @param int $color The color + * @return int The GD image index of the color + * @access private + */ + function _color($color = false) + { + if (($color === false) || ($color === 'opague') || ($color === 'transparent')) { + return ImageColorTransparent($this->_canvas); + } else { + return Image_Canvas_Color::allocateColor($this->_canvas, $color); + } + } + + /** + * Get the GD applicable linestyle + * + * @param mixed $lineStyle The line style to return, false if the one + * explicitly set + * @return mixed A GD compatible linestyle + * @access private + */ + function _getLineStyle($lineStyle = false) + { + if ($this->_gd2) { + ImageSetThickness($this->_canvas, $this->_thickness); + } + + if ($lineStyle == 'transparent') { + return false; + } elseif ($lineStyle === false) { + if (is_array($this->_lineStyle)) { + $colors = array(); + foreach ($this->_lineStyle as $color) { + if ($color === 'transparent') { + $color = false; + } + $colors[] = $this->_color($color); + } + ImageSetStyle($this->_canvas, $colors); + return IMG_COLOR_STYLED; + } else { + return $this->_color($this->_lineStyle); + } + } else { + return $this->_color($lineStyle); + } + } + + /** + * Get the GD applicable fillstyle + * + * @param mixed $fillStyle The fillstyle to return, false if the one + * explicitly set + * @return mixed A GD compatible fillstyle + * @access private + */ + function _getFillStyle($fillStyle = false, $x0 = 0, $y0 = 0, $x1 = 0, $y1 = 0) + { + if ($this->_tileImage != null) { + ImageDestroy($this->_tileImage); + $this->_tileImage = null; + } + if ($fillStyle == 'transparent') { + return false; + } elseif ($fillStyle === false) { + if (is_resource($this->_fillStyle)) { + $x = min($x0, $x1); + $y = min($y0, $y1); + $w = abs($x1 - $x0) + 1; + $h = abs($y1 - $y0) + 1; + if ($this->_gd2) { + $this->_tileImage = ImageCreateTrueColor( + $this->getWidth(), + $this->getHeight() + ); + + ImageCopyResampled( + $this->_tileImage, + $this->_fillStyle, + $x, + $y, + 0, + 0, + $w, + $h, + ImageSX($this->_fillStyle), + ImageSY($this->_fillStyle) + ); + } else { + $this->_tileImage = ImageCreate( + $this->getWidth(), + $this->getHeight() + ); + + ImageCopyResized( + $this->_tileImage, + $this->_fillStyle, + $x, + $y, + 0, + 0, + $w, + $h, + ImageSX($this->_fillStyle), + ImageSY($this->_fillStyle) + ); + } + ImageSetTile($this->_canvas, $this->_tileImage); + return IMG_COLOR_TILED; + } elseif ((is_array($this->_fillStyle)) && (isset($this->_fillStyle['direction']))) { + $width = abs($x1 - $x0) + 1; + $height = abs($y1 - $y0) + 1; + + switch ($this->_fillStyle['direction']) { + case 'horizontal': + $count = $width; + break; + + case 'vertical': + $count = $height; + break; + + case 'horizontal_mirror': + $count = $width / 2; + break; + + case 'vertical_mirror': + $count = $height / 2; + break; + + case 'diagonal_tl_br': + case 'diagonal_bl_tr': + $count = sqrt($width * $width + $height * $height); + break; + + case 'radial': + $count = max($width, $height, sqrt($width * $width + $height * $height)) + 1; + break; + + } + + $count = round($count); + + if ($this->_gd2) { + $this->_tileImage = ImageCreateTrueColor( + $this->getWidth(), + $this->getHeight() + ); + } else { + $this->_tileImage = ImageCreate( + $this->getWidth(), + $this->getHeight() + ); + } + + + $startColor = Image_Canvas_Color::color2RGB( + ($this->_fillStyle['direction'] == 'radial' ? + $this->_fillStyle['end'] : + $this->_fillStyle['start'] + ) + ); + $endColor = Image_Canvas_Color::color2RGB( + ($this->_fillStyle['direction'] == 'radial' ? + $this->_fillStyle['start'] : + $this->_fillStyle['end'] + ) + ); + + $redIncrement = ($endColor[0] - $startColor[0]) / $count; + $greenIncrement = ($endColor[1] - $startColor[1]) / $count; + $blueIncrement = ($endColor[2] - $startColor[2]) / $count; + + $color = false; + for ($i = 0; $i < $count; $i ++) { + unset($color); + if ($i == 0) { + $color = $startColor; + unset($color[3]); + } else { + $color[0] = round(($redIncrement * $i) + + $redIncrement + $startColor[0]); + $color[1] = round(($greenIncrement * $i) + + $greenIncrement + $startColor[1]); + $color[2] = round(($blueIncrement * $i) + + $blueIncrement + $startColor[2]); + } + $color = Image_Canvas_Color::allocateColor( + $this->_tileImage, + $color + ); + + switch ($this->_fillStyle['direction']) { + case 'horizontal': + ImageLine($this->_tileImage, + $x0 + $i, + $y0, + $x0 + $i, + $y1, $color); + break; + + case 'vertical': + ImageLine($this->_tileImage, + $x0, + $y1 - $i, + $x1, + $y1 - $i, $color); + break; + + case 'horizontal_mirror': + if (($x0 + $i) <= ($x1 - $i)) { + ImageLine($this->_tileImage, + $x0 + $i, + $y0, + $x0 + $i, + $y1, $color); + + ImageLine($this->_tileImage, + $x1 - $i, + $y0, + $x1 - $i, + $y1, $color); + } + break; + + case 'vertical_mirror': + if (($y0 + $i) <= ($y1 - $i)) { + ImageLine($this->_tileImage, + $x0, + $y0 + $i, + $x1, + $y0 + $i, $color); + ImageLine($this->_tileImage, + $x0, + $y1 - $i, + $x1, + $y1 - $i, $color); + } + break; + + case 'diagonal_tl_br': + if (($i > $width) && ($i > $height)) { + $polygon = array ( + $x1, $y0 + $i - $width - 1, + $x1, $y1, + $x0 + $i - $height - 1, $y1); + } elseif ($i > $width) { + $polygon = array ( + $x0, $y0 + $i, + $x0, $y1, + $x1, $y1, + $x1, $y0 + $i - $width - 1); + } elseif ($i > $height) { + $polygon = array ( + $x0 + $i - $height - 1, $y1, + $x1, $y1, + $x1, $y0, + $x0 + $i, $y0); + } else { + $polygon = array ( + $x0, $y0 + $i, + $x0, $y1, + $x1, $y1, + $x1, $y0, + $x0 + $i, $y0); + } + ImageFilledPolygon( + $this->_tileImage, + $polygon, + count($polygon) / 2, + $color + ); + break; + + case 'diagonal_bl_tr': + if (($i > $width) && ($i > $height)) { + $polygon = array ( + $x1, $y1 - $i + $width - 1, + $x1, $y0, + $x0 + $i - $height - 1, $y0); + } elseif ($i > $width) { + $polygon = array ( + $x0, $y1 - $i, + $x0, $y0, + $x1, $y0, + $x1, $y1 - $i + $width - 1); + } elseif ($i > $height) { + $polygon = array ( + $x0 + $i - $height - 1, $y0, + $x1, $y0, + $x1, $y1, + $x0 + $i, $y1); + } else { + $polygon = array ( + $x0, $y1 - $i, + $x0, $y0, + $x1, $y0, + $x1, $y1, + $x0 + $i, $y1); + } + ImageFilledPolygon( + $this->_tileImage, + $polygon, + count($polygon) / 2, + $color + ); + break; + + case 'radial': + if (($this->_gd2) && ($i < $count)) { + ImageFilledEllipse( + $this->_tileImage, + $x0 + $width / 2, + $y0 + $height / 2, + $count - $i, + $count - $i, + $color + ); + } + break; + } + } + ImageSetTile($this->_canvas, $this->_tileImage); + return IMG_COLOR_TILED; + } else { + return $this->_color($this->_fillStyle); + } + } else { + return $this->_color($fillStyle); + } + } + + /** + * Sets an image that should be used for filling + * + * @param string $filename The filename of the image to fill with + */ + function setFillImage($filename) + { + $this->_fillStyle =& $this->_getGD($filename); + } + + /** + * Sets the font options. + * + * The $font array may have the following entries: + * + * 'ttf' = the .ttf file (either the basename, filename or full path) + * If 'ttf' is specified, then the following can be specified + * + * 'size' = size in pixels + * + * 'angle' = the angle with which to write the text + * + * @param array $font The font options. + */ + function setFont($fontOptions) + { + parent::setFont($fontOptions); + + if (isset($this->_font['ttf'])) { + $this->_font['file'] = str_replace('\\', '/', Image_Canvas_Tool::fontMap($this->_font['ttf'])); + } elseif (!isset($this->_font['font'])) { + $this->_font['font'] = 1; + } + + if (!isset($this->_font['color'])) { + $this->_font['color'] = 'black'; + } + + if ((isset($this->_font['angle'])) && ($this->_font['angle'] === false)) { + $this->_font['angle'] = 0; + } + } + + /** + * Calculate pixels on a line + * + * @param int $x0 X start point + * @param int $y0 X start point + * @param int $x1 X end point + * @param int $y1 Y end point + * @return array An associated array of x,y points with all pixels on the + * line + * @access private + */ + function &_linePixels($x0, $y0, $x1, $y1) + { + $pixels = array(); + if (abs($x0 - $x1) > abs($y0 - $y1)) { + if ($x1 != $x0) { + $m = ($y1 - $y0) / ($x1 - $x0); + } else { + $m = 0; + } + $b = $y0 - $m * $x0; + $strx = min($x0, $x1); + $endx = max($x0, $x1); + for ($x = $strx; $x <= $endx; $x++) { + $pixels[] = array('X' => $x, 'Y' => ($m * $x + $b)); + } + } else { + if ($y1 != $y0) { + $m = ($x1 - $x0) / ($y1 - $y0); + } else { + $m = 0; + } + $b = $x0 - $m * $y0; + $stry = min($y0, $y1); + $endy = max($y0, $y1); + for ($y = $stry; $y <= $endy; $y++) { + $pixels[] = array('X' => ($m * $y + $b), 'Y' => $y); + } + } + return $pixels; + } + + /** + * Draws an antialiased line + * + * @param int $x0 X start point + * @param int $y0 X start point + * @param int $x1 X end point + * @param int $y1 Y end point + * @param mixed $color The line color, can be omitted + * @access private + */ + function _antialiasedLine($x0, $y0, $x1, $y1, $color = false) + { + if (($line = $this->_getLineStyle($color)) !== false) { + if ($line >= 0) { + $line = ImageColorsForIndex($this->_canvas, $line); + $pixels = &$this->_linePixels($x0, $y0, $x1, $y1); + foreach ($pixels as $point) { + $this->_antialiasedPixel($point['X'], $point['Y'], $line); + } + unset($pixels); + } + } + } + + + /** + * Draws an antialiased pixel + * + * @param int $x X point + * @param int $y Y point + * @param mixed $color The pixel color + * @access private + */ + function _antialiasedPixel($x, $y, $color) + { + $fx = floor($x); + $fy = floor($y); + $cx = ceil($x); + $cy = ceil($y); + $xa = $x - $fx; + $xb = $cx - $x; + $ya = $y - $fy; + $yb = $cy - $y; + if (($cx == $fx) && ($cy == $fy)) { + $this->_antialisedSubPixel($fx, $fy, 0.0, 1.0, $color); + } else { + $this->_antialisedSubPixel($fx, $fy, $xa + $ya, $xb + $yb, $color); + if ($cy != $fy) { + $this->_antialisedSubPixel($fx, $cy, $xa + $yb, $xb + $ya, $color); + } + if ($cx != $fx) { + $this->_antialisedSubPixel($cx, $fy, $xb + $ya, $xa + $yb, $color); + if ($cy != $fy) { + $this->_antialisedSubPixel($cx, $cy, $xb + $yb, $xa + $ya, $color); + } + } + } + } + + /** + * Antialias'es the pixel around x,y with weights a,b + * + * @param int $x X point + * @param int $y Y point + * @param int $a The weight of the current color + * @param int $b The weight of the applied/wanted color + * @param mixed $color The pixel color + * @access private + */ + function _antialisedSubPixel($x, $y, $a, $b, $color) + { + $x = $this->_getX($x); + $y = $this->_getX($y); + if (($x >=0 ) && ($y >= 0) && ($x < $this->getWidth()) && ($y < $this->getHeight())) { + $tempColor = ImageColorsForIndex($this->_canvas, ImageColorAt($this->_canvas, $x, $y)); + + $newColor[0] = min(255, round($tempColor['red'] * $a + $color['red'] * $b)); + $newColor[1] = min(255, round($tempColor['green'] * $a + $color['green'] * $b)); + $newColor[2] = min(255, round($tempColor['blue'] * $a + $color['blue'] * $b)); + //$newColor[3] = 0; + $color = '#'; + foreach ($newColor as $acolor) { + $color .= sprintf('%02s', dechex($acolor)); + } + $newColor = $this->_color($color);//,'rgb(' . $newColor[0] . ',' . $newColor[1] . ',' . $newColor[2] .')'; + + ImageSetPixel($this->_canvas, $x, $y, $newColor); + } + } + + + /** + * Draw a line end + * + * Parameter array: + * + * 'x': int X point + * + * 'y': int Y point + * + * 'end': string The end type of the end + * + * 'size': int The size of the end + * + * 'color': string The color of the end + * + * 'angle': int [optional] The angle with which to draw the end + * + * @param array $params Parameter array + */ + function drawEnd($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $size = $params['size']; + //var_dump($params); + $angle = deg2rad((isset($params['angle']) ? $params['angle'] : 0)); + $pi2 = pi() / 2; + switch ($params['end']) { + case 'lollipop': + case 'circle': + $this->ellipse( + array( + 'x' => $x, + 'y' => $y, + 'rx' => $size / 2, + 'ry' => $size / 2, + 'fill' => $params['color'], + 'line' => $params['color'] + ) + ); + break; + case 'diamond': + $x0 = round($params['x'] + cos($angle) * $size * 0.65); + $y0 = round($params['y'] - sin($angle) * $size * 0.65); + $shape = array( + $x0 + round(cos($angle) * $size * 0.65), + $y0 - round(sin($angle) * $size * 0.65), + $x0 + round(cos($angle + $pi2) * $size * 0.65), + $y0 - round(sin($angle + $pi2) * $size * 0.65), + $x0 + round(cos($angle + pi()) * $size * 0.65), + $y0 - round(sin($angle + pi()) * $size * 0.65), + $x0 + round(cos($angle + 3 * $pi2) * $size * 0.65), + $y0 - round(sin($angle + 3 * $pi2) * $size * 0.65) + ); + break; + case 'line': + $this->line( + array( + 'x0' => $x + round(cos($angle + $pi2) * $size / 2), + 'y0' => $y - round(sin($angle + $pi2) * $size / 2), + 'x1' => $x + round(cos($angle + 3 * $pi2) * $size / 2), + 'y1' => $y - round(sin($angle + 3 * $pi2) * $size / 2), + 'color' => $params['color'] + ) + ); + break; + case 'box': + case 'rectangle': + $x0 = round($params['x'] + cos($angle) * $size / 2); + $y0 = round($params['y'] - sin($angle) * $size / 2); + $pi4 = pi() / 4; + $shape = array( + $x0 + round(cos($angle + $pi4) * $size / 2), + $y0 - round(sin($angle + $pi4) * $size / 2), + $x0 + round(cos($angle + $pi2 + $pi4) * $size / 2), + $y0 - round(sin($angle + $pi2 + $pi4) * $size / 2), + $x0 + round(cos($angle + pi() + $pi4) * $size / 2), + $y0 - round(sin($angle + pi() + $pi4) * $size / 2), + $x0 + round(cos($angle + 3 * $pi2 + $pi4) * $size / 2), + $y0 - round(sin($angle + 3 * $pi2 + $pi4) * $size / 2) + ); + break; + case 'arrow': + $shape = array( + $x + cos($angle) * $size, + $y - sin($angle) * $size, + $x + cos($angle + $pi2) * $size * 0.4, + $y - sin($angle + $pi2) * $size * 0.4, + $x + cos($angle + 3 * $pi2) * $size * 0.4, + $y - sin($angle + 3 * $pi2) * $size * 0.4, + ); + break; + case 'arrow2': + $shape = array( + $x + round(cos($angle) * $size), + $y - round(sin($angle) * $size), + $x + round(cos($angle + $pi2 + deg2rad(45)) * $size), + $y - round(sin($angle + $pi2 + deg2rad(45)) * $size), + $x, + $y, + $x + round(cos($angle + 3 * $pi2 - deg2rad(45)) * $size), + $y - round(sin($angle + 3 * $pi2 - deg2rad(45)) * $size), + ); + break; + } + + if (isset($shape)) { + // output the shape + if (($fill = $this->_getFillStyle($params['color'])) !== false) { + ImageFilledPolygon($this->_canvas, $shape, count($shape)/2, $fill); + } + } + parent::drawEnd($params); + } + + /** + * Draw a line + * + * Parameter array: + * + * 'x0': int X start point + * + * 'y0': int Y start point + * + * 'x1': int X end point + * + * 'y1': int Y end point + * + * 'color': mixed [optional] The line color + * + * @param array $params Parameter array + */ + function line($params) + { + $x0 = $this->_getX($params['x0']); + $y0 = $this->_getY($params['y0']); + $x1 = $this->_getX($params['x1']); + $y1 = $this->_getY($params['y1']); + $color = (isset($params['color']) ? $params['color'] : false); + + $x0 = $this->_getX($x0); + $y0 = $this->_getY($y0); + $x1 = $this->_getX($x1); + $y1 = $this->_getY($y1); + if (($this->_antialias === 'driver') && ($x0 != $x1) && ($y0 != $y1)) { + $this->_antialiasedLine($x0, $y0, $x1, $y1, $color); + } elseif (($line = $this->_getLineStyle($color)) !== false) { + ImageLine($this->_canvas, $x0, $y0, $x1, $y1, $line); + } + parent::line($params); + } + + /** + * Parameter array: + * + * 'connect': bool [optional] Specifies whether the start point should be + * connected to the endpoint (closed polygon) or not (connected line) + * + * 'fill': mixed [optional] The fill color + * + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function polygon($params) + { + include_once 'Image/Canvas/Tool.php'; + + $connectEnds = (isset($params['connect']) ? $params['connect'] : false); + $fillColor = (isset($params['fill']) ? $params['fill'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + if (!$connectEnds) { + $fillColor = 'transparent'; + } + $style = $this->_getLineStyle($lineColor) . $this->_getFillStyle($fillColor); + + $lastPoint = false; + foreach ($this->_polygon as $point) { + if (($lastPoint) && (isset($lastPoint['P1X'])) && + (isset($lastPoint['P1Y'])) && (isset($lastPoint['P2X'])) && + (isset($lastPoint['P2Y']))) + { + $dx = abs($point['X'] - $lastPoint['X']); + $dy = abs($point['Y'] - $lastPoint['Y']); + $d = sqrt($dx * $dx + $dy * $dy); + if ($d > 0) { + $interval = 1 / $d; + for ($t = 0; $t <= 1; $t = $t + $interval) { + $x = Image_Canvas_Tool::bezier( + $t, + $lastPoint['X'], + $lastPoint['P1X'], + $lastPoint['P2X'], + $point['X'] + ); + + $y = Image_Canvas_Tool::bezier( + $t, + $lastPoint['Y'], + $lastPoint['P1Y'], + $lastPoint['P2Y'], + $point['Y'] + ); + + if (!isset($low['X'])) { + $low['X'] = $x; + } else { + $low['X'] = min($x, $low['X']); + } + if (!isset($high['X'])) { + $high['X'] = $x; + } else { + $high['X'] = max($x, $high['X']); + } + if (!isset($low['Y'])) { + $low['Y'] = $y; + } else { + $low['Y'] = min($y, $low['Y']); + } + if (!isset($high['Y'])) { + $high['Y'] = $y; + } else { + $high['Y'] = max($y, $high['Y']); + } + $polygon[] = $x; + $polygon[] = $y; + } + if (($t - $interval) < 1) { + $x = Image_Canvas_Tool::bezier( + 1, + $lastPoint['X'], + $lastPoint['P1X'], + $lastPoint['P2X'], + $point['X'] + ); + + $y = Image_Canvas_Tool::bezier( + 1, + $lastPoint['Y'], + $lastPoint['P1Y'], + $lastPoint['P2Y'], + $point['Y'] + ); + + $polygon[] = $x; + $polygon[] = $y; + } + } + } else { + if (!isset($low['X'])) { + $low['X'] = $point['X']; + } else { + $low['X'] = min($point['X'], $low['X']); + } + if (!isset($high['X'])) { + $high['X'] = $point['X']; + } else { + $high['X'] = max($point['X'], $high['X']); + } + if (!isset($low['Y'])) { + $low['Y'] = $point['Y']; + } else { + $low['Y'] = min($point['Y'], $low['Y']); + } + if (!isset($high['Y'])) { + $high['Y'] = $point['Y']; + } else { + $high['Y'] = max($point['Y'], $high['Y']); + } + + $polygon[] = $point['X']; + $polygon[] = $point['Y']; + } + $lastPoint = $point; + } + + if ((isset($polygon)) && (is_array($polygon))) { + if ($connectEnds) { + if (($fill = $this->_getFillStyle($fillColor, $low['X'], $low['Y'], $high['X'], $high['Y'])) !== false) { + ImageFilledPolygon($this->_canvas, $polygon, count($polygon)/2, $fill); + } + if ($this->_antialias === 'driver') { + $pfirst = $p0 = false; + reset($polygon); + + while (list(, $x) = each($polygon)) { + list(, $y) = each($polygon); + if ($p0 !== false) { + $this->_antialiasedLine($p0['X'], $p0['Y'], $x, $y, $lineColor); + } + if ($pfirst === false) { + $pfirst = array('X' => $x, 'Y' => $y); + } + $p0 = array('X' => $x, 'Y' => $y);; + } + + $this->_antialiasedLine($p0['X'], $p0['Y'], $pfirst['X'], $pfirst['Y'], $lineColor); + } elseif (($line = $this->_getLineStyle($lineColor)) !== false) { + ImagePolygon($this->_canvas, $polygon, count($polygon)/2, $line); + } + } else { + $prev_point = false; + if ($this->_antialias === 'driver') { + reset($polygon); + while (list(, $x) = each($polygon)) { + list(, $y) = each($polygon); + if ($prev_point) { + $this->_antialiasedLine( + $prev_point['X'], + $prev_point['Y'], + $x, + $y, + $lineColor + ); + } + $prev_point = array('X' => $x, 'Y' => $y);; + } + } elseif (($line = $this->_getLineStyle($lineColor)) !== false) { + reset($polygon); + while (list(, $x) = each($polygon)) { + list(, $y) = each($polygon); + if ($prev_point) { + ImageLine( + $this->_canvas, + $prev_point['X'], + $prev_point['Y'], + $x, + $y, + $line + ); + } + $prev_point = array('X' => $x, 'Y' => $y);; + } + } + } + } + + parent::polygon($params); + } + + /** + * Draw a rectangle + * + * Parameter array: + * + * 'x0': int X start point + * + * 'y0': int Y start point + * + * 'x1': int X end point + * + * 'y1': int Y end point + * + * 'fill': mixed [optional] The fill color + * + * 'line': mixed [optional] The line color + * + * @param array $params Parameter array + */ + function rectangle($params) + { + $x0 = $this->_getX($params['x0']); + $y0 = $this->_getY($params['y0']); + $x1 = $this->_getX($params['x1']); + $y1 = $this->_getY($params['y1']); + $fillColor = (isset($params['fill']) ? $params['fill'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + if (($fill = $this->_getFillStyle($fillColor, $x0, $y0, $x1, $y1)) !== false) { + ImageFilledRectangle($this->_canvas, $x0, $y0, $x1, $y1, $fill); + } + + if (($line = $this->_getLineStyle($lineColor)) !== false) { + ImageRectangle($this->_canvas, $x0, $y0, $x1, $y1, $line); + } + + parent::rectangle($params); + } + + /** + * Draw an ellipse + * + * Parameter array: + * + * 'x': int X center point + * + * 'y': int Y center point + * + * 'rx': int X radius + * + * 'ry': int Y radius + * + * 'fill': mixed [optional] The fill color + * + * 'line': mixed [optional] The line color + * + * @param array $params Parameter array + */ + function ellipse($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $rx = $this->_getX($params['rx']); + $ry = $this->_getY($params['ry']); + $fillColor = (isset($params['fill']) ? $params['fill'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + if (($fill = $this->_getFillStyle($fillColor, $x - $rx, $y - $ry, $x + $rx, $y + $ry)) !== false) { + ImageFilledEllipse($this->_canvas, $x, $y, $rx * 2, $ry * 2, $fill); + } + + if (($line = $this->_getLineStyle($lineColor)) !== false) { + ImageEllipse($this->_canvas, $x, $y, $rx * 2, $ry * 2, $line); + } + parent::ellipse($params); + } + + /** + * Draw a pie slice + * + * Parameter array: + * + * 'x': int X center point + * + * 'y': int Y center point + * + * 'rx': int X radius + * + * 'ry': int Y radius + * + * 'v1': int The starting angle (in degrees) + * + * 'v2': int The end angle (in degrees) + * + * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut) + * + * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut) + * + * 'fill': mixed [optional] The fill color + * + * 'line': mixed [optional] The line color + * + * @param array $params Parameter array + */ + function pieslice($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $rx = $params['rx']; + $ry = $params['ry']; + $v1 = $params['v1']; + $v2 = $params['v2']; + $srx = (isset($params['srx']) ? $params['srx'] : 0); + $sry = (isset($params['sry']) ? $params['sry'] : 0); + $fillColor = (isset($params['fill']) ? $params['fill'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + $dA = 0.1; + + if (($srx !== false) && ($sry !== false)) { + $angle = max($v1, $v2); + while ($angle >= min($v1, $v2)) { + $polygon[] = ($x + $srx * cos(deg2rad($angle % 360))); + $polygon[] = ($y + $sry * sin(deg2rad($angle % 360))); + $angle -= $dA; + } + if (($angle + $dA) > min($v1, $v2)) { + $polygon[] = ($x + $srx * cos(deg2rad(min($v1, $v2) % 360))); + $polygon[] = ($y + $sry * sin(deg2rad(min($v1, $v2) % 360))); + } + } else { + $polygon[] = $x; + $polygon[] = $y; + } + + $angle = min($v1, $v2); + while ($angle <= max($v1, $v2)) { + $polygon[] = ($x + $rx * cos(deg2rad($angle % 360))); + $polygon[] = ($y + $ry * sin(deg2rad($angle % 360))); + $angle += $dA; + } + + if (($angle - $dA) < max($v1, $v2)) { + $polygon[] = ($x + $rx * cos(deg2rad(max($v1, $v2) % 360))); + $polygon[] = ($y + $ry * sin(deg2rad(max($v1, $v2) % 360))); + } + + if (($fill = $this->_getFillStyle($fillColor, $x - $rx - 1, $y - $ry - 1, $x + $rx + 1, $y + $ry + 1)) !== false) { + ImageFilledPolygon($this->_canvas, $polygon, count($polygon) / 2, $fill); + } + + if (($line = $this->_getLineStyle($lineColor)) !== false) { + ImagePolygon($this->_canvas, $polygon, count($polygon) / 2, $line); + } + + parent::pieSlice($params); + } + + /** + * Get the width of a text, + * + * @param string $text The text to get the width of + * @return int The width of the text + */ + function textWidth($text) + { + if (isset($this->_font['file'])) { + $angle = 0; + if (isset($this->_font['angle'])) { + $angle = $this->_font['angle']; + } + + $width = 0; + $lines = explode("\n", $text); + foreach ($lines as $line) { + $bounds = ImageTTFBBox( + $this->_font['size'], + $angle, + $this->_font['file'], + $text + ); + + $x0 = min($bounds[0], $bounds[2], $bounds[4], $bounds[6]); + $x1 = max($bounds[0], $bounds[2], $bounds[4], $bounds[6]); + $width = max(abs($x0 - $x1), $width); + } + return $width; + } else { + if ((isset($this->_font['vertical'])) && ($this->_font['vertical'])) { + return ImageFontHeight($this->_font['font']) * (substr_count($text, "\n") + 1); + } else { + $width = 0; + $lines = explode("\n", $text); + foreach ($lines as $line) { + $width = max($width, ImageFontWidth($this->_font['font']) * strlen($line)); + } + return $width; + } + } + } + + /** + * Get the height of a text. + * + * Note! This method can give some peculiar results, since ImageTTFBBox() returns the total + * bounding box of a text, where ImageTTF() writes the text on the baseline of the text, that + * is 'g', 'p', 'q' and other letters that dig under the baseline will appear to have a larger + * height than they actually do. Have a look at the tests/text.php test case - the first two + * columns, 'left and 'center', both look alright, whereas the last column, 'right', appear + * with a larger space between the first text and the second. This is because the total height + * is actually smaller by exactly the number of pixels that the 'g' digs under the baseline. + * Remove the 'g' from the text and they appear correct. + * + * @param string $text The text to get the height of + * @param bool $force Force the method to calculate the size + * @return int The height of the text + */ + function textHeight($text, $force = false) + { + if (isset($this->_font['file'])) { + $angle = 0; + if (isset($this->_font['angle'])) { + $angle = $this->_font['angle']; + } + + $linebreaks = substr_count($text, "\n"); + if (($angle == 0) && ($linebreaks == 0) && ($force === false)) { + /* + * if the angle is 0 simply return the size, due to different + * heights for example for x-axis labels, making the labels + * _not_ appear as written on the same baseline + */ + return $this->_font['size'] + 2; + } + + $height = 0; + $lines = explode("\n", $text); + foreach ($lines as $line) { + $bounds = ImageTTFBBox( + $this->_font['size'], + $angle, + $this->_font['file'], + $line + ); + + $y0 = min($bounds[1], $bounds[3], $bounds[5], $bounds[7]); + $y1 = max($bounds[1], $bounds[3], $bounds[5], $bounds[7]); + $height += abs($y0 - $y1); + } + return $height + $linebreaks * 2; + } else { + if ((isset($this->_font['vertical'])) && ($this->_font['vertical'])) { + $width = 0; + $lines = explode("\n", $text); + foreach ($lines as $line) { + $width = max($width, ImageFontWidth($this->_font['font']) * strlen($line)); + } + return $width; + } else { + return ImageFontHeight($this->_font['font']) * (substr_count($text, "\n") + 1); + } + } + } + + /** + * Writes text + * + * Parameter array: + * + * 'x': int X-point of text + * + * 'y': int Y-point of text + * + * 'text': string The text to add + * + * 'alignment': array [optional] Alignment + * + * 'color': mixed [optional] The color of the text + */ + function addText($params) + { + $x0 = $this->_getX($params['x']); + $y0 = $this->_getY($params['y']); + $text = $params['text']; + $color = (isset($params['color']) ? $params['color'] : false); + $alignment = (isset($params['alignment']) ? $params['alignment'] : false); + + $text = str_replace("\r", '', $text); + + if (!is_array($alignment)) { + $alignment = array('vertical' => 'top', 'horizontal' => 'left'); + } + + if (!isset($alignment['vertical'])) { + $alignment['vertical'] = 'top'; + } + + if (!isset($alignment['horizontal'])) { + $alignment['horizontal'] = 'left'; + } + + if ($alignment['vertical'] == 'bottom') { + $y0 = $y0 - $this->textHeight($text, true); + } elseif ($alignment['vertical'] == 'center') { + $y0 = $y0 - ($this->textHeight($text, true) / 2); + } + + $lines = explode("\n", $text); + foreach ($lines as $line) { + $textWidth = $this->textWidth($line); + $textHeight = $this->textHeight($line, true); + + $x = $x0; + $y = $y0; + + $y0 += $textHeight + 2; + + if ($alignment['horizontal'] == 'right') { + $x = $x - $textWidth; + } elseif ($alignment['horizontal'] == 'center') { + $x = $x - ($textWidth / 2); + } + + if (($color === false) && (isset($this->_font['color']))) { + $color = $this->_font['color']; + } + + if ($color != 'transparent') { + if (isset($this->_font['file'])) { + if (($this->_font['angle'] < 180) && ($this->_font['angle'] >= 0)) { + $y += $textHeight; + } + if (($this->_font['angle'] >= 90) && ($this->_font['angle'] < 270)) { + $x += $textWidth; + } + + ImageTTFText( + $this->_canvas, + $this->_font['size'], + $this->_font['angle'], + $x, + $y, + $this->_color($color), + $this->_font['file'], + $line + ); + + } else { + if ((isset($this->_font['vertical'])) && ($this->_font['vertical'])) { + ImageStringUp( + $this->_canvas, + $this->_font['font'], + $x, + $y + $this->textHeight($text), + $line, + $this->_color($color) + ); + } else { + ImageString( + $this->_canvas, + $this->_font['font'], + $x, + $y, + $line, + $this->_color($color) + ); + } + } + } + } + parent::addText($params); + } + + /** + * Overlay image + * + * Parameter array: + * + * 'x': int X-point of overlayed image + * + * 'y': int Y-point of overlayed image + * + * 'filename': string The filename of the image to overlay + * + * 'width': int [optional] The width of the overlayed image (resizing if possible) + * + * 'height': int [optional] The height of the overlayed image (resizing if possible) + * + * 'alignment': array [optional] Alignment + */ + function image($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $filename = $params['filename']; + $width = (isset($params['width']) ? $params['width'] : false); + $height = (isset($params['height']) ? $params['height'] : false); + $alignment = (isset($params['alignment']) ? $params['alignment'] : false); + + if (!is_array($alignment)) { + $alignment = array('vertical' => 'top', 'horizontal' => 'left'); + } + + if (!isset($alignment['vertical'])) { + $alignment['vertical'] = 'top'; + } + + if (!isset($alignment['horizontal'])) { + $alignment['horizontal'] = 'left'; + } + + if (file_exists($filename)) { + if (strtolower(substr($filename, -4)) == '.png') { + $image = ImageCreateFromPNG($filename); + } elseif (strtolower(substr($filename, -4)) == '.gif') { + $image = ImageCreateFromGIF($filename); + } else { + $image = ImageCreateFromJPEG($filename); + } + + $imgWidth = ImageSX($image); + $imgHeight = ImageSY($image); + + $outputWidth = ($width !== false ? $width : $imgWidth); + $outputHeight = ($height !== false ? $height : $imgHeight); + + if ($alignment['horizontal'] == 'right') { + $x -= $outputWidth; + } elseif ($alignment['horizontal'] == 'center') { + $x -= $outputWidth / 2; + } + + if ($alignment['vertical'] == 'bottom') { + $y -= $outputHeight; + } elseif ($alignment['vertical'] == 'center') { + $y -= $outputHeight / 2; + } + + if ((($width !== false) && ($width != $imgWidth)) || + (($height !== false) && ($height != $imgHeight))) + { + if ($this->_gd2) { + ImageCopyResampled( + $this->_canvas, + $image, + $x, + $y, + 0, + 0, + $width, + $height, + $imgWidth, + $imgHeight + ); + } else { + ImageCopyResized( + $this->_canvas, + $image, + $x, + $y, + 0, + 0, + $width, + $height, + $imgWidth, + $imgHeight + ); + } + } else { + ImageCopy( + $this->_canvas, + $image, + $x, + $y, + 0, + 0, + $imgWidth, + $imgHeight + ); + } + ImageDestroy($image); + } + parent::image($params); + } + + /** + * Set clipping to occur + * + * Parameter array: + * + * 'x0': int X point of Upper-left corner + * 'y0': int X point of Upper-left corner + * 'x1': int X point of lower-right corner + * 'y1': int Y point of lower-right corner + */ + function setClipping($params = false) + { + if ($params === false) { + $index = count($this->_clipping) - 1; + if (isset($this->_clipping[$index])) { + $params = $this->_clipping[$index]; + $canvas = $params['canvas']; + ImageCopy( + $canvas, + $this->_canvas, + min($params['x0'], $params['x1']), + min($params['y0'], $params['y1']), + min($params['x0'], $params['x1']), + min($params['y0'], $params['y1']), + abs($params['x1'] - $params['x0'] + 1), + abs($params['y1'] - $params['y0'] + 1) + ); + $this->_canvas = $canvas; + unset($this->_clipping[$index]); + } + } + else { + $params['canvas'] = $this->_canvas; + + if ($this->_gd2) { + $this->_canvas = ImageCreateTrueColor( + $this->_width, + $this->_height + ); + if ($this->_alpha) { + ImageAlphaBlending($this->_canvas, true); + } + } else { + $this->_canvas = ImageCreate($this->_width, $this->_height); + } + + if (($this->_gd2) && ($this->_antialias === 'native')) { + ImageAntialias($this->_canvas, true); + } + + ImageCopy($this->_canvas, $params['canvas'], 0, 0, 0, 0, $this->_width, $this->_height); + + $this->_clipping[count($this->_clipping)] = $params; + } + } + + /** + * Get a canvas specific HTML tag. + * + * This method implicitly saves the canvas to the filename in the + * filesystem path specified and parses it as URL specified by URL path + * + * Parameter array: + * + * 'filename' string + * + * 'filepath': string Path to the file on the file system. Remember the final slash + * + * 'urlpath': string Path to the file available through an URL. Remember the final slash + * + * 'alt': string [optional] Alternative text on image + * + * 'cssclass': string [optional] The CSS Stylesheet class + * + * 'border': int [optional] The border width on the image + */ + function toHtml($params) + { + parent::toHtml($params); + return '' . $params['alt'] . '_imageMap) ? ' usemap="#' . $params['filename'] . '"' : '') . '>' . + (isset($this->_imageMap) ? "\n" . $this->_imageMap->toHtml(array('name' => $params['filename'])) : ''); + } + + /** + * Resets the canvas. + * + * Include fillstyle, linestyle, thickness and polygon + * @access private + */ + function _reset() + { + if ($this->_gd2) { + ImageSetThickness($this->_canvas, 1); + } + if ($this->_tileImage != null) { + ImageDestroy($this->_tileImage); + $this->_tileImage = null; + } + parent::_reset(); + $this->_font = array('font' => 1, 'color' => 'black'); + } + + /** + * Check which version of GD is installed + * + * @return int 0 if GD isn't installed, 1 if GD 1.x is installed and 2 if GD + * 2.x is installed + * @access private + */ + function _version() + { + $result = false; + if (function_exists('gd_info')) { + $info = gd_info(); + $version = $info['GD Version']; + } else { + ob_start(); + phpinfo(8); + $php_info = ob_get_contents(); + ob_end_clean(); + + if (ereg("]*>GD Version *<\/td>]*>([^<]*)<\/td>", + $php_info, $result)) + { + $version = $result[1]; + } + } + + if (ereg('1\.[0-9]{1,2}', $version)) { + return 1; + } elseif (ereg('2\.[0-9]{1,2}', $version)) { + return 2; + } else { + return 0; + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/GD/JPG.php b/config/archive/dspam/pear/Image/Canvas/GD/JPG.php new file mode 100644 index 00000000..ef78aeca --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/GD/JPG.php @@ -0,0 +1,119 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Include file Image/Canvas/GD.php + */ +require_once 'Image/Canvas/GD.php'; + +/** + * JPEG Canvas class. + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ +class Image_Canvas_GD_JPG extends Image_Canvas_GD +{ + + /** + * The JPEG quality + * @var int + * @access private + */ + var $_quality = 75; + + /** + * Create the JPEG canvas + * + * Additional parameters other than those available for common {@link + * Image_Graph_Canvas_GD} class are: + * + * 'quality' The JPEG quality in as a percentage value from 0 (lowest + * quality, smallest file) to 100 (highest quality, biggest file) + * + * @param array $param Parameter array + */ + function Image_Canvas_GD_JPG($param) + { + parent::Image_Canvas_GD($param); + + if (isset($param['quality'])) { + $this->_quality = max(0, min(100, $param['quality'])); + } + + $this->rectangle( + array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_left + $this->_width - 1, + 'y1' => $this->_top + $this->_height - 1, + 'fill' => 'white', + 'line' => 'transparent' + ) + ); + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + * @abstract + */ + function show($param = false) + { + parent::show($param); + header('Content-type: image/jpg'); + header('Content-Disposition: inline; filename = \"'. basename($_SERVER['PHP_SELF'], '.php') . '.jpg\"'); + ImageJPEG($this->_canvas, '', $this->_quality); + ImageDestroy($this->_canvas); + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + * @abstract + */ + function save($param = false) + { + parent::save($param); + ImageJPEG($this->_canvas, $param['filename'], $this->_quality); + ImageDestroy($this->_canvas); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/GD/PNG.php b/config/archive/dspam/pear/Image/Canvas/GD/PNG.php new file mode 100644 index 00000000..75184d8c --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/GD/PNG.php @@ -0,0 +1,125 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Include file Image/Canvas/GD.php + */ +require_once 'Image/Canvas/GD.php'; + +/** + * PNG Canvas class. + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ +class Image_Canvas_GD_PNG extends Image_Canvas_GD +{ + + /** + * Create the PNG canvas + * + * @param array $param Parameter array + */ + function Image_Canvas_GD_PNG($param) + { + parent::Image_Canvas_GD($param); + + if ((isset($param['transparent'])) && ($param['transparent']) && + ($this->_gd2) + ) { + if ($param['transparent'] === true) { + $transparent = '#123ABD'; + } else { + $transparent = $param['transparent']; + } + $color = $this->_color($transparent); + $trans = ImageColorTransparent($this->_canvas, $color); + + $this->rectangle( + array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_left + $this->_width - 1, + 'y1' => $this->_top + $this->_height - 1, + 'fill' => 'opague', + 'line' => 'transparent' + ) + ); + } else { + $this->rectangle( + array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_left + $this->_width - 1, + 'y1' => $this->_top + $this->_height - 1, + 'fill' => 'white', + 'line' => 'transparent' + ) + ); + } + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + * @abstract + */ + function show($param = false) + { + parent::show($param); + header('Content-type: image/png'); + header('Content-Disposition: inline; filename = \"'. basename($_SERVER['PHP_SELF'], '.php') . '.png\"'); + ImagePNG($this->_canvas); + ImageDestroy($this->_canvas); + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + * @abstract + */ + function save($param = false) + { + parent::save($param); + ImagePNG($this->_canvas, $param['filename']); + ImageDestroy($this->_canvas); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/ImageMap.php b/config/archive/dspam/pear/Image/Canvas/ImageMap.php new file mode 100644 index 00000000..e69f3de2 --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/ImageMap.php @@ -0,0 +1,354 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Class for handling output as a HTML imagemap + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + * @since version 0.2.0 + */ +class Image_Canvas_ImageMap extends Image_Canvas +{ + + /** + * The image map (if any) + * @var array + * @access private + */ + var $_map = array(); + + /** + * Add a map tag + * @param string $shape The shape, either rect, circle or polygon + * @param string $coords The list of coordinates for the shape + * @param array $params Parameter array + */ + function _addMapTag($shape, $coords, $params) + { + if (isset($params['url'])) { + $url = $params['url']; + $target = (isset($params['target']) ? $params['target'] : false); + $alt = (isset($params['alt']) ? $params['alt'] : false); + + $tags = ''; + if (isset($params['htmltags'])) { + foreach ($params['htmltags'] as $key => $value) { + $tags .= ' '; + if (strpos($value, '"') !== false) { + $tags .= $key . '=\'' . $value . '\''; + } else { + $tags .= $key . '="' . $value . '"'; + } + } + } + + $this->_map[] = + '' . $alt . ''; + } + } + + /** + * Draw a line + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'color': mixed [optional] The line color + * 'mapsize': int [optional] The size of the image map (surrounding the line) + * @param array $params Parameter array + */ + function line($params) + { + if (isset($params['url'])) { + $mapsize = (isset($params['mapsize']) ? $params['mapsize'] : 2); + $this->_addMapTag( + 'polygon', + $this->_getX($params['x0'] - $mapsize) . ',' . + $this->_getY($params['y0'] - $mapsize) . ',' . + $this->_getX($params['x1'] + $mapsize) . ',' . + $this->_getY($params['y1'] - $mapsize) . ',' . + + $this->_getX($params['x1'] + $mapsize) . ',' . + $this->_getY($params['y1'] + $mapsize) . ',' . + $this->_getX($params['x0'] - $mapsize) . ',' . + $this->_getY($params['y0'] + $mapsize), + $params + ); + } + parent::line($params); + } + + /** + * Draws a polygon + * + * Parameter array: + * 'connect': bool [optional] Specifies whether the start point should be + * connected to the endpoint (closed polygon) or not (connected line) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * 'map_vertices': bool [optional] Specifies whether the image map should map the vertices instead of the polygon as a whole + * 'url': string [optional] URL to link the polygon as a whole to (also used for default in case 'map_vertices' is used) + * 'alt': string [optional] Alternative text to show in the image map (also used for default in case 'map_vertices' is used) + * 'target': string [optional] The link target on the image map (also used for default in case 'map_vertices' is used) + * @param array $params Parameter array + */ + function polygon($params) + { + if ((isset($params['map_vertices'])) && ($params['map_vertices'] === true)) { + $mapsize = (isset($params['mapsize']) ? $params['mapsize'] : 2); + foreach ($this->_polygon as $point) { + $vertex_param = $params; + if (isset($point['url'])) { + $vertex_param['url'] = $point['url']; + } + if (isset($point['target'])) { + $vertex_param['target'] = $point['target']; + } + if (isset($point['alt'])) { + $vertex_param['alt'] = $point['alt']; + } + $vertex_mapsize = $mapsize; + if (isset($point['mapsize'])) { + $vertex_mapsize = $point['mapsize']; + } + if (isset($point['htmltags'])) { + $vertex_param['htmltags'] = $point['htmltags']; + } + $this->_addMapTag( + 'circle', + $this->_getX($point['X']) . ',' . + $this->_getY($point['Y']) . ',' . + $mapsize, + $vertex_param + ); + } + } + else if (isset($params['url'])) { + $points = ''; + foreach ($this->_polygon as $point) { + if ($points != '') { + $points .= ','; + } + $points .= $this->_getX($point['X']) . ',' . $this->_getY($point['Y']); + } + $this->_addMapTag('polygon', $points, $params); + } + parent::polygon($params); + } + + /** + * Draw a rectangle + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function rectangle($params) + { + if (isset($params['url'])) { + $this->_addMapTag( + 'rect', + $this->_getX($params['x0']) . ',' . + $this->_getY($params['y0']) . ',' . + $this->_getX($params['x1']) . ',' . + $this->_getY($params['y1']), + $params + ); + } + parent::rectangle($params); + } + + /** + * Draw an ellipse + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function ellipse($params) + { + if (isset($params['url'])) { + if ($params['rx'] == $params['ry']) { + $this->_addMapTag( + 'circle', + $this->_getX($params['x']) . ',' . + $this->_getY($params['y']) . ',' . + $this->_getX($params['rx']), + $params + ); + } else { + $points = ''; + for ($v = 0; $v <= 360; $v += 30) { + if ($points != '') { + $points .= ','; + } + $points .= + round($this->_getX($params['x']) + $this->_getX($params['rx']) * cos(deg2rad($v % 360))) . ',' . + round($this->_getY($params['y']) + $this->_getX($params['ry']) * sin(deg2rad($v % 360))); + } + $this->_addMapTag( + 'polygon', + $points, + $params + ); + } + } + parent::ellipse($params); + } + + /** + * Draw a pie slice + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'v1': int The starting angle (in degrees) + * 'v2': int The end angle (in degrees) + * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut) + * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function pieslice($params) + { + if (isset($params['url'])) { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $rx = $params['rx']; + $ry = $params['ry']; + $v1a = $params['v1']; + $v2a = $params['v2']; + $v1 = min($v1a, $v2a); + $v2 = max($v1a, $v2a); + $srx = (isset($params['srx']) ? $params['srx'] : 0); + $sry = (isset($params['sry']) ? $params['sry'] : 0); + + $points = + round(($x + $srx * cos(deg2rad($v1 % 360)))) . ',' . + round(($y + $sry * sin(deg2rad($v1 % 360)))) . ','; + + for ($v = $v1; $v < $v2; $v += 30) { + $points .= + round(($x + $rx * cos(deg2rad($v % 360)))) . ',' . + round(($y + $ry * sin(deg2rad($v % 360)))) . ','; + } + + $points .= + round(($x + $rx * cos(deg2rad($v2 % 360)))) . ',' . + round(($y + $ry * sin(deg2rad($v2 % 360)))); + + if (($srx != 0) || ($sry != 0)) { + $points .= ','; + for ($v = $v2; $v > $v1; $v -= 30) { + $points .= + round(($x + $srx * cos(deg2rad($v % 360)))) . ',' . + round(($y + $sry * sin(deg2rad($v % 360)))) . ','; + } + + } + + $this->_addMapTag('polygon', $points, $params); + } + parent::pieslice($params); + } + + /** + * Output the result of the canvas to the browser + * + * @param array $params Parameter array, the contents and meaning depends on the actual Canvas + * @abstract + */ + function show($params = false) + { + parent::show($params); + if (count($this->_map) > 0) { + print $this->toHtml($params); + } + } + + /** + * Save the result of the canvas to a file + * + * Parameter array: + * 'filename': string The file to output to + * @param array $params Parameter array, the contents and meaning depends on the actual Canvas + * @abstract + */ + function save($params = false) + { + parent::save($params); + $file = fopen($param['filename'], 'w+'); + fwrite($file, $this->toHtml($params)); + fclose($file); + } + + /** + * Get a canvas specific HTML tag. + * + * Parameter array: + * 'name': string The name of the image map + */ + function toHtml($params) + { + if (count($this->_map) > 0) { + return '' . "\n\t" . implode($this->_map, "\n\t") . "\n"; + } + return ''; + } +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/PDF.php b/config/archive/dspam/pear/Image/Canvas/PDF.php new file mode 100644 index 00000000..180263cb --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/PDF.php @@ -0,0 +1,1007 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Include file Image/Canvas.php + */ +require_once 'Image/Canvas.php'; + +/** + * Include file Image/Canvas/Color.php + */ +require_once 'Image/Canvas/Color.php'; + +/** + * PDF Canvas class. + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ +class Image_Canvas_PDF extends Image_Canvas +{ + + /** + * The PDF document + * @var resource + * @access private + */ + var $_pdf; + + /** + * The major version of PDFlib + * @var int + * @access private + */ + var $_pdflib; + + /** + * The font + * @var mixed + * @access private + */ + var $_pdfFont = false; + + /** + * The width of the page + * @var int + * @access private + */ + var $_pageWidth; + + /** + * The height of the page + * @var int + * @access private + */ + var $_pageHeight; + + /** + * Create the PDF canvas. + * + * Parameters available: + * + * 'page' Specify the page/paper format for the graph's page, available + * formats are: A0, A1, A2, A3, A4, A5, A6, B5, letter, legal, ledger, + * 11x17, cd_front, inlay, inlay_nosides + * + * 'align' Alignment of the graph on the page, available options are: + * topleft, topcenter, topright, leftcenter, center, rightcenter, + * leftbottom, centerbottom, rightbottom + * + * 'orientation' Specifies the paper orientation, default is 'portrait' and + * 'landscape' is also supported. + * + * 'creator' The creator tag of the PDF/graph + * + * 'author' The author tag of the PDF/graph + * + * 'title' The title tag of the PDF/graph + * + * 'width' The width of the graph on the page + * + * 'height' The height of the graph on the page + * + * 'left' The left offset of the graph on the page + * + * 'top' The top offset of the graph on the page + * + * 'filename' The PDF file to open/add page to, using 'filename' requires + * the commercial version of PDFlib (http://www.pdflib.com/), this has for + * obvious ($ 450) reasons not been tested + * + * 'pdf' An existing PDFlib PDF document to add the page to + * + * 'add_page' (true/false) Used together with 'pdf', to specify whether the + * canvas should add a new graph page (true) or create the graph on the + * current page (false), default is 'true' + * + * The 'page' and 'width' & 'height' can be mutually omitted, if 'page' is + * omitted the page is created using dimensions of width x height, and if + * width and height are omitted the page dimensions are used for the graph. + * + * If 'pdf' is specified, 'filename', 'creator', 'author' and 'title' has no + * effect. + * + * 'left' and 'top' are overridden by 'align' + * + * It is required either to specify 'width' & 'height' or 'page'. + * + * The PDF format/PDFlib has some limitations on the capabilities, which + * means some functionality available using other canvass (fx. alpha + * blending and gradient fills) are not supported with PDF (see Canvas.txt + * in the docs/ folder for further details) + * + * @param array $param Parameter array + */ + function Image_Canvas_PDF($param) + { + if (isset($param['page'])) { + switch (strtoupper($param['page'])) { + case 'A0': + $this->_pageWidth = 2380; + $this->_pageHeight = 3368; + break; + + case 'A1': + $this->_pageWidth = 1684; + $this->_pageHeight = 2380; + break; + + case 'A2': + $this->_pageWidth = 1190; + $this->_pageHeight = 1684; + break; + + case 'A3': + $this->_pageWidth = 842; + $this->_pageHeight = 1190; + break; + + case 'A4': + $this->_pageWidth = 595; + $this->_pageHeight = 842; + break; + + case 'A5': + $this->_pageWidth = 421; + $this->_pageHeight = 595; + break; + + case 'A6': + $this->_pageWidth = 297; + $this->_pageHeight = 421; + break; + + case 'B5': + $this->_pageWidth = 501; + $this->_pageHeight = 709; + break; + + case 'LETTER': + $this->_pageWidth = 612; + $this->_pageHeight = 792; + break; + + case 'LEGAL': + $this->_pageWidth = 612; + $this->_pageHeight = 1008; + break; + + case 'LEDGER': + $this->_pageWidth = 1224; + $this->_pageHeight = 792; + break; + + case '11X17': + $this->_pageWidth = 792; + $this->_pageHeight = 1224; + break; + + case 'CD_FRONT': + $this->_pageWidth = 337; + $this->_pageHeight = 337; + break; + + case 'INLAY': + $this->_pageWidth = 425; + $this->_pageHeight = 332; + break; + + case 'INLAY_NOSIDES': + $this->_pageWidth = 390; + $this->_pageHeight = 332; + break; + } + } + + if ((isset($param['orientation'])) && (strtoupper($param['orientation']) == 'LANDSCAPE')) { + $w = $this->_pageWidth; + $this->_pageWidth = $this->_pageHeight; + $this->_pageHeight = $w; + } + + parent::Image_Canvas($param); + + if (!$this->_pageWidth) { + $this->_pageWidth = $this->_width; + } elseif (!$this->_width) { + $this->_width = $this->_pageWidth; + } + + if (!$this->_pageHeight) { + $this->_pageHeight = $this->_height; + } elseif (!$this->_height) { + $this->_height = $this->_pageHeight; + } + + $this->_width = min($this->_width, $this->_pageWidth); + $this->_height = min($this->_height, $this->_pageHeight); + + if ((isset($param['align'])) && + (($this->_width != $this->_pageWidth) || ($this->_height != $this->_pageHeight)) + ) { + switch (strtoupper($param['align'])) { + case 'TOPLEFT': + $this->_top = 0; + $this->_left = 0; + break; + + case 'TOPCENTER': + $this->_top = 0; + $this->_left = ($this->_pageWidth - $this->_width) / 2; + break; + + case 'TOPRIGHT': + $this->_top = 0; + $this->_left = $this->_pageWidth - $this->_width; + break; + + case 'LEFTCENTER': + $this->_top = ($this->_pageHeight - $this->_height) / 2; + $this->_left = 0; + break; + + case 'CENTER': + $this->_top = ($this->_pageHeight - $this->_height) / 2; + $this->_left = ($this->_pageWidth - $this->_width) / 2; + break; + + case 'RIGHTCENTER': + $this->_top = ($this->_pageHeight - $this->_height) / 2; + $this->_left = $this->_pageWidth - $this->_width; + break; + + case 'LEFTBOTTOM': + $this->_top = $this->_pageHeight - $this->_height; + $this->_left = 0; + break; + + case 'CENTERBOTTOM': + $this->_top = $this->_pageHeight - $this->_height; + $this->_left = ($this->_pageWidth - $this->_width) / 2; + break; + + case 'RIGHTBOTTOM': + $this->_top = $this->_pageHeight - $this->_height; + $this->_left = $this->_pageWidth - $this->_width; + break; + } + } + + $this->_pdflib = $this->_version(); + + $addPage = true; + if ((isset($param['pdf'])) && (is_resource($param['pdf']))) { + $this->_pdf =& $param['pdf']; + if ((isset($param['add_page'])) && ($param['add_page'] === false)) { + $addPage = false; + } + } else { + $this->_pdf = pdf_new(); + + if (isset($param['filename'])) { + pdf_open_file($this->_pdf, $param['filename']); + } else { + pdf_open_file($this->_pdf, ''); + } + + pdf_set_parameter($this->_pdf, 'warning', 'true'); + + pdf_set_info($this->_pdf, 'Creator', (isset($param['creator']) ? $param['creator'] : 'PEAR::Image_Canvas')); + pdf_set_info($this->_pdf, 'Author', (isset($param['author']) ? $param['author'] : 'Jesper Veggerby')); + pdf_set_info($this->_pdf, 'Title', (isset($param['title']) ? $param['title'] : 'Image_Canvas')); + } + + if ($addPage) { + pdf_begin_page($this->_pdf, $this->_pageWidth, $this->_pageHeight); + } + $this->_reset(); + } + + /** + * Get the x-point from the relative to absolute coordinates + * + * @param float $x The relative x-coordinate (in percentage of total width) + * @return float The x-coordinate as applied to the canvas + * @access private + */ + function _getX($x) + { + return $this->_left + $x; + } + + /** + * Get the y-point from the relative to absolute coordinates + * + * @param float $y The relative y-coordinate (in percentage of total width) + * @return float The y-coordinate as applied to the canvas + * @access private + */ + function _getY($y) + { + return $this->_pageHeight - ($this->_top + $y); + } + + /** + * Get the color index for the RGB color + * + * @param int $color The color + * @return int The GD image index of the color + * @access private + */ + function _color($color = false) + { + if (($color === false) || ($color === 'opague') || ($color === 'transparent')) { + return false; + } else { + $color = Image_Canvas_Color::color2RGB($color); + $color[0] = $color[0]/255; + $color[1] = $color[1]/255; + $color[2] = $color[2]/255; + return $color; + } + } + + /** + * Get the PDF linestyle + * + * @param mixed $lineStyle The line style to return, false if the one + * explicitly set + * @return bool True if set (so that a line should be drawn) + * @access private + */ + function _setLineStyle($lineStyle = false) + { + if ($lineStyle === false) { + $lineStyle = $this->_lineStyle; + } + + if (($lineStyle == 'transparent') || ($lineStyle === false)) { + return false; + } + + if (is_array($lineStyle)) { + // TODO Implement linestyles in PDFlib (using pdf_setcolor(.., 'pattern'...); ? + reset($lineStyle); + $lineStyle = current($lineStyle); + } + + $color = $this->_color($lineStyle); + + pdf_setlinewidth($this->_pdf, $this->_thickness); + if ($this->_pdflib < 4) { + pdf_setrgbcolor_stroke($this->_pdf, $color[0]/255, $color[1]/255, $color[2]/255); + } else { + pdf_setcolor($this->_pdf, 'stroke', 'rgb', $color[0], $color[1], $color[2], 0); + } + return true; + } + + /** + * Set the PDF fill style + * + * @param mixed $fillStyle The fillstyle to return, false if the one + * explicitly set + * @return bool True if set (so that a line should be drawn) + * @access private + */ + function _setFillStyle($fillStyle = false) + { + if ($fillStyle === false) { + $fillStyle = $this->_fillStyle; + } + + if (($fillStyle == 'transparent') || ($fillStyle === false)) { + return false; + } + + $color = $this->_color($fillStyle); + + if ($this->_pdflib < 4) { + pdf_setrgbcolor_fill($this->_pdf, $color[0]/255, $color[1]/255, $color[2]/255); + } else { + pdf_setcolor($this->_pdf, 'fill', 'rgb', $color[0], $color[1], $color[2], 0); + } + return true; + } + + /** + * Set the PDF font + * + * @access private + */ + function _setFont() + { + $this->_pdfFont = false; + if (isset($this->_font['name'])) { + pdf_set_parameter($this->_pdf, 'FontOutline', $this->_font['name'] . '=' . $this->_font['file']); + $this->_pdfFont = pdf_findfont($this->_pdf, $this->_font['name'], $this->_font['encoding'], 1); + + if ($this->_pdfFont) { + pdf_setfont($this->_pdf, $this->_pdfFont, $this->_font['size']); + $this->_setFillStyle($this->_font['color']); + } + } else { + $this->_setFillStyle('black'); + } + } + + /** + * Sets an image that should be used for filling. + * + * Image filling is not supported with PDF, filling 'transparent' + * + * @param string $filename The filename of the image to fill with + */ + function setFillImage($filename) + { + $this->_fillStyle = 'transparent'; + } + + /** + * Sets a gradient fill + * + * Gradient filling is not supported with PDF, end color used as solid fill. + * + * @param array $gradient Gradient fill options + */ + function setGradientFill($gradient) + { + $this->_fillStyle = $gradient['end']; + } + + /** + * Sets the font options. + * + * The $font array may have the following entries: + * + * 'ttf' = the .ttf file (either the basename, filename or full path) + * If 'ttf' is specified, then the following can be specified + * + * 'size' = size in pixels + * + * 'angle' = the angle with which to write the text + * + * @param array $font The font options. + */ + function setFont($fontOptions) + { + parent::setFont($fontOptions); + + if (!isset($this->_font['size'])) { + $this->_font['size'] = 12; + } + + if (!isset($this->_font['encoding'])) { + $this->_font['encoding'] = 'winansi'; + } + + if (!isset($this->_font['color'])) { + $this->_font['color'] = 'black'; + } + } + + /** + * Resets the canvas. + * + * Includes fillstyle, linestyle, thickness and polygon + * + * @access private + */ + function _reset() + { + pdf_initgraphics($this->_pdf); + parent::_reset(); + } + + /** + * Draw a line + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'color': mixed [optional] The line color + * @param array $params Parameter array + */ + function line($params) + { + $color = (isset($params['color']) ? $params['color'] : false); + if ($this->_setLineStyle($color)) { + pdf_moveto($this->_pdf, $this->_getX($params['x0']), $this->_getY($params['y0'])); + pdf_lineto($this->_pdf, $this->_getX($params['x1']), $this->_getY($params['x1'])); + pdf_stroke($this->_pdf); + } + parent::line($params); + } + + /** + * Parameter array: + * 'connect': bool [optional] Specifies whether the start point should be + * connected to the endpoint (closed polygon) or not (connected line) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function polygon($params = array()) + { + $connectEnds = (isset($params['connect']) ? $params['connect'] : false); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + $line = $this->_setLineStyle($lineColor); + $fill = false; + if ($connectEnds) { + $fill = $this->_setFillStyle($fillColor); + } + + $first = true; + foreach ($this->_polygon as $point) { + if ($first === true) { + pdf_moveto($this->_pdf, $point['X'], $point['Y']); + $first = $point; + } else { + if (isset($last['P1X'])) { + pdf_curveto($this->_pdf, + $last['P1X'], + $last['P1Y'], + $last['P2X'], + $last['P2Y'], + $point['X'], + $point['Y'] + ); + } else { + pdf_lineto($this->_pdf, + $point['X'], + $point['Y'] + ); + } + } + $last = $point; + } + + if ($connectEnds) { + if (isset($last['P1X'])) { + pdf_curveto($this->_pdf, + $last['P1X'], + $last['P1Y'], + $last['P2X'], + $last['P2Y'], + $first['X'], + $first['Y'] + ); + } else { + pdf_lineto($this->_pdf, + $first['X'], + $first['Y'] + ); + } + } + + if (($line) && ($fill)) { + pdf_fill_stroke($this->_pdf); + } elseif ($line) { + pdf_stroke($this->_pdf); + } elseif ($fill) { + pdf_fill($this->_pdf); + } + parent::polygon($params); + } + + /** + * Draw a rectangle + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function rectangle($params) + { + $x0 = $this->_getX($params['x0']); + $y0 = $this->_getY($params['y0']); + $x1 = $this->_getX($params['x1']); + $y1 = $this->_getY($params['y1']); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + $line = $this->_setLineStyle($lineColor); + $fill = $this->_setFillStyle($fillColor); + if (($line) || ($fill)) { + pdf_rect($this->_pdf, $this->_getX(min($x0, $x1)), $this->_getY(max($y0, $y1)), abs($x1 - $x0), abs($y1 - $y0)); + if (($line) && ($fill)) { + pdf_fill_stroke($this->_pdf); + } elseif ($line) { + pdf_stroke($this->_pdf); + } elseif ($fill) { + pdf_fill($this->_pdf); + } + } + parent::rectangle($params); + } + + /** + * Draw an ellipse + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function ellipse($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $rx = $this->_getX($params['rx']); + $ry = $this->_getY($params['ry']); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + $line = $this->_setLineStyle($lineColor); + $fill = $this->_setFillStyle($fillColor); + if (($line) || ($fill)) { + if ($rx == $ry) { + pdf_circle($this->_pdf, $this->_getX($x), $this->_getY($y), $rx); + } else { + pdf_moveto($this->_pdf, $this->_getX($x - $rx), $this->_getY($y)); + pdf_curveto($this->_pdf, + $this->_getX($x - $rx), $this->_getY($y), + $this->_getX($x - $rx), $this->_getY($y - $ry), + $this->_getX($x), $this->_getY($y - $ry) + ); + pdf_curveto($this->_pdf, + $this->_getX($x), $this->_getY($y - $ry), + $this->_getX($x + $rx), $this->_getY($y - $ry), + $this->_getX($x + $rx), $this->_getY($y) + ); + pdf_curveto($this->_pdf, + $this->_getX($x + $rx), $this->_getY($y), + $this->_getX($x + $rx), $this->_getY($y + $ry), + $this->_getX($x), $this->_getY($y + $ry) + ); + pdf_curveto($this->_pdf, + $this->_getX($x), $this->_getY($y + $ry), + $this->_getX($x - $rx), $this->_getY($y + $ry), + $this->_getX($x - $rx), $this->_getY($y) + ); + } + + if (($line) && ($fill)) { + pdf_fill_stroke($this->_pdf); + } elseif ($line) { + pdf_stroke($this->_pdf); + } elseif ($fill) { + pdf_fill($this->_pdf); + } + } + parent::ellipse($params); + } + + /** + * Draw a pie slice + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'v1': int The starting angle (in degrees) + * 'v2': int The end angle (in degrees) + * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut) + * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function pieslice($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $rx = $this->_getX($params['rx']); + $ry = $this->_getY($params['ry']); + $v1 = $this->_getX($params['v1']); + $v2 = $this->_getY($params['v2']); + $srx = $this->_getX($params['srx']); + $sry = $this->_getY($params['sry']); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + // TODO Implement PDFLIB::pieSlice() + parent::pieslice($params); + } + + /** + * Get the width of a text, + * + * @param string $text The text to get the width of + * @return int The width of the text + */ + function textWidth($text) + { + if ($this->_pdfFont === false) { + return $this->_font['size'] * 0.7 * strlen($text); + } else { + return pdf_stringwidth($this->_pdf, $text, $this->_pdfFont, $this->_font['size']); + } + } + + /** + * Get the height of a text, + * + * @param string $text The text to get the height of + * @return int The height of the text + */ + function textHeight($text) + { + if (isset($this->_font['size'])) { + return $this->_font['size']; + } else { + return 12; + } + } + + /** + * Writes text + * + * Parameter array: + * 'x': int X-point of text + * 'y': int Y-point of text + * 'text': string The text to add + * 'alignment': array [optional] Alignment + * 'color': mixed [optional] The color of the text + */ + function addText($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $text = $params['text']; + $color = (isset($params['color']) ? $params['color'] : false); + $alignment = (isset($params['alignment']) ? $params['alignment'] : false); + + $this->_setFont(); + + $textWidth = $this->textWidth($text); + $textHeight = $this->textHeight($text); + + if (!is_array($alignment)) { + $alignment = array('vertical' => 'top', 'horizontal' => 'left'); + } + + if (!isset($alignment['vertical'])) { + $alignment['vertical'] = 'top'; + } + + if (!isset($alignment['horizontal'])) { + $alignment['horizontal'] = 'left'; + } + + if ($alignment['horizontal'] == 'right') { + $x = $x - $textWidth; + } elseif ($alignment['horizontal'] == 'center') { + $x = $x - ($textWidth / 2); + } + + if ($alignment['vertical'] == 'top') { + $y = $y + $textHeight; + } elseif ($alignment['vertical'] == 'center') { + $y = $y + ($textHeight / 2); + } + + if (($color === false) && (isset($this->_font['color']))) { + $color = $this->_font['color']; + } + + pdf_show_xy($this->_pdf, $text, $this->_getX($x), $this->_getY($y)); + + parent::addText($params); + } + + /** + * Overlay image + * + * Parameter array: + * 'x': int X-point of overlayed image + * 'y': int Y-point of overlayed image + * 'filename': string The filename of the image to overlay + * 'width': int [optional] The width of the overlayed image (resizing if possible) + * 'height': int [optional] The height of the overlayed image (resizing if possible) + * 'alignment': array [optional] Alignment + */ + function image($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $filename = $params['filename']; + $width = (isset($params['width']) ? $params['width'] : false); + $height = (isset($params['height']) ? $params['height'] : false); + $alignment = (isset($params['alignment']) ? $params['alignment'] : false); + + if (substr($filename, -4) == '.png') { + $type = 'png'; + } elseif (substr($filename, -4) == '.jpg') { + $type = 'jpeg'; + } + + $image = pdf_load_image($this->_pdf, $type, realpath($filename), ''); + $width_ = pdf_get_value($this->_pdf, 'imagewidth', $image); + $height_ = pdf_get_value($this->_pdf, 'imageheight', $image); + + $outputWidth = ($width !== false ? $width : $width_); + $outputHeight = ($height !== false ? $height : $height_); + + if (!is_array($alignment)) { + $alignment = array('vertical' => 'top', 'horizontal' => 'left'); + } + + if (!isset($alignment['vertical'])) { + $alignment['vertical'] = 'top'; + } + + if (!isset($alignment['horizontal'])) { + $alignment['horizontal'] = 'left'; + } + + if ($alignment['horizontal'] == 'right') { + $x -= $outputWidth; + } elseif ($alignment['horizontal'] == 'center') { + $x -= $outputWidth / 2; + } + + if ($alignment['vertical'] == 'top') { + $y += $outputHeight; + } elseif ($alignment['vertical'] == 'center') { + $y += $outputHeight / 2; + } + + if (($width === false) && ($height === false)) { + $scale = 1; + } else { + $scale = max(($height/$height_), ($width/$width_)); + } + + pdf_place_image($this->_pdf, $image, $this->_getX($x), $this->_getY($y), $scale); + pdf_close_image($this->_pdf, $image); + + parent::image($params); + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + * @abstract + */ + function show($param = false) + { + parent::show($param); + pdf_end_page($this->_pdf); + pdf_close($this->_pdf); + + $buf = pdf_get_buffer($this->_pdf); + $len = strlen($buf); + + header('Content-type: application/pdf'); + header('Content-Length: ' . $len); + header('Content-Disposition: inline; filename=image_graph.pdf'); + print $buf; + + pdf_delete($this->_pdf); + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + * @abstract + */ + function save($param = false) + { + parent::save($param); + pdf_end_page($this->_pdf); + pdf_close($this->_pdf); + + $buf = pdf_get_buffer($this->_pdf); + $len = strlen($buf); + + $fp = @fopen($param['filename'], 'wb'); + if ($fp) { + fwrite($fp, $buf, strlen($buf)); + fclose($fp); + } + pdf_delete($this->_pdf); + } + + /** + * Get a canvas specific HTML tag. + * + * This method implicitly saves the canvas to the filename in the + * filesystem path specified and parses it as URL specified by URL path + * + * Parameter array: + * 'filename': string + * 'filepath': string Path to the file on the file system. Remember the final slash + * 'urlpath': string Path to the file available through an URL. Remember the final slash + * 'title': string The url title + */ + function toHtml($params) + { + parent::toHtml($params); + return '' . $params['title'] . ''; + } + + /** + * Check which major version of PDFlib is installed + * + * @return int The mahor version number of PDFlib + * @access private + */ + function _version() + { + $result = false; + if (function_exists('pdf_get_majorversion')) { + $version = pdf_get_majorversion(); + } else { + ob_start(); + phpinfo(8); + $php_info = ob_get_contents(); + ob_end_clean(); + + if (ereg("]*>PDFlib GmbH Version *<\/td>]*>([^<]*)<\/td>", + $php_info, $result)) + { + $version = $result[1]; + } + } + + if (ereg('([0-9]{1,2})\.[0-9]{1,2}(\.[0-9]{1,2})?', trim($version), $result)) { + return $result[1]; + } else { + return 0; + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/SVG.php b/config/archive/dspam/pear/Image/Canvas/SVG.php new file mode 100644 index 00000000..3fed62ba --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/SVG.php @@ -0,0 +1,918 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Include file Image/Canvas.php + */ +require_once 'Image/Canvas.php'; + +/** + * Include file Image/Canvas/Color.php + */ +require_once 'Image/Canvas/Color.php'; + +/** + * SVG Canvas class. + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ +class Image_Canvas_SVG extends Image_Canvas +{ + + /** + * The SVG elements + * @var string + * @access private + */ + var $_elements = ''; + + /** + * The SVG defines + * @var string + * @access private + */ + var $_defs = ''; + + /** + * The current indention level + * @var string + * @access private + */ + var $_indent = ' '; + + /** + * A unieuq id counter + * @var int + * @access private + */ + var $_id = 1; + + /** + * The current group ids + * @var array + * @access private + */ + var $_groupIDs = array(); + + /** + * Create the SVG canvas. + * + * Parameters available: + * + * 'width' The width of the graph + * + * 'height' The height of the graph + * + * @param array $param Parameter array + */ + function Image_Canvas_SVG($param) + { + parent::Image_Canvas($param); + $this->_reset(); + } + + /** + * Add a SVG "element" to the output + * + * @param string $element The element + * @access private + */ + function _addElement($element, $params = array()) { + $elementdata = $this->_indent . $element . "\n"; + + if (isset($params['url'])) { + $url = $params['url']; + $target = (isset($params['target']) ? $params['target'] : false); + $alt = (isset($params['alt']) ? $params['alt'] : false); + + $tags = ''; + if (isset($params['htmltags'])) { + foreach ($params['htmltags'] as $key => $value) { + $tags .= ' '; + if (strpos($value, '"') >= 0) { + $tags .= $key . '=\'' . $value . '\''; + } else { + $tags .= $key . '="' . $value . '"'; + } + } + } + + $elementdata = + $this->_indent . '' . "\n" . + ' ' . $elementdata . + $this->_indent . '' . "\n"; + } + + + $this->_elements .= $elementdata; + } + + /** + * Add a SVG "define" to the output + * + * @param string $def The define + * @access private + */ + function _addDefine($def) { + $this->_defs .= ' ' . $def . "\n"; + } + + /** + * Get the color index for the RGB color + * + * @param int $color The color + * @return int A SVG compatible color + * @access private + */ + function _color($color = false) + { + if ($color === false) { + return 'transparent'; + } else { + $color = Image_Canvas_Color::color2RGB($color); + return 'rgb(' . $color[0] . ',' . $color[1] . ',' . $color[2] . ')'; + } + } + + /** + * Get the opacity for the RGB color + * + * @param int $color The color + * @return int A SVG compatible opacity value + * @access private + */ + function _opacity($color = false) + { + if ($color === false) { + return false; + } else { + $color = Image_Canvas_Color::color2RGB($color); + if ($color[3] != 255) { + return sprintf('%0.1f', $color[3]/255); + } else { + return false; + } + } + } + + /** + * Get the SVG applicable linestyle + * + * @param mixed $lineStyle The line style to return, false if the one + * explicitly set + * @return mixed A SVG compatible linestyle + * @access private + */ + function _getLineStyle($lineStyle = false) + { + $result = ''; + if ($lineStyle === false) { + $lineStyle = $this->_lineStyle; + } + + // TODO Linestyles (i.e. fx. dotted) does not work + + if (($lineStyle != 'transparent') && ($lineStyle !== false)) { + $result = 'stroke-width:' . $this->_thickness . ';'; + $result .= 'stroke:' .$this->_color($lineStyle) . ';'; + if ($opacity = $this->_opacity($lineStyle)) { + $result .= 'stroke-opacity:' . $opacity . ';'; + } + } + return $result; + } + + /** + * Get the SVG applicable fillstyle + * + * @param mixed $fillStyle The fillstyle to return, false if the one + * explicitly set + * @return mixed A SVG compatible fillstyle + * @access private + */ + function _getFillStyle($fillStyle = false) + { + $result = ''; + if ($fillStyle === false) { + $fillStyle = $this->_fillStyle; + } + + if (is_array($fillStyle)) { + if ($fillStyle['type'] == 'gradient') { + $id = 'gradient_' . ($this->_id++); + $startColor = $this->_color($fillStyle['start']); + $endColor = $this->_color($fillStyle['end']); + $startOpacity = $this->_opacity($fillStyle['start']); + $endOpacity = $this->_opacity($fillStyle['end']); + + switch ($fillStyle['direction']) { + case 'horizontal': + case 'horizontal_mirror': + $x1 = '0%'; + $y1 = '0%'; + $x2 = '100%'; + $y2 = '0%'; + break; + + case 'vertical': + case 'vertical_mirror': + $x1 = '0%'; + $y1 = '100%'; + $x2 = '0%'; + $y2 = '0%'; + break; + + case 'diagonal_tl_br': + $x1 = '0%'; + $y1 = '0%'; + $x2 = '100%'; + $y2 = '100%'; + break; + + case 'diagonal_bl_tr': + $x1 = '0%'; + $y1 = '100%'; + $x2 = '100%'; + $y2 = '0%'; + break; + + case 'radial': + $cx = '50%'; + $cy = '50%'; + $r = '100%'; + $fx = '50%'; + $fy = '50%'; + break; + + } + + if ($fillStyle['direction'] == 'radial') { + $this->_addDefine( + '' + ); + $this->_addDefine( + ' ' + ); + $this->_addDefine( + ' ' + ); + $this->_addDefine( + '' + ); + } elseif (($fillStyle['direction'] == 'vertical_mirror') || + ($fillStyle['direction'] == 'horizontal_mirror')) + { + $this->_addDefine( + '' + ); + $this->_addDefine( + ' ' + ); + $this->_addDefine( + ' ' + ); + $this->_addDefine( + ' ' + ); + $this->_addDefine( + '' + ); + } else { + $this->_addDefine( + '' + ); + $this->_addDefine( + ' ' + ); + $this->_addDefine( + ' ' + ); + $this->_addDefine( + '' + ); + } + + return 'fill:url(#' . $id . ');'; + } + } elseif (($fillStyle != 'transparent') && ($fillStyle !== false)) { + $result = 'fill:' . $this->_color($fillStyle) . ';'; + if ($opacity = $this->_opacity($fillStyle)) { + $result .= 'fill-opacity:' . $opacity . ';'; + } + return $result; + } else { + return 'fill:none;'; + } + } + + /** + * Sets an image that should be used for filling + * + * @param string $filename The filename of the image to fill with + */ + function setFillImage($filename) + { + } + + /** + * Sets a gradient fill + * + * @param array $gradient Gradient fill options + */ + function setGradientFill($gradient) + { + $this->_fillStyle = $gradient; + $this->_fillStyle['type'] = 'gradient'; + } + + /** + * Sets the font options. + * + * The $font array may have the following entries: + * 'type' = 'ttf' (TrueType) or omitted for default
+ * If 'type' = 'ttf' then the following can be specified
+ * 'size' = size in pixels
+ * 'angle' = the angle with which to write the text + * 'file' = the .ttf file (either the basename, filename or full path) + * + * @param array $font The font options. + */ + function setFont($fontOptions) + { + parent::setFont($fontOptions); + if (!isset($this->_font['size'])) { + $this->_font['size'] = 10; + } + } + + /** + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'color': mixed [optional] The line color + * @param array $params Parameter array + */ + function line($params) + { + $x0 = $this->_getX($params['x0']); + $y0 = $this->_getY($params['y0']); + $x1 = $this->_getX($params['x1']); + $y1 = $this->_getY($params['y1']); + $color = (isset($params['color']) ? $params['color'] : false); + + $style = $this->_getLineStyle($color) . $this->_getFillStyle('transparent'); + if ($style != '') { + $this->_addElement( + '', + $params + ); + } + parent::line($params); + } + + /** + * Parameter array: + * 'connect': bool [optional] Specifies whether the start point should be + * connected to the endpoint (closed polygon) or not (connected line) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function polygon($params = array()) + { + $connectEnds = (isset($params['connect']) ? $params['connect'] : false); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + if (!$connectEnds) { + $fillColor = 'transparent'; + } + $style = $this->_getLineStyle($lineColor) . $this->_getFillStyle($fillColor); + + $first = true; + $spline = false; + $lastpoint = false; + foreach($this->_polygon as $point) { + if ($first) { + $points = 'M'; + } elseif (!$spline) { + $points .= ' L'; + } + + if (($spline) && ($lastpoint !== false)) { + $points .= ' ' .round($lastpoint['P1X']) . ',' . round($lastpoint['P1Y']) . ' ' . + round($lastpoint['P2X']) . ',' . round($lastpoint['P2Y']); + } + + $points .= ' ' . round($point['X']) . ',' . round($point['Y']); + + if ((isset($point['P1X'])) && (isset($point['P1Y'])) && + (isset($point['P2X'])) && (isset($point['P2Y']))) + { + if (($first) || (!$spline)) { + $points .= ' C'; + } + $lastpoint = $point; + $spline = true; + } else { + $spline = false; + } + $first = false; + } + if ($connectEnds) { + $point .= ' Z'; + } + $this->_addElement( + '', + $params + ); + + parent::polygon($params); + } + + /** + * Draw a rectangle + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function rectangle($params) + { + $x0 = min($this->_getX($params['x0']), $this->_getX($params['x1'])); + $y0 = min($this->_getY($params['y0']), $this->_getY($params['y1'])); + $x1 = max($this->_getX($params['x0']), $this->_getX($params['x1'])); + $y1 = max($this->_getY($params['y0']), $this->_getY($params['y1'])); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + $style = $this->_getLineStyle($lineColor) . $this->_getFillStyle($fillColor); + if ($style != '') { + $this->_addElement( + '', + $params + ); + } + parent::rectangle($params); + } + + /** + * Draw an ellipse + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function ellipse($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $rx = $this->_getX($params['rx']); + $ry = $this->_getY($params['ry']); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + $style = $this->_getLineStyle($lineColor) . $this->_getFillStyle($fillColor); + if ($style != '') { + $this->_addElement( + '', + $params + ); + } + parent::ellipse($params); + } + + /** + * Draw a pie slice + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'v1': int The starting angle (in degrees) + * 'v2': int The end angle (in degrees) + * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut) + * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function pieslice($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $rx = $this->_getX($params['rx']); + $ry = $this->_getY($params['ry']); + $v1 = $this->_getX($params['v1']); + $v2 = $this->_getY($params['v2']); + $srx = (isset($params['srx']) ? $this->_getX($params['srx']) : false); + $sry = (isset($params['sry']) ? $this->_getX($params['sry']) : false); + $fillColor = (isset($params['fill']) ? $params['line'] : false); + $lineColor = (isset($params['line']) ? $params['line'] : false); + + $dv = max($v2, $v1) - min($v2, $v1); + if ($dv >= 360) { + $this->ellipse($params); + } + else { + $style = $this->_getLineStyle($lineColor) . $this->_getFillStyle($fillColor); + if ($style != '') { + $x1 = ($x + $rx * cos(deg2rad(min($v1, $v2) % 360))); + $y1 = ($y + $ry * sin(deg2rad(min($v1, $v2) % 360))); + $x2 = ($x + $rx * cos(deg2rad(max($v1, $v2) % 360))); + $y2 = ($y + $ry * sin(deg2rad(max($v1, $v2) % 360))); + $this->_addElement( + '', + $params + ); + } + + parent::pieslice($params); + } + } + + /** + * Get the width of a text, + * + * @param string $text The text to get the width of + * @return int The width of the text + */ + function textWidth($text) + { + if ((isset($this->_font['vertical'])) && ($this->_font['vertical'])) { + return $this->_font['size']; + } else { + return round($this->_font['size'] * 0.7 * strlen($text)); + } + } + + /** + * Get the height of a text, + * + * @param string $text The text to get the height of + * @return int The height of the text + */ + function textHeight($text) + { + if ((isset($this->_font['vertical'])) && ($this->_font['vertical'])) { + return round($this->_font['size'] * 0.7 * strlen($text)); + } else { + return $this->_font['size']; + } + } + + /** + * Writes text + * + * Parameter array: + * 'x': int X-point of text + * 'y': int Y-point of text + * 'text': string The text to add + * 'alignment': array [optional] Alignment + * 'color': mixed [optional] The color of the text + */ + function addText($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $text = $params['text']; + $color = (isset($params['color']) ? $params['color'] : false); + $alignment = (isset($params['alignment']) ? $params['alignment'] : false); + + $textHeight = $this->textHeight($text); + + if (!is_array($alignment)) { + $alignment = array('vertical' => 'top', 'horizontal' => 'left'); + } + + if (!isset($alignment['vertical'])) { + $alignment['vertical'] = 'top'; + } + + if (!isset($alignment['horizontal'])) { + $alignment['horizontal'] = 'left'; + } + + $align = ''; + + if ((isset($this->_font['vertical'])) && ($this->_font['vertical'])) { +// $align .= 'writing-mode: tb-rl;'; + + if ($alignment['vertical'] == 'bottom') { + $align .= 'text-anchor:end;'; + //$y = $y + $textHeight; + } elseif ($alignment['vertical'] == 'center') { + //$y = $y + ($textHeight / 2); + $align .= 'text-anchor:middle;'; + } + } else { + if ($alignment['horizontal'] == 'right') { + $align .= 'text-anchor:end;'; + } elseif ($alignment['horizontal'] == 'center') { + $align .= 'text-anchor:middle;'; + } + + if ($alignment['vertical'] == 'top') { + $y = $y + $textHeight; + } elseif ($alignment['vertical'] == 'center') { + $y = $y + ($textHeight / 2); + } + } + + if (($color === false) && (isset($this->_font['color']))) { + $color = $this->_font['color']; + } + + $textColor = $this->_color($color); + $textOpacity = $this->_opacity($color); + + $this->_addElement( + '' . "\n" . + $this->_indent . ' _font['angle']) && ($this->_font['angle'] > 0) ? + 'transform="rotate(' . $this->_font['angle'] . ')" ' : + '' + ) . + 'style="' . + (isset($this->_font['name']) ? + 'font-family:' . $this->_font['name'] . ';' : '') . + 'font-size:' . $this->_font['size'] . 'px;fill:' . + $textColor . ($textOpacity ? ';fill-opacity:' . + $textOpacity : + '' + ) . ';' . $align . '">' . + htmlspecialchars($text) . + '' . "\n" . + $this->_indent . '', + $params + ); + parent::addText($params); + } + + /** + * Overlay image + * + * Parameter array: + * 'x': int X-point of overlayed image + * 'y': int Y-point of overlayed image + * 'filename': string The filename of the image to overlay + * 'width': int [optional] The width of the overlayed image (resizing if possible) + * 'height': int [optional] The height of the overlayed image (resizing if possible) + * 'alignment': array [optional] Alignment + */ + function image($params) + { + $x = $this->_getX($params['x']); + $y = $this->_getY($params['y']); + $filename = $params['filename']; + + list($width, $height, $type, $attr) = getimagesize($filename); + $width = (isset($params['width']) ? $params['width'] : $width); + $height = (isset($params['height']) ? $params['height'] : $height); + $alignment = (isset($params['alignment']) ? $params['alignment'] : false); + + $file = fopen($filename, 'rb'); + $filedata = fread($file, filesize($filename)); + fclose($file); + + $data = 'data:' . image_type_to_mime_type($type) . ';base64,' . base64_encode($filedata); + $this->_addElement( + '', + $params + ); + parent::image($params); + } + + /** + * Start a group. + * + * What this does, depends on the canvas/format. + * + * @param string $name The name of the group + */ + function startGroup($name = false) + { + $name = strtolower(str_replace(' ', '_', $name)); + if (in_array($name, $this->_groupIDs)) { + $name .= $this->_id; + $this->_id++; + } + $this->_groupIDs[] = $name; + $this->_addElement(''); + $this->_indent .= ' '; + } + + /** + * End the "current" group. + * + * What this does, depends on the canvas/format. + */ + function endGroup() + { + $this->_indent = substr($this->_indent, 0, -4); + $this->_addElement(''); + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + */ + function show($param = false) + { + parent::show($param); + $output = '' . "\n" . + '' . "\n" . + '' . "\n" . + ($this->_defs ? + ' ' . "\n" . + $this->_defs . + ' ' . "\n" : + '' + ) . + $this->_elements . + ''; + + header('Content-Type: image/svg+xml'); + header('Content-Disposition: inline; filename = "' . basename($_SERVER['PHP_SELF'], '.php') . '.svg"'); + print $output; + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + */ + function save($param = false) + { + parent::save($param); + $output = '' . "\n" . + '' . "\n" . + '' . "\n" . + ($this->_defs ? + ' ' . "\n" . + $this->_defs . + ' ' . "\n" : + '' + ) . + $this->_elements . + ''; + + $file = fopen($param['filename'], 'w+'); + fwrite($file, $output); + fclose($file); + } + + /** + * Set clipping to occur + * + * Parameter array: + * + * 'x0': int X point of Upper-left corner + * 'y0': int X point of Upper-left corner + * 'x1': int X point of lower-right corner + * 'y1': int Y point of lower-right corner + */ + function setClipping($params = false) + { + if ($params === false) { + $this->_addElement(''); + } + else { + $group = "clipping_" . $this->_id; + $this->_id++; + $this->_addElement(''); + + $this->_addDefine(''); + $this->_addDefine(' '); + $this->_addDefine(''); + } + } + + /** + * Get a canvas specific HTML tag. + * + * This method implicitly saves the canvas to the filename in the + * filesystem path specified and parses it as URL specified by URL path + * + * Parameter array: + * 'filename': string + * 'filepath': string Path to the file on the file system. Remember the final slash + * 'urlpath': string Path to the file available through an URL. Remember the final slash + * 'width': int The width in pixels + * 'height': int The height in pixels + */ + function toHtml($params) + { + parent::toHtml($params); + return ''; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/Tool.php b/config/archive/dspam/pear/Image/Canvas/Tool.php new file mode 100644 index 00000000..3b87122c --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/Tool.php @@ -0,0 +1,217 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * This class contains a set of tool-functions. + * + * These functions are all to be called statically + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + * @abstract + */ +class Image_Canvas_Tool +{ + + /** + * Maps a font name to an actual font file (fx. a .ttf file) + * + * Used to translate names (i.e. 'Courier New' to 'cour.ttf' or + * '/Windows/Fonts/Cour.ttf') + * + * Font names are translated using the tab-separated file + * Image/Canvas/Tool/fontmap.txt. + * + * The translated font-name (or the original if no translation) exists is + * then returned if it is an existing file, otherwise the file is searched + * first in the path specified by IMAGE_CANVAS_SYSTEM_FONT_PATH defined in + * Image/Canvas.php, then in the Image/Canvas/Fonts folder. If a font is + * still not found and the name is not beginning with a '/' the search is + * left to the library, otherwise the font is deemed non-existing. + * + * @param string $name The name of the font + * @param string $type The needed file type of the font + * @return string The filename of the font + * @static + */ + function fontMap($name, $type = '.ttf') + { + static $_fontMap; + + if (!is_array($_fontMap)) { + if (file_exists($fontmap = (dirname(__FILE__) . '/Fonts/fontmap.txt'))) { + $file = file($fontmap); + foreach($file as $fontmapping) { + list($fontname, $filenames) = explode(',', $fontmapping, 2); + $fontname = trim($fontname); + $filenames = trim($filenames); + $filenames = explode(',', $filenames); + foreach ($filenames as $filename) { + $type_pos = strrpos($filename, '.'); + $type = substr($filename, $type_pos); + $_fontMap[$fontname][$type] = $filename; + } + } + } + } + + $type = strtolower($type); + + if ((isset($_fontMap[$name])) && (isset($_fontMap[$name][$type]))) { + $filename = $_fontMap[$name][$type]; + } else { + $filename = $name; + } + + if (substr($filename, -strlen($type)) !== $type) { + $filename .= $type; + } + + $result = false; + if (file_exists($filename)) { + $result = $filename; + } elseif (file_exists($file = (IMAGE_CANVAS_SYSTEM_FONT_PATH . $filename))) { + $result = $file; + } elseif (file_exists($file = (dirname(__FILE__) . '/Fonts/' . $filename))) { + $result = $file; + } elseif (substr($name, 0, 1) !== '/') { + // leave it to the library to find the font + $result = $name; + } + + return str_replace('\\', '/', $result); + } + + /** + * Return the average of 2 points + * + * @param double P1 1st point + * @param double P2 2nd point + * @return double The average of P1 and P2 + * @static + */ + function mid($p1, $p2) + { + return ($p1 + $p2) / 2; + } + + /** + * Mirrors P1 in P2 by a amount of Factor + * + * @param double $p1 1st point, point to mirror + * @param double $o2 2nd point, mirror point + * @param double $factor Mirror factor, 0 returns $p2, 1 returns a pure + * mirror, ie $p1 on the exact other side of $p2 + * @return double $p1 mirrored in $p2 by Factor + * @static + */ + function mirror($p1, $p2, $factor = 1) + { + return $p2 + $factor * ($p2 - $p1); + } + + /** + * Calculates a Bezier control point, this function must be called for BOTH + * X and Y coordinates (will it work for 3D coordinates!?) + * + * @param double $p1 1st point + * @param double $p2 Point to + * @param double $factor Mirror factor, 0 returns P2, 1 returns a pure + * mirror, i.e. P1 on the exact other side of P2 + * @return double P1 mirrored in P2 by Factor + * @static + */ + function controlPoint($p1, $p2, $factor, $smoothFactor = 0.75) + { + $sa = Image_Canvas_Tool::mirror($p1, $p2, $smoothFactor); + $sb = Image_Canvas_Tool::mid($p2, $sa); + + $m = Image_Canvas_Tool::mid($p2, $factor); + + $pC = Image_Canvas_Tool::mid($sb, $m); + + return $pC; + } + + /** + * Calculates a Bezier point, this function must be called for BOTH X and Y + * coordinates (will it work for 3D coordinates!?) + * + * @param double $t A position between $p2 and $p3, value between 0 and 1 + * @param double $p1 Point to use for calculating control points + * @param double $p2 Point 1 to calculate bezier curve between + * @param double $p3 Point 2 to calculate bezier curve between + * @param double $p4 Point to use for calculating control points + * @return double The bezier value of the point t between $p2 and $p3 using + * $p1 and $p4 to calculate control points + * @static + */ + function bezier($t, $p1, $p2, $p3, $p4) + { + // (1-t)^3*p1 + 3*(1-t)^2*t*p2 + 3*(1-t)*t^2*p3 + t^3*p4 + return pow(1 - $t, 3) * $p1 + + 3 * pow(1 - $t, 2) * $t * $p2 + + 3 * (1 - $t) * pow($t, 2) * $p3 + + pow($t, 3) * $p4; + } + + /** + * Gets the angle / slope of a line relative to horizontal (left -> right) + * + * @param double $x0 The starting x point + * @param double $y0 The starting y point + * @param double $x1 The ending x point + * @param double $y1 The ending y point + * @param double The angle in degrees of the line + * @static + */ + function getAngle($x0, $y0, $x1, $y1) + { + + $dx = ($x1 - $x0); + $dy = ($y1 - $y0); + $l = sqrt($dx * $dx + $dy * $dy); + $v = rad2deg(asin(($y0 - $y1) / $l)); + if ($dx < 0) { + $v = 180 - $v; + } + return $v; + + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Canvas/WithMap.php b/config/archive/dspam/pear/Image/Canvas/WithMap.php new file mode 100644 index 00000000..dc43ec4d --- /dev/null +++ b/config/archive/dspam/pear/Image/Canvas/WithMap.php @@ -0,0 +1,278 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + */ + +/** + * Class for handling different output formats including a HTML image map + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=212 + * @since version 0.2.0 + * @abstract + */ +class Image_Canvas_WithMap extends Image_Canvas +{ + + /** + * The image map + * @var Image_Canvas_ImageMap + * @access private + */ + var $_imageMap = null; + + /** + * Create the canvas. + * + * Parameters available: + * + * 'width' The width of the graph on the canvas + * + * 'height' The height of the graph on the canvas + * + * 'left' The left offset of the graph on the canvas + * + * 'top' The top offset of the graph on the canvas + * + * 'usemap' Initialize an image map + * + * @param array $params Parameter array + * @abstract + */ + function Image_Canvas_WithMap($params) + { + parent::Image_Canvas($params); + + if ((isset($params['usemap'])) && ($params['usemap'] === true)) { + $this->_imageMap =& Image_Canvas::factory( + 'ImageMap', + array( + 'left' => $this->_left, + 'top' => $this->_top, + 'width' => $this->_width, + 'height' => $this->_height + ) + ); + } + } + /** + * Draw a line + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'color': mixed [optional] The line color + * @param array $params Parameter array + */ + function line($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->line($params); + } + parent::line($params); + } + + /** + * Adds vertex to a polygon + * + * Parameter array: + * 'x': int X point + * 'y': int Y point + * @param array $params Parameter array + */ + function addVertex($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->addVertex($params); + } + parent::addVertex($params); + } + + /** + * Adds "splined" vertex to a polygon + * + * Parameter array: + * 'x': int X point + * 'y': int Y point + * 'p1x': X Control point 1 + * 'p1y': Y Control point 1 + * 'p2x': X Control point 2 + * 'p2y': Y Control point 2 + * @param array $params Parameter array + */ + function addSpline($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->addSpline($params); + } + parent::addSpline($params); + } + + /** + * Draws a polygon + * + * Parameter array: + * 'connect': bool [optional] Specifies whether the start point should be + * connected to the endpoint (closed polygon) or not (connected line) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function polygon($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->polygon($params); + } + parent::polygon($params); + } + + /** + * Draw a rectangle + * + * Parameter array: + * 'x0': int X start point + * 'y0': int Y start point + * 'x1': int X end point + * 'y1': int Y end point + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function rectangle($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->rectangle($params); + } + parent::rectangle($params); + } + + /** + * Draw an ellipse + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function ellipse($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->ellipse($params); + } + parent::ellipse($params); + } + + /** + * Draw a pie slice + * + * Parameter array: + * 'x': int X center point + * 'y': int Y center point + * 'rx': int X radius + * 'ry': int Y radius + * 'v1': int The starting angle (in degrees) + * 'v2': int The end angle (in degrees) + * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut) + * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut) + * 'fill': mixed [optional] The fill color + * 'line': mixed [optional] The line color + * @param array $params Parameter array + */ + function pieslice($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->pieslice($params); + } + parent::pieslice($params); + } + + /** + * Writes text + * + * Parameter array: + * 'x': int X-point of text + * 'y': int Y-point of text + * 'text': string The text to add + * 'alignment': array [optional] Alignment + * 'color': mixed [optional] The color of the text + */ + function addText($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->addText($params); + } + parent::addText($params); + } + + /** + * Overlay image + * + * Parameter array: + * 'x': int X-point of overlayed image + * 'y': int Y-point of overlayed image + * 'filename': string The filename of the image to overlay + * 'width': int [optional] The width of the overlayed image (resizing if possible) + * 'height': int [optional] The height of the overlayed image (resizing if possible) + * 'alignment': array [optional] Alignment + */ + function image($params) + { + if (isset($this->_imageMap)) { + $this->_imageMap->image($params); + } + parent::image($params); + } + + /** + * Get the imagemap + * @return Image_Graph_ImageMap The image map (or false if none) + */ + function &getImageMap() + { + $result = null; + if (isset($this->_imageMap)) { + $result =& $this->_imageMap; + } + return $result; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Color.php b/config/archive/dspam/pear/Image/Color.php new file mode 100644 index 00000000..1b20125d --- /dev/null +++ b/config/archive/dspam/pear/Image/Color.php @@ -0,0 +1,719 @@ + + * @author Andrew Morton + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Color + */ + +/** + * Image_Color handles color conversion and mixing. + * + * The class is quick, simple to use, and does its job fairly well but it's got + * some code smells: + * - Call setColors() for some functions but not others. + * - Different functions expect different color formats. setColors() only + * accepts hex while allocateColor() will accept named or hex (provided the + * hex ones start with the # character). + * - Some conversions go in only one direction, ie HSV->RGB but no RGB->HSV. + * I'm going to try to straighten out some of this but I'll be hard to do so + * without breaking backwards compatibility. + * + * @category Image + * @package Image_Color + * @author Jason Lotito + * @author Andrew Morton + * @copyright 2003-2005 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version Release: 0.1.2 + * @link http://pear.php.net/package/Image_Color + */ +class Image_Color +{ + /** + * First color that the class handles for ranges and mixes. + * @var array + * @access public + * @see setColors() + */ + var $color1 = array(); + + /** + * Second color that the class handles for ranges and mixes. + * @var array + * @access public + * @see setColors() + */ + var $color2 = array(); + + /** + * Boolean value for determining whether colors outputted should be limited + * to the web safe pallet or not. + * + * @var boolean + * @access private + * @see setWebSafe() + */ + var $_websafeb = false; + + /** + * Mix two colors together by finding their average. If the colors are not + * passed as parameters, the class's colors will be mixed instead. + * + * @param string $col1 The first color you want to mix + * @param string $col2 The second color you want to mix + * @return string The mixed color. + * @access public + * @author Jason Lotito + * @uses _setColors() to assign the colors if any are passed to the + * class. + */ + function mixColors($col1 = false, $col2 = false) + { + if ($col1) { + $this->_setColors($col1, $col2); + } + + // after finding the average, it will be a float. add 0.5 and then + // cast to an integer to properly round it to an integer. + $color3[0] = (int) ((($this->color1[0] + $this->color2[0]) / 2) + 0.5); + $color3[1] = (int) ((($this->color1[1] + $this->color2[1]) / 2) + 0.5); + $color3[2] = (int) ((($this->color1[2] + $this->color2[2]) / 2) + 0.5); + + if ($this->_websafeb) { + array_walk($color3, '_makeWebSafe'); + } + + return Image_Color::rgb2hex($color3); + } + + /** + * Determines whether colors the returned by this class will be rounded to + * the nearest web safe value. + * + * @param boolean $bool Indicates if colors should be limited to the + * websafe pallet. + * @return void + * @access public + * @author Jason Lotito + */ + function setWebSafe($bool = true) + { + $this->_websafeb = (boolean) $bool; + } + + /** + * Set the two colors this class uses for mixing and ranges. + * + * @param string $col1 The first color in hex format + * @param string $col2 The second color in hex format + * @return void + * @access public + * @author Jason Lotito + */ + function setColors($col1, $col2) + { + $this->_setColors($col1, $col2); + } + + /** + * Get the range of colors between the class's two colors, given a degree. + * + * @param integer $degrees How large a 'step' we should take between the + * colors. + * @return array Returns an array of hex strings, one element for each + * color. + * @access public + * @author Jason Lotito + * @todo Allow for degrees for individual parts of the colors. + */ + function getRange($degrees = 2) + { + if ($degrees == 0) { + $degrees = 1; + } + + // The degrees give us how much we should advance each color at each + // phase of the loop. This way, the advance is equal throughout all + // the colors. + + $red_steps = ($this->color2[0] - $this->color1[0]) / $degrees; + $green_steps = ($this->color2[1] - $this->color1[1]) / $degrees; + $blue_steps = ($this->color2[2] - $this->color1[2]) / $degrees; + + $allcolors = array(); + + /** + * The loop stops once any color has gone beyond the end color. + */ + + // Loop through all the degrees between the colors + for ($x = 0; $x < $degrees; $x++) { + $col[0] = $red_steps * $x; + $col[1] = $green_steps * $x; + $col[2] = $blue_steps * $x; + + // Loop through each R, G, and B + for ($i = 0; $i < 3; $i++) { + $partcolor = $this->color1[$i] + $col[$i]; + // If the color is less than 256 + if ($partcolor < 256) { + // Makes sure the colors is not less than 0 + if ($partcolor > -1) { + $newcolor[$i] = $partcolor; + } else { + $newcolor[$i] = 0; + } + // Color was greater than 255 + } else { + $newcolor[$i] = 255; + } + } + + if ($this->_websafeb) { + array_walk($newcolor, '_makeWebSafe'); + } + + $allcolors[] = Image_Color::rgb2hex($newcolor); + } + + return $allcolors; + } + + /** + * Change the lightness of the class's two colors. + * + * @param integer $degree The degree of the change. Positive values + * lighten the color while negative values will darken it. + * @return void + * @access public + * @author Jason Lotito + * @uses Image_Color::$color1 as an input and return value. + * @uses Image_Color::$color2 as an input and return value. + */ + function changeLightness($degree = 10) + { + $color1 =& $this->color1; + $color2 =& $this->color2; + + for ($x = 0; $x < 3; $x++) { + if (($color1[$x] + $degree) < 256) { + if (($color1[$x] + $degree) > -1) { + $color1[$x] += $degree; + } else { + $color1[$x] = 0; + } + } else { + $color1[$x] = 255; + } + + if (($color2[$x] + $degree) < 256) { + if (($color2[$x] + $degree) > -1) { + $color2[$x] += $degree; + } else { + $color2[$x] = 0; + } + } else { + $color2[$x] = 255; + } + } + } + + /** + * Determine if a light or dark text color would be more readable on a + * background of a given color. This is determined by the G(reen) value of + * RGB. You can change the dark and the light colors from their default + * black and white. + * + * @param string $color The hex color to analyze + * @param string $light The light color value to return if we should + * have light text. + * @param string $dark The dark color value to return if we should have + * dark text. + * @return string The light or dark value which would make the text most + * readable. + * @access public + * @static + * @author Jason Lotito + */ + function getTextColor($color, $light = '#FFFFFF', $dark = '#000000') + { + $color = Image_Color::_splitColor($color); + if ($color[1] > hexdec('66')) { + return $dark; + } else { + return $light; + } + } + + + /** + * Internal method to set the colors. + * + * @param string $col1 First color, either a name or hex value + * @param string $col2 Second color, either a name or hex value + * @return void + * @access private + * @author Jason Lotito + */ + function _setColors($col1, $col2) + { + if ($col1) { + $this->color1 = Image_Color::_splitColor($col1); + } + if ($col2) { + $this->color2 = Image_Color::_splitColor($col2); + } + } + + /** + * Given a color, properly split it up into a 3 element RGB array. + * + * @param string $color The color. + * @return array A three element RGB array. + * @access private + * @static + * @author Jason Lotito + */ + function _splitColor($color) + { + $color = str_replace('#', '', $color); + $c[] = hexdec(substr($color, 0, 2)); + $c[] = hexdec(substr($color, 2, 2)); + $c[] = hexdec(substr($color, 4, 2)); + return $c; + } + + /** + * This is deprecated. Use rgb2hex() instead. + * @access private + * @deprecated Function deprecated after 1.0.1 + * @see rgb2hex(). + */ + function _returnColor ( $color ) + { + return Image_Color::rgb2hex($color); + } + + /** + * Convert an RGB array to a hex string. + * + * @param array $color 3 element RGB array. + * @return string Hex color string. + * @access public + * @static + * @author Jason Lotito + * @see hex2rgb() + */ + function rgb2hex($color) + { + return sprintf('%02X%02X%02X',$color[0],$color[1],$color[2]); + } + + /** + * Convert a hex color string into an RGB array. An extra fourth element + * will be returned with the original hex value. + * + * @param string $hex Hex color string. + * @return array RGB color array with an extra 'hex' element containing + * the original hex string. + * @access public + * @static + * @author Jason Lotito + * @see rgb2hex() + */ + function hex2rgb($hex) + { + $return = Image_Color::_splitColor($hex); + $return['hex'] = $hex; + return $return; + } + + /** + * Convert an HSV (Hue, Saturation, Brightness) value to RGB. + * + * @param integer $h Hue + * @param integer $s Saturation + * @param integer $v Brightness + * @return array RGB array. + * @access public + * @static + * @author Jason Lotito + * @uses hsv2hex() to convert the HSV value to Hex. + * @uses hex2rgb() to convert the Hex value to RGB. + */ + function hsv2rgb($h, $s, $v) + { + return Image_Color::hex2rgb(Image_Color::hsv2hex($h, $s, $v)); + } + + /** + * Convert HSV (Hue, Saturation, Brightness) to a hex color string. + * + * Originally written by Jurgen Schwietering. Integrated into the class by + * Jason Lotito. + * + * @param integer $h Hue + * @param integer $s Saturation + * @param integer $v Brightness + * @return string The hex string. + * @access public + * @static + * @author Jurgen Schwietering + * @uses rgb2hex() to convert the return value to a hex string. + */ + function hsv2hex($h, $s, $v) + { + $s /= 256.0; + $v /= 256.0; + if ($s == 0.0) { + $r = $g = $b = $v; + return ''; + } else { + $h = $h / 256.0 * 6.0; + $i = floor($h); + $f = $h - $i; + + $v *= 256.0; + $p = (integer)($v * (1.0 - $s)); + $q = (integer)($v * (1.0 - $s * $f)); + $t = (integer)($v * (1.0 - $s * (1.0 - $f))); + switch($i) { + case 0: + $r = $v; + $g = $t; + $b = $p; + break; + + case 1: + $r = $q; + $g = $v; + $b = $p; + break; + + case 2: + $r = $p; + $g = $v; + $b = $t; + break; + + case 3: + $r = $p; + $g = $q; + $b = $v; + break; + + case 4: + $r = $t; + $g = $p; + $b = $v; + break; + + default: + $r = $v; + $g = $p; + $b = $q; + break; + } + } + return $this->rgb2hex(array($r, $g, $b)); + } + + /** + * Allocates a color in the given image. + * + * User defined color specifications get translated into an array of RGB + * values. + * + * @param resource $img Image handle + * @param string|array $color Name or hex string or an RGB array. + * @return resource Image color handle. + * @access public + * @static + * @uses ImageColorAllocate() to allocate the color. + * @uses color2RGB() to parse the color into RGB values. + */ + function allocateColor(&$img, $color) { + $color = Image_Color::color2RGB($color); + + return ImageColorAllocate($img, $color[0], $color[1], $color[2]); + } + + /** + * Convert a named or hex color string to an RGB array. If the color begins + * with the # character it will be treated as a hex value. Everything else + * will be treated as a named color. If the named color is not known, black + * will be returned. + * + * @param string $color + * @return array RGB color + * @access public + * @static + * @author Laurent Laville + * @uses hex2rgb() to convert colors begining with the # character. + * @uses namedColor2RGB() to convert everything not starting with a #. + */ + function color2RGB($color) + { + $c = array(); + + if ($color{0} == '#') { + $c = Image_Color::hex2rgb($color); + } else { + $c = Image_Color::namedColor2RGB($color); + } + + return $c; + } + + /** + * Convert a named color to an RGB array. If the color is unknown black + * is returned. + * + * @param string $color Case insensitive color name. + * @return array RGB color array. If the color was unknown, the result + * will be black. + * @access public + * @static + * @author Sebastian Bergmann + */ + function namedColor2RGB($color) + { + static $colornames; + + if (!isset($colornames)) { + $colornames = array( + 'aliceblue' => array(240, 248, 255), + 'antiquewhite' => array(250, 235, 215), + 'aqua' => array( 0, 255, 255), + 'aquamarine' => array(127, 255, 212), + 'azure' => array(240, 255, 255), + 'beige' => array(245, 245, 220), + 'bisque' => array(255, 228, 196), + 'black' => array( 0, 0, 0), + 'blanchedalmond' => array(255, 235, 205), + 'blue' => array( 0, 0, 255), + 'blueviolet' => array(138, 43, 226), + 'brown' => array(165, 42, 42), + 'burlywood' => array(222, 184, 135), + 'cadetblue' => array( 95, 158, 160), + 'chartreuse' => array(127, 255, 0), + 'chocolate' => array(210, 105, 30), + 'coral' => array(255, 127, 80), + 'cornflowerblue' => array(100, 149, 237), + 'cornsilk' => array(255, 248, 220), + 'crimson' => array(220, 20, 60), + 'cyan' => array( 0, 255, 255), + 'darkblue' => array( 0, 0, 13), + 'darkcyan' => array( 0, 139, 139), + 'darkgoldenrod' => array(184, 134, 11), + 'darkgray' => array(169, 169, 169), + 'darkgreen' => array( 0, 100, 0), + 'darkkhaki' => array(189, 183, 107), + 'darkmagenta' => array(139, 0, 139), + 'darkolivegreen' => array( 85, 107, 47), + 'darkorange' => array(255, 140, 0), + 'darkorchid' => array(153, 50, 204), + 'darkred' => array(139, 0, 0), + 'darksalmon' => array(233, 150, 122), + 'darkseagreen' => array(143, 188, 143), + 'darkslateblue' => array( 72, 61, 139), + 'darkslategray' => array( 47, 79, 79), + 'darkturquoise' => array( 0, 206, 209), + 'darkviolet' => array(148, 0, 211), + 'deeppink' => array(255, 20, 147), + 'deepskyblue' => array( 0, 191, 255), + 'dimgray' => array(105, 105, 105), + 'dodgerblue' => array( 30, 144, 255), + 'firebrick' => array(178, 34, 34), + 'floralwhite' => array(255, 250, 240), + 'forestgreen' => array( 34, 139, 34), + 'fuchsia' => array(255, 0, 255), + 'gainsboro' => array(220, 220, 220), + 'ghostwhite' => array(248, 248, 255), + 'gold' => array(255, 215, 0), + 'goldenrod' => array(218, 165, 32), + 'gray' => array(128, 128, 128), + 'green' => array( 0, 128, 0), + 'greenyellow' => array(173, 255, 47), + 'honeydew' => array(240, 255, 240), + 'hotpink' => array(255, 105, 180), + 'indianred' => array(205, 92, 92), + 'indigo' => array(75, 0, 130), + 'ivory' => array(255, 255, 240), + 'khaki' => array(240, 230, 140), + 'lavender' => array(230, 230, 250), + 'lavenderblush' => array(255, 240, 245), + 'lawngreen' => array(124, 252, 0), + 'lemonchiffon' => array(255, 250, 205), + 'lightblue' => array(173, 216, 230), + 'lightcoral' => array(240, 128, 128), + 'lightcyan' => array(224, 255, 255), + 'lightgoldenrodyellow' => array(250, 250, 210), + 'lightgreen' => array(144, 238, 144), + 'lightgrey' => array(211, 211, 211), + 'lightpink' => array(255, 182, 193), + 'lightsalmon' => array(255, 160, 122), + 'lightseagreen' => array( 32, 178, 170), + 'lightskyblue' => array(135, 206, 250), + 'lightslategray' => array(119, 136, 153), + 'lightsteelblue' => array(176, 196, 222), + 'lightyellow' => array(255, 255, 224), + 'lime' => array( 0, 255, 0), + 'limegreen' => array( 50, 205, 50), + 'linen' => array(250, 240, 230), + 'magenta' => array(255, 0, 255), + 'maroon' => array(128, 0, 0), + 'mediumaquamarine' => array(102, 205, 170), + 'mediumblue' => array( 0, 0, 205), + 'mediumorchid' => array(186, 85, 211), + 'mediumpurple' => array(147, 112, 219), + 'mediumseagreen' => array( 60, 179, 113), + 'mediumslateblue' => array(123, 104, 238), + 'mediumspringgreen' => array( 0, 250, 154), + 'mediumturquoise' => array(72, 209, 204), + 'mediumvioletred' => array(199, 21, 133), + 'midnightblue' => array( 25, 25, 112), + 'mintcream' => array(245, 255, 250), + 'mistyrose' => array(255, 228, 225), + 'moccasin' => array(255, 228, 181), + 'navajowhite' => array(255, 222, 173), + 'navy' => array( 0, 0, 128), + 'oldlace' => array(253, 245, 230), + 'olive' => array(128, 128, 0), + 'olivedrab' => array(107, 142, 35), + 'orange' => array(255, 165, 0), + 'orangered' => array(255, 69, 0), + 'orchid' => array(218, 112, 214), + 'palegoldenrod' => array(238, 232, 170), + 'palegreen' => array(152, 251, 152), + 'paleturquoise' => array(175, 238, 238), + 'palevioletred' => array(219, 112, 147), + 'papayawhip' => array(255, 239, 213), + 'peachpuff' => array(255, 218, 185), + 'peru' => array(205, 133, 63), + 'pink' => array(255, 192, 203), + 'plum' => array(221, 160, 221), + 'powderblue' => array(176, 224, 230), + 'purple' => array(128, 0, 128), + 'red' => array(255, 0, 0), + 'rosybrown' => array(188, 143, 143), + 'royalblue' => array( 65, 105, 225), + 'saddlebrown' => array(139, 69, 19), + 'salmon' => array(250, 128, 114), + 'sandybrown' => array(244, 164, 96), + 'seagreen' => array( 46, 139, 87), + 'seashell' => array(255, 245, 238), + 'sienna' => array(160, 82, 45), + 'silver' => array(192, 192, 192), + 'skyblue' => array(135, 206, 235), + 'slateblue' => array(106, 90, 205), + 'slategray' => array(112, 128, 144), + 'snow' => array(255, 250, 250), + 'springgreen' => array( 0, 255, 127), + 'steelblue' => array( 70, 130, 180), + 'tan' => array(210, 180, 140), + 'teal' => array( 0, 128, 128), + 'thistle' => array(216, 191, 216), + 'tomato' => array(255, 99, 71), + 'turquoise' => array( 64, 224, 208), + 'violet' => array(238, 130, 238), + 'wheat' => array(245, 222, 179), + 'white' => array(255, 255, 255), + 'whitesmoke' => array(245, 245, 245), + 'yellow' => array(255, 255, 0), + 'yellowgreen' => array(154, 205, 50) + ); + } + + $color = strtolower($color); + + if (isset($colornames[$color])) { + return $colornames[$color]; + } else { + return array(0, 0, 0); + } + } + + /** + * Convert an RGB percentage string into an RGB array. + * + * @param string $color Percentage color string like "50%,20%,100%". + * @return array RGB color array. + * @access public + * @static + */ + function percentageColor2RGB($color) + { + // remove spaces + $color = str_replace(' ', '', $color); + // remove the percent signs + $color = str_replace('%', '', $color); + // split the string by commas + $color = explode(',', $color); + + $ret = array(); + foreach ($color as $k => $v) { + // range checks + if ($v <= 0) { + $ret[$k] = 0; + } else if ($v <= 100) { + // add 0.5 then cast to an integer to round the value. + $ret[$k] = (integer) ((2.55 * $v) + 0.5); + } else { + $ret[$k] = 255; + } + } + + return $ret; + } +} + +// For Array Walk +// {{{ +/** + * Function for array_walk() to round colors to the closest web safe value. + * + * @param integer $color One channel of an RGB color. + * @return integer The websafe equivalent of the color channel. + * @author Jason Lotito + * @author Andrew Morton + * @access private + * @static + */ +function _makeWebSafe(&$color) +{ + if ($color < 0x1a) { + $color = 0x00; + } else if ($color < 0x4d) { + $color = 0x33; + } else if ($color < 0x80) { + $color = 0x66; + } else if ($color < 0xB3) { + $color = 0x99; + } else if ($color < 0xE6) { + $color = 0xCC; + } else { + $color = 0xFF; + } + return $color; +} +// }}} + +?> diff --git a/config/archive/dspam/pear/Image/Graph.php b/config/archive/dspam/pear/Image/Graph.php new file mode 100644 index 00000000..d2e2492b --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph.php @@ -0,0 +1,851 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + + +/** + * Include PEAR.php + */ +require_once 'PEAR.inc'; + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * Include file Image/Graph/Constants.php + */ +require_once 'Image/Graph/Constants.php'; + +/** + * Main class for the graph creation. + * + * This is the main class, it manages the canvas and performs the final output + * by sequentialy making the elements output their results. The final output is + * handled using the {@link Image_Canvas} classes which makes it possible + * to use different engines (fx GD, PDFlib, libswf, etc) for output to several + * formats with a non-intersecting API. + * + * This class also handles coordinates and the correct managment of setting the + * correct coordinates on child elements. + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph extends Image_Graph_Element +{ + + /** + * Show generation time on graph + * @var bool + * @access private + */ + var $_showTime = false; + + /** + * Display errors on the canvas + * @var boolean + * @access private + */ + var $_displayErrors = false; + + /** + * Image_Graph [Constructor]. + * + * If passing the 3 parameters they are defined as follows:' + * + * Fx.: + * + * $Graph =& new Image_Graph(400, 300); + * + * or using the factory method: + * + * $Graph =& Image_Graph::factory('graph', array(400, 300)); + * + * This causes a 'png' canvas to be created by default. + * + * Otherwise use a single parameter either as an associated array or passing + * the canvas along to the constructor: + * + * 1) Create a new canvas with the following parameters: + * + * 'canvas' - The canvas type, can be any of 'gd', 'jpg', 'png' or 'svg' + * (more to come) - if omitted the default is 'gd' + * + * 'width' - The width of the graph + * + * 'height' - The height of the graph + * + * An example of this usage: + * + * $Graph =& Image_Graph::factory('graph', array(array('width' => 400, + * 'height' => 300, 'canvas' => 'jpg'))); + * + * NB! In thïs case remember the "double" array (see {@link Image_Graph:: + * factory()}) + * + * 2) Use the canvas specified, pass a valid Image_Canvas as + * parameter. Remember to pass by reference, i. e. &$canvas, fx.: + * + * $Graph =& new Image_Graph($Canvas); + * + * or using the factory method: + * + * $Graph =& Image_Graph::factory('graph', $Canvas)); + * + * @param mixed $params The width of the graph, an indexed array + * describing a new canvas or a valid {@link Image_Canvas} object + * @param int $height The height of the graph in pixels + * @param bool $createTransparent Specifies whether the graph should be + * created with a transparent background (fx for PNG's - note: transparent + * PNG's is not supported by Internet Explorer!) + */ + function Image_Graph($params, $height = false, $createTransparent = false) + { + parent::Image_Graph_Element(); + + $this->setFont(Image_Graph::factory('Image_Graph_Font')); + + if (defined('IMAGE_GRAPH_DEFAULT_CANVAS_TYPE')) { + $canvasType = IMAGE_GRAPH_DEFAULT_CANVAS_TYPE; + } else { + $canvasType = 'png'; // use GD as default, if nothing else is specified + } + + if (is_array($params)) { + if (isset($params['canvas'])) { + $canvasType = $params['canvas']; + } + + $width = 0; + $height = 0; + + if (isset($params['width'])) { + $width = $params['width']; + } + + if (isset($params['height'])) { + $height = $params['height']; + } + } elseif (is_a($params, 'Image_Canvas')) { + $this->_canvas =& $params; + $width = $this->_canvas->getWidth(); + $height = $this->_canvas->getHeight(); + } elseif (is_numeric($params)) { + $width = $params; + } + + if ($this->_canvas == null) { + include_once 'Image/Canvas.php'; + $this->_canvas =& + Image_Canvas::factory( + $canvasType, + array('width' => $width, 'height' => $height) + ); + } + + $this->_setCoords(0, 0, $width - 1, $height - 1); + } + + /** + * Gets the canvas for this graph. + * + * The canvas is set by either passing it to the constructor {@link + * Image_Graph::ImageGraph()} or using the {@link Image_Graph::setCanvas()} + * method. + * + * @return Image_Canvas The canvas used by this graph + * @access private + * @since 0.3.0dev2 + */ + function &_getCanvas() + { + return $this->_canvas; + } + + /** + * Sets the canvas for this graph. + * + * Calling this method makes this graph use the newly specified canvas for + * handling output. This method should be called whenever multiple + * 'outputs' are required. Invoke this method after calls to {@link + * Image_Graph:: done()} has been performed, to switch canvass. + * + * @param Image_Canvas $canvas The new canvas + * @return Image_Canvas The new canvas + * @since 0.3.0dev2 + */ + function &setCanvas(&$canvas) + { + if (!is_a($this->_canvas, 'Image_Canvas')) { + return $this->_error('The canvas introduced is not an Image_Canvas object'); + } + + $this->_canvas =& $canvas; + $this->_setCoords( + 0, + 0, + $this->_canvas->getWidth() - 1, + $this->_canvas->getHeight() - 1 + ); + return $this->_canvas; + } + + /** + * Gets a very precise timestamp + * + * @return The number of seconds to a lot of decimals + * @access private + */ + function _getMicroTime() + { + list($usec, $sec) = explode(' ', microtime()); + return ((float)$usec + (float)$sec); + } + + /** + * Gets the width of this graph. + * + * The width is returned as 'defined' by the canvas. + * + * @return int the width of this graph + */ + function width() + { + return $this->_canvas->getWidth(); + } + + /** + * Gets the height of this graph. + * + * The height is returned as 'defined' by the canvas. + * + * @return int the height of this graph + */ + function height() + { + return $this->_canvas->getHeight(); + } + + /** + * Enables displaying of errors on the output. + * + * Use this method to enforce errors to be displayed on the output. Calling + * this method makes PHP uses this graphs error handler as default {@link + * Image_Graph::_default_error_handler()}. + */ + function displayErrors() + { + $this->_displayErrors = true; + set_error_handler(array(&$this, '_default_error_handler')); + } + + /** + * Sets the log method for this graph. + * + * Use this method to enable logging. This causes any errors caught + * by either the error handler {@see Image_Graph::displayErrors()} + * or explicitly by calling {@link Image_Graph_Common::_error()} be + * logged using the specified logging method. + * + * If a filename is specified as log method, a Log object is created (using + * the 'file' handler), with a handle of 'Image_Graph Error Log'. + * + * Logging requires {@link Log}. + * + * @param mixed $log The log method, either a Log object or filename to log + * to + * @since 0.3.0dev2 + */ + function setLog($log) + { + } + + /** + * Factory method to create Image_Graph objects. + * + * Used for 'lazy including', i.e. loading only what is necessary, when it + * is necessary. If only one parameter is required for the constructor of + * the class simply pass this parameter as the $params parameter, unless the + * parameter is an array or a reference to a value, in that case you must + * 'enclose' the parameter in an array. Similar if the constructor takes + * more than one parameter specify the parameters in an array, i.e + * + * Image_Graph::factory('MyClass', array($param1, $param2, &$param3)); + * + * Variables that need to be passed by reference *must* have the & + * before the variable, i.e: + * + * Image_Graph::factory('line', &$Dataset); + * + * or + * + * Image_graph::factory('bar', array(array(&$Dataset1, &$Dataset2), + * 'stacked')); + * + * Class name can be either of the following: + * + * 1 The 'real' Image_Graph class name, i.e. Image_Graph_Plotarea or + * Image_Graph_Plot_Line + * + * 2 Short class name (leave out Image_Graph) and retain case, i.e. + * Plotarea, Plot_Line *not* plot_line + * + * 3 Class name 'alias', the following are supported: + * + * 'graph' = Image_Graph + * + * 'plotarea' = Image_Graph_Plotarea + * + * 'line' = Image_Graph_Plot_Line + * + * 'area' = Image_Graph_Plot_Area + * + * 'bar' = Image_Graph_Plot_Bar + * + * 'pie' = Image_Graph_Plot_Pie + * + * 'radar' = Image_Graph_Plot_Radar + * + * 'step' = Image_Graph_Plot_Step + * + * 'impulse' = Image_Graph_Plot_Impulse + * + * 'dot' or 'scatter' = Image_Graph_Plot_Dot + * + * 'smooth_line' = Image_Graph_Plot_Smoothed_Line + * + * 'smooth_area' = Image_Graph_Plot_Smoothed_Area + + * 'dataset' = Image_Graph_Dataset_Trivial + * + * 'random' = Image_Graph_Dataset_Random + * + * 'function' = Image_Graph_Dataset_Function + * + * 'vector' = Image_Graph_Dataset_VectorFunction + * + * 'category' = Image_Graph_Axis_Category + * + * 'axis' = Image_Graph_Axis + * + * 'axis_log' = Image_Graph_Axis_Logarithmic + * + * 'title' = Image_Graph_Title + * + * 'line_grid' = Image_Graph_Grid_Lines + * + * 'bar_grid' = Image_Graph_Grid_Bars + * + * 'polar_grid' = Image_Graph_Grid_Polar + * + * 'legend' = Image_Graph_Legend + * + * 'font' = Image_Graph_Font + * + * 'ttf_font' = Image_Graph_Font + * + * 'Image_Graph_Font_TTF' = Image_Graph_Font (to maintain BC with Image_Graph_Font_TTF) + * + * 'gradient' = Image_Graph_Fill_Gradient + * + * 'icon_marker' = Image_Graph_Marker_Icon + * + * 'value_marker' = Image_Graph_Marker_Value + * + * @param string $class The class for the new object + * @param mixed $params The paramaters to pass to the constructor + * @return object A new object for the class + * @static + */ + function &factory($class, $params = null) + { + static $Image_Graph_classAliases = array( + 'graph' => 'Image_Graph', + 'plotarea' => 'Image_Graph_Plotarea', + + 'line' => 'Image_Graph_Plot_Line', + 'area' => 'Image_Graph_Plot_Area', + 'bar' => 'Image_Graph_Plot_Bar', + 'smooth_line' => 'Image_Graph_Plot_Smoothed_Line', + 'smooth_area' => 'Image_Graph_Plot_Smoothed_Area', + 'pie' => 'Image_Graph_Plot_Pie', + 'radar' => 'Image_Graph_Plot_Radar', + 'step' => 'Image_Graph_Plot_Step', + 'impulse' => 'Image_Graph_Plot_Impulse', + 'dot' => 'Image_Graph_Plot_Dot', + 'scatter' => 'Image_Graph_Plot_Dot', + + 'dataset' => 'Image_Graph_Dataset_Trivial', + 'random' => 'Image_Graph_Dataset_Random', + 'function' => 'Image_Graph_Dataset_Function', + 'vector' => 'Image_Graph_Dataset_VectorFunction', + + 'category' => 'Image_Graph_Axis_Category', + 'axis' => 'Image_Graph_Axis', + 'axis_log' => 'Image_Graph_Axis_Logarithmic', + + 'title' => 'Image_Graph_Title', + + 'line_grid' => 'Image_Graph_Grid_Lines', + 'bar_grid' => 'Image_Graph_Grid_Bars', + 'polar_grid' => 'Image_Graph_Grid_Polar', + + 'legend' => 'Image_Graph_Legend', + 'font' => 'Image_Graph_Font', + 'ttf_font' => 'Image_Graph_Font', + 'Image_Graph_Font_TTF' => 'Image_Graph_Font', // BC with Image_Graph_Font_TTF + 'gradient' => 'Image_Graph_Fill_Gradient', + + 'icon_marker' => 'Image_Graph_Marker_Icon', + 'value_marker' => 'Image_Graph_Marker_Value' + ); + + if (substr($class, 0, 11) != 'Image_Graph') { + if (isset($Image_Graph_classAliases[$class])) { + $class = $Image_Graph_classAliases[$class]; + } else { + $class = 'Image_Graph_' . $class; + } + } + + include_once str_replace('_', '/', $class) . '.php'; + + $obj = null; + + if (is_array($params)) { + switch (count($params)) { + case 1: + $obj =& new $class( + $params[0] + ); + break; + + case 2: + $obj =& new $class( + $params[0], + $params[1] + ); + break; + + case 3: + $obj =& new $class( + $params[0], + $params[1], + $params[2] + ); + break; + + case 4: + $obj =& new $class( + $params[0], + $params[1], + $params[2], + $params[3] + ); + break; + + case 5: + $obj =& new $class( + $params[0], + $params[1], + $params[2], + $params[3], + $params[4] + ); + break; + + case 6: + $obj =& new $class( + $params[0], + $params[1], + $params[2], + $params[3], + $params[4], + $params[5] + ); + break; + + case 7: + $obj =& new $class( + $params[0], + $params[1], + $params[2], + $params[3], + $params[4], + $params[5], + $params[6] + ); + break; + + case 8: + $obj =& new $class( + $params[0], + $params[1], + $params[2], + $params[3], + $params[4], + $params[5], + $params[6], + $params[7] + ); + break; + + case 9: + $obj =& new $class( + $params[0], + $params[1], + $params[2], + $params[3], + $params[4], + $params[5], + $params[6], + $params[7], + $params[8] + ); + break; + + case 10: + $obj =& new $class( + $params[0], + $params[1], + $params[2], + $params[3], + $params[4], + $params[5], + $params[6], + $params[7], + $params[8], + $params[9] + ); + break; + + default: + $obj =& new $class(); + break; + + } + } else { + if ($params == null) { + $obj =& new $class(); + } else { + $obj =& new $class($params); + } + } + return $obj; + } + + /** + * Factory method to create layouts. + * + * This method is used for easy creation, since using {@link Image_Graph:: + * factory()} does not work with passing newly created objects from + * Image_Graph::factory() as reference, this is something that is + * fortunately fixed in PHP5. Also used for 'lazy including', i.e. loading + * only what is necessary, when it is necessary. + * + * Use {@link Image_Graph::horizontal()} or {@link Image_Graph::vertical()} + * instead for easier access. + * + * @param mixed $layout The type of layout, can be either 'Vertical' + * or 'Horizontal' (case sensitive) + * @param Image_Graph_Element $part1 The 1st part of the layout + * @param Image_Graph_Element $part2 The 2nd part of the layout + * @param int $percentage The percentage of the layout to split at + * @return Image_Graph_Layout The newly created layout object + * @static + */ + function &layoutFactory($layout, &$part1, &$part2, $percentage = 50) + { + if (($layout != 'Vertical') && ($layout != 'Horizontal')) { + return $this->_error('Layouts must be either \'Horizontal\' or \'Vertical\''); + } + + if (!(is_a($part1, 'Image_Graph_Element'))) { + return $this->_error('Part 1 is not a valid Image_Graph element'); + } + + if (!(is_a($part2, 'Image_Graph_Element'))) { + return $this->_error('Part 2 is not a valid Image_Graph element'); + } + + if ((!is_numeric($percentage)) || ($percentage < 0) || ($percentage > 100)) { + return $this->_error('Percentage has to be a number between 0 and 100'); + } + + include_once "Image/Graph/Layout/$layout.php"; + $class = "Image_Graph_Layout_$layout"; + $obj =& new $class($part1, $part2, $percentage); + return $obj; + } + + /** + * Factory method to create horizontal layout. + * + * See {@link Image_Graph::layoutFactory()} + * + * @param Image_Graph_Element $part1 The 1st (left) part of the layout + * @param Image_Graph_Element $part2 The 2nd (right) part of the layout + * @param int $percentage The percentage of the layout to split at + * (percentage of total height from the left side) + * @return Image_Graph_Layout The newly created layout object + * @static + */ + function &horizontal(&$part1, &$part2, $percentage = 50) + { + $obj =& Image_Graph::layoutFactory('Horizontal', $part1, $part2, $percentage); + return $obj; + } + + /** + * Factory method to create vertical layout. + * + * See {@link Image_Graph::layoutFactory()} + * + * @param Image_Graph_Element $part1 The 1st (top) part of the layout + * @param Image_Graph_Element $part2 The 2nd (bottom) part of the layout + * @param int $percentage The percentage of the layout to split at + * (percentage of total width from the top edge) + * @return Image_Graph_Layout The newly created layout object + * @static + */ + function &vertical(&$part1, &$part2, $percentage = 50) + { + $obj =& Image_Graph::layoutFactory('Vertical', $part1, $part2, $percentage); + return $obj; + } + + /** + * The error handling routine set by set_error_handler(). + * + * This method is used internaly by Image_Graph and PHP as a proxy for {@link + * Image_Graph::_error()}. + * + * @param string $error_type The type of error being handled. + * @param string $error_msg The error message being handled. + * @param string $error_file The file in which the error occurred. + * @param integer $error_line The line in which the error occurred. + * @param string $error_context The context in which the error occurred. + * @access private + */ + function _default_error_handler($error_type, $error_msg, $error_file, $error_line, $error_context) + { + switch( $error_type ) { + case E_ERROR: + $level = 'error'; + break; + + case E_USER_ERROR: + $level = 'user error'; + break; + + case E_WARNING: + $level = 'warning'; + break; + + case E_USER_WARNING: + $level = 'user warning'; + break; + + case E_NOTICE: + $level = 'notice'; + break; + + case E_USER_NOTICE: + $level = 'user notice'; + break; + + default: + $level = '(unknown)'; + break; + + } + + $this->_error("PHP $level: $error_msg", + array( + 'type' => $error_type, + 'file' => $error_file, + 'line' => $error_line, + 'context' => $error_context + ) + ); + } + + /** + * Displays the errors on the error stack. + * + * Invoking this method cause all errors on the error stack to be displayed + * on the graph-output, by calling the {@link Image_Graph::_displayError()} + * method. + * + * @access private + */ + function _displayErrors() + { + return true; + } + + /** + * Display an error from the error stack. + * + * This method writes error messages caught from the {@link Image_Graph:: + * _default_error_handler()} if {@Image_Graph::displayErrors()} was invoked, + * and the error explicitly set by the system using {@link + * Image_Graph_Common::_error()}. + * + * @param int $x The horizontal position of the error message + * @param int $y The vertical position of the error message + * @param array $error The error context + * + * @access private + */ + function _displayError($x, $y, $error) + { + } + + /** + * Outputs this graph using the canvas. + * + * This causes the graph to make all elements perform their output. Their + * result is 'written' to the output using the canvas, which also performs + * the actual output, fx. it being to a file or directly to the browser + * (in the latter case, the canvas will also make sure the correct HTTP + * headers are sent, making the browser handle the output correctly, if + * supported by it). + * + * Parameters are the ones supported by the canvas, common ones are: + * + * 'filename' To output to a file instead of browser + * + * 'tohtml' Return a HTML string that encompasses the current graph/canvas - this + * implies an implicit save using the following parameters: 'filename' The "temporary" + * filename of the graph, 'filepath' A path in the file system where Image_Graph can + * store the output (this file must be in DOCUMENT_ROOT scope), 'urlpath' The URL that the + * 'filepath' corresponds to (i.e. filepath + filename must be reachable from a browser using + * urlpath + filename) + * + * @param mixed $param The output parameters to pass to the canvas + * @return bool Was the output 'good' (true) or 'bad' (false). + */ + function done($param = false) + { + $result = $this->_reset(); + if (PEAR::isError($result)) { + return $result; + } + return $this->_done($param); + } + + /** + * Outputs this graph using the canvas. + * + * This causes the graph to make all elements perform their output. Their + * result is 'written' to the output using the canvas, which also performs + * the actual output, fx. it being to a file or directly to the browser + * (in the latter case, the canvas will also make sure the correct HTTP + * headers are sent, making the browser handle the output correctly, if + * supported by it). + * + * @param mixed $param The output parameters to pass to the canvas + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done($param = false) + { + $timeStart = $this->_getMicroTime(); + + if ($this->_shadow) { + $this->setPadding(20); + $this->_setCoords( + $this->_left, + $this->_top, + $this->_right - 10, + $this->_bottom - 10); + } + + $result = $this->_updateCoords(); + if (PEAR::isError($result)) { + return $result; + } + + if ($this->_getBackground()) { + $this->_canvas->rectangle( + array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_right, + 'y1' => $this->_bottom + ) + ); + } + + $result = parent::_done(); + if (PEAR::isError($result)) { + return $result; + } + + if ($this->_displayErrors) { + $this->_displayErrors(); + } + + $timeEnd = $this->_getMicroTime(); + + if (($this->_showTime) || + ((isset($param['showtime'])) && ($param['showtime'] === true)) + ) { + $text = 'Generated in ' . + sprintf('%0.3f', $timeEnd - $timeStart) . ' sec'; + $this->write( + $this->_right, + $this->_bottom, + $text, + IMAGE_GRAPH_ALIGN_RIGHT + IMAGE_GRAPH_ALIGN_BOTTOM, + array('color' => 'red') + ); + } + + if (isset($param['filename'])) { + if ((isset($param['tohtml'])) && ($param['tohtml'])) { + return $this->_canvas->toHtml($param); + } + else { + return $this->_canvas->save($param); + } + } else { + return $this->_canvas->show($param); + } + } +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Axis.php b/config/archive/dspam/pear/Image/Graph/Axis.php new file mode 100644 index 00000000..99da305f --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Axis.php @@ -0,0 +1,1690 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plotarea/Element.php + */ +require_once 'Image/Graph/Plotarea/Element.php'; + +/** + * Diplays a normal linear axis (either X- or Y-axis). + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ + class Image_Graph_Axis extends Image_Graph_Plotarea_Element +{ + + /** + * The type of the axis, possible values are: + *
    + *
  • IMAGE_GRAPH_AXIS_X / IMAGE_GRAPH_AXIS_HORIZONTAL + *
  • IMAGE_GRAPH_AXIS_Y / IMAGE_GRAPH_AXIS_VERTICAL / + * IMAGE_GRAPH_AXIS_Y_SECONDARY + *
+ * @var int + * @access private + */ + var $_type; + + /** + * The minimum value the axis displays + * @var int + * @access private + */ + var $_minimum = false; + + /** + * The minimum value the axis has been explicitly set by the user + * @var bool + * @access private + */ + var $_minimumSet = false; + + /** + * The maximum value the axis displays + * @var int + * @access private + */ + var $_maximum = false; + + /** + * The maximum value the axis has been explicitly set by the user + * @var bool + * @access private + */ + var $_maximumSet = false; + + /** + * The value span of the axis. + * This is primarily included for performance reasons + * @var double + * @access private + */ + var $_axisSpan = false; + + /** + * The value span of the axis. + * This is primarily included for performance reasons + * @var double + * @access private + */ + var $_axisValueSpan = false; + + /** + * The axis padding. + * The index 'low' specifies the padding for the low axis values (when not + * inverted), i.e. to the left on an x-axis and on the bottom of an y-axis, + * vice versa for 'high'. + * + * Axis padding does not make sense on a normal linear y-axis with a 'y-min' + * of 0 since this corresponds to displaying a small part of the y-axis + * below 0! + * + * @var array + * @access private + */ + var $_axisPadding = array('low' => 0, 'high' => 0); + + /** + * The number of "pixels" representing 1 unit on the axis + * + * This is primarily included for performance reasons + * @var double + * @access private + */ + var $_delta = false; + + /** + * Specify if the axis should label the minimum value + * @var bool + * @access private + */ + var $_showLabelMinimum = true; + + /** + * Specify if the axis should label 0 (zero) + * @var bool + * @access private + */ + var $_showLabelZero = false; + + /** + * Specify if the axis should label the maximum value + * @var bool + * @access private + */ + var $_showLabelMaximum = true; + + /** + * Show arrow heads at the 'end' of the axis, default: false + * @var bool + * @access private + */ + var $_showArrow = false; + + /** + * Intersection data of axis + * @var array + * @access private + */ + var $_intersect = array('value' => 'default', 'axis' => 'default'); + + /** + * The fixed size of the axis (i.e. width for y-axis, height for x-axis) + * @var mixed + * @access private + */ + var $_fixedSize = false; + + /** + * The label options + * + * Should text be shows, preferences for ticks. The indexes start at level + * 1, which is chosen for readability + * @var array + * @access private + */ + var $_labelOptions = array( + 1 => array( + 'interval' => 1, + 'type' => 'auto', + 'tick' => array( + 'start' => -2, + 'end' => 2, + 'color' => false // default color + ), + 'showtext' => true, + 'showoffset' => false, + 'font' => array(), + 'offset' => 0, + 'position' => 'outside', + ) + ); + + /** + * The labels that are shown. + * + * This is used to make values show only once... + * @access private + */ + var $_labelText = array(); + + /** + * A data preprocessor for formatting labels, fx showing dates as a standard + * date instead of Unix time stamp + * @var Image_Graph_DatePreProcessor + * @access private + * @see Image_Graph_DataPreProcessor + */ + var $_dataPreProcessor = null; + + /** + * Point marked in the axis + * @var array + * @access private + */ + var $_marks = array(); + + /** + * Specifies whether the values should be 'pushed' by 0.5 + * @var bool + * @access private + */ + var $_pushValues = false; + + /** + * The title of this axis + * @var string + * @access private + */ + var $_title = ''; + + /** + * The font used for the title of this axis + * @var Image_Graph_Font + * @access private + */ + var $_titleFont = false; + + /** + * Invert the axis (i.e. if an y-axis normally displays minimum values at + * the bottom, they are not displayed at the top + * @var bool + * @access private + * @since 0.3.0dev3 + */ + var $_invert = false; + + /** + * Transpose the axis (i.e. is a normal y-axis transposed, so thats it's not show + * vertically as normally expected, but instead horizontally) + * @var bool + * @access private + */ + var $_transpose = false; + + /** + * Image_Graph_Axis [Constructor]. + * Normally a manual creation should not be necessary, axis are created + * automatically by the {@link Image_Graph_Plotarea} constructor unless + * explicitly defined otherwise + * + * @param int $type The type (direction) of the Axis, use IMAGE_GRAPH_AXIS_X + * for an X-axis (default, may be omitted) and IMAGE_GRAPH_AXIS_Y for Y- + * axis) + */ + function Image_Graph_Axis($type = IMAGE_GRAPH_AXIS_X) + { + parent::Image_Graph_Element(); + $this->_type = $type; + $this->_fillStyle = 'black'; + } + + /** + * Push the values by 0.5 (for bar and step chart) + * + * @access private + */ + function _pushValues() + { + $this->_pushValues = true; + } + + /** + * Sets the axis padding for a given position ('low' or 'high') + * @param string $where The position + * @param int $value The number of pixels to "pad" + * @access private + */ + function _setAxisPadding($where, $value) + { + $this->_axisPadding[$where] = $value; + } + + /** + * Gets the font of the title. + * + * If not font has been set, the parent font is propagated through it's + * children. + * + * @return array An associated array used for canvas + * @access private + */ + function _getTitleFont() + { + if ($this->_titleFont === false) { + if ($this->_defaultFontOptions !== false) { + return $this->_defaultFontOptions; + } else { + return $this->_getFont(); + } + } else { + if (is_object($this->_titleFont)) { + return $this->_titleFont->_getFont(); + } elseif (is_array($this->_titleFont)) { + return $this->_getFont($this->_titleFont); + } elseif (is_int($this->_titleFont)) { + return $this->_getFont(array('size' => $this->_titleFont)); + } + } + return array(); + } + + /** + * Shows a label for the the specified values. + * + * Allowed values are combinations of: + *
    + *
  • IMAGE_GRAPH_LABEL_MINIMUM + *
  • IMAGE_GRAPH_LABEL_ZERO + *
  • IMAGE_GRAPH_LABEL_MAXIMUM + *
+ * By default none of these are shows on the axis + * + * @param int $value The values to show labels for + */ + function showLabel($value) + { + $this->_showLabelMinimum = ($value & IMAGE_GRAPH_LABEL_MINIMUM); + $this->_showLabelZero = ($value & IMAGE_GRAPH_LABEL_ZERO); + $this->_showLabelMaximum = ($value & IMAGE_GRAPH_LABEL_MAXIMUM); + } + + /** + * Sets a data preprocessor for formatting the axis labels + * + * @param Image_Graph_DataPreprocessor $dataPreProcessor The data preprocessor + * @see Image_Graph_DataPreprocessor + */ + function setDataPreProcessor(& $dataPreProcessor) + { + $this->_dataPreProcessor =& $dataPreProcessor; + } + + /** + * Gets the minimum value the axis will show + * + * @return double The minumum value + * @access private + */ + function _getMinimum() + { + return $this->_minimum; + } + + /** + * Gets the maximum value the axis will show + * + * @return double The maximum value + * @access private + */ + function _getMaximum() + { + return $this->_maximum; + } + + /** + * Sets the minimum value the axis will show + * + * @param double $minimum The minumum value to use on the axis + * @access private + */ + function _setMinimum($minimum) + { + if ($this->_minimum === false) { + $this->forceMinimum($minimum, false); + } else { + $this->forceMinimum(min($this->_minimum, $minimum), false); + } + } + + /** + * Sets the maximum value the axis will show + * + * @param double $maximum The maximum value to use on the axis + * @access private + */ + function _setMaximum($maximum) + { + if ($this->_maximum === false) { + $this->forceMaximum($maximum, false); + } else { + $this->forceMaximum(max($this->_maximum, $maximum), false); + } + } + + /** + * Forces the minimum value of the axis + * + * @param double $minimum The minumum value to use on the axis + * @param bool $userEnforce This value should not be set, used internally + */ + function forceMinimum($minimum, $userEnforce = true) + { + if (($userEnforce) || (!$this->_minimumSet)) { + $this->_minimum = $minimum; + $this->_minimumSet = $userEnforce; + } + $this->_calcLabelInterval(); + } + + /** + * Forces the maximum value of the axis + * + * @param double $maximum The maximum value to use on the axis + * @param bool $userEnforce This value should not be set, used internally + */ + function forceMaximum($maximum, $userEnforce = true) + { + if (($userEnforce) || (!$this->_maximumSet)) { + $this->_maximum = $maximum; + $this->_maximumSet = $userEnforce; + } + $this->_calcLabelInterval(); + } + + /** + * Show an arrow head on the 'end' of the axis + */ + function showArrow() + { + $this->_showArrow = true; + } + + /** + * Do not show an arrow head on the 'end' of the axis (default) + */ + function hideArrow() + { + $this->_showArrow = false; + } + + /** + * Return the label distance. + * + * @param int $level The label level to return the distance of + * @return int The distance between 2 adjacent labels + * @access private + */ + function _labelDistance($level = 1) + { + $l1 = $this->_getNextLabel(false, $level); + $l2 = $this->_getNextLabel($l1, $level);; + return abs($this->_point($l2) - $this->_point($l1)); + } + + /** + * Sets an interval for when labels are shown on the axis. + * + * By default 'auto' is used, forcing the axis to calculate a approximate + * best label interval to be used. Specify an array to use user-defined + * values for labels. + * + * @param mixed $labelInterval The interval with which labels are shown + * @param int $level The label level to set the interval on + */ + function setLabelInterval($labelInterval = 'auto', $level = 1) + { + if (!isset($this->_labelOptions[$level])) { + $this->_labelOptions[$level] = array(); + } + + if ($labelInterval === 'auto') { + $this->_labelOptions[$level]['type'] = 'auto'; + $this->_calcLabelInterval(); + } else { + $this->_labelOptions[$level]['type'] = 'manual'; + $this->_labelOptions[$level]['interval'] = $labelInterval; + } + } + + /** + * Sets options for the label at a specific level. + * + * Possible options are: + * + * 'showtext' true or false whether label text should be shown or not + * + * 'showoffset' should the label be shown at an offset, i.e. should the + * label be shown at a position so that it does not overlap with prior + * levels. Only applies to multilevel labels with text + * + * 'font' The font options as an associated array + * + * 'position' The position at which the labels are written ('inside' or + * 'outside' the axis). NB! This relative position only applies to the + * default location of the axis, i.e. if an x-axis is inverted then + * 'outside' still refers to the "left" side of a normal y-axis (since this + * is normally 'outside') but the actual output will be labels on the + * "inside"! + * + * 'format' To format the label text according to a sprintf statement + * + * 'dateformat' To format the label as a date, fx. j. M Y = 29. Jun 2005 + * + * @param string $option The label option name (see detailed description + * for possible values) + * @param mixed $value The value for the option + * @param int $level The label level to set the interval on + */ + function setLabelOption($option, $value, $level = 1) + { + if (!isset($this->_labelOptions[$level])) { + $this->_labelOptions[$level] = array('type' => 'auto'); + } + + $this->_labelOptions[$level][$option] = $value; + } + + /** + * Sets options for the label at a specific level. + * + * The possible options are specified in {@link Image_Graph_Axis:: + * setLabelOption()}. + * + * @param array $options An assciated array with label options + * @param int $level The label level to set the interval on + */ + function setLabelOptions($options, $level = 1) + { + if (is_array($options)) { + if (isset($this->_labelOptions[$level])) { + $this->_labelOptions[$level] = array_merge($this->_labelOptions[$level], $options); + } else { + $this->_labelOptions[$level] = $options; + } + + } + } + + /** + * Sets the title of this axis. + * + * This is used as an alternative (maybe better) method, than using layout's + * for axis-title generation. + * + * To use the current propagated font, but just set it vertically, simply + * pass 'vertical' as second parameter for vertical alignment down-to-up or + * 'vertical2' for up-to-down alignment. + * + * @param string $title The title of this axis + * @param Image_Graph_Font $font The font used for the title + * @since 0.3.0dev2 + */ + function setTitle($title, $font = false) + { + $this->_title = $title; + if ($font === 'vertical') { + $this->_titleFont = array('vertical' => true, 'angle' => 90); + } elseif ($font === 'vertical2') { + $this->_titleFont = array('vertical' => true, 'angle' => 270); + } else { + $this->_titleFont =& $font; + } + } + + /** + * Sets a fixed "size" for the axis. + * + * If the axis is any type of y-axis the size relates to the width of the + * axis, if an x-axis is concerned the size is the height. + * + * @param int $size The fixed size of the axis + * @since 0.3.0dev5 + */ + function setFixedSize($size) + { + $this->_fixedSize = $size; + } + + /** + * Preprocessor for values, ie for using logarithmic axis + * + * @param double $value The value to preprocess + * @return double The preprocessed value + * @access private + */ + function _value($value) + { + return $value - $this->_getMinimum() + ($this->_pushValues ? 0.5 : 0); + } + + /** + * Apply the dataset to the axis + * + * @param Image_Graph_Dataset $dataset The dataset + * @access private + */ + function _applyDataset(&$dataset) + { + if ($this->_type == IMAGE_GRAPH_AXIS_X) { + $this->_setMinimum($dataset->minimumX()); + $this->_setMaximum($dataset->maximumX()); + } else { + $this->_setMinimum($dataset->minimumY()); + $this->_setMaximum($dataset->maximumY()); + } + } + + /** + * Get the pixel position represented by a value on the canvas + * + * @param double $value the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _point($value) + { + if ((($this->_type == IMAGE_GRAPH_AXIS_X) && (!$this->_transpose)) || + (($this->_type != IMAGE_GRAPH_AXIS_X) && ($this->_transpose))) + { + if ($this->_invert) { + return max($this->_left, $this->_right - $this->_axisPadding['high'] - $this->_delta * $this->_value($value)); + } else { + return min($this->_right, $this->_left + $this->_axisPadding['low'] + $this->_delta * $this->_value($value)); + } + } else { + if ($this->_invert) { + return min($this->_bottom, $this->_top + $this->_axisPadding['high'] + $this->_delta * $this->_value($value)); + } else { + return max($this->_top, $this->_bottom - $this->_axisPadding['low'] - $this->_delta * $this->_value($value)); + } + } + } + + + /** + * Get the axis intersection pixel position + * + * This is only to be called prior to output! I.e. between the user + * invokation of Image_Graph::done() and any actual output is performed. + * This is because it can change the axis range. + * + * @param double $value the intersection value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _intersectPoint($value) + { + + if (($value === 'min') || ($value < $this->_getMinimum())) { + if ($this->_type == IMAGE_GRAPH_AXIS_X) { + if ($this->_invert) { + return ($this->_transpose ? $this->_top : $this->_right); + } else { + return ($this->_transpose ? $this->_bottom : $this->_left); + } + } else { + if ($this->_invert) { + return ($this->_transpose ? $this->_right : $this->_top); + } else { + return ($this->_transpose ? $this->_left : $this->_bottom); + } + } + } elseif (($value === 'max') || ($value > $this->_getMaximum())) { + if ($this->_type == IMAGE_GRAPH_AXIS_X) { + if ($this->_invert) { + return ($this->_transpose ? $this->_bottom : $this->_left); + } else { + return ($this->_transpose ? $this->_top : $this->_right); + } + } else { + if ($this->_invert) { + return ($this->_transpose ? $this->_left : $this->_bottom); + } else { + return ($this->_transpose ? $this->_right : $this->_top); + } + } + } + + return $this->_point($value); + } + + /** + * Calculate the delta value (the number of pixels representing one unit + * on the axis) + * + * @return double The label interval + * @access private + */ + function _calcDelta() + { + if ($this->_axisValueSpan == 0) { + $this->_delta = false; + } elseif ($this->_type == IMAGE_GRAPH_AXIS_X) { + $this->_delta = (($this->_transpose ? $this->height() : $this->width()) - ($this->_axisPadding['low'] + $this->_axisPadding['high'])) / ($this->_axisValueSpan + ($this->_pushValues ? 1 : 0)); + } else { + $this->_delta = (($this->_transpose ? $this->width() : $this->height()) - ($this->_axisPadding['low'] + $this->_axisPadding['high'])) / ($this->_axisValueSpan + ($this->_pushValues ? 1 : 0)); + } + } + + /** + * Calculate the label interval + * + * If explicitly defined this will be calucated to an approximate best. + * + * @return double The label interval + * @access private + */ + function _calcLabelInterval() + { + $min = $this->_getMinimum(); + $max = $this->_getMaximum(); + + $this->_axisValueSpan = $this->_axisSpan = abs($max - $min); + + if ((!empty($min)) && (!empty($max)) && ($min > $max)) { + $this->_labelOptions[1]['interval'] = 1; + return true; + } + + $span = 0; + foreach($this->_labelOptions as $level => $labelOptions) { + if ((!isset($labelOptions['type'])) || ($labelOptions['type'] !== 'auto')) { + $span = false; + } elseif ($level == 1) { + $span = $this->_axisValueSpan; + } else { + $l1 = $this->_getNextLabel(false, $level - 1); + $l2 = $this->_getNextLabel($l1, $level - 1); + if ((!is_numeric($l1)) || (!is_numeric($l2))) { + $span == false; + } else { + $span = $l2 - $l1; + } + } + + if ($span !== false) { + $interval = pow(10, floor(log10($span))); + + if ($interval == 0) { + $interval = 1; + } + + if ((($span) / $interval) < 3) { + $interval = $interval / 4; + } elseif ((($span) / $interval) < 5) { + $interval = $interval / 2; + } elseif ((($span) / $interval) > 10) { + $interval = $interval * 2; + } + + if (($interval -floor($interval) == 0.5) && ($interval != 0.5)) { + $interval = floor($interval); + } + + // just to be 100% sure that an interval of 0 is not returned some + // additional checks are performed + if ($interval == 0) { + $interval = ($span) / 5; + } + + if ($interval == 0) { + $interval = 1; + } + + $this->_labelOptions[$level]['interval'] = $interval; + } + } + } + + /** + * Get next label point + * + * @param doubt $currentLabel The current label, if omitted or false, the + * first is returned + * @param int $level The label level to get the next label from + * @return double The next label point + * @access private + */ + function _getNextLabel($currentLabel = false, $level = 1) + { + if (!isset($this->_labelOptions[$level])) { + return false; + } + + if (is_array($this->_labelOptions[$level]['interval'])) { + if ($currentLabel === false) { + reset($this->_labelOptions[$level]['interval']); + } + + if (list(, $label) = each($this->_labelOptions[$level]['interval'])) { + return $label; + } else { + return false; + } + } else { + $li = $this->_labelInterval($level); + if (($this->_axisSpan == 0) || ($this->_axisValueSpan == 0) || + ($li == 0) + ) { + return false; + } + + $labelInterval = $this->_axisSpan / ($this->_axisValueSpan / $li); + + if ($labelInterval == 0) { + return false; + } + + if ($currentLabel === false) { + $label = ((int) ($this->_getMinimum() / $labelInterval)) * + $labelInterval - $labelInterval; + while ($label < $this->_getMinimum()) { + $label += $labelInterval; + } + return $label; + } else { + if ($currentLabel + $labelInterval > $this->_getMaximum()) { + return false; + } else { + return $currentLabel + $labelInterval; + } + } + } + } + + /** + * Get the interval with which labels are shown on the axis. + * + * If explicitly defined this will be calucated to an approximate best. + * + * @param int $level The label level to get the label interval for + * @return double The label interval + * @access private + */ + function _labelInterval($level = 1) + { + if ((!isset($this->_labelOptions[$level])) || + (!isset($this->_labelOptions[$level]['interval'])) + ) { + return 1; + } + + return (is_array($this->_labelOptions[$level]['interval']) + ? 1 + : $this->_labelOptions[$level]['interval'] + ); + } + + /** + * Get the size in pixels of the axis. + * + * For an x-axis this is the width of the axis including labels, and for an + * y-axis it is the corrresponding height + * + * @return int The size of the axis + * @access private + */ + function _size() + { + if (!$this->_visible) { + return 0; + } + + if ($this->_fixedSize !== false) { + return $this->_fixedSize; + } + + krsort($this->_labelOptions); + + $totalMaxSize = 0; + + foreach ($this->_labelOptions as $level => $labelOptions) { + if ((isset($labelOptions['showoffset'])) && ($labelOptions['showoffset'] === true)) { + $this->_labelOptions[$level]['offset'] += $totalMaxSize; + } elseif (!isset($this->_labelOptions[$level]['offset'])) { + $this->_labelOptions[$level]['offset'] = 0; + } + if ( + (isset($labelOptions['showtext'])) && + ($labelOptions['showtext'] === true) && + ( + (!isset($labelOptions['position'])) || + ($labelOptions['position'] == 'outside') + ) + ) { + if (isset($labelOptions['font'])) { + $font = $this->_getFont($labelOptions['font']); + } else { + if ($this->_defaultFontOptions !== false) { + $font = $this->_defaultFontOptions; + } else { + $font = $this->_getFont(); + } + } + $this->_canvas->setFont($font); + + $value = false; + $maxSize = 0; + while (($value = $this->_getNextLabel($value, $level)) !== false) { + if ((abs($value) > 0.0001) && ($value > $this->_getMinimum()) && + ($value < $this->_getMaximum())) + { + if (is_object($this->_dataPreProcessor)) { + $labelText = $this->_dataPreProcessor->_process($value); + } elseif (isset($labelOptions['format'])) { + $labelText = sprintf($labelOptions['format'], $value); + } elseif (isset($labelOptions['dateformat'])) { + $labelText = date($labelOptions['dateformat'], $value); + } else { + $labelText = $value; + } + + if ((($this->_type == IMAGE_GRAPH_AXIS_X) && (!$this->_transpose)) || + (($this->_type != IMAGE_GRAPH_AXIS_X) && ($this->_transpose))) + { + $maxSize = max($maxSize, $this->_canvas->textHeight($labelText)); + } else { + $maxSize = max($maxSize, $this->_canvas->textWidth($labelText)); + } + } + } + if ((isset($labelOptions['showoffset'])) && ($labelOptions['showoffset'] === true)) { + $totalMaxSize += $maxSize; + } else { + $totalMaxSize = max($totalMaxSize, $maxSize); + } + } + } + + if ($this->_title) { + $this->_canvas->setFont($this->_getTitleFont()); + + if ((($this->_type == IMAGE_GRAPH_AXIS_X) && (!$this->_transpose)) || + (($this->_type != IMAGE_GRAPH_AXIS_X) && ($this->_transpose))) + { + $totalMaxSize += $this->_canvas->textHeight($this->_title); + } else { + $totalMaxSize += $this->_canvas->textWidth($this->_title); + } + $totalMaxSize += 10; + } + + return $totalMaxSize + 3; + } + + /** + * Adds a mark to the axis at the specified value + * + * @param double $value The value + * @param double $value2 The second value (for a ranged mark) + */ + function addMark($value, $value2 = false, $text = false) + { + if ($value2 === false) { + $this->_marks[] = $value; + } else { + $this->_marks[] = array($value, $value2); + } + } + + /** + * Is the axis numeric or not? + * + * @return bool True if numeric, false if not + * @access private + */ + function _isNumeric() + { + return true; + } + + /** + * Set the major tick appearance. + * + * The positions are specified in pixels relative to the axis, meaning that + * a value of -1 for start will draw the major tick 'line' starting at 1 + * pixel outside (negative) value the axis (i.e. below an x-axis and to the + * left of a normal y-axis). + * + * @param int $start The start position relative to the axis + * @param int $end The end position relative to the axis + * @param int $level The label level to set the tick options for + * @since 0.3.0dev2 + */ + function setTickOptions($start, $end, $level = 1) + { + if (!isset($this->_labelOptions[$level])) { + $this->_labelOptions[$level] = array(); + } + + $this->_labelOptions[$level]['tick'] = array( + 'start' => $start, + 'end' => $end + ); + } + + /** + * Invert the axis direction + * + * If the minimum values are normally displayed fx. at the bottom setting + * axis inversion to true, will cause the minimum values to be displayed at + * the top and maximum at the bottom. + * + * @param bool $invert True if the axis is to be inverted, false if not + * @since 0.3.0dev3 + */ + function setInverted($invert) + { + $this->_invert = $invert; + } + + /** + * Set axis intersection. + * + * Sets the value at which the axis intersects other axis, fx. at which Y- + * value the x-axis intersects the y-axis (normally at 0). + * + * Possible values are 'default', 'min', 'max' or a number between axis min + * and max (the value will automatically be limited to this range). + * + * For a coordinate system with 2 y-axis, the x-axis can either intersect + * the primary or the secondary y-axis. To make the x-axis intersect the + * secondary y-axis at a given value pass IMAGE_GRAPH_AXIS_Y_SECONDARY as + * second parameter. + * + * @param mixed $intersection The value at which the axis intersect the + * 'other' axis + * @param mixed $axis The axis to intersect. Only applies to x-axis with + * both a primary and secondary y-axis available. + * @since 0.3.0dev2 + */ + function setAxisIntersection($intersection, $axis = 'default') + { + if ($axis == 'x') { + $axis = IMAGE_GRAPH_AXIS_X; + } elseif ($axis == 'y') { + $axis = IMAGE_GRAPH_AXIS_Y; + } elseif ($axis == 'ysec') { + $axis = IMAGE_GRAPH_AXIS_Y_SECONDARY; + } + $this->_intersect = array( + 'value' => $intersection, + 'axis' => $axis + ); + } + + /** + * Get axis intersection data. + * + * @return array An array with the axis intersection data. + * @since 0.3.0dev2 + * @access private + */ + function _getAxisIntersection() + { + $value = $this->_intersect['value']; + $axis = $this->_intersect['axis']; + if (($this->_type == IMAGE_GRAPH_AXIS_Y) + || ($this->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY) + ) { + $axis = IMAGE_GRAPH_AXIS_X; + } elseif ($axis == 'default') { + $axis = IMAGE_GRAPH_AXIS_Y; + } + + if ($value === 'default') { + switch ($this->_type) { + case IMAGE_GRAPH_AXIS_Y: + $value = 'min'; + break; + case IMAGE_GRAPH_AXIS_Y_SECONDARY: + $value = 'max'; + break; + case IMAGE_GRAPH_AXIS_X: + $value = 0; + break; + } + } + + return array('value' => $value, 'axis' => $axis); + } + + /** + * Resets the elements + * + * @access private + */ + function _reset() + { + parent::_reset(); + $this->_labelText = array(); + } + + /** + * Output an axis tick mark. + * + * @param int $value The value to output + * @param int $level The label level to draw the tick for + * @access private + */ + function _drawTick($value, $level = 1) + { + if (isset($this->_labelOptions[$level])) { + $labelOptions = $this->_labelOptions[$level]; + $labelPosition = $this->_point($value); + + if (isset($labelOptions['offset'])) { + $offset = $labelOptions['offset']; + } else { + $offset = 0; + } + + if ((isset($labelOptions['showtext'])) && ($labelOptions['showtext'] === true)) { + if (is_object($this->_dataPreProcessor)) { + $labelText = $this->_dataPreProcessor->_process($value); + } elseif (isset($labelOptions['format'])) { + $labelText = sprintf($labelOptions['format'], $value); + } elseif (isset($labelOptions['dateformat'])) { + $labelText = date($labelOptions['dateformat'], $value); + } else { + $labelText = $value; + } + + if (!in_array($labelText, $this->_labelText)) { + $this->_labelText[] = $labelText; + + if (isset($labelOptions['font'])) { + $font = $this->_getFont($labelOptions['font']); + } else { + if ($this->_defaultFontOptions !== false) { + $font = $this->_defaultFontOptions; + } else { + $font = $this->_getFont(); + } + } + $this->_canvas->setFont($font); + + if ( + (isset($labelOptions['position'])) && + ($labelOptions['position'] == 'inside') + ) { + $labelInside = true; + } else { + $labelInside = false; + } + + if ($this->_type == IMAGE_GRAPH_AXIS_Y) { + if ($this->_transpose) { + if ($labelInside) { + $this->write( + $labelPosition, + $this->_top - 3 - $offset, + $labelText, + IMAGE_GRAPH_ALIGN_BOTTOM | IMAGE_GRAPH_ALIGN_CENTER_X, + $font + ); + } else { + $this->write( + $labelPosition, + $this->_top + 6 + $offset + $font['size'] * (substr_count($labelText, "\n") + 1), + $labelText, + IMAGE_GRAPH_ALIGN_BOTTOM | IMAGE_GRAPH_ALIGN_CENTER_X, + $font + ); + } + } + else { + if ($labelInside) { + $this->write( + $this->_right + 3 + $offset, + $labelPosition, + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, + $font + ); + } else { + $this->write( + $this->_right - 3 - $offset, + $labelPosition, + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_RIGHT, + $font + ); + } + } + } elseif ($this->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY) { + if ($this->_transpose) { + if ($labelInside) { + $this->write( + $labelPosition, + $this->_bottom + 6 + $offset + $font['size'] * (substr_count($labelText, "\n") + 1), + $labelText, + IMAGE_GRAPH_ALIGN_BOTTOM | IMAGE_GRAPH_ALIGN_CENTER_X, + $font + ); + } else { + $this->write( + $labelPosition, + $this->_bottom - 3 - $offset, + $labelText, + IMAGE_GRAPH_ALIGN_BOTTOM | IMAGE_GRAPH_ALIGN_CENTER_X, + $font + ); + } + } + else { + if ($labelInside) { + $this->write( + $this->_left - 3 - $offset, + $labelPosition, + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_RIGHT, + $font + ); + } else { + $this->write( + $this->_left + 3 + $offset, + $labelPosition, + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, + $font + ); + } + } + } else { + if ($this->_transpose) { + if ($labelInside) { + $this->write( + $this->_right + 3 + $offset, + $labelPosition, + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, + $font + ); + } else { + $this->write( + $this->_right - 3 - $offset, + $labelPosition, + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_RIGHT, + $font + ); + } + } + else { + if ($labelInside === true) { + $this->write( + $labelPosition, + $this->_top - 3 - $offset, + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_X | IMAGE_GRAPH_ALIGN_BOTTOM, + $font + ); + } else { + $this->write( + $labelPosition, + $this->_top + 6 + $offset + $font['size'] * (substr_count($labelText, "\n") + 1), + $labelText, + IMAGE_GRAPH_ALIGN_CENTER_X | IMAGE_GRAPH_ALIGN_BOTTOM, + $font + ); + } + } + } + } + } + + $tickColor = false; + if (isset($this->_labelOptions[$level]['tick'])) { + if (isset($this->_labelOptions[$level]['tick']['start'])) { + $tickStart = $this->_labelOptions[$level]['tick']['start']; + } else { + $tickStart = false; + } + + if (isset($this->_labelOptions[$level]['tick']['end'])) { + $tickEnd = $this->_labelOptions[$level]['tick']['end']; + } else { + $tickEnd = false; + } + + if ((isset($this->_labelOptions[$level]['tick']['color'])) && ($this->_labelOptions[$level]['tick']['color'] !== false)) { + $tickColor = $this->_labelOptions[$level]['tick']['color']; + } + } + + if ($tickStart === false) { + $tickStart = -2; + } + + if ($tickEnd === false) { + $tickEnd = 2; + } + + if ($tickColor !== false) { + $this->_canvas->setLineColor($tickColor); + } + else { + $this->_getLineStyle(); + } + + if ($this->_type == IMAGE_GRAPH_AXIS_Y) { + if ($tickStart === 'auto') { + $tickStart = -$offset; + } + if ($this->_transpose) { + $this->_canvas->line( + array( + 'x0' => $labelPosition, + 'y0' => $this->_top + $tickStart, + 'x1' => $labelPosition, + 'y1' => $this->_top + $tickEnd + ) + ); + } + else { + $this->_canvas->line( + array( + 'x0' => $this->_right + $tickStart, + 'y0' => $labelPosition, + 'x1' => $this->_right + $tickEnd, + 'y1' => $labelPosition + ) + ); + } + } elseif ($this->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY) { + if ($tickStart === 'auto') { + $tickStart = $offset; + } + if ($this->_transpose) { + $this->_canvas->line( + array( + 'x0' => $labelPosition, + 'y0' => $this->_bottom - $tickStart, + 'x1' => $labelPosition, + 'y1' => $this->_bottom - $tickEnd + ) + ); + } + else { + $this->_canvas->line( + array( + 'x0' => $this->_left - $tickStart, + 'y0' => $labelPosition, + 'x1' => $this->_left - $tickEnd, + 'y1' => $labelPosition + ) + ); + } + } else { + if ($tickStart === 'auto') { + $tickStart = $offset; + } + if ($this->_transpose) { + $this->_canvas->line( + array( + 'x0' => $this->_right + $tickStart, + 'y0' => $labelPosition, + 'x1' => $this->_right + $tickEnd, + 'y1' => $labelPosition + ) + ); + } + else { + $this->_canvas->line( + array( + 'x0' => $labelPosition, + 'y0' => $this->_top - $tickStart, + 'x1' => $labelPosition, + 'y1' => $this->_top - $tickEnd + ) + ); + } + } + } + } + + /** + * Draws axis lines. + * + * @access private + */ + function _drawAxisLines() + { + if ($this->_type == IMAGE_GRAPH_AXIS_X) { + $this->_getLineStyle(); + $this->_getFillStyle(); + + if ($this->_transpose) { + $data = array( + 'x0' => $this->_right, + 'y0' => $this->_top, + 'x1' => $this->_right, + 'y1' => $this->_bottom + ); + } else { + $data = array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_right, + 'y1' => $this->_top + ); + } + + if ($this->_showArrow) { + if ($this->_getMaximum() <= 0) { + $data['end0'] = 'arrow2'; + $data['size0'] = 7; + } + else { + $data['end1'] = 'arrow2'; + $data['size1'] = 7; + } + } + + $this->_canvas->line($data); + + if ($this->_title) { + if (!$this->_transpose) { + $y = $this->_bottom; + $x = $this->_left + $this->width() / 2; + $this->write($x, $y, $this->_title, IMAGE_GRAPH_ALIGN_CENTER_X + IMAGE_GRAPH_ALIGN_BOTTOM, $this->_getTitleFont()); + } + else { + $y = $this->_top + $this->height() / 2; + $x = $this->_left; + $this->write($x, $y, $this->_title, IMAGE_GRAPH_ALIGN_LEFT + IMAGE_GRAPH_ALIGN_CENTER_Y, $this->_getTitleFont()); + } + } + } elseif ($this->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY) { + $this->_getLineStyle(); + $this->_getFillStyle(); + + if ($this->_transpose) { + $data = array( + 'x0' => $this->_left, + 'y0' => $this->_bottom, + 'x1' => $this->_right, + 'y1' => $this->_bottom + ); + } else { + $data = array( + 'x0' => $this->_left, + 'y0' => $this->_bottom, + 'x1' => $this->_left, + 'y1' => $this->_top + ); + } + if ($this->_showArrow) { + if ($this->_getMaximum() <= 0) { + $data['end0'] = 'arrow2'; + $data['size0'] = 7; + } + else { + $data['end1'] = 'arrow2'; + $data['size1'] = 7; + } + } + $this->_canvas->line($data); + + if ($this->_title) { + if ($this->_transpose) { + $y = $this->_top; + $x = $this->_left + $this->width() / 2; + $this->write($x, $y, $this->_title, IMAGE_GRAPH_ALIGN_CENTER_X + IMAGE_GRAPH_ALIGN_TOP, $this->_getTitleFont()); + } + else { + $y = $this->_top + $this->height() / 2; + $x = $this->_right; + $this->write($x, $y, $this->_title, IMAGE_GRAPH_ALIGN_RIGHT + IMAGE_GRAPH_ALIGN_CENTER_Y, $this->_getTitleFont()); + } + } + } else { + $this->_getLineStyle(); + $this->_getFillStyle(); + + if ($this->_transpose) { + $data = array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_right, + 'y1' => $this->_top + ); + } else { + $data = array( + 'x0' => $this->_right, + 'y0' => $this->_bottom, + 'x1' => $this->_right, + 'y1' => $this->_top + ); + } + if ($this->_showArrow) { + if ($this->_getMaximum() <= 0) { + $data['end0'] = 'arrow2'; + $data['size0'] = 7; + } + else { + $data['end1'] = 'arrow2'; + $data['size1'] = 7; + } + } + $this->_canvas->line($data); + + if ($this->_title) { + if ($this->_transpose) { + $y = $this->_bottom; + $x = $this->_left + $this->width() / 2; + $this->write($x, $y, $this->_title, IMAGE_GRAPH_ALIGN_CENTER_X + IMAGE_GRAPH_ALIGN_BOTTOM, $this->_getTitleFont()); + } + else { + $y = $this->_top + $this->height() / 2; + $x = $this->_left; + $this->write($x, $y, $this->_title, IMAGE_GRAPH_ALIGN_LEFT + IMAGE_GRAPH_ALIGN_CENTER_Y, $this->_getTitleFont()); + } + } + } + } + + /** + * Causes the object to update all sub elements coordinates + * + * (Image_Graph_Common, does not itself have coordinates, this is basically + * an abstract method) + * + * @access private + */ + function _updateCoords() + { + parent::_updateCoords(); + $this->_calcDelta(); + } + + /** + * Output the axis + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $this->_canvas->startGroup(get_class($this)); + + if (parent::_done() === false) { + return false; + } + + $this->_drawAxisLines(); + + $this->_canvas->startGroup(get_class($this) . '_ticks'); + ksort($this->_labelOptions); + foreach ($this->_labelOptions as $level => $labelOption) { + $value = false; + while (($value = $this->_getNextLabel($value, $level)) !== false) { + if ((((abs($value) > 0.0001) || ($this->_showLabelZero)) && + (($value > $this->_getMinimum()) || ($this->_showLabelMinimum)) && + (($value < $this->_getMaximum()) || ($this->_showLabelMaximum))) && + ($value >= $this->_getMinimum()) && ($value <= $this->_getMaximum()) + ) { + $this->_drawTick($value, $level); + } + } + } + $this->_canvas->endGroup(); + + $tickStart = -3; + $tickEnd = 2; + + foreach ($this->_marks as $mark) { + if (is_array($mark)) { + if ($this->_type == IMAGE_GRAPH_AXIS_X) { + if ($this->_transpose) { + $x0 = $this->_right + $tickStart; + $y0 = $this->_point($mark[1]); + $x1 = $this->_right + $tickEnd; + $y1 = $this->_point($mark[0]); + } + else { + $x0 = $this->_point($mark[0]); + $y0 = $this->_top + $tickStart; + $x1 = $this->_point($mark[1]); + $y1 = $this->_top + $tickEnd; + } + } elseif ($this->_type == IMAGE_GRAPH_AXIS_Y) { + if ($this->_transpose) { + $x0 = $this->_point($mark[0]); + $y0 = $this->_top + $tickStart; + $x1 = $this->_point($mark[1]); + $y1 = $this->_top + $tickEnd; + } + else { + $x0 = $this->_right + $tickStart; + $y0 = $this->_point($mark[1]); + $x1 = $this->_right + $tickEnd; + $y1 = $this->_point($mark[0]); + } + } elseif ($this->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY) { + if ($this->_transpose) { + $x0 = $this->_point($mark[0]); + $y0 = $this->_bottom + $tickStart; + $x1 = $this->_point($mark[1]); + $y1 = $this->_bottom + $tickEnd; + } + else { + $x0 = $this->_left + $tickStart; + $y0 = $this->_point($mark[1]); + $x1 = $this->_left + $tickEnd; + $y1 = $this->_point($mark[0]); + } + } + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->rectangle(array('x0' => $x0, 'y0' => $y0, 'x1' => $x1, 'y1' => $y1)); + } else { + if ($this->_type == IMAGE_GRAPH_AXIS_X) { + if ($this->_transpose) { + $x0 = $this->_right + 5; + $y0 = $this->_point($mark); + $x1 = $this->_right + 15; + $y1 = $y0; + } + else { + $x0 = $this->_point($mark); + $y0 = $this->_top - 5; + $x1 = $x0; + $y1 = $this->_top - 15; + } + } elseif ($this->_type == IMAGE_GRAPH_AXIS_Y) { + if ($this->_transpose) { + $x0 = $this->_point($mark); + $y0 = $this->_top - 5; + $x1 = $x0; + $y1 = $this->_top - 15; + } + else { + $x0 = $this->_right + 5; + $y0 = $this->_point($mark); + $x1 = $this->_right + 15; + $y1 = $y0; + } + } elseif ($this->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY) { + if ($this->_transpose) { + $x0 = $this->_point($mark); + $y0 = $this->_bottom + 5; + $x1 = $x0; + $y1 = $this->_bottom + 15; + } + else { + $x0 = $this->_left - 5; + $y0 = $this->_point($mark); + $x1 = $this->_left - 15; + $y1 = $y0; + } + } + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $x0, + 'y0' => $y0, + 'x1' => $x1, + 'y1' => $y1, + 'end0' => 'arrow2', + 'size0' => 5 + ) + ); + } + } + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Axis/Category.php b/config/archive/dspam/pear/Image/Graph/Axis/Category.php new file mode 100644 index 00000000..b6451496 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Axis/Category.php @@ -0,0 +1,437 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Axis.php + */ +require_once 'Image/Graph/Axis.php'; + +/** + * A normal axis thats displays labels with a 'interval' of 1. + * This is basically a normal axis where the range is + * the number of labels defined, that is the range is explicitly defined + * when constructing the axis. + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Axis_Category extends Image_Graph_Axis +{ + + /** + * The labels shown on the axis + * @var array + * @access private + */ + var $_labels = false; + + /** + * Image_Graph_Axis_Category [Constructor]. + * + * @param int $type The type (direction) of the Axis + */ + function Image_Graph_Axis_Category($type = IMAGE_GRAPH_AXIS_X) + { + parent::Image_Graph_Axis($type); + $this->_labels = array(); + $this->setlabelInterval(1); + } + + /** + * Gets the minimum value the axis will show. + * + * This is always 0 + * + * @return double The minumum value + * @access private + */ + function _getMinimum() + { + return 0; + } + + /** + * Gets the maximum value the axis will show. + * + * This is always the number of labels passed to the constructor. + * + * @return double The maximum value + * @access private + */ + function _getMaximum() + { + return count($this->_labels) - 1; + } + + /** + * Sets the minimum value the axis will show. + * + * A minimum cannot be set on a SequentialAxis, it is always 0. + * + * @param double Minimum The minumum value to use on the axis + * @access private + */ + function _setMinimum($minimum) + { + } + + /** + * Sets the maximum value the axis will show + * + * A maximum cannot be set on a SequentialAxis, it is always the number + * of labels passed to the constructor. + * + * @param double Maximum The maximum value to use on the axis + * @access private + */ + function _setMaximum($maximum) + { + } + + /** + * Forces the minimum value of the axis + * + * A minimum cannot be set on this type of axis + * + * To modify the labels which are displayed on the axis, instead use + * setLabelInterval($labels) where $labels is an array containing the + * values/labels the axis should display. Note! Only values in + * this array will then be displayed on the graph! + * + * @param double $minimum A minimum cannot be set on this type of axis + */ + function forceMinimum($minimum, $userEnforce = true) + { + } + + /** + * Forces the maximum value of the axis + * + * A maximum cannot be set on this type of axis + * + * To modify the labels which are displayed on the axis, instead use + * setLabelInterval($labels) where $labels is an array containing the + * values/labels the axis should display. Note! Only values in + * this array will then be displayed on the graph! + * + * @param double $maximum A maximum cannot be set on this type of axis + */ + function forceMaximum($maximum, $userEnforce = true) + { + } + + /** + * Sets an interval for where labels are shown on the axis. + * + * The label interval is rounded to nearest integer value. + * + * @param double $labelInterval The interval with which labels are shown + */ + function setLabelInterval($labelInterval = 'auto', $level = 1) + { + if (is_array($labelInterval)) { + parent::setLabelInterval($labelInterval); + } elseif ($labelInterval == 'auto') { + parent::setLabelInterval(1); + } else { + parent::setLabelInterval(round($labelInterval)); + } + } + + /** + * Preprocessor for values, ie for using logarithmic axis + * + * @param double $value The value to preprocess + * @return double The preprocessed value + * @access private + */ + function _value($value) + { +// $the_value = array_search($value, $this->_labels); + if (isset($this->_labels[$value])) { + $the_value = $this->_labels[$value]; + if ($the_value !== false) { + return $the_value + ($this->_pushValues ? 0.5 : 0); + } else { + return 0; + } + } + } + + + /** + * Get the minor label interval with which axis label ticks are drawn. + * + * For a sequential axis this is always disabled (i.e false) + * + * @return double The minor label interval, always false + * @access private + */ + function _minorLabelInterval() + { + return false; + } + + /** + * Get the size in pixels of the axis. + * + * For an x-axis this is the width of the axis including labels, and for an + * y-axis it is the corrresponding height + * + * @return int The size of the axis + * @access private + */ + function _size() + { + if (!$this->_visible) { + return 0; + } + + $this->_canvas->setFont($this->_getFont()); + + $maxSize = 0; + foreach($this->_labels as $label => $id) { + $labelPosition = $this->_point($label); + + if (is_object($this->_dataPreProcessor)) { + $labelText = $this->_dataPreProcessor->_process($label); + } else { + $labelText = $label; + } + + if ((($this->_type == IMAGE_GRAPH_AXIS_X) && (!$this->_transpose)) || + (($this->_type != IMAGE_GRAPH_AXIS_X) && ($this->_transpose))) + { + $maxSize = max($maxSize, $this->_canvas->textHeight($labelText)); + } else { + $maxSize = max($maxSize, $this->_canvas->textWidth($labelText)); + } + } + + if ($this->_title) { + $this->_canvas->setFont($this->_getTitleFont()); + + if ((($this->_type == IMAGE_GRAPH_AXIS_X) && (!$this->_transpose)) || + (($this->_type != IMAGE_GRAPH_AXIS_X) && ($this->_transpose))) + { + $maxSize += $this->_canvas->textHeight($this->_title); + } else { + $maxSize += $this->_canvas->textWidth($this->_title); + } + $maxSize += 10; + } + return $maxSize +3; + } + + /** + * Apply the dataset to the axis. + * + * This calculates the order of the categories, which is very important + * for fx. line plots, so that the line does not "go backwards", consider + * these X-sets:

+ * 1: (1, 2, 3, 4, 5, 6)
+ * 2: (0, 1, 2, 3, 4, 5, 6, 7)

+ * If they are not ordered, but simply appended, the categories on the axis + * would be:

+ * X: (1, 2, 3, 4, 5, 6, 0, 7)

+ * Which would render the a line for the second plot to show incorrectly. + * Instead this algorithm, uses and 'value- is- before' method to see that + * the 0 is before a 1 in the second set, and that it should also be before + * a 1 in the X set. Hence:

+ * X: (0, 1, 2, 3, 4, 5, 6, 7) + * + * @param Image_Graph_Dataset $dataset The dataset + * @access private + */ + function _applyDataset(&$dataset) + { + $newLabels = array(); + $allLabels = array(); + + $dataset->_reset(); + $count = 0; + $count_new = 0; + while ($point = $dataset->_next()) { + if ($this->_type == IMAGE_GRAPH_AXIS_X) { + $data = $point['X']; + } else { + $data = $point['Y']; + } + if (!isset($this->_labels[$data])) { + $newLabels[$data] = $count_new++; + //$this->_labels[] = $data; + } + $allLabels[$data] = $count++; + } + + if (count($this->_labels) == 0) { + $this->_labels = $newLabels; + } elseif ((is_array($newLabels)) && (count($newLabels) > 0)) { + // get all intersecting labels + $intersect = array_intersect(array_keys($allLabels), array_keys($this->_labels)); + // traverse all new and find their relative position withing the + // intersec, fx value X0 is before X1 in the intersection, which + // means that X0 should be placed before X1 in the label array + foreach($newLabels as $newLabel => $id) { + $key = $allLabels[$newLabel]; + reset($intersect); + $this_value = false; + // intersect indexes are the same as in allLabels! + $first = true; + while ((list($id, $value) = each($intersect)) && + ($this_value === false)) + { + if (($first) && ($id > $key)) { + $this_value = $value; + } elseif ($id >= $key) { + $this_value = $value; + } + $first = false; + } + + if ($this_value === false) { + // the new label was not found before anything in the + // intersection -> append it + $this->_labels[$newLabel] = count($this->_labels); + } else { + // the new label was found before $this_value in the + // intersection, insert the label before this position in + // the label array +// $key = $this->_labels[$this_value]; + $keys = array_keys($this->_labels); + $key = array_search($this_value, $keys); + $pre = array_slice($keys, 0, $key); + $pre[] = $newLabel; + $post = array_slice($keys, $key); + $this->_labels = array_flip(array_merge($pre, $post)); + } + } + unset($keys); + } + + $labels = array_keys($this->_labels); + $i = 0; + foreach ($labels as $label) { + $this->_labels[$label] = $i++; + } + +// $this->_labels = array_values(array_unique($this->_labels)); + $this->_calcLabelInterval(); + } + + /** + * Return the label distance. + * + * @return int The distance between 2 adjacent labels + * @access private + */ + function _labelDistance($level = 1) + { + reset($this->_labels); + list($l1) = each($this->_labels); + list($l2) = each($this->_labels); + return abs($this->_point($l2) - $this->_point($l1)); + } + + /** + * Get next label point + * + * @param doubt $point The current point, if omitted or false, the first is + * returned + * @return double The next label point + * @access private + */ + function _getNextLabel($currentLabel = false, $level = 1) + { + if ($currentLabel === false) { + reset($this->_labels); + } + $result = false; + $count = ($currentLabel === false ? $this->_labelInterval() - 1 : 0); + while ($count < $this->_labelInterval()) { + $result = (list($label) = each($this->_labels)); + $count++; + } + if ($result) { + return $label; + } else { + return false; + } + } + + /** + * Is the axis numeric or not? + * + * @return bool True if numeric, false if not + * @access private + */ + function _isNumeric() + { + return false; + } + + /** + * Output the axis + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $result = true; + if (Image_Graph_Element::_done() === false) { + $result = false; + } + + $this->_canvas->startGroup(get_class($this)); + + $this->_drawAxisLines(); + + $this->_canvas->startGroup(get_class($this) . '_ticks'); + $label = false; + while (($label = $this->_getNextLabel($label)) !== false) { + $this->_drawTick($label); + } + $this->_canvas->endGroup(); + + $this->_canvas->endGroup(); + + return $result; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Axis/Logarithmic.php b/config/archive/dspam/pear/Image/Graph/Axis/Logarithmic.php new file mode 100644 index 00000000..2675ee4c --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Axis/Logarithmic.php @@ -0,0 +1,152 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Axis.php + */ +require_once 'Image/Graph/Axis.php'; + +/** + * Diplays a logarithmic axis (either X- or Y-axis). + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Axis_Logarithmic extends Image_Graph_Axis +{ + + /** + * Image_Graph_AxisLogarithmic [Constructor]. + * + * Normally a manual creation should not be necessary, axis are + * created automatically by the {@link Image_Graph_Plotarea} constructor + * unless explicitly defined otherwise + * + * @param int $type The type (direction) of the Axis, use IMAGE_GRAPH_AXIS_X + * for an X-axis (default, may be omitted) and IMAGE_GRAPH_AXIS_Y for Y- + * axis) + */ + function Image_Graph_Axis_Logarithmic($type = IMAGE_GRAPH_AXIS_X) + { + parent::Image_Graph_Axis($type); + $this->showLabel(IMAGE_GRAPH_LABEL_MINIMUM + IMAGE_GRAPH_LABEL_MAXIMUM); + $this->_minimum = 1; + $this->_minimumSet = true; + } + + /** + * Calculate the label interval + * + * If explicitly defined this will be calucated to an approximate best. + * + * @return double The label interval + * @access private + */ + function _calcLabelInterval() + { + $result = parent::_calcLabelInterval(); + $this->_axisValueSpan = $this->_value($this->_axisSpan); + return $result; + } + + /** + * Preprocessor for values, ie for using logarithmic axis + * + * @param double $value The value to preprocess + * @return double The preprocessed value + * @access private + */ + function _value($value) + { + return log10($value) - log10($this->_minimum); + } + + /** + * Get next label point + * + * @param doubt $point The current point, if omitted or false, the first is + * returned + * @return double The next label point + * @access private + */ + function _getNextLabel($currentLabel = false, $level = 1) + { + if (is_array($this->_labelOptions[$level]['interval'])) { + return parent::_getNextLabel($currentLabel, $level); + } + + if ($currentLabel !== false) { + $value = log10($currentLabel); + $base = floor($value); + $frac = $value - $base; + for ($i = 2; $i < 10; $i++) { + if ($frac <= (log10($i)-0.01)) { + $label = pow(10, $base)*$i; + if ($label > $this->_getMaximum()) { + return false; + } else { + return $label; + } + } + } + return pow(10, $base+1); + } + + return max(1, $this->_minimum); + } + + /** + * Get the axis intersection pixel position + * + * This is only to be called prior to output! I.e. between the user + * invokation of Image_Graph::done() and any actual output is performed. + * This is because it can change the axis range. + * + * @param double $value the intersection value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _intersectPoint($value) + { + if (($value <= 0) && ($value !== 'max') && ($value !== 'min')) { + $value = 1; + } + return parent::_intersectPoint($value); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Axis/Marker/Area.php b/config/archive/dspam/pear/Image/Graph/Axis/Marker/Area.php new file mode 100644 index 00000000..1931ab48 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Axis/Marker/Area.php @@ -0,0 +1,156 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Grid.php + */ +require_once 'Image/Graph/Grid.php'; + +/** + * Display a grid + * + * {@link Image_Graph_Grid} + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Axis_Marker_Area extends Image_Graph_Grid +{ + + /** + * The lower bound + * @var double + * @access private + */ + var $_lower = false; + + /** + * The upper bound + * @var double + * @access private + */ + var $_upper = false; + + /** + * [Constructor] + */ + function Image_Graph_Axis_Marker_Area() + { + parent::Image_Graph_Grid(); + $this->_lineStyle = false; + } + + /** + * Sets the lower bound of the area (value on the axis) + * + * @param double $lower the lower bound + */ + function setLowerBound($lower) + { + $this->_lower = $lower; + } + + /** + * Sets the upper bound of the area (value on the axis) + * + * @param double $upper the upper bound + */ + function setUpperBound($upper) + { + $this->_upper = $upper; + } + + /** + * Output the grid + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!$this->_primaryAxis) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $i = 0; + + $this->_lower = max($this->_primaryAxis->_getMinimum(), $this->_lower); + $this->_upper = min($this->_primaryAxis->_getMaximum(), $this->_upper); + + $secondaryPoints = $this->_getSecondaryAxisPoints(); + + reset($secondaryPoints); + list ($id, $previousSecondaryValue) = each($secondaryPoints); + while (list ($id, $secondaryValue) = each($secondaryPoints)) { + if ($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_X) { + $p1 = array ('Y' => $secondaryValue, 'X' => $this->_lower); + $p2 = array ('Y' => $previousSecondaryValue, 'X' => $this->_lower); + $p3 = array ('Y' => $previousSecondaryValue, 'X' => $this->_upper); + $p4 = array ('Y' => $secondaryValue, 'X' => $this->_upper); + } else { + $p1 = array ('X' => $secondaryValue, 'Y' => $this->_lower); + $p2 = array ('X' => $previousSecondaryValue, 'Y' => $this->_lower); + $p3 = array ('X' => $previousSecondaryValue, 'Y' => $this->_upper); + $p4 = array ('X' => $secondaryValue, 'Y' => $this->_upper); + } + + $this->_canvas->addVertex(array('x' => $this->_pointX($p1), 'y' => $this->_pointY($p1))); + $this->_canvas->addVertex(array('x' => $this->_pointX($p2), 'y' => $this->_pointY($p2))); + $this->_canvas->addVertex(array('x' => $this->_pointX($p3), 'y' => $this->_pointY($p3))); + $this->_canvas->addVertex(array('x' => $this->_pointX($p4), 'y' => $this->_pointY($p4))); + + $previousSecondaryValue = $secondaryValue; + + $this->_getLineStyle(); + $this->_getFillStyle(); + $this->_canvas->polygon(array('connect' => true)); + } + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Axis/Marker/Line.php b/config/archive/dspam/pear/Image/Graph/Axis/Marker/Line.php new file mode 100644 index 00000000..0c46c144 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Axis/Marker/Line.php @@ -0,0 +1,124 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Grid.php + */ +require_once 'Image/Graph/Grid.php'; + +/** + * Display a grid + * + * {@link Image_Graph_Grid} + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Axis_Marker_Line extends Image_Graph_Grid +{ + + /** + * The value + * @var double + * @access private + */ + var $_value = false; + + /** + * Sets the value of the line marker (value on the axis) + * + * @param double $value the value + */ + function setValue($value) + { + $this->_value = $value; + } + + /** + * Output the grid + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!$this->_primaryAxis) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $i = 0; + + $this->_value = min($this->_primaryAxis->_getMaximum(), max($this->_primaryAxis->_getMinimum(), $this->_value)); + + $secondaryPoints = $this->_getSecondaryAxisPoints(); + + reset($secondaryPoints); + list ($id, $previousSecondaryValue) = each($secondaryPoints); + while (list ($id, $secondaryValue) = each($secondaryPoints)) { + if ($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_X) { + $p1 = array ('X' => $this->_value, 'Y' => $secondaryValue); + $p2 = array ('X' => $this->_value, 'Y' => $previousSecondaryValue); + } else { + $p1 = array ('X' => $secondaryValue, 'Y' => $this->_value); + $p2 = array ('X' => $previousSecondaryValue, 'Y' => $this->_value); + } + + $x1 = $this->_pointX($p1); + $y1 = $this->_pointY($p1); + $x2 = $this->_pointX($p2); + $y2 = $this->_pointY($p2); + + $previousSecondaryValue = $secondaryValue; + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x1, 'y0' => $y1, 'x1' => $x2, 'y1' => $y2)); + } + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Axis/Radar.php b/config/archive/dspam/pear/Image/Graph/Axis/Radar.php new file mode 100644 index 00000000..7348254c --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Axis/Radar.php @@ -0,0 +1,204 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Axis/Category.php + */ +require_once 'Image/Graph/Axis/Category.php'; + +/** + * Displays an 'X'-axis in a radar plot chart. + * + * This axis maps the number of elements in the dataset to a angle (from 0- + * 360 degrees). Displaying the axis consist of drawing a number of lines from + * center to the edge of the 'circle' than encloses the radar plot. The labels + * are drawn on the 'ends' of these radial lines. + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Axis_Radar extends Image_Graph_Axis_Category +{ + + /** + * Specifies the number of pixels, the labels is offsetted from the end of + * the axis + * + * @var int + * @access private + */ + var $_distanceFromEnd = 5; + + /** + * Gets the minimum value the axis will show. + * + * This is always 0 + * + * @return double The minumum value + * @access private + */ + function _getMinimum() + { + return 0; + } + + /** + * Gets the maximum value the axis will show. + * + * This is always the number of labels passed to the constructor. + * + * @return double The maximum value + * @access private + */ + function _getMaximum() + { + return count($this->_labels); + } + + /** + * Calculate the delta value (the number of pixels representing one unit + * on the axis) + * + * @return double The label interval + * @access private + */ + function _calcDelta() + { + if (abs($this->_getMaximum() - $this->_getMinimum()) == 0) { + $this->_delta = false; + } else { + $this->_delta = 360 / ($this->_getMaximum() - $this->_getMinimum()); + } + } + + /** + * Get the pixel position represented by a value on the canvas + * + * @param double $value the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _point($value) + { + return (90 + (int) ($this->_value($value) * $this->_delta)) % 360; + } + + /** + * Get the size in pixels of the axis. + * + * For a radar plot this is always 0 + * + * @return int The size of the axis + * @access private + */ + function _size() + { + return 0; + } + + /** + * Sets the distance from the end of the category lines to the label. + * + * @param int $distance The distance in pixels + */ + function setDistanceFromEnd($distance = 5) + { + $this->_distanceFromEnd = $distance; + } + + /** + * Draws axis lines. + * + * @access private + */ + function _drawAxisLines() + { + } + + /** + * Output an axis tick mark. + * + * @param int $value The value to output + * @access private + */ + function _drawTick($value, $level = 1) + { + $centerX = (int) (($this->_left + $this->_right) / 2); + $centerY = (int) (($this->_top + $this->_bottom) / 2); + + $radius = min($this->height(), $this->width()) / 2; + + $endPoint = array ('X' => $value, 'Y' => '#max#'); + $dX = $this->_pointX($endPoint); + $dY = $this->_pointY($endPoint); + + $offX = ($dX - $centerX); + $offY = ($dY - $centerY); + + $hyp = sqrt($offX*$offX + $offY*$offY); + if ($hyp != 0) { + $scale = $this->_distanceFromEnd / $hyp; + } else { + $scale = 1; + } + + $adX = $dX + $offX * $scale; + $adY = $dY + $offY * $scale; + + if (is_object($this->_dataPreProcessor)) { + $labelText = $this->_dataPreProcessor->_process($value); + } else { + $labelText = $value; + } + + if ((abs($dX - $centerX) < 1.5) && ($dY < $centerY)) { + $align = IMAGE_GRAPH_ALIGN_BOTTOM + IMAGE_GRAPH_ALIGN_CENTER_X; + } elseif ((abs($dX - $centerX) < 1.5) && ($dY > $centerY)) { + $align = IMAGE_GRAPH_ALIGN_TOP + IMAGE_GRAPH_ALIGN_CENTER_X; + } elseif ($dX < $centerX) { + $align = IMAGE_GRAPH_ALIGN_RIGHT + IMAGE_GRAPH_ALIGN_CENTER_Y; + } else { + $align = IMAGE_GRAPH_ALIGN_LEFT + IMAGE_GRAPH_ALIGN_CENTER_Y; + } + $this->write($adX, $adY, $labelText, $align); + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $centerX, 'y0' => $centerY, 'x1' => $dX, 'y1' => $dY)); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Common.php b/config/archive/dspam/pear/Image/Graph/Common.php new file mode 100644 index 00000000..f695cb58 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Common.php @@ -0,0 +1,313 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +if (!function_exists('is_a')) { + + /** + * Check if an object is of a given class, this function is available as of PHP 4.2.0, so if it exist it will not be declared + * + * @link http://www.php.net/manual/en/function.is-a.php PHP.net Online Manual for function is_a() + * @param object $object The object to check class for + * @param string $class_name The name of the class to check the object for + * @return bool Returns TRUE if the object is of this class or has this class as one of its parents + */ + function is_a($object, $class_name) + { + if (empty ($object)) { + return false; + } + $object = is_object($object) ? get_class($object) : $object; + if (strtolower($object) == strtolower($class_name)) { + return true; + } + return is_a(get_parent_class($object), $class_name); + } +} + +/** + * Include file Image/Canvas.php + */ +require_once 'Image/Canvas.php'; + +/** + * The ultimate ancestor of all Image_Graph classes. + * + * This class contains common functionality needed by all Image_Graph classes. + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Common +{ + + /** + * The parent container of the current Image_Graph object + * + * @var Image_Graph_Common + * @access private + */ + var $_parent = null; + + /** + * The sub-elements of the current Image_Graph container object + * + * @var array + * @access private + */ + var $_elements; + + /** + * The canvas for output. + * + * Enables support for multiple output formats. + * + * @var Image_Canvas + * @access private + */ + var $_canvas = null; + + /** + * Is the object visible? + * + * @var bool + * @access private + */ + var $_visible = true; + + /** + * Constructor [Image_Graph_Common] + */ + function Image_Graph_Common() + { + } + + /** + * Resets the elements + * + * @access private + */ + function _reset() + { + if (is_array($this->_elements)) { + $keys = array_keys($this->_elements); + foreach ($keys as $key) { + if (is_object($this->_elements[$key])) { + $this->_elements[$key]->_setParent($this); + $result =& $this->_elements[$key]->_reset(); + if (PEAR::isError($result)) { + return $result; + } + } + } + unset($keys); + } + return true; + } + + /** + * Sets the parent. The parent chain should ultimately be a GraPHP object + * + * @see Image_Graph_Common + * @param Image_Graph_Common $parent The parent + * @access private + */ + function _setParent(& $parent) + { + $this->_parent =& $parent; + $this->_canvas =& $this->_parent->_getCanvas(); + + if (is_array($this->_elements)) { + $keys = array_keys($this->_elements); + foreach ($keys as $key) { + if (is_object($this->_elements[$key])) { + $this->_elements[$key]->_setParent($this); + } + } + unset($keys); + } + } + + /** + * Hide the element + */ + function hide() + { + $this->_visible = false; + } + + /** + * Get the canvas + * + * @return Image_Canvas The canvas + * @access private + */ + function &_getCanvas() + { + if (($this->_canvas !== null) || ($this->_canvas !== false)) { + return $this->_canvas; + } elseif (is_a($this->_parent, 'Image_Graph_Common')) { + $this->_canvas =& $this->_parent->_getCanvas(); + return $this->_canvas; + } else { + $this->_error('Invalid canvas'); + $result = null; + return $result; + } + } + + /** + * Adds an element to the objects element list. + * + * The new Image_Graph_elements parent is automatically set. + * + * @param Image_Graph_Common $element The new Image_Graph_element + * @return Image_Graph_Common The new Image_Graph_element + */ + function &add(& $element) + { + if (!is_a($element, 'Image_Graph_Font')) { + $this->_elements[] = &$element; + } + $element->_setParent($this); + return $element; + } + + /** + * Creates an object from the class and adds it to the objects element list. + * + * Creates an object from the class specified and adds it to the objects + * element list. If only one parameter is required for the constructor of + * the class simply pass this parameter as the $params parameter, unless the + * parameter is an array or a reference to a value, in that case you must + * 'enclose' the parameter in an array. Similar if the constructor takes + * more than one parameter specify the parameters in an array. + * + * @see Image_Graph::factory() + * @param string $class The class for the object + * @param mixed $params The paramaters to pass to the constructor + * @return Image_Graph_Common The new Image_Graph_element + */ + function &addNew($class, $params = null, $additional = false) + { + include_once 'Image/Graph.php'; + $element =& Image_Graph::factory($class, $params); + if ($additional === false) { + $obj =& $this->add($element); + } else { + $obj =& $this->add($element, $additional); + } + return $obj; + } + + /** + * Shows an error message box on the canvas + * + * @param string $text The error text + * @param array $params An array containing error specific details + * @param int $error_code Error code + * @access private + */ + function _error($text, $params = false, $error_code = IMAGE_GRAPH_ERROR_GENERIC) + { + if ((is_array($params)) && (count($params) > 0)) { + foreach ($params as $name => $key) { + if (isset($parameters)) { + $parameters .= ' '; + } + else { + $parameters = ''; + } + $parameters .= $name . '=' . $key; + } + } + $error =& PEAR::raiseError( + $text . + ($error_code != IMAGE_GRAPH_ERROR_GENERIC ? ' error:' . IMAGE_GRAPH_ERROR_GENERIC : '') . + (isset($parameters) ? ' parameters:[' . $parameters . ']' : '') + ); + } + + /** + * Causes the object to update all sub elements coordinates + * + * (Image_Graph_Common, does not itself have coordinates, this is basically + * an abstract method) + * + * @access private + */ + function _updateCoords() + { + if (is_array($this->_elements)) { + $keys = array_keys($this->_elements); + foreach ($keys as $key) { + if (is_object($this->_elements[$key])) { + $this->_elements[$key]->_updateCoords(); + } + } + unset($keys); + } + return true; + } + + /** + * Causes output to canvas + * + * The last method to call. Calling Done causes output to the canvas. All + * sub elements done() method will be invoked + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (($this->_canvas == null) || (!is_a($this->_canvas, 'Image_Canvas'))) { + return false; + } + + if (is_array($this->_elements)) { + $keys = array_keys($this->_elements); + foreach ($keys as $key) { + if (($this->_elements[$key]->_visible) && ($this->_elements[$key]->_done() === false)) { + return false; + } + } + unset($keys); + } + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Config.php b/config/archive/dspam/pear/Image/Graph/Config.php new file mode 100644 index 00000000..ece8a91b --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Config.php @@ -0,0 +1,30 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Constants.php b/config/archive/dspam/pear/Image/Graph/Constants.php new file mode 100644 index 00000000..f03674ba --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Constants.php @@ -0,0 +1,225 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Font.php + */ +require_once 'Image/Graph/Font.php'; + +// Constant declarations + +/** + * Defines an X (horizontal) axis + */ +define('IMAGE_GRAPH_AXIS_X', 1); + +/** + * Defines an Y (vertical) axis + */ +define('IMAGE_GRAPH_AXIS_Y', 2); + +/** + * Defines an Y (vertical) axis + */ +define('IMAGE_GRAPH_AXIS_Y_SECONDARY', 3); + +/** + * Defines an horizontal (X) axis + */ +define('IMAGE_GRAPH_AXIS_HORIZONTAL', 1); + +/** + * Defines an vertical (Y) axis + */ +define('IMAGE_GRAPH_AXIS_VERTICAL', 2); + +/** + * Define if label should be shown for axis minimum value + */ +define('IMAGE_GRAPH_LABEL_MINIMUM', 1); + +/** + * Define if label should be shown for axis 0 (zero) value + */ +define('IMAGE_GRAPH_LABEL_ZERO', 2); + +/** + * Define if label should be shown for axis maximum value + */ +define('IMAGE_GRAPH_LABEL_MAXIMUM', 4); + +/** + * Defines a horizontal gradient fill + */ +define('IMAGE_GRAPH_GRAD_HORIZONTAL', 1); + +/** + * Defines a vertical gradient fill + */ +define('IMAGE_GRAPH_GRAD_VERTICAL', 2); + +/** + * Defines a horizontally mirrored gradient fill + */ +define('IMAGE_GRAPH_GRAD_HORIZONTAL_MIRRORED', 3); + +/** + * Defines a vertically mirrored gradient fill + */ +define('IMAGE_GRAPH_GRAD_VERTICAL_MIRRORED', 4); + +/** + * Defines a diagonal gradient fill from top-left to bottom-right + */ +define('IMAGE_GRAPH_GRAD_DIAGONALLY_TL_BR', 5); + +/** + * Defines a diagonal gradient fill from bottom-left to top-right + */ +define('IMAGE_GRAPH_GRAD_DIAGONALLY_BL_TR', 6); + +/** + * Defines a radial gradient fill + */ +define('IMAGE_GRAPH_GRAD_RADIAL', 7); + +/** + * Defines the default builtin font + */ +define('IMAGE_GRAPH_FONT', 1); + +/** + * Defines a X value should be used + */ +define('IMAGE_GRAPH_VALUE_X', 0); + +/** + * Defines a Y value should be used + */ +define('IMAGE_GRAPH_VALUE_Y', 1); + +/** + * Defines a min X% value should be used + */ +define('IMAGE_GRAPH_PCT_X_MIN', 2); + +/** + * Defines a max X% value should be used + */ +define('IMAGE_GRAPH_PCT_X_MAX', 3); + +/** + * Defines a min Y% value should be used + */ +define('IMAGE_GRAPH_PCT_Y_MIN', 4); + +/** + * Defines a max Y% value should be used + */ +define('IMAGE_GRAPH_PCT_Y_MAX', 5); + +/** + * Defines a total Y% value should be used + */ +define('IMAGE_GRAPH_PCT_Y_TOTAL', 6); + +/** + * Defines a ID value should be used + */ +define('IMAGE_GRAPH_POINT_ID', 7); + +/** + * Align text left + */ +define('IMAGE_GRAPH_ALIGN_LEFT', 0x1); + +/** + * Align text right + */ +define('IMAGE_GRAPH_ALIGN_RIGHT', 0x2); + +/** + * Align text center x (horizontal) + */ +define('IMAGE_GRAPH_ALIGN_CENTER_X', 0x4); + +/** + * Align text top + */ +define('IMAGE_GRAPH_ALIGN_TOP', 0x8); + +/** + * Align text bottom + */ +define('IMAGE_GRAPH_ALIGN_BOTTOM', 0x10); + +/** + * Align text center y (vertical) + */ +define('IMAGE_GRAPH_ALIGN_CENTER_Y', 0x20); + +/** + * Align text center (both x and y) + */ +define('IMAGE_GRAPH_ALIGN_CENTER', IMAGE_GRAPH_ALIGN_CENTER_X + IMAGE_GRAPH_ALIGN_CENTER_Y); + +/** + * Align text top left + */ +define('IMAGE_GRAPH_ALIGN_TOP_LEFT', IMAGE_GRAPH_ALIGN_TOP + IMAGE_GRAPH_ALIGN_LEFT); + +/** + * Align text top right + */ +define('IMAGE_GRAPH_ALIGN_TOP_RIGHT', IMAGE_GRAPH_ALIGN_TOP + IMAGE_GRAPH_ALIGN_RIGHT); + +/** + * Align text bottom left + */ +define('IMAGE_GRAPH_ALIGN_BOTTOM_LEFT', IMAGE_GRAPH_ALIGN_BOTTOM + IMAGE_GRAPH_ALIGN_LEFT); + +/** + * Align text bottom right + */ +define('IMAGE_GRAPH_ALIGN_BOTTOM_RIGHT', IMAGE_GRAPH_ALIGN_BOTTOM + IMAGE_GRAPH_ALIGN_RIGHT); + +/** + * Align vertical + */ +define('IMAGE_GRAPH_ALIGN_VERTICAL', IMAGE_GRAPH_ALIGN_TOP); + +/** + * Align horizontal + */ +define('IMAGE_GRAPH_ALIGN_HORIZONTAL', IMAGE_GRAPH_ALIGN_LEFT); + +// Error codes +define('IMAGE_GRAPH_ERROR_GENERIC', 0); + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor.php new file mode 100644 index 00000000..f135d539 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor.php @@ -0,0 +1,74 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Data preprocessor used for preformatting a data. + * + * A data preprocessor is used in cases where a value from a dataset or label must be + * displayed in another format or way than entered. This could for example be the need + * to display X-values as a date instead of 1, 2, 3, .. or even worse unix-timestamps. + * It could also be when a {@link Image_Graph_Marker_Value} needs to display values as percentages + * with 1 decimal digit instead of the default formatting (fx. 12.01271 -> 12.0%). + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_DataPreprocessor +{ + + /** + * Image_Graph_DataPreprocessor [Constructor]. + */ + function Image_Graph_DataPreprocessor() + { + } + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + return $value; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Array.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Array.php new file mode 100644 index 00000000..08e62378 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Array.php @@ -0,0 +1,103 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor.php + */ +require_once 'Image/Graph/DataPreprocessor.php'; + +/** + * Format data as looked up in an array. + * + * ArrayData is useful when a numercal value is to be translated to + * something thats cannot directly be calculated from this value, this could for + * example be a dataset meant to plot population of various countries. Since x- + * values are numerical and they should really be country names, but there is no + * linear correlation between the number and the name, we use an array to 'map' + * the numbers to the name, i.e. $array[0] = 'Denmark'; $array[1] = 'Sweden'; + * ..., where the indexes are the numerical values from the dataset. This is NOT + * usefull when the x-values are a large domain, i.e. to map unix timestamps to + * date-strings for an x-axis. This is because the x-axis will selecte arbitrary + * values for labels, which would in principle require the ArrayData to hold + * values for every unix timestamp. However ArrayData can still be used to solve + * such a situation, since one can use another value for X-data in the dataset + * and then map this (smaller domain) value to a date. That is we for example + * instead of using the unix-timestamp we use value 0 to represent the 1st date, + * 1 to represent the next date, etc. + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_Array extends Image_Graph_DataPreprocessor +{ + + /** + * The data label array + * @var array + * @access private + */ + var $_dataArray; + + /** + * Image_Graph_ArrayData [Constructor]. + * + * @param array $array The array to use as a lookup table + */ + function Image_Graph_DataPreprocessor_Array($array) + { + parent::Image_Graph_DataPreprocessor(); + $this->_dataArray = $array; + } + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + if ((is_array($this->_dataArray)) && (isset ($this->_dataArray[$value]))) { + return $this->_dataArray[$value]; + } else { + return $value; + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Currency.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Currency.php new file mode 100644 index 00000000..2d3b5e2f --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Currency.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor/Formatted.php + */ +require_once 'Image/Graph/DataPreprocessor/Formatted.php'; + +/** + * Format data as a currency. + * + * Uses the {@link Image_Graph_DataPreprocessor_Formatted} to represent the + * values as a currency, i.e. 10 => € 10.00 + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_Currency extends Image_Graph_DataPreprocessor_Formatted +{ + + /** + * Image_Graph_CurrencyData [Constructor]. + * + * @param string $currencySymbol The symbol representing the currency + */ + function Image_Graph_DataPreprocessor_Currency($currencySymbol) + { + parent::Image_Graph_DataPreprocessor_Formatted("$currencySymbol %0.2f"); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Date.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Date.php new file mode 100644 index 00000000..74695264 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Date.php @@ -0,0 +1,90 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor.php + */ +require_once 'Image/Graph/DataPreprocessor.php'; + +/** + * Formats Unix timestamp as a date using specified format. + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_Date extends Image_Graph_DataPreprocessor +{ + + /** + * The format of the Unix time stamp. + * See PHP + * Manual for a description + * @var string + * @access private + */ + var $_format; + + /** + * Create a DateData preprocessor [Constructor] + * + * @param string $format See {@link http://www.php.net/manual/en/function.date.php + * PHP Manual} for a description + */ + function Image_Graph_DataPreprocessor_Date($format) + { + parent::Image_Graph_DataPreprocessor(); + $this->_format = $format; + } + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + if (!$value) { + return false; + } else { + return date($this->_format, $value); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Formatted.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Formatted.php new file mode 100644 index 00000000..ff7335a0 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Formatted.php @@ -0,0 +1,90 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor.php + */ +require_once 'Image/Graph/DataPreprocessor.php'; + +/** + * Format data using a (s)printf pattern. + * + * This method is useful when data must displayed using a simple (s) printf + * pattern as described in the {@link http://www.php. net/manual/en/function. + * sprintf.php PHP manual} + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_Formatted extends Image_Graph_DataPreprocessor +{ + + /** + * A (s)printf format string. + * See {@link http://www.php.net/manual/en/function.sprintf.php PHP Manual} + * for a description + * @var string + * @access private + */ + var $_format; + + /** + * Create a (s)printf format data preprocessor + * + * @param string $format See {@link http://www.php.net/manual/en/function.sprintf.php + * PHP Manual} for a description + */ + function Image_Graph_DataPreprocessor_Formatted($format) + { + parent::Image_Graph_DataPreprocessor(); + $this->_format = $format; + } + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + return sprintf($this->_format, $value); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Function.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Function.php new file mode 100644 index 00000000..b23a718d --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Function.php @@ -0,0 +1,92 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor.php + */ +require_once 'Image/Graph/DataPreprocessor.php'; + +/** + * Formatting a value using a userdefined function. + * + * Use this method to convert/format a value to a 'displayable' lable using a (perhaps) + * more complex function. An example could be (not very applicable though) if one would + * need for values to be displayed on the reverse order, i.e. 1234 would be displayed as + * 4321, then this method can solve this by creating the function that converts the value + * and use the FunctionData datapreprocessor to make Image_Graph use this function. + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_Function extends Image_Graph_DataPreprocessor +{ + + /** + * The name of the PHP function + * @var string + * @access private + */ + var $_dataFunction; + + /** + * Create a FunctionData preprocessor + * + * @param string $function The name of the PHP function to use as + * a preprocessor, this function must take a single parameter and return a + * formatted version of this parameter + */ + function Image_Graph_DataPreprocessor_Function($function) + { + parent::Image_Graph_DataPreprocessor(); + $this->_dataFunction = $function; + } + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + $function = $this->_dataFunction; + return call_user_func($function, $value); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/NumberText.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/NumberText.php new file mode 100644 index 00000000..a7d6874e --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/NumberText.php @@ -0,0 +1,89 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor.php + */ +require_once 'Image/Graph/DataPreprocessor.php'; + +/** + * Formatting a number as its written in languages supported by Numbers_Words. + * + * Used to display values as text, i.e. 123 is displayed as one hundred and twenty three. + * Requires Numbers_Words + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_NumberText extends Image_Graph_DataPreprocessor +{ + + /** + * The language identifier + * @var string + * @access private + */ + var $_language; + + /** + * Image_Graph_NumberText [Constructor]. + * + * Supported languages see {@link http://pear.php.net/package/Numbers_Words Numbers_Words} + * + * @param string $langugage The language identifier for the language. + */ + function Image_Graph_DataPreprocessor_NumberText($language = 'en_US') + { + parent::Image_Graph_DataPreprocessor(); + $this->_language = $language; + require_once 'Numbers/Words.php'; + } + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + return Numbers_Words::toWords($value, $this->_language); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/RomanNumerals.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/RomanNumerals.php new file mode 100644 index 00000000..0bfcdb62 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/RomanNumerals.php @@ -0,0 +1,79 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor.php + */ +require_once 'Image/Graph/DataPreprocessor.php'; + +/** + * Formatting a value as a roman numerals. + * + * Values are formatted as roman numeral, i.e. 1 = I, 2 = II, 9 = IX, 2004 = MMIV. + * Requires Numbers_Roman + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_RomanNumerals extends Image_Graph_DataPreprocessor +{ + + /** + * Create a RomanNumerals preprocessor + * + * See {@link http://pear.php.net/package/Numbers_Roman Numbers_Roman} + */ + function Image_Graph_DataPreprocessor_RomanNumerals() + { + parent::Image_Graph_DataPreprocessor(); + include_once 'Numbers/Roman.php'; + } + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + return Numbers_Roman::toNumeral($value); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Sequential.php b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Sequential.php new file mode 100644 index 00000000..248f0be9 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataPreprocessor/Sequential.php @@ -0,0 +1,67 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataPreprocessor/Array.php + */ +require_once 'Image/Graph/DataPreprocessor/Array.php'; + +/** + * Formatting values using a sequential data label array, ie. returning the + * 'next label' when asked for any label. + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataPreprocessor_Sequential extends Image_Graph_DataPreprocessor_Array +{ + + /** + * Process the value + * + * @param var $value The value to process/format + * @return string The processed value + * @access private + */ + function _process($value) + { + list ($id, $value) = each($this->_dataArray); + return $value; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataSelector.php b/config/archive/dspam/pear/Image/Graph/DataSelector.php new file mode 100644 index 00000000..0a81716c --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataSelector.php @@ -0,0 +1,67 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Filter used for selecting which data to show as markers + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataSelector +{ + + /** + * Image_Graph_DataSelector [Constructor] + */ + function Image_Graph_DataSelector() + { + } + + /** + * Check if a specified value should be 'selected', ie shown as a marker + * + * @param array $values The values to check + * @return bool True if the Values should cause a marker to be shown, false if not + * @access private + */ + function _select($values) + { + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataSelector/EveryNthPoint.php b/config/archive/dspam/pear/Image/Graph/DataSelector/EveryNthPoint.php new file mode 100644 index 00000000..62581222 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataSelector/EveryNthPoint.php @@ -0,0 +1,97 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataSelector.php + */ +require_once 'Image/Graph/DataSelector.php'; + +/** + * Filter out all points except every Nth point. + * + * Use this dataselector if you have a large number of datapoints, but only want to + * show markers for a small number of them, say every 10th. + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataSelector_EveryNthPoint extends Image_Graph_DataSelector +{ + + /** + * The number of points checked + * @var int + * @access private + */ + var $_pointNum = 0; + + /** + * The number of points between every 'show', default: 10 + * @var int + * @access private + */ + var $_pointInterval = 10; + + /** + * EvertNthPoint [Constructor] + * + * @param int $pointInterval The number of points between every 'show', + * default: 10 + */ + function Image_Graph_DataSelector_EveryNthpoint($pointInterval = 10) + { + parent::Image_Graph_DataSelector(); + $this->_pointInterval = $pointInterval; + } + + /** + * Check if a specified value should be 'selected', ie shown as a marker + * + * @param array $values The values to check + * @return bool True if the Values should cause a marker to be shown, + * false if not + * @access private + */ + function _select($values) + { + $oldPointNum = $this->_pointNum; + $this->_pointNum++; + return (($oldPointNum % $this->_pointInterval) == 0); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataSelector/NoZeros.php b/config/archive/dspam/pear/Image/Graph/DataSelector/NoZeros.php new file mode 100644 index 00000000..f32b918e --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataSelector/NoZeros.php @@ -0,0 +1,68 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataSelector.php + */ +require_once 'Image/Graph/DataSelector.php'; + +/** + * Filter out all zero's. + * + * Display all Y-values as markers, except those with Y = 0 + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataSelector_NoZeros extends Image_Graph_DataSelector +{ + + /** + * Check if a specified value should be 'selected', ie shown as a marker + * + * @param array $values The values to check + * @return bool True if the Values should cause a marker to be shown, false + * if not + * @access private + */ + function _select($values) + { + return ($values['Y'] != 0); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/DataSelector/Values.php b/config/archive/dspam/pear/Image/Graph/DataSelector/Values.php new file mode 100644 index 00000000..412e6ea9 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/DataSelector/Values.php @@ -0,0 +1,90 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/DataSelector.php + */ +require_once 'Image/Graph/DataSelector.php'; + +/** + * Filter out all but the specified values. + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_DataSelector_Values extends Image_Graph_DataSelector { + + /** + * The array with values that should be included + * @var array + * @access private + */ + var $_values; + + /** + * ValueArray [Constructor] + * + * @param array $valueArray The array to use as filter (default empty) + */ + function &Image_Graph_DataSelector_Values($values) + { + parent::Image_Graph_DataSelector(); + $this->_values = $values; + } + + /** + * Sets the array to use + */ + function setValueArray($values) + { + $this->_values = $values; + } + + /** + * Check if a specified value should be 'selected', ie shown as a marker + * + * @param array $values The values to check + * @return bool True if the Values should cause a marker to be shown, false + * if not + * @access private + */ + function _select($values) + { + return ( in_array($values['Y'], $this->_values) ); + } +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Dataset.php b/config/archive/dspam/pear/Image/Graph/Dataset.php new file mode 100644 index 00000000..4c349980 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Dataset.php @@ -0,0 +1,483 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + + +/** + * Data set used to represent a data collection to plot in a chart + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Dataset +{ + + /** + * The pointer of the data set + * @var int + * @access private + */ + var $_posX = 0; + + /** + * The minimum X value of the dataset + * @var int + * @access private + */ + var $_minimumX = 0; + + /** + * The maximum X value of the dataset + * @var int + * @access private + */ + var $_maximumX = 0; + + /** + * The minimum Y value of the dataset + * @var int + * @access private + */ + var $_minimumY = 0; + + /** + * The maximum Y value of the dataset + * @var int + * @access private + */ + var $_maximumY = 0; + + /** + * The number of points in the dataset + * @var int + * @access private + */ + var $_count = 0; + + /** + * The name of the dataset, used for legending + * @var string + * @access private + */ + var $_name = ''; + + /** + * Image_Graph_Dataset [Constructor] + */ + function Image_Graph_Dataset() + { + } + + /** + * Sets the name of the data set, used for legending + * + * @param string $name The name of the dataset + */ + function setName($name) + { + $this->_name = $name; + } + + /** + * Add a point to the dataset + * + * $ID can contain either the ID of the point, i.e. 'DK', 123, 'George', etc. or it can contain + * values used for creation of the HTML image map. This is achieved using is an an associated array + * with the following values: + * + * 'url' The URL to create the link to + * + * 'alt' [optional] The alt text on the link + * + * 'target' [optional] The target of the link + * + * 'htmltags' [optional] An associated array with html tags (tag as key), fx. 'onMouseOver' => 'history.go(-1);', 'id' => 'thelink' + * + * @param int $x The X value to add + * @param int $y The Y value to add, can be omited + * @param var $ID The ID of the point + */ + function addPoint($x, $y = false, $ID = false) + { + if ($y !== null) { + if (is_array($y)) { + $maxY = max($y); + $minY = min($y); + } else { + $maxY = $y; + $minY = $y; + } + } + + if ($this->_count) { + $this->_minimumX = min($x, $this->_minimumX); + $this->_maximumX = max($x, $this->_maximumX); + if ($y !== null) { + $this->_minimumY = min($minY, $this->_minimumY); + $this->_maximumY = max($maxY, $this->_maximumY); + } + } else { + $this->_minimumX = $x; + $this->_maximumX = $x; + if ($y !== null) { + $this->_minimumY = $minY; + $this->_maximumY = $maxY; + } + } + + $this->_count++; + } + + /** + * The number of values in the dataset + * + * @return int The number of values in the dataset + */ + function count() + { + return $this->_count; + } + + /** + * Gets a X point from the dataset + * + * @param var $x The variable to return an X value from, fx in a vector + * function data set + * @return var The X value of the variable + * @access private + */ + function _getPointX($x) + { + return $x; + } + + /** + * Gets a Y point from the dataset + * + * @param var $x The variable to return an Y value from, fx in a vector + * function data set + * @return var The Y value of the variable + * @access private + */ + function _getPointY($x) + { + return $x; + } + + /** + * Gets a ID from the dataset + * + * @param var $x The variable to return an Y value from, fx in a vector + * function data set + * @return var The ID value of the variable + * @access private + */ + function _getPointID($x) + { + return false; + } + + /** + * Gets point data from the dataset + * + * @param var $x The variable to return an Y value from, fx in a vector + * function data set + * @return array The data for the point + * @access private + */ + function _getPointData($x) + { + return false; + } + + /** + * The minimum X value + * + * @return var The minimum X value + */ + function minimumX() + { + return $this->_minimumX; + } + + /** + * The maximum X value + * + * @return var The maximum X value + */ + function maximumX() + { + return $this->_maximumX; + } + + /** + * The minimum Y value + * + * @return var The minimum Y value + */ + function minimumY() + { + return $this->_minimumY; + } + + /** + * The maximum Y value + * + * @return var The maximum Y value + */ + function maximumY() + { + return $this->_maximumY; + } + + /** + * The first point + * + * @return array The last point + */ + function first() + { + return array('X' => $this->minimumX(), 'Y' => $this->minimumY()); + } + + /** + * The last point + * + * @return array The first point + */ + function last() + { + return array('X' => $this->maximumX(), 'Y' => $this->maximumY()); + } + + /** + * The minimum X value + * + * @param var $value The minimum X value + * @access private + */ + function _setMinimumX($value) + { + $this->_minimumX = $value; + } + + /** + * The maximum X value + * + * @param var $value The maximum X value + * @access private + */ + function _setMaximumX($value) + { + $this->_maximumX = $value; + } + + /** + * The minimum Y value + * + * @param var $value The minimum X value + * @access private + */ + function _setMinimumY($value) + { + $this->_minimumY = $value; + } + + /** + * The maximum Y value + * + * @param var $value The maximum X value + * @access private + */ + function _setMaximumY($value) + { + $this->_maximumY = $value; + } + + /** + * The interval between 2 adjacent X values + * + * @return var The interval + * @access private + */ + function _stepX() + { + return 1; + } + + /** + * The interval between 2 adjacent Y values + * + * @return var The interval + * @access private + */ + function _stepY() + { + return 1; + } + + /** + * Reset the intertal dataset pointer + * + * @return var The first X value + * @access private + */ + function _reset() + { + $this->_posX = $this->_minimumX; + return $this->_posX; + } + + /** + * Get a point close to the internal pointer + * + * @param int Step Number of points next to the internal pointer, negative + * Step is towards lower X values, positive towards higher X values + * @return array The point + * @access private + */ + function _nearby($step = 0) + { + $x = $this->_getPointX($this->_posX + $this->_stepX() * $step); + $y = $this->_getPointY($this->_posX + $this->_stepX() * $step); + $ID = $this->_getPointID($this->_posX + $this->_stepX() * $step); + $data = $this->_getPointData($this->_posX + $this->_stepX() * $step); + if (($x === false) || ($y === false)) { + return false; + } else { + return array ('X' => $x, 'Y' => $y, 'ID' => $ID, 'data' => $data); + } + } + + /** + * Get the next point the internal pointer refers to and advance the pointer + * + * @return array The next point + * @access private + */ + function _next() + { + if ($this->_posX > $this->_maximumX) { + return false; + } + + $x = $this->_getPointX($this->_posX); + $y = $this->_getPointY($this->_posX); + $ID = $this->_getPointID($this->_posX); + $data = $this->_getPointData($this->_posX); + $this->_posX += $this->_stepX(); + + return array ('X' => $x, 'Y' => $y, 'ID' => $ID, 'data' => $data); + } + + /** + * Get the average of the dataset's Y points + * + * @return var The Y-average across the dataset + * @access private + */ + function _averageY() + { + $posX = $this->_minimumX; + $count = 0; + $total = 0; + while ($posX < $this->_maximumX) { + $count ++; + $total += $this->_getPointY($posX); + $posX += $this->_stepX(); + } + + if ($count != 0) { + return $total / $count; + } else { + return false; + } + } + + /** + * Get the median of the array passed Y points + * + * @param array $data The data-array to get the median from + * @param int $quartile The quartile to return the median from + * @return var The Y-median across the dataset from the specified quartile + * @access private + */ + function _median($data, $quartile = 'second') + { + sort($data); + $point = (count($data) - 1) / 2; + + if ($quartile == 'first') { + $lowPoint = 0; + $highPoint = floor($point); + } elseif ($quartile == 'third') { + $lowPoint = round($point); + $highPoint = count($data) - 1; + } else { + $lowPoint = 0; + $highPoint = count($data) - 1; + } + + $point = ($lowPoint + $highPoint) / 2; + + if (floor($point) != $point) { + $point = floor($point); + return ($data[$point] + $data[($point + 1)]) / 2; + } else { + return $data[$point]; + } + } + + /** + * Get the median of the datasets Y points + * + * @param int $quartile The quartile to return the median from + * @return var The Y-median across the dataset from the specified quartile + * @access private + */ + function _medianY($quartile = 'second') + { + $pointsY = array(); + $posX = $this->_minimumX; + while ($posX <= $this->_maximumX) { + $pointsY[] = $this->_getPointY($posX); + $posX += $this->_stepX(); + } + return $this->_median($pointsY, $quartile); + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Dataset/Function.php b/config/archive/dspam/pear/Image/Graph/Dataset/Function.php new file mode 100644 index 00000000..08174b1d --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Dataset/Function.php @@ -0,0 +1,147 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Dataset.php + */ +require_once 'Image/Graph/Dataset.php'; + +/** + * Function data set, points are generated by calling an external function. + * + * The function must be a single variable function and return a the result, + * builtin functions that are fx sin() or cos(). User defined function can be + * used if they are such, i.e: function myFunction($variable) + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Dataset_Function extends Image_Graph_Dataset +{ + + /** + * The name of the function + * @var string + * @access private + */ + var $_dataFunction; + + /** + * Image_Graph_FunctionDataset [Constructor] + * + * @param double $minimumX The minimum X value + * @param double $maximumX The maximum X value + * @param string $function The name of the function, if must be a single + * parameter function like fx sin(x) or cos(x) + * @param int $points The number of points to create + */ + function Image_Graph_Dataset_Function($minimumX, $maximumX, $function, $points) + { + parent::Image_Graph_Dataset(); + $this->_minimumX = $minimumX; + $this->_maximumX = $maximumX; + $this->_dataFunction = $function; + $this->_count = $points; + $this->_calculateMaxima(); + } + + /** + * Add a point to the dataset. + * + * You can't add points to a function dataset + * + * @param int $x The X value to add + * @param int $y The Y value to add, can be omited + * @param var $ID The ID of the point + */ + function addPoint($x, $y = false, $ID = false) + { + } + + /** + * Gets a Y point from the dataset + * + * @param var $x The variable to apply the function to + * @return var The function applied to the X value + * @access private + */ + function _getPointY($x) + { + $function = $this->_dataFunction; + return $function ($x); + } + + /** + * The number of values in the dataset + * + * @return int The number of values in the dataset + * @access private + */ + function _count() + { + return $this->_count; + } + + /** + * The interval between 2 adjacent Y values + * + * @return var The interval + * @access private + */ + function _stepX() + { + return ($this->_maximumX - $this->_minimumX) / $this->_count(); + } + + /** + * Calculates the Y extrema of the function + * + * @access private + */ + function _calculateMaxima() + { + $x = $this->_minimumX; + while ($x <= $this->_maximumX) { + $y = $this->_getPointY($x); + $this->_minimumY = min($y, $this->_minimumY); + $this->_maximumY = max($y, $this->_maximumY); + $x += $this->_stepX(); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Dataset/Random.php b/config/archive/dspam/pear/Image/Graph/Dataset/Random.php new file mode 100644 index 00000000..0b2d7c68 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Dataset/Random.php @@ -0,0 +1,77 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Dataset/Trivial.php + */ +require_once 'Image/Graph/Dataset/Trivial.php'; + +/** + * Random data set, points are generated by random. + * + * This dataset is mostly (if not solely) used for demo-purposes. + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Dataset_Random extends Image_Graph_Dataset_Trivial +{ + + /** + * RandomDataset [Constructor] + * + * @param int $count The number of points to create + * @param double $minimum The minimum value the random set can be + * @param double $maximum The maximum value the random set can be + * @param bool $includeZero Whether 0 should be included or not as an X + * value, may be omitted, default: false + */ + function Image_Graph_Dataset_Random($count, $minimum, $maximum, $includeZero = false) + { + parent::Image_Graph_Dataset_Trivial(); + $i = 0; + while ($i < $count) { + $this->addPoint( + $ixc = ($includeZero ? $i : $i +1), + rand($minimum, $maximum) + ); + $i ++; + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Dataset/Sequential.php b/config/archive/dspam/pear/Image/Graph/Dataset/Sequential.php new file mode 100644 index 00000000..2605c409 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Dataset/Sequential.php @@ -0,0 +1,114 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Dataset/Trivial.php + */ +require_once 'Image/Graph/Dataset/Trivial.php'; + +/** + * Sequential data set, simply add points (y) 1 by 1. + * + * This is a single point (1D) dataset, all points are of the type (0, y1), (1, + * y2), (2, y3)... Where the X-value is implicitly incremented. This is useful + * for example for barcharts, where you could fx. use an {@link + * Image_Graph_Dataset_Array} datapreprocessor to make sence of the x-values. + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Dataset_Sequential extends Image_Graph_Dataset_Trivial +{ + + /** + * Image_Graph_SequentialDataset [Constructor] + */ + function Image_Graph_Dataset_Sequential($dataArray = false) + { + parent::Image_Graph_Dataset_Trivial(); + if (is_array($dataArray)) { + reset($dataArray); + foreach ($dataArray as $value) { + $this->addPoint($value); + } + } + } + + /** + * Add a point to the dataset + * + * @param int $y The Y value to add, can be omited + * @param var $ID The ID of the point + */ + function addPoint($y, $ID = false) + { + parent::addPoint($this->count(), $y); + } + + /** + * Gets a X point from the dataset + * + * @param var $x The variable to return an X value from, fx in a + * vector function data set + * @return var The X value of the variable + * @access private + */ + function _getPointX($x) + { + return ((int) $x); + } + + /** + * The minimum X value + * @return var The minimum X value + */ + function minimumX() + { + return 0; + } + + /** + * The maximum X value + * @return var The maximum X value + */ + function maximumX() + { + return $this->count(); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Dataset/Trivial.php b/config/archive/dspam/pear/Image/Graph/Dataset/Trivial.php new file mode 100644 index 00000000..84af1c4b --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Dataset/Trivial.php @@ -0,0 +1,260 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Dataset.php + */ +require_once 'Image/Graph/Dataset.php'; + +/** + * Trivial data set, simply add points (x, y) 1 by 1 + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Dataset_Trivial extends Image_Graph_Dataset +{ + + /** + * Data storage + * @var array + * @access private + */ + var $_data; + + /** + * Image_Graph_Dataset_Trivial [Constructor] + * + * Pass an associated array ($data[$x] = $y) to the constructor for easy + * data addition. Alternatively (if multiple entries with same x value is + * required) pass an array with (x, y) values: $data[$id] = array('x' => $x, + * 'y' => $y); + * + * NB! If passing the 1st type array at this point, the x-values will also + * be used for ID tags, i.e. when using {@link Image_Graph_Fill_Array}. In + * the 2nd type the key/index of the "outermost" array will be the id tag + * (i.e. $id in the example) + * + * @param array $dataArray An associated array with values to the dataset + */ + function Image_Graph_Dataset_Trivial($dataArray = false) + { + parent::Image_Graph_Dataset(); + $this->_data = array (); + if (is_array($dataArray)) { + reset($dataArray); + $keys = array_keys($dataArray); + foreach ($keys as $x) { + $y =& $dataArray[$x]; + if ((is_array($y)) && (isset($y['x'])) && (isset($y['y']))) { + $this->addPoint($y['x'], $y['y'], (isset($y['id']) ? $y['id'] : $x)); + } else { + $this->addPoint($x, $y, $x); + } + } + } + } + + /** + * Add a point to the dataset + * + * $ID can contain either the ID of the point, i.e. 'DK', 123, 'George', etc. or it can contain + * values used for creation of the HTML image map. This is achieved using is an an associated array + * with the following values: + * + * 'url' The URL to create the link to + * + * 'alt' [optional] The alt text on the link + * + * 'target' [optional] The target of the link + * + * 'htmltags' [optional] An associated array with html tags (tag as key), fx. 'onMouseOver' => 'history.go(-1);', 'id' => 'thelink' + * + * @param int $x The X value to add + * @param int $y The Y value to add, can be omited + * @param var $ID The ID of the point + */ + function addPoint($x, $y = false, $ID = false) + { + parent::addPoint($x, $y, $ID); + + if (is_array($ID)) { + $data = $ID; + $ID = (isset($data['id']) ? $data['id'] : false); + } else { + $data = false; + } + + $this->_data[] = array ('X' => $x, 'Y' => $y, 'ID' => $ID, 'data' => $data); + if (!is_numeric($x)) { + $this->_maximumX = count($this->_data); + } + } + + /** + * The first point + * + * @return array The last point + */ + function first() + { + reset($this->_data); + return current($this->_data); + } + + /** + * The last point + * + * @return array The first point + */ + function last() + { + return end($this->_data); + } + + /** + * Gets a X point from the dataset + * + * @param var $x The variable to return an X value from, fx in a + * vector function data set + * @return var The X value of the variable + * @access private + */ + function _getPointX($x) + { + if (isset($this->_data[$x])) { + return $this->_data[$x]['X']; + } else { + return false; + } + } + + /** + * Gets a Y point from the dataset + * + * @param var $x The variable to return an Y value from, fx in a + * vector function data set + * @return var The Y value of the variable + * @access private + */ + function _getPointY($x) + { + if (isset($this->_data[$x])) { + return $this->_data[$x]['Y']; + } else { + return false; + } + } + + /** + * Gets a ID from the dataset + * + * @param var $x The variable to return an Y value from, fx in a + * vector function data set + * @return var The ID value of the variable + * @access private + */ + function _getPointID($x) + { + if (isset($this->_data[$x])) { + return $this->_data[$x]['ID']; + } else { + return false; + } + } + + /** + * Gets point data from the dataset + * + * @param var $x The variable to return an Y value from, fx in a vector + * function data set + * @return array The data for the point + * @access private + */ + function _getPointData($x) + { + if (isset($this->_data[$x])) { + return $this->_data[$x]['data']; + } else { + return false; + } + } + + /** + * The number of values in the dataset + * + * @return int The number of values in the dataset + */ + function count() + { + return count($this->_data); + } + + /** + * Reset the intertal dataset pointer + * + * @return var The first X value + * @access private + */ + function _reset() + { + $this->_posX = 0; + return $this->_posX; + } + + /** + * Get the next point the internal pointer refers to and advance the pointer + * + * @return array The next point + * @access private + */ + function _next() + { + if ($this->_posX >= $this->count()) { + return false; + } + $x = $this->_getPointX($this->_posX); + $y = $this->_getPointY($this->_posX); + $ID = $this->_getPointID($this->_posX); + $data = $this->_getPointData($this->_posX); + $this->_posX += $this->_stepX(); + + return array('X' => $x, 'Y' => $y, 'ID' => $ID, 'data' => $data); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Dataset/VectorFunction.php b/config/archive/dspam/pear/Image/Graph/Dataset/VectorFunction.php new file mode 100644 index 00000000..4250bbc0 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Dataset/VectorFunction.php @@ -0,0 +1,185 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Dataset.php + */ +require_once 'Image/Graph/Dataset.php'; + +/** + * Vector Function data set. + * + * Points are generated by calling 2 external functions, fx. x = sin(t) and y = + * cos(t) + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Dataset_VectorFunction extends Image_Graph_Dataset +{ + + /** + * The name of the X function + * @var string + * @access private + */ + var $_functionX; + + /** + * The name of the Y function + * @var string + * @access private + */ + var $_functionY; + + /** + * The minimum of the vector function variable + * @var double + * @access private + */ + var $_minimumT; + + /** + * The maximum of the vector function variable + * @var double + * @access private + */ + var $_maximumT; + + /** + * Image_Graph_VectorFunctionDataset [Constructor] + * + * @param double $minimumT The minimum value of the vector function variable + * @param double $maximumT The maximum value of the vector function variable + * @param string $functionX The name of the X function, if must be a single + * parameter function like fx sin(x) or cos(x) + * @param string $functionY The name of the Y function, if must be a single + * parameter function like fx sin(x) or cos(x) + * @param int $points The number of points to create + */ + function Image_Graph_Dataset_VectorFunction($minimumT, $maximumT, $functionX, $functionY, $points) + { + parent::Image_Graph_Dataset(); + $this->_minimumT = $minimumT; + $this->_maximumT = $maximumT; + $this->_functionX = $functionX; + $this->_functionY = $functionY; + $this->_count = $points; + $this->_calculateMaxima(); + } + + /** + * Add a point to the dataset + * + * @param int $x The X value to add + * @param int $y The Y value to add, can be omited + * @param var $ID The ID of the point + */ + function addPoint($x, $y = false, $ID = false) + { + } + + /** + * Gets a X point from the dataset + * + * @param var $x The variable to apply the X function to + * @return var The X function applied to the X value + * @access private + */ + function _getPointX($x) + { + $functionX = $this->_functionX; + return $functionX ($x); + } + + /** + * Gets a Y point from the dataset + * + * @param var $x The variable to apply the Y function to + * @return var The Y function applied to the X value + * @access private + */ + function _getPointY($x) + { + $functionY = $this->_functionY; + return $functionY ($x); + } + + /** + * Reset the intertal dataset pointer + * + * @return var The first T value + * @access private + */ + function _reset() + { + $this->_posX = $this->_minimumT; + return $this->_posX; + } + + /** + * The interval between 2 adjacent T values + * + * @return var The interval + * @access private + */ + function _stepX() + { + return ($this->_maximumT - $this->_minimumT) / $this->count(); + } + + /** + * Calculates the X and Y extrema of the functions + * + * @access private + */ + function _calculateMaxima() + { + $t = $this->_minimumT; + while ($t <= $this->_maximumT) { + $x = $this->_getPointX($t); + $y = $this->_getPointY($t); + $this->_minimumX = min($x, $this->_minimumX); + $this->_maximumX = max($x, $this->_maximumX); + $this->_minimumY = min($y, $this->_minimumY); + $this->_maximumY = max($y, $this->_maximumY); + $t += $this->_stepX(); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Element.php b/config/archive/dspam/pear/Image/Graph/Element.php new file mode 100644 index 00000000..7c352ee5 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Element.php @@ -0,0 +1,763 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Common.php + */ +require_once 'Image/Graph/Common.php'; + +/** + * Representation of a element. + * + * The Image_Graph_Element can be drawn on the canvas, ie it has coordinates, + * {@link Image_Graph_Line}, {@link Image_Graph_Fill}, border and background - + * although not all of these may apply to all children. + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Element extends Image_Graph_Common +{ + + /** + * The leftmost pixel of the element on the canvas + * @var int + * @access private + */ + var $_left = 0; + + /** + * The topmost pixel of the element on the canvas + * @var int + * @access private + */ + var $_top = 0; + + /** + * The rightmost pixel of the element on the canvas + * @var int + * @access private + */ + var $_right = 0; + + /** + * The bottommost pixel of the element on the canvas + * @var int + * @access private + */ + var $_bottom = 0; + + /** + * Background of the element. Default: None + * @var FillStyle + * @access private + */ + var $_background = null; + + /** + * Borderstyle of the element. Default: None + * @var LineStyle + * @access private + */ + var $_borderStyle = null; + + /** + * Line style of the element. Default: None + * @var LineStyle + * @access private + */ + var $_lineStyle = 'black'; + + /** + * Fill style of the element. Default: None + * @var FillStyle + * @access private + */ + var $_fillStyle = 'white'; + + /** + * Font of the element. Default: Standard font - FONT + * @var Font + * @access private + * @see $IMAGE_GRAPH_FONT + */ + var $_font = null; + + /** + * Font options + * @var array + * @access private + */ + var $_fontOptions = array(); + + /** + * Default font options + * + * This option is included for performance reasons. The value is calculated + * before output and reused in default cases to avoid unnecessary recursive + * calls. + * + * @var array + * @access private + */ + var $_defaultFontOptions = false; + + /** + * Shadows options of the element + * @var mixed + * @access private + */ + var $_shadow = false; + + /** + * The padding displayed on the element + * @var int + * @access private + */ + var $_padding = array('left' => 0, 'top' => 0, 'right' => 0, 'bottom' => 0); + + /** + * Sets the background fill style of the element + * + * @param Image_Graph_Fill $background The background + * @see Image_Graph_Fill + */ + function setBackground(& $background) + { + if (!is_a($background, 'Image_Graph_Fill')) { + $this->_error( + 'Could not set background for ' . get_class($this) . ': ' . + get_class($background), array('background' => &$background) + ); + } else { + $this->_background =& $background; + $this->add($background); + } + } + + /** + * Shows shadow on the element + */ + function showShadow($color = 'black@0.2', $size = 5) + { + $this->_shadow = array( + 'color' => $color, + 'size' => $size + ); + } + + /** + * Sets the background color of the element. + * + * See colors.txt in the docs/ folder for a list of available named colors. + * + * @param mixed $color The color + */ + function setBackgroundColor($color) + { + $this->_background = $color; + } + + /** + * Gets the background fill style of the element + * + * @return int A GD fillstyle representing the background style + * @see Image_Graph_Fill + * @access private + */ + function _getBackground() + { + if (is_object($this->_background)) { + $this->_canvas->setFill($this->_background->_getFillStyle()); + } elseif ($this->_background != null) { + $this->_canvas->setFill($this->_background); + } else { + return false; + } + return true; + } + + /** + * Sets the border line style of the element + * + * @param Image_Graph_Line $borderStyle The line style of the border + * @see Image_Graph_Line + */ + function setBorderStyle(& $borderStyle) + { + if (!is_a($borderStyle, 'Image_Graph_Line')) { + $this->_error( + 'Could not set border style for ' . get_class($this) . ': ' . + get_class($borderStyle), array('borderstyle' => &$borderStyle) + ); + } else { + $this->_borderStyle =& $borderStyle; + $this->add($borderStyle); + } + } + + /** + * Sets the border color of the element. + * + * See colors.txt in the docs/ folder for a list of available named colors. + * @param mixed $color The color + */ + function setBorderColor($color) + { + $this->_borderStyle = $color; + } + + /** + * Gets the border line style of the element + * + * @return int A GD linestyle representing the borders line style + * @see Image_Graph_Line + * @access private + */ + function _getBorderStyle() + { + if (is_object($this->_borderStyle)) { + $result = $this->_borderStyle->_getLineStyle(); + $this->_canvas->setLineThickness($result['thickness']); + $this->_canvas->setLineColor($result['color']); + } elseif ($this->_borderStyle != null) { + $this->_canvas->setLineThickness(1); + $this->_canvas->setLineColor($this->_borderStyle); + } else { + return false; + } + return true; + } + + /** + * Sets the line style of the element + * + * @param Image_Graph_Line $lineStyle The line style of the element + * @see Image_Graph_Line + */ + function setLineStyle(& $lineStyle) + { + if (!is_object($lineStyle)) { + $this->_error( + 'Could not set line style for ' . get_class($this) . ': ' . + get_class($lineStyle), array('linestyle' => &$lineStyle) + ); + } else { + $this->_lineStyle =& $lineStyle; + $this->add($lineStyle); + } + } + + /** + * Sets the line color of the element. + * + * See colors.txt in the docs/ folder for a list of available named colors. + * + * @param mixed $color The color + */ + function setLineColor($color) + { + $this->_lineStyle = $color; + } + + /** + * Gets the line style of the element + * + * @return int A GD linestyle representing the line style + * @see Image_Graph_Line + * @access private + */ + function _getLineStyle($ID = false) + { + if (is_object($this->_lineStyle)) { + $result = $this->_lineStyle->_getLineStyle($ID); + if (is_array($result)) { + $this->_canvas->setLineThickness($result['thickness']); + $this->_canvas->setLineColor($result['color']); + } else { + $this->_canvas->setLineThickness(1); + $this->_canvas->setLineColor($result); + } + } elseif ($this->_lineStyle != null) { + $this->_canvas->setLineThickness(1); + $this->_canvas->setLineColor($this->_lineStyle); + } else { + return false; + } + return true; + } + + /** + * Sets the fill style of the element + * + * @param Image_Graph_Fill $fillStyle The fill style of the element + * @see Image_Graph_Fill + */ + function setFillStyle(& $fillStyle) + { + if (!is_a($fillStyle, 'Image_Graph_Fill')) { + $this->_error( + 'Could not set fill style for ' . get_class($this) . ': ' . + get_class($fillStyle), array('fillstyle' => &$fillStyle) + ); + } else { + $this->_fillStyle =& $fillStyle; + $this->add($fillStyle); + } + } + + /** + * Sets the fill color of the element. + * + * See colors.txt in the docs/ folder for a list of available named colors. + * + * @param mixed $color The color + */ + function setFillColor($color) + { + $this->_fillStyle = $color; + } + + + /** + * Gets the fill style of the element + * + * @return int A GD filestyle representing the fill style + * @see Image_Graph_Fill + * @access private + */ + function _getFillStyle($ID = false) + { + if (is_object($this->_fillStyle)) { + $this->_canvas->setFill($this->_fillStyle->_getFillStyle($ID)); + } elseif ($this->_fillStyle != null) { + $this->_canvas->setFill($this->_fillStyle); + } else { + return false; + } + return true; + } + + /** + * Gets the font of the element. + * + * If not font has been set, the parent font is propagated through it's + * children. + * + * @return array An associated array used for canvas + * @access private + */ + function _getFont($options = false) + { + if (($options === false) && ($this->_defaultFontOptions !== false)) { + return $this->_defaultFontOptions; + } + + if ($options === false) { + $saveDefault = true; + } else { + $saveDefault = false; + } + + if ($options === false) { + $options = $this->_fontOptions; + } else { + $options = array_merge($this->_fontOptions, $options); + } + + if ($this->_font == null) { + $result = $this->_parent->_getFont($options); + } else { + $result = $this->_font->_getFont($options); + } + + if ((isset($result['size'])) && (isset($result['size_rel']))) { + $result['size'] += $result['size_rel']; + unset($result['size_rel']); + } + + if ($saveDefault) { + $this->_defaultFontOptions = $result; + } + + return $result; + } + + /** + * Sets the font of the element + * + * @param Image_Graph_Font $font The font of the element + * @see Image_Graph_Font + */ + function setFont(& $font) + { + if (!is_a($font, 'Image_Graph_Font')) { + $this->_error('Invalid font set on ' . get_class($this)); + } else { + $this->_font =& $font; + $this->add($font); + } + } + + /** + * Sets the font size + * + * @param int $size The size of the font + */ + function setFontSize($size) + { + $this->_fontOptions['size'] = $size; + } + + /** + * Sets the font angle + * + * @param int $angle The angle of the font + */ + function setFontAngle($angle) + { + if ($angle == 'vertical') { + $this->_fontOptions['vertical'] = true; + $this->_fontOptions['angle'] = 90; + } else { + $this->_fontOptions['angle'] = $angle; + } + } + + /** + * Sets the font color + * + * @param mixed $color The color of the font + */ + function setFontColor($color) + { + $this->_fontOptions['color'] = $color; + } + + /** + * Clip the canvas to the coordinates of the element + * + * @param $enable bool Whether clipping should be enabled or disabled + * @access protected + */ + function _clip($enable) + { + $this->_canvas->setClipping( + ($enable ? + array( + 'x0' => min($this->_left, $this->_right), + 'y0' => min($this->_top, $this->_bottom), + 'x1' => max($this->_left, $this->_right), + 'y1' => max($this->_top, $this->_bottom) + ) + : false + ) + ); + } + + /** + * Sets the coordinates of the element + * + * @param int $left The leftmost pixel of the element on the canvas + * @param int $top The topmost pixel of the element on the canvas + * @param int $right The rightmost pixel of the element on the canvas + * @param int $bottom The bottommost pixel of the element on the canvas + * @access private + */ + function _setCoords($left, $top, $right, $bottom) + { + if ($left === false) { + $left = $this->_left; + } + + if ($top === false) { + $top = $this->_top; + } + + if ($right === false) { + $right = $this->_right; + } + + if ($bottom === false) { + $bottom = $this->_bottom; + } + + $this->_left = min($left, $right); + $this->_top = min($top, $bottom); + $this->_right = max($left, $right); + $this->_bottom = max($top, $bottom); + } + + /** + * Moves the element + * + * @param int $deltaX Number of pixels to move the element to the right + * (negative values move to the left) + * @param int $deltaY Number of pixels to move the element downwards + * (negative values move upwards) + * @access private + */ + function _move($deltaX, $deltaY) + { + $this->_left += $deltaX; + $this->_right += $deltaX; + $this->_top += $deltaY; + $this->_bottom += $deltaY; + } + + /** + * Sets the width of the element relative to the left side + * + * @param int $width Number of pixels the element should be in width + * @access private + */ + function _setWidth($width) + { + $this->_right = $this->_left + $width; + } + + /** + * Sets the height of the element relative to the top + * + * @param int $width Number of pixels the element should be in height + * @access private + */ + function _setHeight($height) + { + $this->_bottom = $this->_top + $height; + } + + /** + * Sets padding of the element + * + * @param mixed $padding Number of pixels the element should be padded with + * or an array of paddings (left, top, right and bottom as index) + */ + function setPadding($padding) + { + if (is_array($padding)) { + $this->_padding = array(); + $this->_padding['left'] = (isset($padding['left']) ? $padding['left'] : 0); + $this->_padding['top'] = (isset($padding['top']) ? $padding['top'] : 0); + $this->_padding['right'] = (isset($padding['right']) ? $padding['right'] : 0); + $this->_padding['bottom'] = (isset($padding['bottom']) ? $padding['bottom'] : 0); + } + else { + $this->_padding = array( + 'left' => $padding, + 'top' => $padding, + 'right' => $padding, + 'bottom' => $padding + ); + } + } + + /** + * The width of the element on the canvas + * + * @return int Number of pixels representing the width of the element + */ + function width() + { + return abs($this->_right - $this->_left) + 1; + } + + /** + * The height of the element on the canvas + * + * @return int Number of pixels representing the height of the element + */ + function height() + { + return abs($this->_bottom - $this->_top) + 1; + } + + /** + * Left boundary of the background fill area + * + * @return int Leftmost position on the canvas + * @access private + */ + function _fillLeft() + { + return $this->_left + $this->_padding['left']; + } + + /** + * Top boundary of the background fill area + * + * @return int Topmost position on the canvas + * @access private + */ + function _fillTop() + { + return $this->_top + $this->_padding['top']; + } + + /** + * Right boundary of the background fill area + * + * @return int Rightmost position on the canvas + * @access private + */ + function _fillRight() + { + return $this->_right - $this->_padding['right']; + } + + /** + * Bottom boundary of the background fill area + * + * @return int Bottommost position on the canvas + * @access private + */ + function _fillBottom() + { + return $this->_bottom - $this->_padding['bottom']; + } + + /** + * Returns the filling width of the element on the canvas + * + * @return int Filling width + * @access private + */ + function _fillWidth() + { + return $this->_fillRight() - $this->_fillLeft() + 1; + } + + /** + * Returns the filling height of the element on the canvas + * + * @return int Filling height + * @access private + */ + function _fillHeight() + { + return $this->_fillBottom() - $this->_fillTop() + 1; + } + + /** + * Draws a shadow 'around' the element + * + * Not implemented yet. + * + * @access private + */ + function _displayShadow() + { + if (is_array($this->_shadow)) { + $this->_canvas->startGroup(get_class($this) . '_shadow'); + $this->_canvas->setFillColor($this->_shadow['color']); + $this->_canvas->addVertex(array('x' => $this->_right + 1, 'y' => $this->_top + $this->_shadow['size'])); + $this->_canvas->addVertex(array('x' => $this->_right + $this->_shadow['size'], 'y' => $this->_top + $this->_shadow['size'])); + $this->_canvas->addVertex(array('x' => $this->_right + $this->_shadow['size'], 'y' => $this->_bottom + $this->_shadow['size'])); + $this->_canvas->addVertex(array('x' => $this->_left + $this->_shadow['size'], 'y' => $this->_bottom + $this->_shadow['size'])); + $this->_canvas->addVertex(array('x' => $this->_left + $this->_shadow['size'], 'y' => $this->_bottom + 1)); + $this->_canvas->addVertex(array('x' => $this->_right + 1, 'y' => $this->_bottom + 1)); + $this->_canvas->polygon(array('connect' => true)); + $this->_canvas->endGroup(); + } + } + + /** + * Writes text to the canvas. + * + * @param int $x The x position relative to alignment + * @param int $y The y position relative to alignment + * @param string $text The text + * @param int $alignmen The text alignment (both vertically and horizontally) + */ + function write($x, $y, $text, $alignment = false, $font = false) + { + if (($font === false) && ($this->_defaultFontOptions !== false)) { + $font = $this->_defaultFontOptions; + } else { + $font = $this->_getFont($font); + } + + if ($alignment === false) { + $alignment = IMAGE_GRAPH_ALIGN_LEFT + IMAGE_GRAPH_ALIGN_TOP; + } + + $align = array(); + + if (($alignment & IMAGE_GRAPH_ALIGN_TOP) != 0) { + $align['vertical'] = 'top'; + } else if (($alignment & IMAGE_GRAPH_ALIGN_BOTTOM) != 0) { + $align['vertical'] = 'bottom'; + } else { + $align['vertical'] = 'center'; + } + + if (($alignment & IMAGE_GRAPH_ALIGN_LEFT) != 0) { + $align['horizontal'] = 'left'; + } else if (($alignment & IMAGE_GRAPH_ALIGN_RIGHT) != 0) { + $align['horizontal'] = 'right'; + } else { + $align['horizontal'] = 'center'; + } + + $this->_canvas->setFont($font); + $this->_canvas->addText(array('x' => $x, 'y' => $y, 'text' => $text, 'alignment' => $align)); + } + + /** + * Output the element to the canvas + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @see Image_Graph_Common + * @access private + */ + function _done() + { + $background = $this->_getBackground(); + $border = $this->_getBorderStyle(); + if (($background) || ($border)) { + $this->_canvas->rectangle(array('x0' => $this->_left, 'y0' => $this->_top, 'x1' => $this->_right, 'y1' => $this->_bottom)); + } + + $result = parent::_done(); + + if ($this->_shadow !== false) { + $this->_displayShadow(); + } + + return $result; + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Figure/Circle.php b/config/archive/dspam/pear/Image/Graph/Figure/Circle.php new file mode 100644 index 00000000..a3f1652e --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Figure/Circle.php @@ -0,0 +1,64 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Figure/Ellipse.php + */ +require_once 'Image/Graph/Figure/Ellipse.php'; + +/** + * Circle to draw on the canvas + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Figure_Circle extends Image_Graph_Figure_Ellipse +{ + + /** + * Image_Graph_Circle [Constructor] + * + * @param int $x The center pixel of the circle on the canvas + * @param int $y The center pixel of the circle on the canvas + * @param int $radius The radius in pixels of the circle + */ + function Image_Graph_Figure_Circle($x, $y, $radius) + { + parent::Image_Graph_Ellipse($x, $y, $radius, $radius); + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Figure/Ellipse.php b/config/archive/dspam/pear/Image/Graph/Figure/Ellipse.php new file mode 100644 index 00000000..8e42f2b1 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Figure/Ellipse.php @@ -0,0 +1,97 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * Ellipse to draw on the canvas + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Figure_Ellipse extends Image_Graph_Element +{ + + /** + * Ellipse [Constructor] + * + * @param int $x The center pixel of the ellipse on the canvas + * @param int $y The center pixel of the ellipse on the canvas + * @param int $radiusX The width in pixels of the box on the canvas + * @param int $radiusY The height in pixels of the box on the canvas + */ + function Image_Graph_Figure_Ellipse($x, $y, $radiusX, $radiusY) + { + parent::Image_Graph_Element(); + $this->_setCoords($x - $radiusX, $y - $radiusY, $x + $radiusX, $y + $radiusY); + } + + /** + * Output the ellipse + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->ellipse( + array( + 'x' => ($this->_left + $this->_right) / 2, + 'y' => ($this->_top + $this->_bottom) / 2, + 'rx' => $this->width(), + 'ry' => $this->height() + ) + ); + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Figure/Polygon.php b/config/archive/dspam/pear/Image/Graph/Figure/Polygon.php new file mode 100644 index 00000000..5b78f635 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Figure/Polygon.php @@ -0,0 +1,94 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * Polygon to draw on the canvas + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Figure_Polygon extends Image_Graph_Element +{ + + /** + * Polygon vertices + * + * @var array + * @access private + */ + var $_polygon = array (); + + /** + * Add a vertex to the polygon + * + * @param int $x X-coordinate + * @param int $y Y-coordinate + */ + function addVertex($x, $y) + { + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + + /** + * Output the polygon + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->polygon(array('connect' => true)); + + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Figure/Rectangle.php b/config/archive/dspam/pear/Image/Graph/Figure/Rectangle.php new file mode 100644 index 00000000..dbca58e0 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Figure/Rectangle.php @@ -0,0 +1,96 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * Rectangle to draw on the canvas + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Figure_Rectangle extends Image_Graph_Element +{ + + /** + * Rectangle [Construcor] + * + * @param int $x The leftmost pixel of the box on the canvas + * @param int $y The topmost pixel of the box on the canvas + * @param int $width The width in pixels of the box on the canvas + * @param int $height The height in pixels of the box on the canvas + */ + function Image_Graph_Figure_Rectangle($x, $y, $width, $height) + { + parent::Image_Graph_Element(); + $this->_setCoords($x, $y, $x + $width, $y + $height); + } + + /** + * Output the box + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->rectangle( + array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_right, + 'y1' => $this->_bottom + ) + ); + + $this->_canvas->endGroup(); + + return true; + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Fill.php b/config/archive/dspam/pear/Image/Graph/Fill.php new file mode 100644 index 00000000..f1cd36d7 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Fill.php @@ -0,0 +1,63 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * Style used for filling elements. + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Fill extends Image_Graph_Common +{ + + /** + * Resets the fillstyle + * + * @access private + */ + function _reset() + { + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Fill/Array.php b/config/archive/dspam/pear/Image/Graph/Fill/Array.php new file mode 100644 index 00000000..8d0b2dfa --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Fill/Array.php @@ -0,0 +1,137 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Fill.php + */ +require_once 'Image/Graph/Fill.php'; + +/** + * A sequential array of fillstyles. + * + * This is used for filling multiple objects within the same element with + * different styles. This is done by adding multiple fillstyles to a FillArrray + * structure. The fillarray will then when requested return the 'next' fillstyle + * in sequential order. It is possible to specify ID tags to each fillstyle, + * which is used to make sure some data uses a specific fillstyle (i.e. in a + * multiple-/stackedbarchart you name the {@link Image_Graph_Dataset}s and uses + * this name as ID tag when adding the dataset's associated fillstyle to the + * fillarray. + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Fill_Array extends Image_Graph_Fill +{ + + /** + * The fill array + * @var array + * @access private + */ + var $_fillStyles = array (); + + /** + * Resets the fillstyle + * + * @access private + */ + function _reset() + { + reset($this->_fillStyles); + } + + /** + * Add a fill style to the array + * + * @param Image_Graph_Fill $style The style to add + * @param string $id The id or name of the style + */ + function &add(& $style, $id = '') + { + if ($id == '') { + $this->_fillStyles[] =& $style; + } else { + $this->_fillStyles[$id] =& $style; + } + reset($this->_fillStyles); + return $style; + } + + /** + * Add a color to the array + * + * @param int $color The color + * @param string $id The id or name of the color + */ + function addColor($color, $id = false) + { + if ($id !== false) { + $this->_fillStyles[$id] = $color; + } else { + $this->_fillStyles[] = $color; + } + reset($this->_fillStyles); + } + + /** + * Return the fillstyle + * + * @return int A GD fillstyle + * @access private + */ + function _getFillStyle($ID = false) + { + if (($ID === false) || (!isset($this->_fillStyles[$ID]))) { + $ID = key($this->_fillStyles); + if (!next($this->_fillStyles)) { + reset($this->_fillStyles); + } + } + $fillStyle =& $this->_fillStyles[$ID]; + + if (is_object($fillStyle)) { + return $fillStyle->_getFillStyle($ID); + } elseif ($fillStyle !== null) { + return $fillStyle; + } else { + return parent::_getFillStyle($ID); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Fill/Gradient.php b/config/archive/dspam/pear/Image/Graph/Fill/Gradient.php new file mode 100644 index 00000000..9cf23a6b --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Fill/Gradient.php @@ -0,0 +1,149 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Fill/Image.php + */ +require_once 'Image/Graph/Fill/Image.php'; + +/** + * Fill using a gradient color. + * This creates a scaled fillstyle with colors flowing gradiently between 2 + * specified RGB values. Several directions are supported: + * + * 1 Vertically (IMAGE_GRAPH_GRAD_VERTICAL) + * + * 2 Horizontally (IMAGE_GRAPH_GRAD_HORIZONTAL) + * + * 3 Mirrored vertically (the color grades from a- b-a vertically) + * (IMAGE_GRAPH_GRAD_VERTICAL_MIRRORED) + * + * 4 Mirrored horizontally (the color grades from a-b-a horizontally) + * IMAGE_GRAPH_GRAD_HORIZONTAL_MIRRORED + * + * 5 Diagonally from top-left to right-bottom + * (IMAGE_GRAPH_GRAD_DIAGONALLY_TL_BR) + * + * 6 Diagonally from bottom-left to top-right + * (IMAGE_GRAPH_GRAD_DIAGONALLY_BL_TR) + * + * 7 Radially (concentric circles in the center) (IMAGE_GRAPH_GRAD_RADIAL) + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Fill_Gradient extends Image_Graph_Fill //Image_Graph_Fill_Image +{ + + /** + * The direction of the gradient + * @var int + * @access private + */ + var $_direction; + + /** + * The first color to gradient + * @var mixed + * @access private + */ + var $_startColor; + + /** + * The last color to gradient + * @var mixed + * @access private + */ + var $_endColor; + + /** + * Image_Graph_GradientFill [Constructor] + * + * @param int $direction The direction of the gradient + * @param mixed $startColor The value of the starting color + * @param mixed $endColor The value of the ending color + */ + function Image_Graph_Fill_Gradient($direction, $startColor, $endColor) + { + parent::Image_Graph_Fill(); + $this->_direction = $direction; + $this->_startColor = $startColor; + $this->_endColor = $endColor; + } + + /** + * Return the fillstyle + * + * @return int A GD fillstyle + * @access private + */ + function _getFillStyle($ID = false) + { + switch ($this->_direction) { + case IMAGE_GRAPH_GRAD_HORIZONTAL: + $direction = 'horizontal'; + break; + case IMAGE_GRAPH_GRAD_VERTICAL: + $direction = 'vertical'; + break; + case IMAGE_GRAPH_GRAD_HORIZONTAL_MIRRORED: + $direction = 'horizontal_mirror'; + break; + case IMAGE_GRAPH_GRAD_VERTICAL_MIRRORED: + $direction = 'vertical_mirror'; + break; + case IMAGE_GRAPH_GRAD_DIAGONALLY_TL_BR: + $direction = 'diagonal_tl_br'; + break; + case IMAGE_GRAPH_GRAD_DIAGONALLY_BL_TR: + $direction = 'diagonal_bl_tr'; + break; + case IMAGE_GRAPH_GRAD_RADIAL: + $direction = 'radial'; + break; + } + + return array( + 'type' => 'gradient', + 'start' => $this->_startColor, + 'end' => $this->_endColor, + 'direction' => $direction + ); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Fill/Image.php b/config/archive/dspam/pear/Image/Graph/Fill/Image.php new file mode 100644 index 00000000..9b1fb142 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Fill/Image.php @@ -0,0 +1,97 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Fill.php + */ +require_once 'Image/Graph/Fill.php'; + +/** + * Fill using an image. + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Fill_Image extends Image_Graph_Fill +{ + + /** + * The file name + * @var stirng + * @access private + */ + var $_filename; + + /** + * The GD Image resource + * @var resource + * @access private + */ + var $_image; + + /** + * Resize the image to the bounding box of the area to fill + * @var bool + * @access private + */ + var $_resize = true; + + /** + * Image_Graph_ImageFill [Constructor] + * + * @param string $filename The filename and path of the image to use for filling + */ + function Image_Graph_Fill_Image($filename) + { + parent::Image_Graph_Fill(); + $this->_filename = $filename; + } + + /** + * Return the fillstyle + * + * @param (something) $ID (Add description) + * @return int A GD fillstyle + * @access private + */ + function _getFillStyle($ID = false) + { + return $this->_filename; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Font.php b/config/archive/dspam/pear/Image/Graph/Font.php new file mode 100644 index 00000000..ad018a27 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Font.php @@ -0,0 +1,158 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Common.php + */ +require_once 'Image/Graph/Common.php'; + +/** + * A font. + * + * @category Images + * @package Image_Graph + * @subpackage Text + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Font extends Image_Graph_Common +{ + + /** + * The name of the font + * @var string + * @access private + */ + var $_name = false; + + /** + * The angle of the output + * @var int + * @access private + */ + var $_angle = false; + + /** + * The size of the font + * @var int + * @access private + */ + var $_size = 11; + + /** + * The color of the font + * @var Color + * @access private + */ + var $_color = 'black'; + + /** + * Image_Graph_Font [Constructor] + */ + function Image_Graph_Font($name = false, $size = false) + { + parent::Image_Graph_Common(); + if ($name !== false) { + $this->_name = $name; + } + if ($size !== false) { + $this->_size = $size; + } + } + + /** + * Set the color of the font + * + * @param mixed $color The color object of the Font + */ + function setColor($color) + { + $this->_color = $color; + } + + /** + * Set the angle slope of the output font. + * + * 0 = normal, 90 = bottom and up, 180 = upside down, 270 = top and down + * + * @param int $angle The angle in degrees to slope the text + */ + function setAngle($angle) + { + $this->_angle = $angle; + } + + /** + * Set the size of the font + * + * @param int $size The size in pixels of the font + */ + function setSize($size) + { + $this->_size = $size; + } + + /** + * Get the font 'array' + * + * @return array The font 'summary' to pass to the canvas + * @access private + */ + function _getFont($options = false) + { + if ($options === false) { + $options = array(); + } + + if ($this->_name !== false) { + $options['name'] = $this->_name; + } + + if (!isset($options['color'])) { + $options['color'] = $this->_color; + } + + if (!isset($options['size'])) { + $options['size'] = $this->_size; + } + + if ((!isset($options['angle'])) && ($this->_angle !== false)) { + $options['angle'] = $this->_angle; + } + return $options; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Grid.php b/config/archive/dspam/pear/Image/Graph/Grid.php new file mode 100644 index 00000000..4406dbdd --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Grid.php @@ -0,0 +1,175 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * A grid displayed on the plotarea. + * + * A grid is associated with a primary and a secondary axis. The grid is + * displayed in context of the primary axis' label interval - meaning that a + * grid for an Y-axis displays a grid for every label on the y-axis (fx. a {@link + * Image_Graph_Grid_Lines}, which displays horizontal lines for every label on + * the y-axis from the x-axis minimum to the x-axis maximum). You should always + * add the grid as one of the first elements to the plotarea. This is due to the + * fact that elements are 'outputted' in the order they are added, i.e. if an + * grid is added *after* a chart, the grid will be displayed on top of the chart + * which is (probably) not desired. + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Grid extends Image_Graph_Plotarea_Element +{ + + /** + * The primary axis: the grid 'refers' to + * @var Axis + * @access private + */ + var $_primaryAxis = null; + + /** + * The secondary axis + * @var Axis + * @access private + */ + var $_secondaryAxis = null; + + /** + * Set the primary axis: the grid should 'refer' to + * + * @param Image_Graph_Axis $axis The axis + * @access private + */ + function _setPrimaryAxis(& $axis) + { + $this->_primaryAxis =& $axis; + } + + /** + * Set the secondary axis + * + * @param Image_Graph_Axis $axis The axis + * @access private + */ + function _setSecondaryAxis(& $axis) + { + $this->_secondaryAxis =& $axis; + } + + /** + * Get the points on the secondary axis that the grid should 'connect' + * + * @return array The secondary data values that should mark the grid 'end points' + * @access private + */ + function _getSecondaryAxisPoints() + { + if (is_a($this->_secondaryAxis, 'Image_Graph_Axis_Radar')) { + $secondaryValue = false; + $firstValue = $secondaryValue; + while (($secondaryValue = $this->_secondaryAxis->_getNextLabel($secondaryValue)) !== false) { + $secondaryAxisPoints[] = $secondaryValue; + } + $secondaryAxisPoints[] = $firstValue; + } else { + $secondaryAxisPoints = array ('#min#', '#max#'); + } + return $secondaryAxisPoints; + } + + /** + * Get the X pixel position represented by a value + * + * @param double $point the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointX($point) + { + if (($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_Y) || + ($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY)) + { + $point['AXIS_Y'] = $this->_primaryAxis->_type; + } else { + $point['AXIS_Y'] = $this->_secondaryAxis->_type; + } + return parent::_pointX($point); + } + + /** + * Get the Y pixel position represented by a value + * + * @param double $point the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointY($point) + { + if (($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_Y) || + ($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_Y_SECONDARY)) + { + $point['AXIS_Y'] = $this->_primaryAxis->_type; + } else { + $point['AXIS_Y'] = $this->_secondaryAxis->_type; + } + return parent::_pointY($point); + } + + /** + * Causes the object to update all sub elements coordinates. + * + * @access private + */ + function _updateCoords() + { + $this->_setCoords( + $this->_parent->_plotLeft, + $this->_parent->_plotTop, + $this->_parent->_plotRight, + $this->_parent->_plotBottom + ); + parent::_updateCoords(); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Grid/Bars.php b/config/archive/dspam/pear/Image/Graph/Grid/Bars.php new file mode 100644 index 00000000..a75782f2 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Grid/Bars.php @@ -0,0 +1,117 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Grid.php + */ +require_once 'Image/Graph/Grid.php'; + +/** + * Display alternating bars on the plotarea. + * + * {@link Image_Graph_Grid} + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Grid_Bars extends Image_Graph_Grid +{ + + /** + * Output the grid + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!$this->_primaryAxis) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $i = 0; + $value = false; + + $previousValue = 0; + + $secondaryPoints = $this->_getSecondaryAxisPoints(); + + while (($value = $this->_primaryAxis->_getNextLabel($value)) !== false) { + if ($i == 1) { + reset($secondaryPoints); + list ($id, $previousSecondaryValue) = each($secondaryPoints); + while (list ($id, $secondaryValue) = each($secondaryPoints)) { + if ($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_X) { + $p1 = array ('Y' => $secondaryValue, 'X' => $value); + $p2 = array ('Y' => $previousSecondaryValue, 'X' => $value); + $p3 = array ('Y' => $previousSecondaryValue, 'X' => $previousValue); + $p4 = array ('Y' => $secondaryValue, 'X' => $previousValue); + } else { + $p1 = array ('X' => $secondaryValue, 'Y' => $value); + $p2 = array ('X' => $previousSecondaryValue, 'Y' => $value); + $p3 = array ('X' => $previousSecondaryValue, 'Y' => $previousValue); + $p4 = array ('X' => $secondaryValue, 'Y' => $previousValue); + } + + $this->_canvas->addVertex(array('x' => $this->_pointX($p1), 'y' => $this->_pointY($p1))); + $this->_canvas->addVertex(array('x' => $this->_pointX($p2), 'y' => $this->_pointY($p2))); + $this->_canvas->addVertex(array('x' => $this->_pointX($p3), 'y' => $this->_pointY($p3))); + $this->_canvas->addVertex(array('x' => $this->_pointX($p4), 'y' => $this->_pointY($p4))); + + $this->_getFillStyle(); + $this->_canvas->polygon(array('connect' => true)); + + $previousSecondaryValue = $secondaryValue; + } + } + $i = 1 - $i; + $previousValue = $value; + } + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Grid/Lines.php b/config/archive/dspam/pear/Image/Graph/Grid/Lines.php new file mode 100644 index 00000000..805778ee --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Grid/Lines.php @@ -0,0 +1,114 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Grid.php + */ +require_once 'Image/Graph/Grid.php'; + +/** + * Display a line grid on the plotarea. + * + * {@link Image_Graph_Grid} + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Grid_Lines extends Image_Graph_Grid +{ + + /** + * GridLines [Constructor] + */ + function Image_Graph_Grid_Lines() + { + parent::Image_Graph_Grid(); + $this->_lineStyle = 'lightgrey'; + } + + /** + * Output the grid + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!$this->_primaryAxis) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $value = false; + + $secondaryPoints = $this->_getSecondaryAxisPoints(); + + while (($value = $this->_primaryAxis->_getNextLabel($value)) !== false) { + reset($secondaryPoints); + list ($id, $previousSecondaryValue) = each($secondaryPoints); + while (list ($id, $secondaryValue) = each($secondaryPoints)) { + if ($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_Y) { + $p1 = array ('X' => $secondaryValue, 'Y' => $value); + $p2 = array ('X' => $previousSecondaryValue, 'Y' => $value); + } else { + $p1 = array ('X' => $value, 'Y' => $secondaryValue); + $p2 = array ('X' => $value, 'Y' => $previousSecondaryValue); + } + + $x1 = $this->_pointX($p1); + $y1 = $this->_pointY($p1); + $x2 = $this->_pointX($p2); + $y2 = $this->_pointY($p2); + + $previousSecondaryValue = $secondaryValue; + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x1, 'y0' => $y1, 'x1' => $x2, 'y1' => $y2)); + } + } + + $this->_canvas->endGroup(); + + return true; + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Grid/Polar.php b/config/archive/dspam/pear/Image/Graph/Grid/Polar.php new file mode 100644 index 00000000..03b1b916 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Grid/Polar.php @@ -0,0 +1,111 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Grid.php + */ +require_once 'Image/Graph/Grid.php'; + +/** + * Display a line grid on the plotarea. + * + * {@link Image_Graph_Grid} + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Grid_Polar extends Image_Graph_Grid +{ + + /** + * GridLines [Constructor] + */ + function Image_Graph_Grid_Polar() + { + parent::Image_Graph_Grid(); + $this->_lineStyle = 'lightgrey'; + } + + /** + * Output the grid + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!$this->_primaryAxis) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $value = false; + + $p0 = array ('X' => '#min#', 'Y' => '#min#'); + if ($this->_primaryAxis->_type == IMAGE_GRAPH_AXIS_Y) { + $p1 = array ('X' => '#min#', 'Y' => '#max#'); + $r0 = abs($this->_pointY($p1) - $this->_pointY($p0)); + } else { + $p1 = array ('X' => '#max#', 'Y' => '#min#'); + $r0 = abs($this->_pointX($p1) - $this->_pointX($p0)); + } + + $cx = $this->_pointX($p0); + $cy = $this->_pointY($p0); + + $span = $this->_primaryAxis->_axisSpan; + + while (($value = $this->_primaryAxis->_getNextLabel($value)) !== false) { + $r = $r0 * ($value - $this->_primaryAxis->_getMinimum()) / $span; + + $this->_getLineStyle(); + $this->_canvas->ellipse(array('x' => $cx, 'y' => $cy, 'rx' => $r, 'ry' => $r)); + } + + $this->_canvas->endGroup(); + + return true; + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Images/Icons/pinpoint.png b/config/archive/dspam/pear/Image/Graph/Images/Icons/pinpoint.png new file mode 100644 index 00000000..d23f0b7d Binary files /dev/null and b/config/archive/dspam/pear/Image/Graph/Images/Icons/pinpoint.png differ diff --git a/config/archive/dspam/pear/Image/Graph/Images/Icons/pinpointr.png b/config/archive/dspam/pear/Image/Graph/Images/Icons/pinpointr.png new file mode 100644 index 00000000..2455e09b Binary files /dev/null and b/config/archive/dspam/pear/Image/Graph/Images/Icons/pinpointr.png differ diff --git a/config/archive/dspam/pear/Image/Graph/Images/Maps/README b/config/archive/dspam/pear/Image/Graph/Images/Maps/README new file mode 100644 index 00000000..1b984bbb --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Images/Maps/README @@ -0,0 +1,17 @@ +In this folder the files for the Image_Graph_Plot_Map are located. They should be the +following format: + +[map name].png +[map name].txt + +The [map name].png (fx. europe.png) is the actual image presenting the map. The +[map name].txt file is the location -> (x,y) conversion table. In this file the +named locations is written on every line with the x and y coordinates after the +name (with a TAB), i.e.: + +Denmark 10 30 +England 4 30 + +Where Denmark will be 'located' on (10, 30) on the map, and England at (4, 30). + +No maps are released by default due to we want to avoid possible copyright issues. \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Layout.php b/config/archive/dspam/pear/Image/Graph/Layout.php new file mode 100644 index 00000000..1561aafa --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Layout.php @@ -0,0 +1,219 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plotarea/Element.php + */ +require_once 'Image/Graph/Plotarea/Element.php'; + +/** + * Defines an area of the graph that can be layout'ed. + * + * Any class that extends this abstract class can be used within a layout on the canvas. + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Layout extends Image_Graph_Plotarea_Element +{ + + /** + * Has the coordinates already been updated? + * @var bool + * @access private + */ + var $_updated = false; + + /** + * Alignment of the area for each vertice (left, top, right, bottom) + * @var array + * @access private + */ + var $_alignSize = array ('left' => 0, 'top' => 0, 'right' => 0, 'bottom' => 0); + + /** + * Image_Graph_Layout [Constructor] + */ + function Image_Graph_Layout() + { + parent::Image_Graph_Element(); + $this->_padding = array('left' => 2, 'top' => 2, 'right' => 2, 'bottom' => 2); + } + + /** + * Resets the elements + * + * @access private + */ + function _reset() + { + parent::_reset(); + $this->_updated = false; + } + + /** + * Calculate the edge offset for a specific edge + * @param array $alignSize The alignment of the edge + * @param int $offset The offset/posision of the at 0% edge + * @param int $total The total size (width or height) of the element + * @param int $multiplier +/- 1 if the edge should pushed either toward more + * negative or positive values + * @since 0.3.0dev2 + * @access private + */ + function _calcEdgeOffset($alignSize, $offset, $total, $multiplier) + { + if ($alignSize['unit'] == 'percentage') { + return $offset + $multiplier * ($total * $alignSize['value'] / 100); + } elseif ($alignSize['unit'] == 'pixels') { + if (($alignSize['value'] == 'auto_part1') || ($alignSize['value'] == 'auto_part2')) { + $alignSize['value'] = $multiplier * $this->_parent->_getAbsolute($alignSize['value']); + } + if ($alignSize['value'] < 0) { + return $offset + $multiplier * ($total + $alignSize['value']); + } else { + return $offset + $multiplier * $alignSize['value']; + } + } + return $offset; + } + + /** + * Calculate the edges + * + * @access private + */ + function _calcEdges() + { + if ((is_array($this->_alignSize)) && (!$this->_updated)) { + $left = $this->_calcEdgeOffset( + $this->_alignSize['left'], + $this->_parent->_fillLeft(), + $this->_parent->_fillWidth(), + +1 + ); + $top = $this->_calcEdgeOffset( + $this->_alignSize['top'], + $this->_parent->_fillTop(), + $this->_parent->_fillHeight(), + +1 + ); + $right = $this->_calcEdgeOffset( + $this->_alignSize['right'], + $this->_parent->_fillRight(), + $this->_parent->_fillWidth(), + -1 + ); + $bottom = $this->_calcEdgeOffset( + $this->_alignSize['bottom'], + $this->_parent->_fillBottom(), + $this->_parent->_fillHeight(), + -1 + ); + + $this->_setCoords( + $left + $this->_padding['left'], + $top + $this->_padding['top'], + $right - $this->_padding['right'], + $bottom - $this->_padding['bottom'] + ); + } + } + + /** + * Update coordinates + * + * @access private + */ + function _updateCoords() + { + $this->_calcEdges(); + parent::_updateCoords(); + } + + /** + * Pushes an edge of area a specific distance 'into' the canvas + * + * @param int $edge The edge of the canvas to align relative to + * @param int $size The number of pixels or the percentage of the canvas total size to occupy relative to the selected alignment edge + * @access private + */ + function _push($edge, $size = '100%') + { + $result = array(); + if (ereg("([0-9]*)\%", $size, $result)) { + $this->_alignSize[$edge] = array( + 'value' => min(100, max(0, $result[1])), + 'unit' => 'percentage' + ); + } else { + $this->_alignSize[$edge] = array( + 'value' => $size, + 'unit' => 'pixels' + ); + } + } + + /** + * Sets the coordinates of the element + * + * @param int $left The leftmost pixel of the element on the canvas + * @param int $top The topmost pixel of the element on the canvas + * @param int $right The rightmost pixel of the element on the canvas + * @param int $bottom The bottommost pixel of the element on the canvas + * @access private + */ + function _setCoords($left, $top, $right, $bottom) + { + parent::_setCoords($left, $top, $right, $bottom); + $this->_updated = true; + } + + /** + * Returns the calculated "auto" size + * + * @return int The calculated auto size + * @access private + */ + function _getAutoSize() + { + return false; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Layout/Horizontal.php b/config/archive/dspam/pear/Image/Graph/Layout/Horizontal.php new file mode 100644 index 00000000..414a168c --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Layout/Horizontal.php @@ -0,0 +1,186 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Layout.php + */ +require_once 'Image/Graph/Layout.php'; + +/** + * Layout for displaying two elements side by side. + * + * This splits the area contained by this element in two, side by side by + * a specified percentage (relative to the left side). A layout can be nested. + * Fx. a HorizontalLayout can layout two {@link Image_Graph_Layout_Vertical}s to + * make a 2 by 2 matrix of 'element-areas'. + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Layout_Horizontal extends Image_Graph_Layout +{ + + /** + * Part1 of the layout + * @var GraPHPElemnt + * @access private + */ + var $_part1 = false; + + /** + * Part2 of the layout + * @var GraPHPElemnt + * @access private + */ + var $_part2 = false; + + /** + * The percentage of the graph where the split occurs + * @var int + * @access private + */ + var $_percentage; + + /** + * An absolute position where the split occurs + * @var int + * @access private + */ + var $_absolute; + + /** + * HorizontalLayout [Constructor] + * + * @param Image_Graph_Element $part1 The 1st part of the layout + * @param Image_Graph_Element $part2 The 2nd part of the layout + * @param int $percentage The percentage of the layout to split at + */ + function Image_Graph_Layout_Horizontal(& $part1, & $part2, $percentage = 50) + { + parent::Image_Graph_Layout(); + if (!is_a($part1, 'Image_Graph_Layout')) { + $this->_error( + 'Cannot create layout on non-layouable parts: ' . get_class($part1), + array('part1' => &$part1, 'part2' => &$part2) + ); + } elseif (!is_a($part2, 'Image_Graph_Layout')) { + $this->_error( + 'Cannot create layout on non-layouable parts: ' . get_class($part2), + array('part1' => &$part1, 'part2' => &$part2) + ); + } else { + $this->_part1 =& $part1; + $this->_part2 =& $part2; + $this->add($this->_part1); + $this->add($this->_part2); + }; + if ($percentage === 'auto') { + $this->_percentage = false; + $this->_absolute = 'runtime'; + } else { + $this->_absolute = false; + $this->_percentage = max(0, min(100, $percentage)); + } + $this->_split(); + $this->_padding = array('left' => 0, 'top' => 0, 'right' => 0, 'bottom' => 0); + } + + /** + * Gets the absolute size of one of the parts. + * + * @param string $part The name of the part - auto_part(1|2) + * @return int The number of pixels the edge should be pushed + * @since 0.3.0dev2 + * @access private + */ + function _getAbsolute(&$part) + { + $part1Size = $this->_part1->_getAutoSize(); + $part2Size = $this->_part2->_getAutoSize(); + $this->_percentage = false; + if (($part1Size !== false) and ($part2Size !== false)) { + $width = $this->_fillWidth() * $part1Size / ($part1Size + $part2Size); + } elseif ($part1Size !== false) { + $width = $part1Size; + } elseif ($part2Size !== false) { + $width = -$part2Size; + } else { + $width = $this->_fillWidth() / 2; + } + if ($part == 'auto_part2') { + $width = -$width; + } + + return $width; + } + + /** + * Splits the layout between the parts, by the specified percentage + * + * @access private + */ + function _split() + { + if (($this->_part1) && ($this->_part2)) { + if ($this->_percentage !== false) { + $split1 = 100 - $this->_percentage; + $split2 = $this->_percentage; + $this->_part1->_push('right', "$split1%"); + $this->_part2->_push('left', "$split2%"); + } else { + $this->_part1->_push('right', 'auto_part1'); + $this->_part2->_push('left', 'auto_part2'); + } + } + } + + /** + * Output the layout to the canvas + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (($this->_part1) && ($this->_part2)) { + return (($this->_part1->_done()) && ($this->_part2->_done())); + } + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Layout/Matrix.php b/config/archive/dspam/pear/Image/Graph/Layout/Matrix.php new file mode 100644 index 00000000..8acec871 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Layout/Matrix.php @@ -0,0 +1,201 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Layout.php + */ +require_once 'Image/Graph/Layout.php'; + +/** + * Layout for displaying elements in a matix. + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Layout_Matrix extends Image_Graph_Layout +{ + + /** + * Layout matrix + * @var array + * @access private + */ + var $_matrix = false; + + /** + * The number of rows + * @var int + * @access private + */ + var $_rows = false; + + /** + * The number of columns + * @var int + * @access private + */ + var $_cols = false; + + /** + * Image_Graph_Layout_Matrix [Constructor] + * + * @param int $rows The number of rows + * @param int $cols The number of cols + * @param bool $autoCreate Specifies whether the matrix should automatically + * be filled with newly created Image_Graph_Plotares objects, or they will + * be added manually + */ + function Image_Graph_Layout_Matrix($rows, $cols, $autoCreate = true) + { + parent::Image_Graph_Layout(); + + $this->_rows = $rows; + $this->_cols = $cols; + if (($this->_rows > 0) && ($this->_cols > 0)) { + $this->_matrix = array(array()); + for ($i = 0; $i < $this->_rows; $i++) { + for ($j = 0; $j < $this->_cols; $j++) { + if ($autoCreate) { + $this->_matrix[$i][$j] =& $this->addNew('plotarea'); + $this->_pushEdges($i, $j); + } else { + $this->_matrix[$i][$j] = false; + } + } + } + } + } + + /** + * Pushes the edges on the specified position in the matrix + * + * @param int $row The row + * @param int $col The column + * @access private + */ + function _pushEdges($row, $col) + { + if ((isset($this->_matrix[$row])) && (isset($this->_matrix[$row][$col]))) { + $height = 100/$this->_rows; + $width = 100/$this->_cols; + if ($col > 0) { + $this->_matrix[$row][$col]->_push('left', round($col*$width) . '%'); + } + if ($col+1 < $this->_cols) { + $this->_matrix[$row][$col]->_push('right', round(100-($col+1)*$width) . '%'); + } + if ($row > 0) { + $this->_matrix[$row][$col]->_push('top', round($row*$height) . '%'); + } + if ($row+1 < $this->_rows) { + $this->_matrix[$row][$col]->_push('bottom', round(100-($row+1)*$height) . '%'); + } + } + } + + /** + * Get the area on the specified position in the matrix + * + * @param int $row The row + * @param int $col The column + * @return Image_Graph_Layout The element of position ($row, $col) in the + * matrix + */ + function &getEntry($row, $col) + { + if ((isset($this->_matrix[$row])) && (isset($this->_matrix[$row][$col]))) { + return $this->_matrix[$row][$col]; + } else { + $result = null; + return $result; + } + } + + /** + * Get the area on the specified position in the matrix + * + * @param int $row The row + * @param int $col The column + * @param Image_Graph_Layout $element The element to set in the position + * ($row, $col) in the matrix + */ + function setEntry($row, $col, &$element) + { + $this->_matrix[$row][$col] =& $element; + $this->_pushEdges($row, $col); + } + + /** + * Update coordinates + * + * @access private + */ + function _updateCoords() + { + for ($i = 0; $i < $this->_rows; $i++) { + for ($j = 0; $j < $this->_cols; $j++) { + $element =& $this->getEntry($i, $j); + $this->add($element); + } + } + parent::_updateCoords(); + } + + /** + * Output the layout to the canvas + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $result = true; + for ($i = 0; $i < $this->_rows; $i++) { + for ($j = 0; $j < $this->_cols; $j++) { + $element =& $this->getEntry($i, $j); + if ($element) { + if (!$element->_done()) { + $result = false; + } + } + } + } + return $result; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Layout/Vertical.php b/config/archive/dspam/pear/Image/Graph/Layout/Vertical.php new file mode 100644 index 00000000..2dc6f945 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Layout/Vertical.php @@ -0,0 +1,108 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Layout/Horizontal.php + */ +require_once 'Image/Graph/Layout/Horizontal.php'; + +/** + * Layout for displaying two elements on top of each other. + * + * This splits the area contained by this element in two on top of each other + * by a specified percentage (relative to the top). A layout can be nested. + * Fx. a {@link Image_Graph_Layout_Horizontal} can layout two VerticalLayout's to + * make a 2 by 2 matrix of 'element-areas'. + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Layout_Vertical extends Image_Graph_Layout_Horizontal +{ + + /** + * Gets the absolute size of one of the parts. + * + * @param string $part The name of the part - auto_part(1|2) + * @return int The number of pixels the edge should be pushed + * @since 0.3.0dev2 + * @access private + */ + function _getAbsolute(&$part) + { + $part1Size = $this->_part1->_getAutoSize(); + $part2Size = $this->_part2->_getAutoSize(); + $this->_percentage = false; + if (($part1Size !== false) and ($part2Size !== false)) { + $height = $this->_fillHeight() * $part1Size / ($part1Size + $part2Size); + } elseif ($part1Size !== false) { + $height = $part1Size; + } elseif ($part2Size !== false) { + $height = -$part2Size; + } else { + $height = $this->_fillHeight() / 2; + } + + if ($part == 'auto_part2') { +// $height = $this->_fillHeight() - $height; + } + + return $height; + } + + /** + * Splits the layout between the parts, by the specified percentage + * + * @access private + */ + function _split() + { + if (($this->_part1) && ($this->_part2)) { + if ($this->_percentage !== false) { + $split1 = 100 - $this->_percentage; + $split2 = $this->_percentage; + $this->_part1->_push('bottom', "$split1%"); + $this->_part2->_push('top', "$split2%"); + } else { + $this->_part1->_push('bottom', 'auto_part1'); + $this->_part2->_push('top', 'auto_part2'); + } + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Legend.php b/config/archive/dspam/pear/Image/Graph/Legend.php new file mode 100644 index 00000000..d853dad5 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Legend.php @@ -0,0 +1,385 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Layout.php + */ +require_once 'Image/Graph/Layout.php'; + +/** + * Displays a legend for a plotarea. + * + * A legend can be displayed in two ways: + * + * 1 As an overlayed box within the plotarea + * + * 2 Layout'ed on the canvas smewhere next to the plotarea. + * + * @category Images + * @package Image_Graph + * @subpackage Legend + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Legend extends Image_Graph_Layout +{ + + /** + * Alignment of the text + * @var int + * @access private + */ + var $_alignment = false; + + /** + * The plotarea(s) to show the legend for + * @var array + * @access private + */ + var $_plotareas = array(); + + /** + * Should markers be shown or not on this legend + * @var bool + * @access private + */ + var $_showMarker = false; + + /** + * Image_Graph_Legend [Constructor] + */ + function Image_Graph_Legend() + { + parent::Image_Graph_Layout(); + $this->_padding = array('left' => 5, 'top' => 5, 'right' => 5, 'bottom' => 5); + } + + /** + * The number of actual plots in the plot area + * + * @return int The number of plotes + * @access private + */ + function _plotCount() + { + $count = 0; + $keys = array_keys($this->_plotareas); + foreach($keys as $key) { + $plotarea =& $this->_plotareas[$key]; + if (is_a($plotarea, 'Image_Graph_Plotarea')) { + $keys2 = array_keys($plotarea->_elements); + foreach ($keys2 as $key) { + $element =& $plotarea->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + $count ++; + } + } + unset($keys2); + } + } + unset($keys); + return $count; + } + + /** + * Get a default parameter array for legendSamples + * @param bool $simulate Whether the array should be used for simulation or + * not + * @return array Default parameter array + * @access private + */ + function _parameterArray($simulate = false) + { + $param['left'] = $this->_left + $this->_padding['left']; + $param['top'] = $this->_top + $this->_padding['top']; + $param['right'] = $this->_right - $this->_padding['right']; + $param['bottom'] = $this->_bottom - $this->_padding['bottom']; + $param['align'] = $this->_alignment; + $param['x'] = $this->_left + $this->_padding['left']; + $param['y'] = $this->_top + $this->_padding['top']; + $param['width'] = 16; + $param['height'] = 16; + $param['show_marker'] = $this->_showMarker; + $param['maxwidth'] = 0; + $param['font'] = $this->_getFont(); + if ($simulate) { + $param['simulate'] = true; + } + + return $param; + } + + /** + * The height of the element on the canvas + * + * @return int Number of pixels representing the height of the element + * @access private + */ + function _height() + { + $parent = (is_object($this->_parent) ? get_class($this->_parent) : $this->_parent); + + if (strtolower($parent) == 'image_graph_plotarea') { + $param = $this->_parameterArray(true); + $param['align'] = IMAGE_GRAPH_ALIGN_VERTICAL; + $param0 = $param; + $keys = array_keys($this->_plotareas); + foreach($keys as $key) { + $plotarea =& $this->_plotareas[$key]; + $keys2 = array_keys($plotarea->_elements); + foreach($keys2 as $key) { + $element =& $plotarea->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + $element->_legendSample($param); + } + } + unset($keys2); + } + unset($keys); + return abs($param['y'] - $param0['y']) + $this->_padding['top'] + $this->_padding['bottom']; + } else { + return parent::height(); + } + } + + /** + * The width of the element on the canvas + * + * @return int Number of pixels representing the width of the element + * @access private + */ + function _width() + { + $parent = (is_object($this->_parent) ? get_class($this->_parent) : $this->_parent); + + if (strtolower($parent) == 'image_graph_plotarea') { + $param = $this->_parameterArray(true); + $param['align'] = IMAGE_GRAPH_ALIGN_VERTICAL; + $keys = array_keys($this->_plotareas); + foreach($keys as $key) { + $plotarea =& $this->_plotareas[$key]; + $keys2 = array_keys($plotarea->_elements); + foreach($keys2 as $key) { + $element =& $plotarea->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + $element->_legendSample($param); + } + } + unset($keys2); + } + unset($keys); + return $param['maxwidth']; + } else { + return parent::width(); + } + } + + /** + * Set the alignment of the legend + * + * @param int $alignment The alignment + */ + function setAlignment($alignment) + { + $this->_alignment = $alignment; + } + + /** + * Update coordinates + * + * @access private + */ + function _updateCoords() + { + parent::_updateCoords(); + + $parent = (is_object($this->_parent) ? get_class($this->_parent) : $this->_parent); + + if (strtolower($parent) == 'image_graph_plotarea') { + $w = $this->_width(); + $h = $this->_height(); + + if ($this->_alignment === false) { + $this->_alignment = IMAGE_GRAPH_ALIGN_TOP + IMAGE_GRAPH_ALIGN_RIGHT; + } + + if (($this->_alignment & IMAGE_GRAPH_ALIGN_BOTTOM) != 0) { + $y = $this->_parent->_fillBottom() - $h - $this->_padding['bottom']; + } else { + $y = $this->_parent->_fillTop() + $this->_padding['top']; + } + + if (($this->_alignment & IMAGE_GRAPH_ALIGN_LEFT) != 0) { + $x = $this->_parent->_fillLeft() + $this->_padding['left']; + } else { + $x = $this->_parent->_fillRight() - $w - $this->_padding['right']; + } + + $this->_setCoords($x, $y, $x + $w, $y + $h); + } + } + + /** + * Sets Plotarea + * + * @param Image_Graph_Plotarea $plotarea The plotarea + */ + function setPlotarea(& $plotarea) + { + if (is_a($plotarea, 'Image_Graph_Plotarea')) { + $this->_plotareas[] =& $plotarea; + } + } + + /** + * Sets the parent. The parent chain should ultimately be a GraPHP object + * + * @see Image_Graph + * @param Image_Graph_Common $parent The parent + * @access private + */ + function _setParent(& $parent) + { + parent::_setParent($parent); + if (count($this->_plotareas) == 0) { + $this->setPlotarea($parent); + } + } + + /** + * Set if this legends should show markers + * + * @param bool $showMarker True if markers are to be shown, false is not + */ + function setShowMarker($showMarker) + { + $this->_showMarker = $showMarker; + } + + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + + if (Image_Graph_Element::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this)); + + $param = $this->_parameterArray(); + + $parent = (is_object($this->_parent) ? + get_class($this->_parent) : + $this->_parent + ); + + if (strtolower($parent) == 'image_graph_plotarea') { + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->rectangle( + array( + 'x0' => $this->_left, + 'y0' => $this->_top, + 'x1' => $this->_right, + 'y1' => $this->_bottom + ) + ); + + $param = $this->_parameterArray(); + + $keys = array_keys($this->_plotareas); + foreach($keys as $key) { + $plotarea =& $this->_plotareas[$key]; + $keys2 = array_keys($plotarea->_elements); + foreach($keys2 as $key) { + $element =& $plotarea->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + $element->_legendSample($param); + } + } + unset($keys2); + } + unset($keys); + } else { + $param0 = $param; + $param0['simulate'] = true; + $keys = array_keys($this->_plotareas); + foreach($keys as $key) { + $plotarea =& $this->_plotareas[$key]; + $keys2 = array_keys($plotarea->_elements); + foreach($keys2 as $key) { + $element =& $plotarea->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + $element->_legendSample($param0); + } + } + unset($keys2); + } + unset($keys); + if (($this->_alignment & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + if ($param0['x'] == $param['x']) { + $param['y'] = $param['y'] + ($this->_height() - ($param0['y'] - $param['y']))/2; + } + } else { + if ($param0['y'] == $param['y']) { + $param['x'] = $param['x'] + ($this->_width() - ($param0['x'] - $param['x']))/2; + } + } + + $keys = array_keys($this->_plotareas); + foreach($keys as $key) { + $plotarea =& $this->_plotareas[$key]; + $keys2 = array_keys($plotarea->_elements); + foreach($keys2 as $key) { + $element =& $plotarea->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + $element->_legendSample($param); + } + } + unset($keys2); + } + unset($keys); + } + + $this->_canvas->endGroup(); + + return true; + } +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Line/Array.php b/config/archive/dspam/pear/Image/Graph/Line/Array.php new file mode 100644 index 00000000..5d542141 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Line/Array.php @@ -0,0 +1,129 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Common.php + */ +require_once 'Image/Graph/Common.php'; + +/** + * A sequential array of linestyles. + * + * This is used for multiple objects within the same element with different line + * styles. This is done by adding multiple line styles to a LineArrray + * structure. The linearray will then when requested return the 'next' linestyle + * in sequential order. It is possible to specify ID tags to each linestyle, + * which is used to make sure some data uses a specific linestyle (i.e. in a + * multiple-/stackedbarchart you name the {@link Image_Graph_Dataset}s and uses + * this name as ID tag when adding the dataset's associated linestyle to the + * linearray. + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Line_Array extends Image_Graph_Common +{ + + /** + * The fill array + * @var array + * @access private + */ + var $_lineStyles = array (); + + /** + * Add a line style to the array + * + * @param Image_Graph_Line $style The style to add + */ + function add(& $style, $id = false) + { + if (is_a($style, 'Image_Graph_Element')) { + parent::add($style); + } + if ($id === false) { + $this->_lineStyles[] =& $style; + } else { + $this->_lineStyles[$id] =& $style; + } + reset($this->_lineStyles); + + } + + /** + * Add a color to the array + * + * @param int $color The color + * @param string $id The id or name of the color + */ + function addColor($color, $id = false) + { + if ($id !== false) { + $this->_lineStyles[$id] = $color; + } else { + $this->_lineStyles[] = $color; + } + reset($this->_lineStyles); + } + + /** + * Return the linestyle + * + * @return int A GD Linestyle + * @access private + */ + function _getLineStyle($ID = false) + { + if (($ID === false) || (!isset($this->_lineStyles[$ID]))) { + $ID = key($this->_lineStyles); + if (!next($this->_lineStyles)) { + reset($this->_lineStyles); + } + } + $lineStyle =& $this->_lineStyles[$ID]; + + if (is_object($lineStyle)) { + return $lineStyle->_getLineStyle($ID); + } elseif ($lineStyle !== null) { + return $lineStyle; + } else { + return parent::_getLineStyle($ID); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Line/Dashed.php b/config/archive/dspam/pear/Image/Graph/Line/Dashed.php new file mode 100644 index 00000000..448fb218 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Line/Dashed.php @@ -0,0 +1,76 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Line/Formatted.php + */ +require_once 'Image/Graph/Line/Formatted.php'; + +/** + * Dashed line style. + * + * This style displays as a short line with a shorter space afterwards, i.e + * 4px color1, 2px color2, 4px color1, etc. + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Line_Dashed extends Image_Graph_Line_Formatted +{ + + /** + * Image_Graph_DashedLine [Constructor] + * + * @param mixed $color1 The color for the 'dashes' + * @param mixed $color2 The color for the 'spaces' + */ + function Image_Graph_Line_Dashed($color1, $color2) + { + parent::Image_Graph_Line_Formatted( + array( + $color1, + $color1, + $color1, + $color1, + $color2, + $color2 + ) + ); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Line/Dotted.php b/config/archive/dspam/pear/Image/Graph/Line/Dotted.php new file mode 100644 index 00000000..8574f8da --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Line/Dotted.php @@ -0,0 +1,67 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Line/Formatted.php + */ +require_once 'Image/Graph/Line/Formatted.php'; + +/** + * Dotted line style. + * + * This style displays as a short line with a shorter space afterwards, i.e + * 1px color1, 1px color2, 1px color1, etc. + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Line_Dotted extends Image_Graph_Line_Formatted +{ + + /** + * DottedLine [Constructor] + * + * @param mixed $color1 The color representing the dots + * @param mixed $color2 The color representing the spaces + */ + function Image_Graph_Line_Dotted($color1, $color2) + { + parent::Image_Graph_Line_Formatted(array ($color1, $color2)); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Line/Formatted.php b/config/archive/dspam/pear/Image/Graph/Line/Formatted.php new file mode 100644 index 00000000..e6d0181b --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Line/Formatted.php @@ -0,0 +1,90 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Line/Solid.php + */ +require_once 'Image/Graph/Line/Solid.php'; + +/** + * Formatted user defined line style. + * + * Use this to create a user defined line style. Specify an array of colors that are to + * be used for displaying the line. + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Line_Formatted extends Image_Graph_Line_Solid +{ + + /** + * The style of the line + * + * @var array + * @access private + */ + var $_style; + + /** + * Image_Graph_FormattedLine [Constructor] + * + * @param array $style The style of the line + */ + function Image_Graph_Line_Formatted($style) + { + parent::Image_Graph_Line_Solid(reset($style)); + $this->_style = $style; + } + + /** + * Gets the line style of the element + * + * @return int A GD linestyle representing the line style + * @see Image_Graph_Line + * @access private + */ + function _getLineStyle() + { + return array( + 'color' => $this->_style, + 'thickness' => $this->_thickness + ); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Line/Solid.php b/config/archive/dspam/pear/Image/Graph/Line/Solid.php new file mode 100644 index 00000000..e77e62f1 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Line/Solid.php @@ -0,0 +1,105 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Common.php + */ +require_once 'Image/Graph/Common.php'; + +/** + * Simple colored line style. + * + * Use a color for line style. + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Line_Solid extends Image_Graph_Common +{ + + /** + * The thickness of the line (requires GD 2) + * @var int + * @access private + */ + var $_thickness = 1; + + /** + * The color of the line + * @var mixed + * @access private + */ + var $_color; + + /** + * Image_Graph_SolidLine [Constructor] + * + * @param mixed $color The color of the line + */ + function Image_Graph_Line_Solid($color) + { + parent::Image_Graph_Common(); + $this->_color = $color; + } + + /** + * Set the thickness of the linestyle + * + * @param int $thickness The line width in pixels + */ + function setThickness($thickness) + { + $this->_thickness = $thickness; + } + + /** + * Gets the line style of the element + * + * @return int A GD linestyle representing the line style + * @see Image_Graph_Line + * @access private + */ + function _getLineStyle() + { + return array( + 'color' => $this->_color, + 'thickness' => $this->_thickness + ); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Logo.php b/config/archive/dspam/pear/Image/Graph/Logo.php new file mode 100644 index 00000000..df5fe7e4 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Logo.php @@ -0,0 +1,153 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * Displays a logo on the canvas. + * + * By default the logo is displayed in the top-right corner of the canvas. + * + * @category Images + * @package Image_Graph + * @subpackage Logo + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Logo extends Image_Graph_Element +{ + + /** + * The file name + * @var stirng + * @access private + */ + var $_filename; + + /** + * The GD Image resource + * @var resource + * @access private + */ + var $_image; + + /** + * Alignment of the logo + * @var int + * @access private + */ + var $_alignment; + + /** + * Logo [Constructor] + * + * @param string $filename The filename and path of the image to use for logo + */ + function Image_Graph_Logo($filename, $alignment = IMAGE_GRAPH_ALIGN_TOP_RIGHT) + { + parent::Image_Graph_Element(); + $this->_filename = $filename; + $this->_alignment = $alignment; + } + + /** + * Sets the parent. The parent chain should ultimately be a GraPHP object + * + * @see Image_Graph + * @param Image_Graph_Common $parent The parent + * @access private + */ + function _setParent(& $parent) + { + parent::_setParent($parent); + $this->_setCoords( + $this->_parent->_left, + $this->_parent->_top, + $this->_parent->_right, + $this->_parent->_bottom + ); + } + + /** + * Output the logo + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $align = array(); + + if ($this->_alignment & IMAGE_GRAPH_ALIGN_LEFT) { + $x = $this->_parent->_left + 2; + $align['horizontal'] = 'left'; + } elseif ($this->_alignment & IMAGE_GRAPH_ALIGN_RIGHT) { + $x = $this->_parent->_right - 2; + $align['horizontal'] = 'right'; + } else { + $x = ($this->_parent->_left + $this->_parent->_right) / 2; + $align['horizontal'] = 'center'; + } + + if ($this->_alignment & IMAGE_GRAPH_ALIGN_TOP) { + $y = $this->_parent->_top + 2; + $align['vertical'] = 'top'; + } elseif ($this->_alignment & IMAGE_GRAPH_ALIGN_BOTTOM) { + $y = $this->_parent->_bottom - 2; + $align['vertical'] = 'bottom'; + } else { + $y = ($this->_parent->_top + $this->_parent->_bottom) / 2; + $align['vertical'] = 'center'; + } + + $this->_canvas->image( + array( + 'x' => $x, + 'y' => $y, + 'filename' => $this->_filename, + 'alignment' => $align + ) + ); + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker.php b/config/archive/dspam/pear/Image/Graph/Marker.php new file mode 100644 index 00000000..1c1926fe --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker.php @@ -0,0 +1,123 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plotarea/Element.php + */ +require_once 'Image/Graph/Plotarea/Element.php'; + +/** + * Data point marker. + * + * The data point marker is used for marking the datapoints on a graph with some + * visual label, fx. a cross, a text box with the value or an icon. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Marker extends Image_Graph_Plotarea_Element +{ + + /** + * Secondary marker + * @var Marker + * @access private + */ + var $_secondaryMarker = false; + + /** + * The 'size' of the marker, the meaning depends on the specific Marker + * implementation + * @var int + * @access private + */ + var $_size = 6; + + /** + * Set the 'size' of the marker + * + * @param int $size The 'size' of the marker, the meaning depends on the + * specific Marker implementation + */ + function setSize($size) + { + $this->_size = $size; + } + + /** + * Set the secondary marker + * + * @param Marker $secondaryMarker The secondary marker + */ + function setSecondaryMarker(& $secondaryMarker) + { + $this->_secondaryMarker =& $secondaryMarker; + $this->_secondaryMarker->_setParent($this); + } + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + if (is_a($this->_secondaryMarker, 'Image_Graph_Marker')) { + $this->_secondaryMarker->_drawMarker($x, $y, $values); + } + } + + /** + * Output to the canvas + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Array.php b/config/archive/dspam/pear/Image/Graph/Marker/Array.php new file mode 100644 index 00000000..12fed66c --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Array.php @@ -0,0 +1,105 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * A sequential array of markers. + * + * This is used for displaying different markers for datapoints on a chart. + * This is done by adding multiple markers to a MarkerArrray structure. + * The marker array will then when requested return the 'next' marker in + * sequential order. It is possible to specify ID tags to each marker, which is + * used to make sure some data uses a specific marker. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Array extends Image_Graph_Marker +{ + + /** + * The marker array + * @var array + * @access private + */ + var $_markers = array (); + + /** + * Add a marker style to the array + * + * @param Marker $marker The marker to add + */ + function add(& $marker) + { + if (is_a($marker, 'Image_Graph_Element')) { + parent::add($marker); + } + $this->_markers[] =& $marker; + reset($this->_markers); + } + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $ID = key($this->_markers); + if (!next($this->_markers)) { + reset($this->_markers); + } + $marker =& $this->_markers[$ID]; + + if ($marker != null) { + $marker->_drawMarker($x, $y, $values); + } + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Asterisk.php b/config/archive/dspam/pear/Image/Graph/Marker/Asterisk.php new file mode 100644 index 00000000..effde5a5 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Asterisk.php @@ -0,0 +1,109 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as an asterisk (*) + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Asterisk extends Image_Graph_Marker +{ + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $x - $this->_size, + 'y0' => $y - $this->_size, + 'x1' => $x + $this->_size, + 'y1' => $y + $this->_size + ) + ); + + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $x + $this->_size, + 'y0' => $y - $this->_size, + 'x1' => $x - $this->_size, + 'y1' => $y + $this->_size + ) + ); + + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $x - $this->_size, + 'y0' => $y, + 'x1' => $x + $this->_size, + 'y1' => $y + ) + ); + + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $x, + 'y0' => $y - $this->_size, + 'x1' => $x, + 'y1' => $y + $this->_size + ) + ); + + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Average.php b/config/archive/dspam/pear/Image/Graph/Marker/Average.php new file mode 100644 index 00000000..c4e3e7a4 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Average.php @@ -0,0 +1,91 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * A marker displaying the 'distance' to the datasets average value. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Average extends Image_Graph_Marker +{ + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + if ((isset($values['AVERAGE_Y'])) && + (is_a($this->_parent, 'Image_Graph_Plot'))) + { + $point = $this->_pointXY( + array( + 'X' => $values['APX'], + 'Y' => $values['AVERAGE_Y'] + ) + ); + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $point['X'], 'y1' => $point['Y'])); + + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $point['X'] - 2, + 'y0' => $point['Y'], + 'x1' => $point['X'] + 2, + 'y1' => $point['Y'] + ) + ); + } + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Box.php b/config/archive/dspam/pear/Image/Graph/Marker/Box.php new file mode 100644 index 00000000..5602c33d --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Box.php @@ -0,0 +1,76 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as a box + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Box extends Image_Graph_Marker +{ + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the canvas + * @param array $values The values representing the data the marker 'points' to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->rectangle( + array( + 'x0' => $x - $this->_size, + 'y0' => $y - $this->_size, + 'x1' => $x + $this->_size, + 'y1' => $y + $this->_size + ) + ); + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Bubble.php b/config/archive/dspam/pear/Image/Graph/Marker/Bubble.php new file mode 100644 index 00000000..180ab4e3 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Bubble.php @@ -0,0 +1,91 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker/Circle.php + */ +require_once 'Image/Graph/Marker/Circle.php'; + +/** + * Display a circle with y-value percentage as radius (require GD2). + * + * This will display a circle centered on the datapoint with a radius calculated + * as a percentage of the maximum value. I.e. the radius depends on the y-value + * of the datapoint + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Bubble extends Image_Graph_Marker_Circle +{ + + /** + * The radius of the marker when 100% + * @var int + * @access private + */ + var $_size100Pct = 40; + + /** + * Sets the maximum radius the marker can occupy + * + * @param int $radius The new Image_Graph_max radius + */ + function setMaxRadius($radius) + { + $this->_size100Pct = $radius; + } + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $this->_size = $this->_size100Pct*$values['PCT_MAX_Y']/100; + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Circle.php b/config/archive/dspam/pear/Image/Graph/Marker/Circle.php new file mode 100644 index 00000000..7eeb5cb6 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Circle.php @@ -0,0 +1,96 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as circle (require GD2) + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Circle extends Image_Graph_Marker +{ + + /** + * The 'size' of the marker, the meaning depends on the specific Marker + * implementation + * @var int + * @access private + */ + var $_size = 10; + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $this->_getFillStyle(); + $this->_getLineStyle(); + + $dA = 2*pi()/($this->_size*2); + $angle = 0; + while ($angle < 2*pi()) { + $this->_canvas->addVertex(array('x' => + $x + $this->_size*cos($angle), 'y' => + $y - $this->_size*sin($angle) + )); + $angle += $dA; + } + + $this->_canvas->addVertex(array('x' => + $x + $this->_size*cos(0), 'y' => + $y - $this->_size*sin(0) + )); + + $this->_canvas->polygon(array('connect' => true)); + + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Cross.php b/config/archive/dspam/pear/Image/Graph/Marker/Cross.php new file mode 100644 index 00000000..720f3bb4 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Cross.php @@ -0,0 +1,114 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as a cross. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Cross extends Image_Graph_Marker +{ + + /** + * The thickness of the plus in pixels (thickness is actually double this) + * @var int + * @access private + */ + var $_thickness = 2; + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the canvas + * @param array $values The values representing the data the marker 'points' to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + if ($this->_thickness > 0) { + $this->_getLineStyle(); + $this->_getFillStyle(); + + $d1 = round(0.7071067 * $this->_size); // cos/sin(45 de>) + $d2 = round(0.7071067 * $this->_thickness); // cos/sin(45 deg) + + $this->_canvas->addVertex(array('x' => $x - $d1 - $d2, 'y' => $y - $d1 + $d2)); + $this->_canvas->addVertex(array('x' => $x - $d1 + $d2, 'y' => $y - $d1 - $d2)); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y - 2 * $d2)); + $this->_canvas->addVertex(array('x' => $x + $d1 - $d2, 'y' => $y - $d1 - $d2)); + $this->_canvas->addVertex(array('x' => $x + $d1 + $d2, 'y' => $y - $d1 + $d2)); + $this->_canvas->addVertex(array('x' => $x + 2 * $d2, 'y' => $y)); + $this->_canvas->addVertex(array('x' => $x + $d1 + $d2, 'y' => $y + $d1 - $d2)); + $this->_canvas->addVertex(array('x' => $x + $d1 - $d2, 'y' => $y + $d1 + $d2)); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y + 2 * $d2)); + $this->_canvas->addVertex(array('x' => $x - $d1 + $d2, 'y' => $y + $d1 + $d2)); + $this->_canvas->addVertex(array('x' => $x - $d1 - $d2, 'y' => $y + $d1 - $d2)); + $this->_canvas->addVertex(array('x' => $x - 2 * $d2, 'y' => $y)); + $this->_canvas->polygon(array('connect' => true)); + } else { + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $x - $this->_size, + 'y0' => $y - $this->_size, + 'x1' => $x + $this->_size, + 'y1' => $y + $this->_size + ) + ); + + $this->_getLineStyle(); + $this->_canvas->line( + array( + 'x0' => $x + $this->_size, + 'y0' => $y - $this->_size, + 'x1' => $x - $this->_size, + 'y1' => $y + $this->_size + ) + ); + } + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Diamond.php b/config/archive/dspam/pear/Image/Graph/Marker/Diamond.php new file mode 100644 index 00000000..2a3d68c8 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Diamond.php @@ -0,0 +1,73 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as a diamond. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Diamond extends Image_Graph_Marker +{ + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the canvas + * @param array $values The values representing the data the marker 'points' to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->addVertex(array('x' => $x - $this->_size, 'y' => $y)); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y - $this->_size)); + $this->_canvas->addVertex(array('x' => $x + $this->_size, 'y' => $y)); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y + $this->_size)); + $this->_canvas->polygon(array('connect' => true)); + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Icon.php b/config/archive/dspam/pear/Image/Graph/Marker/Icon.php new file mode 100644 index 00000000..d9b9456f --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Icon.php @@ -0,0 +1,133 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker using an image as icon. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Icon extends Image_Graph_Marker +{ + + /** + * Filename of the image icon + * @var string + * @access private + */ + var $_filename; + + /** + * X Point of the icon to use as data 'center' + * @var int + * @access private + */ + var $_pointX = 0; + + /** + * Y Point of the icon to use as data 'center' + * @var int + * @access private + */ + var $_pointY = 0; + + /** + * Create an icon marker + * + * @param string $filename The filename of the icon + * @param int $width The 'new' width of the icon if it is to be resized + * @param int $height The 'new' height of the icon if it is to be resized + */ + function Image_Graph_Marker_Icon($filename, $width = 0, $height = 0) + { + parent::Image_Graph_Marker(); + $this->_filename = $filename; + } + + /** + * Set the X 'center' point of the marker + * + * @param int $x The X 'center' point of the marker + */ + function setPointX($x) + { + $this->_pointX = $x; + } + + /** + * Set the Y 'center' point of the marker + * + * @param int $y The Y 'center' point of the marker + */ + function setPointY($y) + { + $this->_pointY = $y; + } + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + parent::_drawMarker($x, $y, $values); + if ($this->_filename) { + $this->_canvas->image( + array( + 'x' => $x, + 'y' => $y, + 'filename' => $this->_filename, + 'alignment' => array('horizontal' => 'center', 'vertical' => 'center') + ) + ); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Pinpoint.php b/config/archive/dspam/pear/Image/Graph/Marker/Pinpoint.php new file mode 100644 index 00000000..7b87f153 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Pinpoint.php @@ -0,0 +1,65 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker/Icon.php + */ +require_once 'Image/Graph/Marker/Icon.php'; + +/** + * Data marker using a pinpoint as marker. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Pinpoint extends Image_Graph_Marker_Icon +{ + + /** + * Create the marker as a pin point + */ + function Image_Graph_Marker_Pinpoint() + { + parent::Image_Graph_Marker_Icon( + dirname(__FILE__).'/../Images/Icons/pinpoint.png' + ); + $this->setPointX(0); + $this->setPointY(13); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Plus.php b/config/archive/dspam/pear/Image/Graph/Marker/Plus.php new file mode 100644 index 00000000..0a817cfc --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Plus.php @@ -0,0 +1,98 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as a plus. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Plus extends Image_Graph_Marker +{ + + /** + * The thickness of the plus in pixels (thickness is actually double this) + * @var int + * @access private + */ + var $_thickness = 2; + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + if ($this->_thickness > 0) { + $this->_getLineStyle(); + $this->_getFillStyle(); + $this->_canvas->addVertex(array('x' => $x - $this->_size, 'y' => $y - $this->_thickness)); + $this->_canvas->addVertex(array('x' => $x - $this->_thickness, 'y' => $y - $this->_thickness)); + $this->_canvas->addVertex(array('x' => $x - $this->_thickness, 'y' => $y - $this->_size)); + $this->_canvas->addVertex(array('x' => $x + $this->_thickness, 'y' => $y - $this->_size)); + $this->_canvas->addVertex(array('x' => $x + $this->_thickness, 'y' => $y - $this->_thickness)); + $this->_canvas->addVertex(array('x' => $x + $this->_size, 'y' => $y - $this->_thickness)); + $this->_canvas->addVertex(array('x' => $x + $this->_size, 'y' => $y + $this->_thickness)); + $this->_canvas->addVertex(array('x' => $x + $this->_thickness, 'y' => $y + $this->_thickness)); + $this->_canvas->addVertex(array('x' => $x + $this->_thickness, 'y' => $y + $this->_size)); + $this->_canvas->addVertex(array('x' => $x - $this->_thickness, 'y' => $y + $this->_size)); + $this->_canvas->addVertex(array('x' => $x - $this->_thickness, 'y' => $y + $this->_thickness)); + $this->_canvas->addVertex(array('x' => $x - $this->_size, 'y' => $y + $this->_thickness)); + $this->_canvas->polygon(array('connect' => true)); + } else { + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x - $this->_size, 'y0' => $y, 'x1' => $x + $this->_size, 'y1' => $y)); + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x, 'y0' => $y - $this->_size, 'x1' => $x, 'y1' => $y + $this->_size)); + } + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Pointing.php b/config/archive/dspam/pear/Image/Graph/Marker/Pointing.php new file mode 100644 index 00000000..05ab94e4 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Pointing.php @@ -0,0 +1,140 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as a 'pointing marker'. + * + * Points to the data using another marker (as start and/or end) + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Pointing extends Image_Graph_Marker +{ + + /** + * The starting marker + * @var Marker + * @access private + */ + var $_markerStart; + + /** + * The ending marker + * @var Marker + * @access private + */ + var $_markerEnd; + + /** + * The X offset from the 'data' + * @var int + * @access private + */ + var $_deltaX = -1; + + /** + * The Y offset from the 'data' + * @var int + * @access private + */ + var $_deltaY = -1; + + /** + * Create an pointing marker, ie a pin on a board + * + * @param int $deltaX The the X offset from the real 'data' point + * @param int $deltaY The the Y offset from the real 'data' point + * @param Marker $markerEnd The ending marker that represents 'the head of + * the pin' + */ + function Image_Graph_Marker_Pointing($deltaX, $deltaY, & $markerEnd) + { + parent::Image_Graph_Marker(); + $this->_deltaX = $deltaX; + $this->_deltaY = $deltaY; + $this->_markerStart = null; + $this->_markerEnd =& $markerEnd; + } + + /** + * Sets the starting marker, ie the tip of the pin on a board + * + * @param Marker $markerStart The starting marker that represents 'the tip + * of the pin' + */ + function setMarkerStart(& $markerStart) + { + $this->_markerStart =& $markerStart; + $this->_markerStart->_setParent($this); + } + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + parent::_drawMarker($x, $y, $values); + if ($this->_markerStart) { + $this->_markerStart->_setParent($this); + $this->_markerStart->_drawMarker($x, $y, $values); + } + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $x + $this->_deltaX, 'y1' => $y + $this->_deltaY)); + $this->_markerEnd->_setParent($this); + $this->_markerEnd->_drawMarker( + $x + $this->_deltaX, + $y + $this->_deltaY, + $values + ); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Pointing/Angular.php b/config/archive/dspam/pear/Image/Graph/Marker/Pointing/Angular.php new file mode 100644 index 00000000..93b8b7cf --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Pointing/Angular.php @@ -0,0 +1,105 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker/Pointing.php + */ +require_once 'Image/Graph/Marker/Pointing.php'; + +/** + * Marker that points 'away' from the graph. + * + * Use this as a marker for displaying another marker pointing to the original + * point on the graph - where the 'pointer' is calculated as line orthogonal to + * a line drawn between the points neighbours to both sides (an approximate + * tangent). This should make an the pointer appear to point 'straight' out from + * the graph. The 'head' of the pointer is then another marker of any choice. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Pointing_Angular extends Image_Graph_Marker_Pointing +{ + + /** + * The length of the angular marker + * @var int + * @access private + */ + var $_radius; + + /** + * Image_Graph_AngularPointingMarker [Constructor] + * @param int $radius The 'length' of the pointer + * @param Marker $markerEnd The ending marker that represents 'the head of + * the pin' + */ + function Image_Graph_Marker_Pointing_Angular($radius, & $markerEnd) + { + parent::Image_Graph_Marker_Pointing(0, 0, $markerEnd); + $this->_radius = $radius; + } + + /** + * Draw the marker on the canvas + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + if ((isset($values['LENGTH'])) && ($values['LENGTH'] != 0)) { + $this->_deltaX = - $values['AX'] * $this->_radius / $values['LENGTH']; + $this->_deltaY = - $values['AY'] * $this->_radius / $values['LENGTH']; + } + + if ((isset($values['NPY'])) && (isset($values['APY'])) && + (isset($values['PPY'])) && ($values['NPY'] > $values['APY']) && + ($values['PPY'] > $values['APY'])) + { + $this->_deltaX = - $this->_deltaX; + $this->_deltaY = - $this->_deltaY; + } + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Pointing/Radial.php b/config/archive/dspam/pear/Image/Graph/Marker/Pointing/Radial.php new file mode 100644 index 00000000..ce1a0aac --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Pointing/Radial.php @@ -0,0 +1,91 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker/Pointing.php + */ +require_once 'Image/Graph/Marker/Pointing.php'; + +/** + * A pointing marker in a random angle from the data + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Pointing_Radial extends Image_Graph_Marker_Pointing +{ + + /** + * The radius of the radial marker + * @var int + * @access private + */ + var $_radius; + + /** + * Create an radial pointing marker, ie a marker on a defined distance from + * the data + * @param int $radius The 'length' of the pointer + * @param Marker $markerEnd The ending marker that represents 'the head of + * the pin' + */ + function Image_Graph_Marker_Pointing_Radial($radius, & $markerEnd) + { + parent::Image_Graph_Marker_Pointing(0, 0, $markerEnd); + $this->_radius = $radius; + } + + /** + * Draw the marker on the canvas + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $angle = pi() * rand(0, 360) / 180; + $this->_deltaX = $this->_radius * cos($angle); + $this->_deltaY = $this->_radius * sin($angle); + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/ReversePinpoint.php b/config/archive/dspam/pear/Image/Graph/Marker/ReversePinpoint.php new file mode 100644 index 00000000..57e945ab --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/ReversePinpoint.php @@ -0,0 +1,65 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker/Icon.php + */ +require_once 'Image/Graph/Marker/Icon.php'; + +/** + * Data marker using a (reverse) pinpoint as marker. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_ReversePinpoint extends Image_Graph_Marker_Icon +{ + + /** + * Create the marker as a reverse pin point + */ + function Image_Graph_Marker_ReversePinpoint() + { + parent::Image_Graph_Marker_Icon( + dirname(__FILE__).'/../Images/Icons/pinpointr.png' + ); + $this->setPointX(10); + $this->setPointY(13); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Star.php b/config/archive/dspam/pear/Image/Graph/Marker/Star.php new file mode 100644 index 00000000..67b2b9b3 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Star.php @@ -0,0 +1,88 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as a triangle. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Star extends Image_Graph_Marker +{ + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $this->_getFillStyle(); + $this->_getLineStyle(); + + $d = $this->_size / 5; + $x = round($x); + $y = round($y); + + $this->_canvas->addVertex(array('x' => $x, 'y' => $y - $this->_size)); + $this->_canvas->addVertex(array('x' => $x + round($d), 'y' => $y - round($d))); + $this->_canvas->addVertex(array('x' => $x + $this->_size, 'y' => $y - round($d))); + $this->_canvas->addVertex(array('x' => $x + round(2 * $d), 'y' => $y + round($d))); + $this->_canvas->addVertex(array('x' => $x + round(3 * $d), 'y' => $y + $this->_size)); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y + round(3 * $d))); + $this->_canvas->addVertex(array('x' => $x - round(3 * $d), 'y' => $y + $this->_size)); + $this->_canvas->addVertex(array('x' => $x - round(2 * $d), 'y' => $y + round($d))); + $this->_canvas->addVertex(array('x' => $x - $this->_size, 'y' => $y - round($d))); + $this->_canvas->addVertex(array('x' => $x - round($d), 'y' => $y - round($d))); + $this->_canvas->polygon(array('connect' => true)); + + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Triangle.php b/config/archive/dspam/pear/Image/Graph/Marker/Triangle.php new file mode 100644 index 00000000..626f2589 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Triangle.php @@ -0,0 +1,75 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * Data marker as a triangle. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Triangle extends Image_Graph_Marker +{ + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + $this->_getFillStyle(); + $this->_getLineStyle(); + $this->_canvas->addVertex(array('x' => $x - $this->_size, 'y' => $y + $this->_size)); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y - $this->_size)); + $this->_canvas->addVertex(array('x' => $x + $this->_size, 'y' => $y + $this->_size)); + $this->_canvas->polygon(array('connect' => true)); + parent::_drawMarker($x, $y, $values); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Marker/Value.php b/config/archive/dspam/pear/Image/Graph/Marker/Value.php new file mode 100644 index 00000000..24f142f3 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Marker/Value.php @@ -0,0 +1,214 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Marker.php + */ +require_once 'Image/Graph/Marker.php'; + +/** + * A marker showing the data value. + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Marker_Value extends Image_Graph_Marker +{ + + /** + * Datapreproccesor to format the value + * @var DataPreprocessor + * @access private + */ + var $_dataPreprocessor = null; + + /** + * Which value to use from the data set, ie the X or Y value + * @var int + * @access private + */ + var $_useValue; + + /** + * Create a value marker, ie a box containing the value of the 'pointing + * data' + * + * @param int $useValue Defines which value to use from the dataset, i.e. the + * X or Y value + */ + function Image_Graph_Marker_Value($useValue = IMAGE_GRAPH_VALUE_X) + { + parent::Image_Graph_Marker(); + $this->_padding = array('left' => 2, 'top' => 2, 'right' => 2, 'bottom' => 2); + $this->_useValue = $useValue; + $this->_fillStyle = 'white'; + $this->_borderStyle = 'black'; + } + + /** + * Sets the background fill style of the element + * + * @param Image_Graph_Fill $background The background + * @see Image_Graph_Fill + */ + function setBackground(& $background) + { + $this->setFillStyle($background); + } + + /** + * Sets the background color of the element + * + * @param mixed $color The color + */ + function setBackgroundColor($color) + { + $this->setFillColor($color); + } + + /** + * Sets a data preprocessor for formatting the values + * + * @param DataPreprocessor $dataPreprocessor The data preprocessor + * @return Image_Graph_DataPreprocessor The data preprocessor + */ + function &setDataPreprocessor(& $dataPreprocessor) + { + $this->_dataPreprocessor =& $dataPreprocessor; + return $dataPreprocessor; + } + + /** + * Get the value to display + * + * @param array $values The values representing the data the marker 'points' + * to + * @return string The display value, this is the pre-preprocessor value, to + * support for customized with multiple values. i.e show 'x = y' or '(x, y)' + * @access private + */ + function _getDisplayValue($values) + { + switch ($this->_useValue) { + case IMAGE_GRAPH_VALUE_X: + $value = $values['X']; + break; + + case IMAGE_GRAPH_PCT_X_MIN: + $value = $values['PCT_MIN_X']; + break; + + case IMAGE_GRAPH_PCT_X_MAX: + $value = $values['PCT_MAX_X']; + break; + + case IMAGE_GRAPH_PCT_Y_MIN: + $value = $values['PCT_MIN_Y']; + break; + + case IMAGE_GRAPH_PCT_Y_MAX: + $value = $values['PCT_MAX_Y']; + break; + + case IMAGE_GRAPH_PCT_Y_TOTAL: + if (isset($values['SUM_Y'])) { + $value = 100 * $values['Y'] / $values['SUM_Y']; + } + else { + $value = 0; + } + break; + + case IMAGE_GRAPH_POINT_ID: + $value = $values['ID']; + break; + + default: + $value = $values['Y']; + break; + } + return $value; + } + + /** + * Draw the marker on the canvas + * + * @param int $x The X (horizontal) position (in pixels) of the marker on + * the canvas + * @param int $y The Y (vertical) position (in pixels) of the marker on the + * canvas + * @param array $values The values representing the data the marker 'points' + * to + * @access private + */ + function _drawMarker($x, $y, $values = false) + { + parent::_drawMarker($x, $y, $values); + + $value = $this->_getDisplayValue($values); + + if ($this->_dataPreprocessor) { + $value = $this->_dataPreprocessor->_process($value); + } + + if ($this->_defaultFontOptions !== false) { + $this->_canvas->setFont($this->_defaultFontOptions); + } else { + $this->_canvas->setFont($this->_getFont()); + } + + $width = $this->_canvas->textWidth($value); + $height = $this->_canvas->textHeight($value); + $offsetX = $width/2 + $this->_padding['left']; + $offsetY = $height/2 + $this->_padding['top']; + + $this->_getFillStyle(); + $this->_getBorderStyle(); + $this->_canvas->rectangle( + array( + 'x0' => $x - $offsetX, + 'y0' => $y - $offsetY, + 'x1' => $x + $offsetX, + 'y1' => $y + $offsetY + ) + ); + + $this->write($x, $y, $value, IMAGE_GRAPH_ALIGN_CENTER); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot.php b/config/archive/dspam/pear/Image/Graph/Plot.php new file mode 100644 index 00000000..4a6c16d3 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot.php @@ -0,0 +1,824 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plotarea/Element.php + */ +require_once 'Image/Graph/Plotarea/Element.php'; + +/** + * Framework for a chart + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Plot extends Image_Graph_Plotarea_Element +{ + + /** + * The dataset to plot + * @var Dataset + * @access private + */ + var $_dataset; + + /** + * The marker to plot the data set as + * @var Marker + * @access private + */ + var $_marker = null; + + /** + * The dataselector to use for data marking + * @var DataSelector + * @access private + */ + var $_dataSelector = null; + + /** + * The Y axis to associate the plot with + * @var int + * @access private + */ + var $_axisY = IMAGE_GRAPH_AXIS_Y; + + /** + * The type of the plot if multiple datasets are used + * @var string + * @access private + */ + var $_multiType = 'normal'; + + /** + * The title of the plot, used for legending in case of simple plots + * @var string + * @access private + */ + var $_title = 'plot'; + + /** + * PlotType [Constructor] + * + * Valid values for multiType are: + * + * 'normal' Plot is normal, multiple datasets are displayes next to one + * another + * + * 'stacked' Datasets are stacked on top of each other + * + * 'stacked100pct' Datasets are stacked and displayed as percentages of the + * total sum + * + * I no title is specified a default is used, which is basically the plot + * type (fx. for a 'Image_Graph_Plot_Smoothed_Area' default title is + * 'Smoothed Area') + * + * @param Image_Graph_Dataset $dataset The data set (value containter) to + * plot or an array of datasets + * @param string $multiType The type of the plot + * @param string $title The title of the plot (used for legends, + * {@link Image_Graph_Legend}) + */ + function Image_Graph_Plot(& $dataset, $multiType = 'normal', $title = '') + { + if (!is_a($dataset, 'Image_Graph_Dataset')) { + if (is_array($dataset)) { + $keys = array_keys($dataset); + foreach ($keys as $key) { + if (!is_a($dataset[$key], 'Image_Graph_Dataset')) { + $this->_error('Invalid dataset passed to ' . get_class($this)); + } + } + unset($keys); + } else { + $this->_error('Invalid dataset passed to ' . get_class($this)); + } + } + + parent::Image_Graph_Common(); + if ($dataset) { + if (is_array($dataset)) { + $this->_dataset =& $dataset; + } else { + $this->_dataset = array(&$dataset); + } + } + if ($title) { + $this->_title = $title; + } else { + $this->_title = str_replace('_', ' ', substr(get_class($this), 17)); + } + + $multiType = strtolower($multiType); + if (($multiType == 'normal') || + ($multiType == 'stacked') || + ($multiType == 'stacked100pct')) + { + $this->_multiType = $multiType; + } else { + $this->_error( + 'Invalid multitype: ' . $multiType . + ' expected (normal|stacked|stacked100pct)' + ); + $this->_multiType = 'normal'; + } + } + + /** + * Sets the title of the plot, used for legend + * + * @param string $title The title of the plot + */ + function setTitle($title) + { + $this->_title = $title; + } + + /** + * Parses the URL mapping data in the point and adds it to the parameter array used by + * Image_Canvas + * + * @param array $point The data point (from the dataset) + * @param array $canvasData The The for the canvas method + * @return array The union of the canvas data points and the appropriate points for the dataset + * @access private + */ + function _mergeData($point, $canvasData) + { + if (isset($point['data'])) { + if (isset($point['data']['url'])) { + $canvasData['url'] = $point['data']['url']; + } + if (isset($point['data']['target'])) { + $canvasData['target'] = $point['data']['target']; + } + if (isset($point['data']['alt'])) { + $canvasData['alt'] = $point['data']['alt']; + } + if (isset($point['data']['htmltags'])) { + $canvasData['htmltags'] = $point['data']['htmltags']; + } + } + + return $canvasData; + } + + /** + * Sets the Y axis to plot the data + * + * @param int $axisY The Y axis (either IMAGE_GRAPH_AXIS_Y / 'y' or + * IMAGE_GRAPH_AXIS_Y_SECONDARY / 'ysec' (defaults to IMAGE_GRAPH_AXIS_Y)) + * @access private + */ + function _setAxisY($axisY) + { + if ($axisY == 'y') { + $this->_axisY = IMAGE_GRAPH_AXIS_Y; + } elseif ($axisY == 'ysec') { + $this->_axisY = IMAGE_GRAPH_AXIS_Y_SECONDARY; + } else { + $this->_axisY = $axisY; + } + } + + /** + * Sets the marker to 'display' data points on the graph + * + * @param Marker $marker The marker + */ + function &setMarker(& $marker) + { + $this->add($marker); + $this->_marker =& $marker; + return $marker; + } + + /** + * Sets the dataselector to specify which data should be displayed on the + * plot as markers and which are not + * + * @param DataSelector $dataSelector The dataselector + */ + function setDataSelector(& $dataSelector) + { + $this->_dataSelector =& $dataSelector; + } + + /** + * Calculate marker point data + * + * @param array Point The point to calculate data for + * @param array NextPoint The next point + * @param array PrevPoint The previous point + * @param array Totals The pre-calculated totals, if needed + * @return array An array containing marker point data + * @access private + */ + function _getMarkerData($point, $nextPoint, $prevPoint, & $totals) + { + if (is_array($this->_dataset)) { + if ($this->_multiType == 'stacked') { + if (!isset($totals['SUM_Y'])) { + $totals['SUM_Y'] = array(); + } + $x = $point['X']; + if (!isset($totals['SUM_Y'][$x])) { + $totals['SUM_Y'][$x] = 0; + } + } elseif ($this->_multiType == 'stacked100pct') { + $x = $point['X']; + if ($totals['TOTAL_Y'][$x] != 0) { + if (!isset($totals['SUM_Y'])) { + $totals['SUM_Y'] = array(); + } + if (!isset($totals['SUM_Y'][$x])) { + $totals['SUM_Y'][$x] = 0; + } + } + } + + if (isset($totals['ALL_SUM_Y'])) { + $point['SUM_Y'] = $totals['ALL_SUM_Y']; + } + + if (!$prevPoint) { + $point['AX'] = -5; + $point['AY'] = 5; + $point['PPX'] = 0; + $point['PPY'] = 0; + $point['NPX'] = $nextPoint['X']; + $point['NPY'] = $nextPoint['Y']; + } elseif (!$nextPoint) { + $point['AX'] = 5; + $point['AY'] = 5; + $point['PPX'] = $prevPoint['X']; + $point['PPY'] = $prevPoint['Y']; + $point['NPX'] = 0; + $point['NPY'] = 0; + } else { + $point['AX'] = $this->_pointY($prevPoint) - $this->_pointY($nextPoint); + $point['AY'] = $this->_pointX($nextPoint) - $this->_pointX($prevPoint); + $point['PPX'] = $prevPoint['X']; + $point['PPY'] = $prevPoint['Y']; + $point['NPX'] = $nextPoint['X']; + $point['NPY'] = $nextPoint['Y']; + } + + $point['APX'] = $point['X']; + $point['APY'] = $point['Y']; + + if ((isset($totals['MINIMUM_X'])) && ($totals['MINIMUM_X'] != 0)) { + $point['PCT_MIN_X'] = 100 * $point['X'] / $totals['MINIMUM_X']; + } + if ((isset($totals['MAXIMUM_X'])) && ($totals['MAXIMUM_X'] != 0)) { + $point['PCT_MAX_X'] = 100 * $point['X'] / $totals['MAXIMUM_X']; + } + + if ((isset($totals['MINIMUM_Y'])) && ($totals['MINIMUM_Y'] != 0)) { + $point['PCT_MIN_Y'] = 100 * $point['Y'] / $totals['MINIMUM_Y']; + } + if ((isset($totals['MAXIMUM_Y'])) && ($totals['MAXIMUM_Y'] != 0)) { + $point['PCT_MAX_Y'] = 100 * $point['Y'] / $totals['MAXIMUM_Y']; + } + + $point['LENGTH'] = sqrt($point['AX'] * $point['AX'] + + $point['AY'] * $point['AY']); + + if ((isset($point['LENGTH'])) && ($point['LENGTH'] != 0)) { + $point['ANGLE'] = asin($point['AY'] / $point['LENGTH']); + } + + if ((isset($point['AX'])) && ($point['AX'] > 0)) { + $point['ANGLE'] = pi() - $point['ANGLE']; + } + + if ($this->_parent->_horizontal) { + $point['MARKER_Y1'] = $this->_pointY($point) - + (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0); + + $point['MARKER_Y2'] = $this->_pointY($point) + + (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0); + + $point['COLUMN_WIDTH'] = abs($point['MARKER_Y2'] - + $point['MARKER_Y1']) / count($this->_dataset); + + $point['MARKER_Y'] = $point['MARKER_Y1'] + + ((isset($totals['NUMBER']) ? $totals['NUMBER'] : 0) + 0.5) * + $point['COLUMN_WIDTH']; + + $point['MARKER_X'] = $this->_pointX($point); + + if ($this->_multiType == 'stacked') { + $point['MARKER_Y'] = + ($point['MARKER_Y1'] + $point['MARKER_Y2']) / 2; + + $P1 = array('Y' => $totals['SUM_Y'][$x]); + $P2 = array('Y' => $totals['SUM_Y'][$x] + $point['Y']); + + $point['MARKER_X'] = + ($this->_pointX($P1) + $this->_pointX($P2)) / 2; + } elseif ($this->_multiType == 'stacked100pct') { + $x = $point['X']; + if ($totals['TOTAL_Y'][$x] != 0) { + $point['MARKER_Y'] = + ($point['MARKER_Y1'] + $point['MARKER_Y2']) / 2; + + $P1 = array( + 'Y' => 100 * $totals['SUM_Y'][$x] / $totals['TOTAL_Y'][$x] + ); + + $P2 = array( + 'Y' => 100 * ($totals['SUM_Y'][$x] + $point['Y']) / $totals['TOTAL_Y'][$x] + ); + + $point['MARKER_X'] = + ($this->_pointX($P1) + $this->_pointX($P2)) / 2; + } else { + $point = false; + } + } + } + else { + $point['MARKER_X1'] = $this->_pointX($point) - + (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0); + + $point['MARKER_X2'] = $this->_pointX($point) + + (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0); + + $point['COLUMN_WIDTH'] = abs($point['MARKER_X2'] - + $point['MARKER_X1']) / count($this->_dataset); + + $point['MARKER_X'] = $point['MARKER_X1'] + + ((isset($totals['NUMBER']) ? $totals['NUMBER'] : 0) + 0.5) * + $point['COLUMN_WIDTH']; + + $point['MARKER_Y'] = $this->_pointY($point); + + if ($this->_multiType == 'stacked') { + $point['MARKER_X'] = + ($point['MARKER_X1'] + $point['MARKER_X2']) / 2; + + $P1 = array('Y' => $totals['SUM_Y'][$x]); + $P2 = array('Y' => $totals['SUM_Y'][$x] + $point['Y']); + + $point['MARKER_Y'] = + ($this->_pointY($P1) + $this->_pointY($P2)) / 2; + } elseif ($this->_multiType == 'stacked100pct') { + $x = $point['X']; + if ($totals['TOTAL_Y'][$x] != 0) { + $point['MARKER_X'] = + ($point['MARKER_X1'] + $point['MARKER_X2']) / 2; + + $P1 = array( + 'Y' => 100 * $totals['SUM_Y'][$x] / $totals['TOTAL_Y'][$x] + ); + + $P2 = array( + 'Y' => 100 * ($totals['SUM_Y'][$x] + $point['Y']) / $totals['TOTAL_Y'][$x] + ); + + $point['MARKER_Y'] = + ($this->_pointY($P1) + $this->_pointY($P2)) / 2; + } else { + $point = false; + } + } + } + return $point; + } + } + + /** + * Draws markers on the canvas + * + * @access private + */ + function _drawMarker() + { + if (($this->_marker) && (is_array($this->_dataset))) { + $this->_canvas->startGroup(get_class($this) . '_marker'); + + $totals = $this->_getTotals(); + $totals['WIDTH'] = $this->width() / ($this->_maximumX() + 2) / 2; + + $number = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $totals['MINIMUM_X'] = $dataset->minimumX(); + $totals['MAXIMUM_X'] = $dataset->maximumX(); + $totals['MINIMUM_Y'] = $dataset->minimumY(); + $totals['MAXIMUM_Y'] = $dataset->maximumY(); + $totals['NUMBER'] = $number ++; + $dataset->_reset(); + while ($point = $dataset->_next()) { + $prevPoint = $dataset->_nearby(-2); + $nextPoint = $dataset->_nearby(); + + $x = $point['X']; + $y = $point['Y']; + if (((!is_object($this->_dataSelector)) || + ($this->_dataSelector->_select($point))) && ($point['Y'] !== null)) + { + + $point = $this->_getMarkerData( + $point, + $nextPoint, + $prevPoint, + $totals + ); + + if (is_array($point)) { + $this->_marker->_drawMarker( + $point['MARKER_X'], + $point['MARKER_Y'], + $point + ); + } + } + if (!isset($totals['SUM_Y'])) { + $totals['SUM_Y'] = array(); + } + if (isset($totals['SUM_Y'][$x])) { + $totals['SUM_Y'][$x] += $y; + } else { + $totals['SUM_Y'][$x] = $y; + } + } + } + unset($keys); + $this->_canvas->endGroup(); + } + } + + /** + * Get the minimum X value from the dataset + * + * @return double The minimum X value + * @access private + */ + function _minimumX() + { + if (!is_array($this->_dataset)) { + return 0; + } + + $min = false; + if (is_array($this->_dataset)) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + if ($min === false) { + $min = $this->_dataset[$key]->minimumX(); + } else { + $min = min($min, $this->_dataset[$key]->minimumX()); + } + } + unset($keys); + } + return $min; + } + + /** + * Get the maximum X value from the dataset + * + * @return double The maximum X value + * @access private + */ + function _maximumX() + { + if (!is_array($this->_dataset)) { + return 0; + } + + $max = 0; + if (is_array($this->_dataset)) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $max = max($max, $this->_dataset[$key]->maximumX()); + } + unset($keys); + } + return $max; + } + + /** + * Get the minimum Y value from the dataset + * + * @return double The minimum Y value + * @access private + */ + function _minimumY() + { + if (!is_array($this->_dataset)) { + return 0; + } + + $min = false; + if (is_array($this->_dataset)) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + if ($this->_multiType == 'normal') { + if ($min === false) { + $min = $this->_dataset[$key]->minimumY(); + } else { + $min = min($min, $this->_dataset[$key]->minimumY()); + } + } else { + if ($min === false) { + $min = 0; + } + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($point = $dataset->_next()) { + if ($point['Y'] < 0) { + $x = $point['X']; + if ((!isset($total)) || (!isset($total[$x]))) { + $total[$x] = $point['Y']; + } else { + $total[$x] += $point['Y']; + } + if (isset($min)) { + $min = min($min, $total[$x]); + } else { + $min = $total[$x]; + } + } + } + } + } + unset($keys); + } + return $min; + } + + /** + * Get the maximum Y value from the dataset + * + * @return double The maximum Y value + * @access private + */ + function _maximumY() + { + if ($this->_multiType == 'stacked100pct') { + return 100; + } + + $maxY = 0; + if (is_array($this->_dataset)) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + + if ($this->_multiType == 'normal') { + if (isset($maxY)) { + $maxY = max($maxY, $dataset->maximumY()); + } else { + $maxY = $dataset->maximumY(); + } + } else { + $dataset->_reset(); + while ($point = $dataset->_next()) { + if ($point['Y'] > 0) { + $x = $point['X']; + if ((!isset($total)) || (!isset($total[$x]))) { + $total[$x] = $point['Y']; + } else { + $total[$x] += $point['Y']; + } + if (isset($maxY)) { + $maxY = max($maxY, $total[$x]); + } else { + $maxY = $total[$x]; + } + } + } + } + } + unset($keys); + } + return $maxY; + } + + /** + * Get the X pixel position represented by a value + * + * @param double $point The value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointX($point) + { + $point['AXIS_Y'] = $this->_axisY; + return parent::_pointX($point); + } + + /** + * Get the Y pixel position represented by a value + * + * @param double $point the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointY($point) + { + $point['AXIS_Y'] = $this->_axisY; + return parent::_pointY($point); + } + + /** + * Update coordinates + * + * @access private + */ + function _updateCoords() + { + $this->_setCoords($this->_parent->_plotLeft, $this->_parent->_plotTop, $this->_parent->_plotRight, $this->_parent->_plotBottom); + parent::_updateCoords(); + } + + /** + * Get the dataset + * + * @return Image_Graph_Dataset The dataset(s) + */ + function &dataset() + { + return $this->_dataset; + } + + /** + * Calulate totals + * + * @return array An associated array with the totals + * @access private + */ + function _getTotals() + { + $total = array( + 'MINIMUM_X' => $this->_minimumX(), + 'MAXIMUM_X' => $this->_maximumX(), + 'MINIMUM_Y' => $this->_minimumY(), + 'MAXIMUM_Y' => $this->_maximumY() + ); + $total['ALL_SUM_Y'] = 0; + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + + $dataset->_reset(); + while ($point = $dataset->_next()) { + $x = $point['X']; + + if (is_numeric($point['Y'])) { + $total['ALL_SUM_Y'] += $point['Y']; + if (isset($total['TOTAL_Y'][$x])) { + $total['TOTAL_Y'][$x] += $point['Y']; + } else { + $total['TOTAL_Y'][$x] = $point['Y']; + } + } + + if (is_numeric($point['X'])) { + if (isset($total['TOTAL_X'][$x])) { + $total['TOTAL_X'][$x] += $point['X']; + } else { + $total['TOTAL_X'][$x] = $point['X']; + } + } + } + } + unset($keys); + return $total; + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $this->_canvas->rectangle(array('x0' => $x0, 'y0' => $y0, 'x1' => $x1, 'y1' => $y1)); + } + + /** + * Draw a sample for use with legend + * + * @param array $param The parameters for the legend + * @access private + */ + function _legendSample(&$param) + { + if (!is_array($this->_dataset)) { + return false; + } + + if (is_a($this->_fillStyle, 'Image_Graph_Fill')) { + $this->_fillStyle->_reset(); + } + + $count = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $count++; + + $caption = ($dataset->_name ? $dataset->_name : $this->_title); + + $this->_canvas->setFont($param['font']); + $width = 20 + $param['width'] + $this->_canvas->textWidth($caption); + $param['maxwidth'] = max($param['maxwidth'], $width); + $x2 = $param['x'] + $width; + $y2 = $param['y'] + $param['height'] + 5; + + if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { + $param['y'] = $param['top']; + $param['x'] = $x2; + $y2 = $param['y'] + $param['height']; + } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { + $param['x'] = $param['left']; + $param['y'] = $y2; + $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($caption); + } + + $x = $x0 = $param['x']; + $y = $param['y']; + $y0 = $param['y']; + $x1 = $param['x'] + $param['width']; + $y1 = $param['y'] + $param['height']; + + if (!isset($param['simulate'])) { + $this->_getFillStyle($key); + $this->_getLineStyle(); + $this->_drawLegendSample($x0, $y0, $x1, $y1); + + if (($this->_marker) && ($dataset) && ($param['show_marker'])) { + $dataset->_reset(); + $point = $dataset->_next(); + $prevPoint = $dataset->_nearby(-2); + $nextPoint = $dataset->_nearby(); + + $tmp = array(); + $point = $this->_getMarkerData($point, $nextPoint, $prevPoint, $tmp); + if (is_array($point)) { + $point['MARKER_X'] = $x+$param['width']/2; + $point['MARKER_Y'] = $y; + unset ($point['AVERAGE_Y']); + $this->_marker->_drawMarker($point['MARKER_X'], $point['MARKER_Y'], $point); + } + } + $this->write($x + $param['width'] + 10, $y + $param['height'] / 2, $caption, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); + } + + if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + $param['y'] = $y2; + } else { + $param['x'] = $x2; + } + } + unset($keys); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Area.php b/config/archive/dspam/pear/Image/Graph/Plot/Area.php new file mode 100644 index 00000000..a5288e1a --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Area.php @@ -0,0 +1,194 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Area Chart plot. + * + * An area chart plots all data points similar to a {@link + * Image_Graph_Plot_Line}, but the area beneath the line is filled and the whole + * area 'the-line', 'the right edge', 'the x-axis' and 'the left edge' is + * bounded. Smoothed charts are only supported with non-stacked types + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Area extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 3; + $dy = abs($y1 - $y0) / 3; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y1)); + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y0 + $dy)); + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y0)); + $this->_canvas->addVertex(array('x' => $x0 + 2*$dx, 'y' => $y0 + 2*$dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y0 + $dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + $base = array(); + if ($this->_multiType == 'stacked') { + reset($this->_dataset); + $key = key($this->_dataset); + $dataset =& $this->_dataset[$key]; + + $first = $dataset->first(); + $point = array ('X' => $first['X'], 'Y' => '#min_pos#'); + $base[] = array(); + $base[] = $this->_pointY($point); + $first = $this->_pointX($point); + $base[] = $first; + + $last = $dataset->last(); + $point = array ('X' => $last['X'], 'Y' => '#min_pos#'); + $base[] = array(); + $base[] = $this->_pointY($point); + $base[] = $this->_pointX($point); + + $current = array(); + } + + $minYaxis = $this->_parent->_getMinimum($this->_axisY); + $maxYaxis = $this->_parent->_getMaximum($this->_axisY); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + if ($this->_multiType == 'stacked') { + $plotarea = array_reverse($base); + $base = array(); + while ($point = $dataset->_next()) { + $x = $point['X']; + $p = $point; + if (isset($current[$x])) { + $p['Y'] += $current[$x]; + } else { + $current[$x] = 0; + } + $x1 = $this->_pointX($p); + $y1 = $this->_pointY($p); + $plotarea[] = $x1; + $plotarea[] = $y1; + $plotarea[] = $point; + $base[] = array(); + $base[] = $y1; + $base[] = $x1; + $current[$x] += $point['Y']; + } + } else { + $first = true; + $plotarea = array(); + while ($point = $dataset->_next()) { + if ($first) { + $firstPoint = array ('X' => $point['X'], 'Y' => '#min_pos#'); + $plotarea[] = $this->_pointX($firstPoint); + $plotarea[] = $this->_pointY($firstPoint); + $plotarea[] = array(); + } + $plotarea[] = $this->_pointX($point); + $plotarea[] = $this->_pointY($point); + $plotarea[] = $point; + $lastPoint = $point; + $first = false; + } + $endPoint['X'] = $lastPoint['X']; + $endPoint['Y'] = '#min_pos#'; + $plotarea[] = $this->_pointX($endPoint); + $plotarea[] = $this->_pointY($endPoint); + $plotarea[] = array(); + } + + reset($plotarea); + while (list(, $x) = each($plotarea)) { + list(, $y) = each($plotarea); + list(, $data) = each($plotarea); + $this->_canvas->addVertex( + $this->_mergeData( + $data, + array('x' => $x, 'y' => $y) + ) + ); + } + + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true, 'map_vertices' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Band.php b/config/archive/dspam/pear/Image/Graph/Plot/Band.php new file mode 100644 index 00000000..3d5b629a --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Band.php @@ -0,0 +1,205 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * "Band" (area chart with min AND max) chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_Band extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $h = abs($y1 - $y0) / 6; + $w = round(abs($x1 - $x0) / 5); + $y = ($y0 + $y1) / 2; + + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y - $h * 3)); + $this->_canvas->addVertex(array('x' => $x0 + $w, 'y' => $y - 4 * $h)); + $this->_canvas->addVertex(array('x' => $x0 + 2 * $w, 'y' => $y - $h * 2)); + $this->_canvas->addVertex(array('x' => $x0 + 3 * $w, 'y' => $y - $h * 4)); + $this->_canvas->addVertex(array('x' => $x0 + 4 * $w, 'y' => $y - $h * 3)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y - $h * 2)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y + $h * 3)); + $this->_canvas->addVertex(array('x' => $x0 + 4 * $w, 'y' => $y + $h)); + $this->_canvas->addVertex(array('x' => $x0 + 3 * $w, 'y' => $y + 2 * $h)); + $this->_canvas->addVertex(array('x' => $x0 + 2 * $w, 'y' => $y + 1 * $h)); + $this->_canvas->addVertex(array('x' => $x0 + 1 * $w, 'y' => $y)); + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y + $h)); + + $this->_getLineStyle(); + $this->_getFillStyle(); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $current = array(); + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $upperBand = array(); + $lowerBand = array(); + while ($data = $dataset->_next()) { + if ($this->_parent->_horizontal) { + $point['X'] = $data['X']; + + $point['Y'] = $data['Y']['high']; + $y = $this->_pointY($point); + $x_high = $this->_pointX($point); + + $point['Y'] = $data['Y']['low']; + $x_low = $this->_pointX($point); + + $data = array('X' => $x_high, 'Y' => $y); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $upperBand[] = $data; + + $data = array('X' => $x_low, 'Y' => $y); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $lowerBand[] = $data; + } + else { + $point['X'] = $data['X']; + $y = $data['Y']; + + $point['Y'] = $data['Y']['high']; + $x = $this->_pointX($point); + $y_high = $this->_pointY($point); + + $point['Y'] = $data['Y']['low']; + $y_low = $this->_pointY($point); + + $data = array('X' => $x, 'Y' => $y_high); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $upperBand[] = $data; + + $data = array('X' => $x, 'Y' => $y_low); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $lowerBand[] = $data; + } + } + $lowerBand = array_reverse($lowerBand); + foreach ($lowerBand as $point) { + $this->_canvas->addVertex( + $this->_mergeData( + $point['data'], + array('x' => $point['X'], 'y' => $point['Y']) + ) + ); + } + foreach ($upperBand as $point) { + $this->_canvas->addVertex( + $this->_mergeData( + $point['data'], + array('x' => $point['X'], 'y' => $point['Y']) + ) + ); + } + unset($upperBand); + unset($lowerBand); + + $this->_getLineStyle($key); + $this->_getFillStyle($key); + $this->_canvas->polygon(array('connect' => true, 'map_vertices' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Bar.php b/config/archive/dspam/pear/Image/Graph/Plot/Bar.php new file mode 100644 index 00000000..3e35f92c --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Bar.php @@ -0,0 +1,307 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * A bar chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Bar extends Image_Graph_Plot +{ + + /** + * The space between 2 bars (should be a multipla of 2) + * @var int + * @access private + */ + var $_space = 4; + + /** + * The width of the bars + * @var array + * @access private + */ + var $_width = 'auto'; + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 7; + $this->_canvas->rectangle(array('x0' => $x0 + $dx, 'y0' => $y0, 'x1' => $x1 - $dx, 'y1' => $y1)); + } + + /** + * Set the spacing between 2 neighbouring bars + * + * @param int $space The number of pixels between 2 bars, should be a + * multipla of 2 (ie an even number) + */ + function setSpacing($space) + { + $this->_space = (int) ($space / 2); + } + + /** + * Set the width of a bars. + * + * Specify 'auto' to auto calculate the width based on the positions on the + * x-axis. + * + * Supported units are: + * + * '%' The width is specified in percentage of the total plot width + * + * 'px' The width specified in pixels + * + * @param string $width The width of any bar + * @param string $unit The unit of the width + */ + function setBarWidth($width, $unit = false) + { + if ($width == 'auto') { + $this->_width = $width; + } else { + $this->_width = array( + 'width' => $width, + 'unit' => $unit + ); + } + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + if ($this->_width == 'auto') { + $width = $this->_parent->_labelDistance(IMAGE_GRAPH_AXIS_X) / 2; + } elseif ($this->_width['unit'] == '%') { + $width = $this->_width['width'] * $this->width() / 200; + } elseif ($this->_width['unit'] == 'px') { + $width = $this->_width['width'] / 2; + } + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + + $minYaxis = $this->_parent->_getMinimum($this->_axisY); + $maxYaxis = $this->_parent->_getMaximum($this->_axisY); + + $number = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($point = $dataset->_next()) { + + if ($this->_parent->_horizontal) { + $y1 = $this->_pointY($point) - $width; + $y2 = $this->_pointY($point) + $width; + + if ($y2 - $this->_space > $y1 + $this->_space) { + /* + * Take bar spacing into account _only_ if the space doesn't + * turn the bar "inside-out", i.e. if the actual bar width + * is smaller than the space between the bars + */ + $y2 -= $this->_space; + $y1 += $this->_space; + } + } + else { + $x1 = $this->_pointX($point) - $width; + $x2 = $this->_pointX($point) + $width; + + if ($x2 - $this->_space > $x1 + $this->_space) { + /* + * Take bar spacing into account _only_ if the space doesn't + * turn the bar "inside-out", i.e. if the actual bar width + * is smaller than the space between the bars + */ + $x2 -= $this->_space; + $x1 += $this->_space; + } + } + + + if (($this->_multiType == 'stacked') || + ($this->_multiType == 'stacked100pct')) + { + $x = $point['X']; + + if ($point['Y'] >= 0) { + if (!isset($current[$x])) { + $current[$x] = 0; + } + + if ($this->_multiType == 'stacked') { + $p0 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + $point['Y'] + ); + } else { + $p0 = array( + 'X' => $point['X'], + 'Y' => 100 * $current[$x] / $total['TOTAL_Y'][$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x] + ); + } + $current[$x] += $point['Y']; + } else { + if (!isset($currentNegative[$x])) { + $currentNegative[$x] = 0; + } + + $p0 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + $point['Y'] + ); + $currentNegative[$x] += $point['Y']; + } + } else { + if (count($this->_dataset) > 1) { + $w = 2 * ($width - $this->_space) / count($this->_dataset); + if ($this->_parent->_horizontal) { + $y2 = ($y1 = ($y1 + $y2) / 2 - ($width - $this->_space) + $number * $w) + $w; + } + else { + $x2 = ($x1 = ($x1 + $x2) / 2 - ($width - $this->_space) + $number * $w) + $w; + } + } + $p0 = array('X' => $point['X'], 'Y' => 0); + $p1 = $point; + } + + if ((($minY = min($p0['Y'], $p1['Y'])) < $maxYaxis) && + (($maxY = max($p0['Y'], $p1['Y'])) > $minYaxis) + ) { + $p0['Y'] = $minY; + $p1['Y'] = $maxY; + + if ($p0['Y'] < $minYaxis) { + $p0['Y'] = '#min_pos#'; + } + if ($p1['Y'] > $maxYaxis) { + $p1['Y'] = '#max_neg#'; + } + + if ($this->_parent->_horizontal) { + $x1 = $this->_pointX($p0); + $x2 = $this->_pointX($p1); + } + else { + $y1 = $this->_pointY($p0); + $y2 = $this->_pointY($p1); + } + + $ID = $point['ID']; + if (($ID === false) && (count($this->_dataset) > 1)) { + $ID = $key; + } + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + + if (($y1 != $y2) && ($x1 != $x2)) { + $this->_canvas->rectangle( + $this->_mergeData( + $point, + array( + 'x0' => min($x1, $x2), + 'y0' => min($y1, $y2), + 'x1' => max($x1, $x2), + 'y1' => max($y1, $y2) + ) + ) + ); + } + } + } + $number ++; + } + unset($keys); + + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/BoxWhisker.php b/config/archive/dspam/pear/Image/Graph/Plot/BoxWhisker.php new file mode 100644 index 00000000..59c1ee44 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/BoxWhisker.php @@ -0,0 +1,298 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Box & Whisker chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_BoxWhisker extends Image_Graph_Plot +{ + /** + * Whisker circle size + * @var int + * @access private + */ + var $_whiskerSize = false; + + /** + * Draws a box & whisker + * + * @param int $x The x position + * @param int $w The width of the box + * @param int $r The radius of the circle markers + * @param int $y_min The Y position of the minimum value + * @param int $y_q1 The Y position of the median of the first quartile + * @param int $y_med The Y position of the median + * @param int $y_q3 The Y position of the median of the third quartile + * @param int $y_max The Y position of the maximum value + * @param int $key The ID tag + * @access private + */ + function _drawBoxWhiskerV($x, $w, $r, $y_min, $y_q1, $y_med, $y_q3, $y_max, $key = false) + { + // draw circles + $this->_getLineStyle(); + $this->_getFillStyle('min'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_min, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile1'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_q1, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('median'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_med, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile3'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_q3, $r, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('max'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_max, $r, 'rx' => $r, 'ry' => $r)); + + // draw box and lines + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x, 'y0' => $y_min, 'x1' => $x, 'y1' => $y_q1)); + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x, 'y0' => $y_q3, 'x1' => $x, 'y1' => $y_max)); + + $this->_getLineStyle(); + $this->_getFillStyle('box'); + $this->_canvas->rectangle(array('x0' => $x - $w, 'y0' => $y_q1, 'x1' => $x + $w, 'y1' => $y_q3)); + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x - $w, 'y0' => $y_med, 'x1' => $x + $w, 'y1' => $y_med)); + } + + /** + * Draws a box & whisker + * + * @param int $y The x position + * @param int $h The width of the box + * @param int $r The radius of the circle markers + * @param int $x_min The Y position of the minimum value + * @param int $x_q1 The Y position of the median of the first quartile + * @param int $x_med The Y position of the median + * @param int $x_q3 The Y position of the median of the third quartile + * @param int $x_max The Y position of the maximum value + * @param int $key The ID tag + * @access private + */ + function _drawBoxWhiskerH($y, $h, $r, $x_min, $x_q1, $x_med, $x_q3, $x_max, $key = false) + { + // draw circles + $this->_getLineStyle(); + $this->_getFillStyle('min'); + $this->_canvas->ellipse(array('x' => $x_min, 'y' => $y, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile1'); + $this->_canvas->ellipse(array('x' => $x_q1, 'y' => $y, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('median'); + $this->_canvas->ellipse(array('x' => $x_med, 'y' => $y, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile3'); + $this->_canvas->ellipse(array('x' => $x_q3, 'y' => $y, $r, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('max'); + $this->_canvas->ellipse(array('x' => $x_max, 'y' => $y, $r, 'rx' => $r, 'ry' => $r)); + + // draw box and lines + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x_min, 'y0' => $y, 'x1' => $x_q1, 'y1' => $y)); + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x_q3, 'y0' => $y, 'x1' => $x_max, 'y1' => $y)); + + $this->_getLineStyle(); + $this->_getFillStyle('box'); + $this->_canvas->rectangle(array('x0' => $x_q1, 'y0' => $y - $h, 'x1' => $x_q3, 'y1' => $y + $h)); + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x_med, 'y0' => $y - $h, 'x1' => $x_med, 'y1' => $y + $h)); + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $x = round(($x0 + $x1) / 2); + $h = abs($y1 - $y0) / 9; + $w = round(abs($x1 - $x0) / 5); + $r = 2;//round(abs($x1 - $x0) / 13); + $this->_drawBoxWhiskerV($x, $w, $r, $y1, $y1 - 2 * $h, $y1 - 4 * $h, $y0 + 3 * $h, $y0); + } + + /** + * Sets the whisker circle size + * + * @param int $size Size (radius) of the whisker circle/dot + */ + function setWhiskerSize($size = false) + { + $this->_whiskerSize = $size; + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + $current = array(); + $number = 0; + $width = floor(0.5 * $this->_parent->_labelDistance(IMAGE_GRAPH_AXIS_X) / 2); + + if ($this->_whiskerSize !== false) { + $r = $this->_whiskerSize; + } else { + $r = min(5, $width / 10); + } + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($data = $dataset->_next()) { + if ($this->_parent->_horizontal) { + $point['X'] = $data['X']; + $y = $data['Y']; + + $min = min($y); + $max = max($y); + $q1 = $dataset->_median($y, 'first'); + $med = $dataset->_median($y, 'second'); + $q3 = $dataset->_median($y, 'third'); + + $point['Y'] = $min; + $y = $this->_pointY($point); + $x_min = $this->_pointX($point); + + $point['Y'] = $max; + $x_max = $this->_pointX($point); + + $point['Y'] = $q1; + $x_q1 = $this->_pointX($point); + + $point['Y'] = $med; + $x_med = $this->_pointX($point); + + $point['Y'] = $q3; + $x_q3 = $this->_pointX($point); + + $this->_drawBoxWhiskerH($y, $width, $r, $x_min, $x_q1, $x_med, $x_q3, $x_max, $key); + } + else { + $point['X'] = $data['X']; + $y = $data['Y']; + + $min = min($y); + $max = max($y); + $q1 = $dataset->_median($y, 'first'); + $med = $dataset->_median($y, 'second'); + $q3 = $dataset->_median($y, 'third'); + + $point['Y'] = $min; + $x = $this->_pointX($point); + $y_min = $this->_pointY($point); + + $point['Y'] = $max; + $y_max = $this->_pointY($point); + + $point['Y'] = $q1; + $y_q1 = $this->_pointY($point); + + $point['Y'] = $med; + $y_med = $this->_pointY($point); + + $point['Y'] = $q3; + $y_q3 = $this->_pointY($point); + + $this->_drawBoxWhiskerV($x, $width, $r, $y_min, $y_q1, $y_med, $y_q3, $y_max, $key); + } + } + } + unset($keys); + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/CandleStick.php b/config/archive/dspam/pear/Image/Graph/Plot/CandleStick.php new file mode 100644 index 00000000..b050aea1 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/CandleStick.php @@ -0,0 +1,251 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Candlestick chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_CandleStick extends Image_Graph_Plot +{ + + /** + * (Add basic description here) + * + * @access private + */ + function _drawCandleStickH($y, $h, $x_min, $x_open, $x_close, $x_max, $ID) + { + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => min($x_open, $x_close), + 'y0' => $y, + 'x1' => $x_min, + 'y1' => $y + ) + ); + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => max($x_open, $x_close), + 'y0' => $y, + 'x1' => $x_max, + 'y1' => $y + ) + ); + + $this->_getLineStyle($ID); + $this->_getFillStyle($ID); + $this->_canvas->rectangle( + array( + 'x0' => min($x_open, $x_close), + 'y0' => $y - $h, + 'x1' => max($x_open, $x_close), + 'y1' => $y + $h + ) + ); + } + + /** + * (Add basic description here) + * + * @access private + */ + function _drawCandleStickV($x, $w, $y_min, $y_open, $y_close, $y_max, $ID) + { + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => $x, + 'y0' => min($y_open, $y_close), + 'x1' => $x, + 'y1' => $y_max + ) + ); + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => $x, + 'y0' => max($y_open, $y_close), + 'x1' => $x, + 'y1' => $y_min + ) + ); + + $this->_getLineStyle($ID); + $this->_getFillStyle($ID); + $this->_canvas->rectangle( + array( + 'x0' => $x - $w, + 'y0' => min($y_open, $y_close), + 'x1' => $x + $w, + 'y1' => max($y_open, $y_close) + ) + ); + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $x = round(($x0 + $x1) / 2); + $h = abs($y1 - $y0) / 4; + $w = round(abs($x1 - $x0) / 5); + $this->_drawCandleStickV($x, $w, $y1, $y1 - $h, $y0 + $h, $y0, 'green'); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + $current = array(); + $number = 0; + $width = floor(0.8 * $this->_parent->_labelDistance(IMAGE_GRAPH_AXIS_X) / 2); + + $lastClosed = false; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($data = $dataset->_next()) { + if ($this->_parent->_horizontal) { + $point['X'] = $data['X']; + //$y = $data['Y']; + + if (isset($data['Y']['open'])) { + $point['Y'] = $data['Y']['open']; + } else { + $point['Y'] = $lastClosed; + } + $y = $this->_pointY($point); + $x_open = $this->_pointX($point); + + $lastClosed = $point['Y'] = $data['Y']['close']; + $x_close = $this->_pointX($point); + + $point['Y'] = $data['Y']['min']; + $x_min = $this->_pointX($point); + + $point['Y'] = $data['Y']['max']; + $x_max = $this->_pointX($point); + + if ($data['Y']['close'] < $data['Y']['open']) { + $ID = 'red'; + } else { + $ID = 'green'; + } + + $this->_drawCandleStickH($y, $width, $x_min, $x_open, $x_close, $x_max, $ID); + } + else { + $point['X'] = $data['X']; + //$y = $data['Y']; + + if (isset($data['Y']['open'])) { + $point['Y'] = $data['Y']['open']; + } else { + $point['Y'] = $lastClosed; + } + $x = $this->_pointX($point); + $y_open = $this->_pointY($point); + + $lastClosed = $point['Y'] = $data['Y']['close']; + $y_close = $this->_pointY($point); + + $point['Y'] = $data['Y']['min']; + $y_min = $this->_pointY($point); + + $point['Y'] = $data['Y']['max']; + $y_max = $this->_pointY($point); + + if ($data['Y']['close'] < $data['Y']['open']) { + $ID = 'red'; + } else { + $ID = 'green'; + } + + $this->_drawCandleStickV($x, $width, $y_min, $y_open, $y_close, $y_max, $ID); + } + } + } + unset($keys); + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup($this->_title); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Dot.php b/config/archive/dspam/pear/Image/Graph/Plot/Dot.php new file mode 100644 index 00000000..19352567 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Dot.php @@ -0,0 +1,99 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Dot / scatter chart (only marker). + * + * This plot type only displays a {@link Image_Graph_Marker} for the datapoints. + * The marker must explicitly be defined using {@link Image_Graph_Plot:: + * setMarker()}. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Dot extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + if (isset($this->_marker)) { + $key = key($this->_dataset); + $samplePoint = $this->_dataset[$key]->_nearby(); + $this->_marker->_drawMarker(($x0 + $x1) / 2, ($y0 + $y1) / 2, $samplePoint); + } + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (Image_Graph_Plot::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Fit/Line.php b/config/archive/dspam/pear/Image/Graph/Plot/Fit/Line.php new file mode 100644 index 00000000..07f3b9cc --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Fit/Line.php @@ -0,0 +1,118 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Include file Image/Graph/Tool.php + */ +require_once 'Image/Graph/Tool.php'; + +/** + * Fit the graph (to a line using linear regression). + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Fit_Line extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $y = ($y0 + $y1) / 2; + $dy = abs($y1 - $y0) / 6; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y + $dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y - $dy)); + $this->_canvas->polygon(array('connect' => false)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (Image_Graph_Plot::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $data = array(); + while ($point = $dataset->_next()) { + $data[] = array( + 'X' => $this->_pointX($point), + 'Y' => $this->_pointY($point) + ); + } + + $regression = Image_Graph_Tool::calculateLinearRegression($data); + $this->_getLineStyle($key); + $this->_canvas->line( + array( + 'x0' => $this->_left, + 'y0' => $this->_left * $regression['slope'] + $regression['intersection'], + 'x1' => $this->_right, + 'y1' => $this->_right * $regression['slope'] + $regression['intersection'] + ) + ); + } + $this->_clip(false); + $this->_canvas->endGroup(); + + return true; + } +} + +?> diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Impulse.php b/config/archive/dspam/pear/Image/Graph/Plot/Impulse.php new file mode 100644 index 00000000..91372cd1 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Impulse.php @@ -0,0 +1,204 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Impulse chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Impulse extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $x = ($x0 + $x1) / 2; + $this->_canvas->line(array('x0' => $x, 'y0' => $y0, 'x1' => $x, 'y1' => $y1)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + $current = array(); + $number = 0; + + $minYaxis = $this->_parent->_getMinimum($this->_axisY); + $maxYaxis = $this->_parent->_getMaximum($this->_axisY); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($point = $dataset->_next()) { + $x0 = $this->_pointX($point); + if (($this->_multiType == 'stacked') || + ($this->_multiType == 'stacked100pct')) + { + $x = $point['X']; + + if ($point['Y'] >= 0) { + if (!isset($current[$x])) { + $current[$x] = 0; + } + + if ($this->_multiType == 'stacked') { + $p0 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + $point['Y'] + ); + } else { + $p0 = array( + 'X' => $point['X'], + 'Y' => 100 * $current[$x] / $total['TOTAL_Y'][$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x] + ); + } + $current[$x] += $point['Y']; + } else { + if (!isset($currentNegative[$x])) { + $currentNegative[$x] = 0; + } + + $p0 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + $point['Y'] + ); + $currentNegative[$x] += $point['Y']; + } + } else { + $p0 = array('X' => $point['X'], 'Y' => 0); + $p1 = $point; + } + + if ((($minY = min($p0['Y'], $p1['Y'])) < $maxYaxis) && + (($maxY = max($p0['Y'], $p1['Y'])) > $minYaxis) + ) { + $p0['Y'] = $minY; + $p1['Y'] = $maxY; + + if ($p0['Y'] < $minYaxis) { + $p0['Y'] = '#min_pos#'; + } + if ($p1['Y'] > $maxYaxis) { + $p1['Y'] = '#max_neg#'; + } + + $x1 = $this->_pointX($p0); + $y1 = $this->_pointY($p0); + + $x2 = $this->_pointX($p1); + $y2 = $this->_pointY($p1); + + if ($this->_multiType == 'normal') { + $offset = 5*$number; + $x1 += $offset; + $x2 += $offset; + } + + $ID = $point['ID']; + if (($ID === false) && (count($this->_dataset) > 1)) { + $ID = $key; + } + $this->_getLineStyle($key); + $this->_canvas->line( + $this->_mergeData( + $point, + array( + 'x0' => $x1, + 'y0' => $y1, + 'x1' => $x2, + 'y1' => $y2 + ) + ) + ); + } + } + $number++; + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Line.php b/config/archive/dspam/pear/Image/Graph/Plot/Line.php new file mode 100644 index 00000000..009b4e1f --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Line.php @@ -0,0 +1,171 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Linechart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Line extends Image_Graph_Plot +{ + + /** + * Gets the fill style of the element + * + * @return int A GD filestyle representing the fill style + * @see Image_Graph_Fill + * @access private + */ + function _getFillStyle($ID = false) + { + return IMG_COLOR_TRANSPARENT; + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $y = ($y0 + $y1) / 2; + $dx = abs($x1 - $x0) / 3; + $dy = abs($y1 - $y0) / 5; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y)); + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y - $dy * 2)); + $this->_canvas->addVertex(array('x' => $x1 - $dx, 'y' => $y + $dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y - $dy)); + $this->_canvas->polygon(array('connect' => false)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + reset($this->_dataset); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + + $p1 = false; + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $numPoints = 0; + while ($point = $dataset->_next()) { + if (($this->_multiType == 'stacked') || + ($this->_multiType == 'stacked100pct')) + { + $x = $point['X']; + if (!isset($current[$x])) { + $current[$x] = 0; + } + if ($this->_multiType == 'stacked') { + $py = $current[$x] + $point['Y']; + } else { + $py = 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x]; + } + $current[$x] += $point['Y']; + $point['Y'] = $py; + } + + if ($point['Y'] === null) { + if ($numPoints > 1) { + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + $numPoints = 0; + } else { + $p2['X'] = $this->_pointX($point); + $p2['Y'] = $this->_pointY($point); + + $this->_canvas->addVertex( + $this->_mergeData( + $point, + array('x' => $p2['X'], 'y' => $p2['Y']) + ) + ); + $numPoints++; + } + } + if ($numPoints > 1) { + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Odo.php b/config/archive/dspam/pear/Image/Graph/Plot/Odo.php new file mode 100644 index 00000000..d6bf7969 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Odo.php @@ -0,0 +1,719 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Include file Image/Graph/Tool.php + */ +require_once 'Image/Graph/Tool.php'; + +/** + * 2D Odochart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Maxime Delorme + * @copyright Copyright (C) 2005 Maxime Delorme + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Odo extends Image_Graph_Plot +{ + /** + * the percent of the radius of the chart that will be use as the width of the range + * @access private + * @var int + */ + var $_radiusPercent = 50; + + /** + * the minimun value of the chart or the start value + * @access private + * @var int + */ + var $_value_min = 0; + + /** + * the maximum value of the chart or the end value + * @access private + * @var int + */ + var $_value_max = 100; + + /** + * the start angle + * @access private + * @var int + */ + var $_deg_offset = 135; + + /** + * the angle of the chart , the length of the chart + * 180 min a half circle + * @access private + * @var int + */ + var $_deg_width = 270; + + /** + * the length of the big ticks + * the small ones will be half ot it, the values 160% of it + * 180 min a half circle + * @access private + * @var int + */ + var $_tickLength = 14; + + /** + * how many small ticks a big tick appears + * the small ticks appear every 6° + * so with the default value of 5, every 30° there is a value and a big tick + * 180 min a half circle + * @access private + * @var int + */ + var $_axisTicks = 5; + + /** + * Arrow marker + * @access private + * @var Image_Graph_Marker + */ + var $_arrowMarker; + + /** + * Range marker fill style + * @access private + * @var Image_Graph_Fill + */ + var $_rangeFillStyle = null; + + /** + * The width of the arrow + * @access private + * @var int + */ + var $_arrowWidth = 5; + + /** + * The length of the arrow + * @access private + * @var int + */ + var $_arrowLength = 80; + + /** + * The radius of the plot + * @access private + * @var int + */ + var $_radius = false; + + /** + * The total Y + * @access private + * @var int + */ + var $_totalY = false; + + /** + * Center X of odometer "circle" + * @access private + * @var int + */ + var $_centerX = false; + + /** + * Center y of odometer "circle" + * @access private + * @var int + */ + var $_centerY = false; + + /** + * Plot_Odo [Constructor] + * + * dataset with one data per arrow + * @param Image_Graph_Dataset $dataset The data set (value containter) to + * plot or an array of datasets + * {@link Image_Graph_Legend} + */ + function Image_Graph_Plot_Odo(&$dataset) + { + parent::Image_Graph_Plot($dataset); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + if (isset($min)) { + $min = min($dataset->minimumY(), $min); + } + else { + $min = $dataset->minimumY(); + } + if (isset($max)) { + $max = max($dataset->maximumY(), $max); + } + else { + $max = $dataset->maximumY(); + } + } + $this->_value_min = $min; + $this->_value_max = $max; + } + + /** + * Set the center of the odometer + * + * @param int $centerX The center x point + * @param int $centerY The center y point + */ + function setCenter($centerX, $centerY) + { + $this->_centerX = $centerX; + $this->_centerY = $centerY; + } + + /** + * Convert a value to the angle position onto the odometer + * + * @access private + * @param int $value the value to convert + * @return int the angle'position onto the odometer + */ + function _value2angle($value) + { + return $this->_deg_width * (($value - $this->_value_min) / $this->_totalY) + $this->_deg_offset; + } + + /** + * set some internal var + * + * @access private + */ + function _initialize() + { + $v1 = $this->_deg_offset; + $v2 = $this->_deg_offset + $this->_deg_width; + + $dimensions = Image_Graph_Tool::calculateArcDimensionAndCenter($v1, $v2); + + $radiusX = ($this->width() / 2) / $dimensions['rx']; + $radiusY = ($this->height() / 2) / $dimensions['ry']; + + $this->_radius = min($radiusX, $radiusY); + + if ($this->_marker) { + $this->_radius = $this->_radius * 0.85; + } + + //the center of the plot + if ($this->_centerX === false) { + $this->_centerX = (int) (($this->_left + $this->_right) / 2) + + $this->_radius * ($dimensions['cx'] - 0.5); + } + + if ($this->_centerY === false) { + $this->_centerY = (int) (($this->_top + $this->_bottom) / 2) + + $this->_radius * ($dimensions['cy'] - 0.5); + } + + //the max range + $this->_totalY = abs($this->_value_max - $this->_value_min); + } + + /** + * set min and max value of the range + * + * @access public + * @param integer $value_min the minimun value of the chart or the start value + * @param integer $value_max the maximum value of the chart or the end value + */ + function setRange($value_min, $value_max) + { + $this->_value_min = $value_min; + $this->_value_max = $value_max; + } + + /** + * Set start's angle and amplitude of the chart + * + * @access public + * @param integer $deg_offset the start angle + * @param integer $deg_width the angle of the chart (the length) + */ + function setAngles($deg_offset, $deg_width) + { + $this->_deg_offset = min(360, abs($deg_offset)); + $this->_deg_width = min(360, abs($deg_width)); + } + + /** + * set the width of the chart + * + * @access public + * @param string $radius_percent a value between 0 and 100 + */ + function setRadiusWidth($radius_percent) + { + $this->_radiusPercent = $radius_percent; + } + + /** + * set the width and length of the arrow (in percent of the total plot "radius") + * + * @param int length The length in percent + * @param int width The width in percent + */ + function setArrowSize($length, $width) + { + $this->_arrowWidth = max(0, min(100, $width)); + $this->_arrowLength = max(0, min(100, $length)); + } + + /** + * Set the arrow marker + * @param Image_Graph_Marker $marker The marker to set for arrow marker + */ + function setArrowMarker(&$marker) + { + $this->_arrowMarker =& $marker; + } + + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + $this->_initialize(); + $this->_drawRange(); + $this->_drawAxis(); + $this->_drawArrow(); + $this->_drawMarker(); + return true; + } + + /** + * set the length of the ticks + * + * @access public + * @param string $radius_percent a value between 0 and 100 + */ + function setTickLength($radius) + { + $this->_tickLength = $radius; + } + + /** + * set the length of the ticks + * + * @access public + * @param string $radius_percent a value between 0 and 100 + */ + function setAxisTicks($int) + { + $this->_axisTicks = $int; + } + + /** + * Draw the outline and the axis + * + * @access private + */ + function _drawAxis() + { + //draw outline + $this->_getLineStyle(); + $this->_canvas->pieslice( + array( + 'x' => $this->_centerX, + 'y' => $this->_centerY, + 'rx' => $this->_radius, + 'ry' => $this->_radius, + 'v1' => $this->_deg_offset, + 'v2' => $this->_deg_offset+$this->_deg_width, + 'srx' => $this->_radius * (1 - $this->_radiusPercent / 100), + 'sry' => $this->_radius * (1 - $this->_radiusPercent / 100) + ) + ); + + //step for every 6° + $step = (int) ($this->_totalY / $this->_deg_width * 6); + $value = $this->_value_min; + $i = 0; + while ($value <= $this->_value_max) { + $angle = $this->_value2angle($value); + + $cos = cos(deg2rad($angle)); + $sin = sin(deg2rad($angle)); + $point = array('Y' => $value); + $point['AX'] = $cos; + $point['AY'] = $sin; + $point['LENGTH'] = 1; + $x = $this->_centerX + $this->_radius * $cos; + $y = $this->_centerY + $this->_radius * $sin; + $deltaX = - $cos * $this->_tickLength ; + $deltaY = - $sin * $this->_tickLength ; + $this->_getLineStyle(); + if(($i % $this->_axisTicks) == 0){ + $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $x + $deltaX, 'y1' => $y + $deltaY)); + if ($this->_arrowMarker) { + $this->_arrowMarker->_drawMarker($x + $deltaX * 1.6, $y + $deltaY *1.6, $point); + } + } else { + $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $x + $deltaX * 0.5, 'y1' => $y + $deltaY * 0.5)); + } + $i++; + $value += $step; + } + + } + + /** + * Set the line style of the arrows + * + * @param Image_Graph_Line $lineStyle The line style of the Arrow + * @see Image_Graph_Line + * @access public + */ + function setArrowLineStyle($lineStyle) + { + $this->_arrowLineStyle = &$lineStyle; + } + + /** + * Set the fillstyle of the arrows + * + * @param Image_Graph_Fill $fillStyle The fill style of the arrows + * @see Image_Graph_Fill + * @access public + */ + function setArrowFillStyle($fillStyle) + { + $this->_arrowFillStyle = &$fillStyle; + } + + /** + * Draw the arrows + * + * @access private + */ + function _drawArrow() + { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $this->setLineStyle($this->_arrowLineStyle); + $this->setFillStyle($this->_arrowFillStyle); + while ($point = $dataset->_next()) { + $ID = $point['ID']; + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + $deg = $this->_value2angle($point['Y']); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX + $this->_arrowLength * $this->_radius / 100, $this->_centerY, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX, $this->_centerY - $this->_arrowWidth * $this->_radius/100, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX - $this->_arrowWidth * $this->_radius / 100, $this->_centerY, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX,$this->_centerY + $this->_arrowWidth * $this->_radius / 100, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + $this->_canvas->polygon(array('connect' => true)); + } + } + } + + /** + * Calculate marker point data + * + * @param array $point The point to calculate data for + * @param array $nextPoint The next point + * @param array $prevPoint The previous point + * @param array $totals The pre-calculated totals, if needed + * @return array An array containing marker point data + * @access private + */ + function _getMarkerData($point, $nextPoint, $prevPoint, &$totals) + { + $point = parent::_getMarkerData($point, $nextPoint, $prevPoint, $totals); + + $point['ANGLE'] = $this->_value2angle($point['Y']); + + $point['ANG_X'] = cos(deg2rad($point['ANGLE'])); + $point['ANG_Y'] = sin(deg2rad($point['ANGLE'])); + + $point['AX'] = -$point['ANG_X']; + $point['AY'] = -$point['ANG_Y']; + + $point['LENGTH'] = 2.5; //$radius; + + $point['MARKER_X'] = $totals['CENTER_X'] + + $totals['ODO_RADIUS'] * $point['ANG_X']; + $point['MARKER_Y'] = $totals['CENTER_Y'] + + $totals['ODO_RADIUS'] * $point['ANG_Y']; + + return $point; + } + + /** + * Draws markers of the arrows on the canvas + * + * @access private + */ + function _drawMarker() + { + + if ($this->_marker) { + $this->_marker->_radius += $this->_radius / 2; + $totals = $this->_getTotals(); + + $totals['CENTER_X'] = $this->_centerX; + $totals['CENTER_Y'] = $this->_centerY; + + + /* $keys = array_keys($this->_dataset); + foreach ($keys as $key) { */ + $dataset =& $this->_dataset[0]; + + $totals['RADIUS0'] = false; + $totals['ODO_RADIUS'] = 1.1 * $this->_radius * $this->_arrowLength / 100; + $totals['ALL_SUM_Y'] = $this->_totalY; + + $dataset->_reset(); + while ($point = $dataset->_next()) { + if ((!is_object($this->_dataSelector)) || + ($this->_dataSelector->select($point)) + ) { + $point = $this->_getMarkerData( + $point, + false, + false, + $totals + ); + if (is_array($point)) { + $this->_marker->_drawMarker( + $point['MARKER_X'], + $point['MARKER_Y'], + $point + ); + } + } + } + /* } + unset($keys); */ + } + } + + /** + * Set range + * + * dataset with two data start and end value of the range + * @param Image_Graph_Dataset $dataset The data set (value containter) to + * plot or an array of datasets + * + */ + function addRangeMarker($min, $max, $id = false) + { + $this->_range[] = + array( + 'min' => max($this->_value_min, min($min, $max)), + 'max' => min($this->_value_max, max($min, $max)), + 'id' => $id + ); + } + + /** + * Set the fillstyle of the ranges + * + * @param Image_Graph_Fill $fillStyle The fill style of the range + * @see Image_Graph_Fill + * @access public + */ + function &setRangeMarkerFillStyle(&$rangeMarkerFillStyle) + { + $this->_rangeFillStyle = $rangeMarkerFillStyle; + } + + /** + * Draw the ranges + * + * @access private + */ + function _drawRange() + { + if($this->_range){ + $radius0 = $this->_radius * (1 - $this->_radiusPercent/100); + foreach ($this->_range as $range) { + $angle1 = $this->_value2angle($range['min']); + $angle2 = $this->_value2angle($range['max']); + + if (is_object($this->_rangeFillStyle)) { + $this->_canvas->setFill($this->_rangeFillStyle->_getFillStyle($range['id'])); + } elseif ($this->_rangeFillStyle != null) { + $this->_canvas->setFill($this->_rangeFillStyle); + } + $this->_getLineStyle(); + $this->_canvas->Pieslice( + array( + 'x' => $this->_centerX, + 'y' => $this->_centerY, + 'rx' => $this->_radius, + 'ry' => $this->_radius, + 'v1' => $angle1, + 'v2' => $angle2, + 'srx' => $radius0, + 'sry' => $radius0 + ) + ); + } + } + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 4; + $this->_canvas->addVertex(array('x' => $x0 + $dx , 'y' => $y1)); + $this->_canvas->addVertex(array('x' => ($x0 + $x1) / 2, 'y' => $y0 )); + $this->_canvas->addVertex(array('x' => $x1 - $dx , 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Draw a sample for use with legend + * + * @param array $param The parameters for the legend + * @access private + */ + function _legendSample(&$param) + { + if (is_array($this->_dataset)) { + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + $totals = $this->_getTotals(); + $totals['CENTER_X'] = (int) (($this->_left + $this->_right) / 2); + $totals['CENTER_Y'] = (int) (($this->_top + $this->_bottom) / 2); + $totals['RADIUS'] = min($this->height(), $this->width()) * 0.75 * 0.5; + $totals['CURRENT_Y'] = 0; + + if (is_a($this->_fillStyle, "Image_Graph_Fill")) { + $this->_fillStyle->_reset(); + } + + $count = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $count++; + + $dataset->_reset(); + while ($point = $dataset->_next()) { + $caption = $point['X']; + + $this->_canvas->setFont($param['font']); + $width = 20 + $param['width'] + $this->_canvas->textWidth($caption); + $param['maxwidth'] = max($param['maxwidth'], $width); + $x2 = $param['x'] + $width; + $y2 = $param['y'] + $param['height'] + 5; + + if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { + $param['y'] = $param['top']; + $param['x'] = $x2; + $y2 = $param['y'] + $param['height']; + } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { + $param['x'] = $param['left']; + $param['y'] = $y2; + $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($caption); + } + + $x = $x0 = $param['x']; + $y = $param['y']; + $y0 = $param['y'] - $param['height'] / 2; + $x1 = $param['x'] + $param['width']; + $y1 = $param['y'] + $param['height'] / 2; + + if (!isset($param['simulate'])) { + $this->_getFillStyle($point['ID']); + $this->_getLineStyle($point['ID']); + $this->_drawLegendSample($x0, $y0, $x1, $y1); + + if (($this->_marker) && ($dataset) && ($param['show_marker'])) { + $prevPoint = $dataset->_nearby(-2); + $nextPoint = $dataset->_nearby(); + + $p = $this->_getMarkerData($point, $nextPoint, $prevPoint, $totals); + if (is_array($point)) { + $p['MARKER_X'] = $x+$param['width'] / 2; + $p['MARKER_Y'] = $y; + unset ($p['AVERAGE_Y']); + $this->_marker->_drawMarker($p['MARKER_X'], $p['MARKER_Y'], $p); + } + } + $this->write($x + $param['width'] + 10, $y, $caption, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); + } + + if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + $param['y'] = $y2; + } else { + $param['x'] = $x2; + } + } + } + unset($keys); + $this->_clip(false); + $this->_canvas->endGroup(); + } + } +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Pie.php b/config/archive/dspam/pear/Image/Graph/Plot/Pie.php new file mode 100644 index 00000000..f0e872c3 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Pie.php @@ -0,0 +1,623 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * 2D Piechart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Pie extends Image_Graph_Plot +{ + + /** + * The radius of the 'pie' spacing + * @access private + * @var int + */ + var $_radius = 3; + + /** + * Explode pie slices. + * @access private + * @var mixed + */ + var $_explode = false; + + /** + * The starting angle of the plot + * @access private + * @var int + */ + var $_startingAngle = 0; + + /** + * The angle direction (1 = CCW, -1 = CW) + * @access private + * @var int + */ + var $_angleDirection = 1; + + /** + * The diameter of the pie plot + * @access private + * @var int + */ + var $_diameter = false; + + /** + * Group items below this limit together as "the rest" + * @access private + * @var double + */ + var $_restGroupLimit = false; + + /** + * Rest group title + * @access private + * @var string + */ + var $_restGroupTitle = 'The rest'; + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $y = ($y0 + $y1) / 2; + $this->_canvas->pieslice( + array( + 'x' => $x1, + 'y' => $y, + 'rx' => abs($x1 - $x0) / 2, + 'ry' => abs($y1 - $y0) / 2, + 'v1' => 45, + 'v2' => 315 + ) + ); + } + + /** + * Calculate marker point data + * + * @param array $point The point to calculate data for + * @param array $nextPoint The next point + * @param array $prevPoint The previous point + * @param array $totals The pre-calculated totals, if needed + * @return array An array containing marker point data + * @access private + */ + function _getMarkerData($point, $nextPoint, $prevPoint, &$totals) + { + $point = parent::_getMarkerData($point, $nextPoint, $prevPoint, $totals); + + $y = $totals['CURRENT_Y']; + + if ($this->_angleDirection < 0) { + $y = $totals['ALL_SUM_Y'] - $y; + } + + $point['ANGLE'] = 360 * (($y + ($point['Y'] / 2)) / $totals['ALL_SUM_Y']) + $this->_startingAngle; + $totals['CURRENT_Y'] += $point['Y']; + + $point['ANG_X'] = cos(deg2rad($point['ANGLE'])); + $point['ANG_Y'] = sin(deg2rad($point['ANGLE'])); + + $point['AX'] = -10 * $point['ANG_X']; + $point['AY'] = -10 * $point['ANG_Y']; + + if ((isset($totals['ALL_SUM_Y'])) && ($totals['ALL_SUM_Y'] != 0)) { + $point['PCT_MIN_Y'] = $point['PCT_MAX_Y'] = (100 * $point['Y'] / $totals['ALL_SUM_Y']); + } + + $point['LENGTH'] = 10; //$radius; + + $x = $point['X']; + $explodeRadius = 0; + if ((is_array($this->_explode)) && (isset($this->_explode[$x]))) { + $explodeRadius = $this->_explode[$x]; + } elseif (is_numeric($this->_explode)) { + $explodeRadius = $this->_explode; + } + + $point['MARKER_X'] = $totals['CENTER_X'] + + ($totals['RADIUS'] + $explodeRadius) * $point['ANG_X']; + $point['MARKER_Y'] = $totals['CENTER_Y'] + + ($totals['RADIUS'] + $explodeRadius) * $point['ANG_Y']; + + return $point; + } + + /** + * Draws markers on the canvas + * + * @access private + */ + function _drawMarker() + { + + if ($this->_marker) { + $totals = $this->_getTotals(); + + $totals['CENTER_X'] = (int) (($this->_left + $this->_right) / 2); + $totals['CENTER_Y'] = (int) (($this->_top + $this->_bottom) / 2); + + $totals['CURRENT_Y'] = 0; + $number = 0; + + $diameter = $this->_getDiameter(); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + + if (count($this->_dataset) == 1) { + $totals['RADIUS0'] = false; + $totals['RADIUS'] = $diameter / 2; + } else { + $dr = $diameter / (2 * count($this->_dataset)); + + $totals['RADIUS0'] = $number * $dr + ($number > 0 ? $this->_radius : 0); + $totals['RADIUS'] = ($number + 1) * $dr; + } + + $totals['ALL_SUM_Y'] = 0; + $totals['CURRENT_Y'] = 0; + $dataset->_reset(); + while ($point = $dataset->_next()) { + $totals['ALL_SUM_Y'] += $point['Y']; + } + + $dataset->_reset(); + $currentY = 0; + $the_rest = 0; + while ($point = $dataset->_next()) { + if (($this->_restGroupLimit !== false) && ($point['Y'] <= $this->_restGroupLimit)) { + $the_rest += $point['Y']; + } + else { + if ((!is_object($this->_dataSelector)) || + ($this->_dataSelector->select($point)) + ) { + $point = $this->_getMarkerData( + $point, + false, + false, + $totals + ); + if (is_array($point)) { + $this->_marker->_drawMarker( + $point['MARKER_X'], + $point['MARKER_Y'], + $point + ); + } + } + } + } + if ($the_rest > 0) { + $point = array('X' => $this->_restGroupTitle, 'Y' => $the_rest); + $point = $this->_getMarkerData( + $point, + false, + false, + $totals + ); + if (is_array($point)) { + $this->_marker->_drawMarker( + $point['MARKER_X'], + $point['MARKER_Y'], + $point + ); + } + } + $number++; + } + unset($keys); + } + } + + /** + * Explodes a piece of this pie chart + * + * @param int $explode Radius to explode with (or an array) + * @param string $x The 'x' value to explode or omitted + */ + function explode($explode, $x = false) + { + if ($x === false) { + $this->_explode = $explode; + } else { + $this->_explode[$x] = $explode; + } + } + + /** + * Set the starting angle of the plot + * + * East is 0 degrees + * South is 90 degrees + * West is 180 degrees + * North is 270 degrees + * + * It is also possible to specify the direction of the plot angles (i.e. clockwise 'cw' or + * counterclockwise 'ccw') + */ + function setStartingAngle($angle = 0, $direction = 'ccw') + { + $this->_startingAngle = ($angle % 360); + $this->_angleDirection = ($direction == 'ccw' ? 1 : -1); + } + + /** + * Set the diameter of the pie plot (i.e. the number of pixels the + * pie plot should be across) + * + * Use 'max' for the maximum possible diameter + * + * Use negative values for the maximum possible - minus this value (fx -2 + * to leave 1 pixel at each side) + * + * @param mixed @diameter The number of pixels + */ + function setDiameter($diameter) + { + $this->_diameter = $diameter; + } + + /** + * Set the limit for the y-value, where values below are grouped together + * as "the rest" + * + * @param double $limit The limit + * @param string $title The title to display in the legends (default 'The + * rest') + */ + function setRestGroup($limit, $title = 'The rest') + { + $this->_restGroupLimit = $limit; + $this->_restGroupTitle = $title; + } + + /** + * Get the diameter of the plot + * @return int The number of pixels the diameter is + * @access private + */ + function _getDiameter() + { + $diameter = 0; + if ($this->_diameter === false) { + $diameter = min($this->height(), $this->width()) * 0.75; + } + else { + if ($this->_diameter === 'max') { + $diameter = min($this->height(), $this->width()); + } + elseif ($this->_diameter < 0) { + $diameter = min($this->height(), $this->width()) + $this->_diameter; + } else { + $diameter = $this->_diameter; + } + } + return $diameter; + } + + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $number = 0; + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + + $totalY = 0; + $dataset->_reset(); + while ($point = $dataset->_next()) { + $totalY += $point['Y']; + } + + $centerX = (int) (($this->_left + $this->_right) / 2); + $centerY = (int) (($this->_top + $this->_bottom) / 2); + $diameter = $this->_getDiameter(); + if ($this->_angleDirection < 0) { + $currentY = $totalY; + } else { + $currentY = 0; //rand(0, 100)*$totalY/100; + } + $dataset->_reset(); + + if (count($this->_dataset) == 1) { + $radius0 = false; + $radius1 = $diameter / 2; + } else { + $dr = $diameter / (2 * count($this->_dataset)); + + $radius0 = $number * $dr + ($number > 0 ? $this->_radius : 0); + $radius1 = ($number + 1) * $dr; + } + + $the_rest = 0; + while ($point = $dataset->_next()) { + if (($this->_restGroupLimit !== false) && ($point['Y'] <= $this->_restGroupLimit)) { + $the_rest += $point['Y']; + } + else { + $angle1 = 360 * ($currentY / $totalY) + $this->_startingAngle; + $currentY += $this->_angleDirection * $point['Y']; + $angle2 = 360 * ($currentY / $totalY) + $this->_startingAngle; + + $x = $point['X']; + $id = $point['ID']; + + $dX = 0; + $dY = 0; + $explodeRadius = 0; + if ((is_array($this->_explode)) && (isset($this->_explode[$x]))) { + $explodeRadius = $this->_explode[$x]; + } elseif (is_numeric($this->_explode)) { + $explodeRadius = $this->_explode; + } + + if ($explodeRadius > 0) { + $dX = $explodeRadius * cos(deg2rad(($angle1 + $angle2) / 2)); + $dY = $explodeRadius * sin(deg2rad(($angle1 + $angle2) / 2)); + } + + $ID = $point['ID']; + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + $this->_canvas->pieslice( + $this->_mergeData( + $point, + array( + 'x' => $centerX + $dX, + 'y' => $centerY + $dY, + 'rx' => $radius1, + 'ry' => $radius1, + 'v1' => $angle1, + 'v2' => $angle2, + 'srx' => $radius0, + 'sry' => $radius0 + ) + ) + ); + } + } + + if ($the_rest > 0) { + $angle1 = 360 * ($currentY / $totalY) + $this->_startingAngle; + $currentY += $this->_angleDirection * $the_rest; + $angle2 = 360 * ($currentY / $totalY) + $this->_startingAngle; + + $x = 'rest'; + $id = 'rest'; + + $dX = 0; + $dY = 0; + $explodeRadius = 0; + if ((is_array($this->_explode)) && (isset($this->_explode[$x]))) { + $explodeRadius = $this->_explode[$x]; + } elseif (is_numeric($this->_explode)) { + $explodeRadius = $this->_explode; + } + + if ($explodeRadius > 0) { + $dX = $explodeRadius * cos(deg2rad(($angle1 + $angle2) / 2)); + $dY = $explodeRadius * sin(deg2rad(($angle1 + $angle2) / 2)); + } + + $ID = $id; + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + $this->_canvas->pieslice( + $this->_mergeData( + $point, + array( + 'x' => $centerX + $dX, + 'y' => $centerY + $dY, + 'rx' => $radius1, + 'ry' => $radius1, + 'v1' => $angle1, + 'v2' => $angle2, + 'srx' => $radius0, + 'sry' => $radius0 + ) + ) + ); + } + $number++; + } + unset($keys); + $this->_drawMarker(); + return true; + } + + /** + * Draw a sample for use with legend + * + * @param array $param The parameters for the legend + * @access private + */ + function _legendSample(&$param) + { + if (is_array($this->_dataset)) { + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + $totals = $this->_getTotals(); + $totals['CENTER_X'] = (int) (($this->_left + $this->_right) / 2); + $totals['CENTER_Y'] = (int) (($this->_top + $this->_bottom) / 2); + $totals['RADIUS'] = min($this->height(), $this->width()) * 0.75 * 0.5; + $totals['CURRENT_Y'] = 0; + + if (is_a($this->_fillStyle, "Image_Graph_Fill")) { + $this->_fillStyle->_reset(); + } + + $count = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $count++; + + $dataset->_reset(); + $the_rest = 0; + while ($point = $dataset->_next()) { + $caption = $point['X']; + if (($this->_restGroupLimit !== false) && ($point['Y'] <= $this->_restGroupLimit)) { + $the_rest += $point['Y']; + } + else { + $this->_canvas->setFont($param['font']); + $width = 20 + $param['width'] + $this->_canvas->textWidth($caption); + $param['maxwidth'] = max($param['maxwidth'], $width); + $x2 = $param['x'] + $width; + $y2 = $param['y'] + $param['height']+5; + + if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { + $param['y'] = $param['top']; + $param['x'] = $x2; + $y2 = $param['y'] + $param['height']; + } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { + $param['x'] = $param['left']; + $param['y'] = $y2; + $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($caption); + } + + $x = $x0 = $param['x']; + $y = $param['y']; + $y0 = $param['y'] - $param['height']/2; + $x1 = $param['x'] + $param['width']; + $y1 = $param['y'] + $param['height']/2; + + if (!isset($param['simulate'])) { + $this->_getFillStyle($point['ID']); + $this->_getLineStyle($point['ID']); + $this->_drawLegendSample($x0, $y0, $x1, $y1); + + if (($this->_marker) && ($dataset) && ($param['show_marker'])) { + $prevPoint = $dataset->_nearby(-2); + $nextPoint = $dataset->_nearby(); + + $p = $this->_getMarkerData($point, $nextPoint, $prevPoint, $totals); + if (is_array($point)) { + $p['MARKER_X'] = $x+$param['width']/2; + $p['MARKER_Y'] = $y; + unset ($p['AVERAGE_Y']); + $this->_marker->_drawMarker($p['MARKER_X'], $p['MARKER_Y'], $p); + } + } + $this->write($x + $param['width'] +10, $y, $caption, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); + } + + if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + $param['y'] = $y2; + } else { + $param['x'] = $x2; + } + } + } + if ($the_rest > 0) { + $this->_canvas->setFont($param['font']); + $width = 20 + $param['width'] + $this->_canvas->textWidth($this->_restGroupTitle); + $param['maxwidth'] = max($param['maxwidth'], $width); + $x2 = $param['x'] + $width; + $y2 = $param['y'] + $param['height']+5; + + if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { + $param['y'] = $param['top']; + $param['x'] = $x2; + $y2 = $param['y'] + $param['height']; + } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { + $param['x'] = $param['left']; + $param['y'] = $y2; + $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($this->_restGroupTitle); + } + + $x = $x0 = $param['x']; + $y = $param['y']; + $y0 = $param['y'] - $param['height']/2; + $x1 = $param['x'] + $param['width']; + $y1 = $param['y'] + $param['height']/2; + + if (!isset($param['simulate'])) { + $this->_getFillStyle('rest'); + $this->_getLineStyle('rest'); + $this->_drawLegendSample($x0, $y0, $x1, $y1); + + $this->write($x + $param['width'] + 10, $y, $this->_restGroupTitle, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); + } + + if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + $param['y'] = $y2; + } else { + $param['x'] = $x2; + } + } + } + unset($keys); + $this->_clip(false); + $this->_canvas->endGroup(); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Radar.php b/config/archive/dspam/pear/Image/Graph/Plot/Radar.php new file mode 100644 index 00000000..1bfd9da7 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Radar.php @@ -0,0 +1,118 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Radar chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Radar extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $p = 10; + $rx = abs($x1 - $x0) / 2; + $ry = abs($x1 - $x0) / 2; + $r = min($rx, $ry); + $cx = ($x0 + $x1) / 2; + $cy = ($y0 + $y1) / 2; + $max = 5; + for ($i = 0; $i < $p; $i++) { + $v = 2 * pi() * $i / $p; + $t = $r * rand(3, $max) / $max; + $x = $cx + $t * cos($v); + $y = $cy + $t * sin($v); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + if (is_a($this->_parent, 'Image_Graph_Plotarea_Radar')) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $maxY = $dataset->maximumY(); + $count = $dataset->count(); + + $dataset->_reset(); + while ($point = $dataset->_next()) { + $this->_canvas->addVertex(array('x' => + $this->_pointX($point), 'y' => + $this->_pointY($point) + )); + } + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + unset($keys); + } + $this->_drawMarker(); + + $this->_clip(false); + $this->_canvas->endGroup(); + return parent::_done(); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Area.php b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Area.php new file mode 100644 index 00000000..8ea469dd --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Area.php @@ -0,0 +1,145 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot/Smoothed/Bezier.php + */ +require_once 'Image/Graph/Plot/Smoothed/Bezier.php'; + +/** + * Bezier smoothed area chart + * + * Similar to an {@link Image_Graph_Plot_Area}, but the interconnecting lines + * between two datapoints are smoothed using a Bezier curve, which enables the + * chart to appear as a nice curved plot instead of the sharp edges of a + * conventional {@link Image_Graph_Plot_Area}. Smoothed charts are only supported + * with non-stacked types + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Smoothed_Area extends Image_Graph_Plot_Smoothed_Bezier +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y1)); + $this->_addSamplePoints($x0, $y0, $x1, $y1); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the Bezier smoothed plot as an Area Chart + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $first = true; + while ($p1 = $dataset->_next()) { + $p0 = $dataset->_nearby(-2); + $p2 = $dataset->_nearby(0); + $p3 = $dataset->_nearby(1); + if ($first) { + $p = $p1; + $p['Y'] = '#min_pos#'; + $x = $this->_pointX($p); + $y = $this->_pointY($p); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + + if ($p2) { + $cp = $this->_getControlPoints($p1, $p0, $p2, $p3); + $this->_canvas->addSpline( + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ); + } else { + $x = $this->_pointX($p1); + $y = $this->_pointY($p1); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + $lastPoint = $p1; + $first = false; + } + $lastPoint['Y'] = '#min_pos#'; + $x = $this->_pointX($lastPoint); + $y = $this->_pointY($lastPoint); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php new file mode 100644 index 00000000..bc21b4c8 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php @@ -0,0 +1,173 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Include file Image/Graph/Tool.php + */ +require_once 'Image/Graph/Tool.php'; + +/** + * Bezier smoothed plottype. + * + * The framework for calculating the Bezier smoothed curve from the dataset. + * Used in {@link Image_Graph_Plot_Smoothed_Line} and {@link + * Image_Graph_Plot_Smoothed_Area}. Smoothed charts are only supported with non- + * stacked types + * @link http://homepages.borland.com/efg2lab/Graphics/Jean- + * YvesQueinecBezierCurves.htm efg computer lab - description of bezier curves + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Plot_Smoothed_Bezier extends Image_Graph_Plot +{ + + /** + * Image_Graph_Plot_Smoothed_Bezier [Constructor] + * + * Only 'normal' multitype supported + * + * @param Dataset $dataset The data set (value containter) to plot + * @param string $title The title of the plot (used for legends, {@link + * Image_Graph_Legend}) + */ + function Image_Graph_Plot_Smoothed_Bezier(& $dataset, $title = '') + { + parent::Image_Graph_Plot($dataset, 'normal', $title); + } + + /** + * Return the minimum Y point + * + * @return double The minumum Y point + * @access private + */ + function _minimumY() + { + return 1.05 * parent::_minimumY(); + } + + /** + * Return the maximum Y point + * + * @return double The maximum Y point + * @access private + */ + function _maximumY() + { + return 1.05 * parent::_maximumY(); + } + + /** + * Calculates all Bezier points, for the curve + * + * @param array $p1 The actual point to calculate control points for + * @param array $p0 The point "just before" $p1 + * @param array $p2 The point "just after" $p1 + * @param array $p3 The point "just after" $p2 + * @return array Array of Bezier points + * @access private + */ + function _getControlPoints($p1, $p0, $p2, $p3) + { + $p1 = $this->_pointXY($p1); + if ($p2) { + $p2 = $this->_pointXY($p2); + } + if (!$p0) { + $p0['X'] = $p1['X'] - abs($p2['X'] - $p1['X']); + $p0['Y'] = $p1['Y']; //-($p2['Y']-$p1['Y']); + } else { + $p0 = $this->_pointXY($p0); + } + if (!$p3) { + $p3['X'] = $p1['X'] + 2*abs($p1['X'] - $p0['X']); + $p3['Y'] = $p1['Y']; + } else { + $p3 = $this->_pointXY($p3); + } + + if (!$p2) { + $p2['X'] = $p1['X'] + abs($p1['X'] - $p0['X']); + $p2['Y'] = $p1['Y']; + } + + $pC1['X'] = Image_Graph_Tool::controlPoint($p0['X'], $p1['X'], $p2['X']); + $pC1['Y'] = Image_Graph_Tool::controlPoint($p0['Y'], $p1['Y'], $p2['Y']); + $pC2['X'] = Image_Graph_Tool::controlPoint($p3['X'], $p2['X'], $p1['X']); + $pC2['Y'] = Image_Graph_Tool::controlPoint($p3['Y'], $p2['Y'], $p1['Y']); + + return array( + 'X' => $p1['X'], + 'Y' => $p1['Y'], + 'P1X' => $pC1['X'], + 'P1Y' => $pC1['Y'], + 'P2X' => $pC2['X'], + 'P2Y' => $pC2['Y'] + ); + } + + /** + * Create legend sample data for the canvas. + * + * Common for all smoothed plots + * + * @access private + */ + function _addSamplePoints($x0, $y0, $x1, $y1) + { + $p = abs($x1 - $x0); + $cy = ($y0 + $y1) / 2; + $h = abs($y1 - $y0); + $dy = $h / 4; + $dw = abs($x1 - $x0) / $p; + for ($i = 0; $i < $p; $i++) { + $v = 2 * pi() * $i / $p; + $x = $x0 + $i * $dw; + $y = $cy + 2 * $v * sin($v); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Line.php b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Line.php new file mode 100644 index 00000000..00692839 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Line.php @@ -0,0 +1,172 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot/Smoothed/Bezier.php + */ +require_once 'Image/Graph/Plot/Smoothed/Bezier.php'; + +/** + * Bezier smoothed line chart. + * + * Similar to a {@link Image_Graph_Plot_Line}, but the interconnecting lines + * between two datapoints are smoothed using a Bezier curve, which enables the + * chart to appear as a nice curved plot instead of the sharp edges of a + * conventional {@link Image_Graph_Plot_Line}. Smoothed charts are only supported + * with non-stacked types + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Smoothed_Line extends Image_Graph_Plot_Smoothed_Bezier +{ + + /** + * Gets the fill style of the element + * + * @return int A GD filestyle representing the fill style + * @see Image_Graph_Fill + * @access private + */ + function _getFillStyle($ID = false) + { + return IMG_COLOR_TRANSPARENT; + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $this->_addSamplePoints($x0, $y0, $x1, $y1); + $this->_canvas->polygon(array('connect' => false)); + } + + /** + * Output the Bezier smoothed plot as an Line Chart + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $numPoints = 0; + while ($p1 = $dataset->_next()) { + if ($p1['Y'] === null) { + if ($numPoints > 1) { + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + $numPoints = 0; + } else { + $p0 = $dataset->_nearby(-2); + $p2 = $dataset->_nearby(0); + $p3 = $dataset->_nearby(1); + + if (($p0) && ($p0['Y'] === null)) { + $p0 = false; + } + if (($p2) && ($p2['Y'] === null)) { + $p2 = false; + } + if (($p3) && ($p3['Y'] === null)) { + $p3 = false; + } + + if ($p2) { + $cp = $this->_getControlPoints($p1, $p0, $p2, $p3); + $this->_canvas->addSpline( + $this->_mergeData( + $p1, + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ) + ); + } else { + $x = $this->_pointX($p1); + $y = $this->_pointY($p1); + $this->_canvas->addVertex( + $this->_mergeData( + $p1, + array('x' => $x, 'y' => $y) + ) + ); + } + $numPoints++; + } + } + if ($numPoints > 1) { + $this->_getLineStyle(); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php new file mode 100644 index 00000000..d505a11f --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php @@ -0,0 +1,142 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot/Smoothed/Bezier.php + */ +require_once 'Image/Graph/Plot/Smoothed/Bezier.php'; + +/** + * Smoothed radar chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_Smoothed_Radar extends Image_Graph_Plot_Smoothed_Bezier +{ + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + if (is_a($this->_parent, 'Image_Graph_Plotarea_Radar')) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + if ($dataset->count() >= 3) { + $dataset->_reset(); + $p1_ = $dataset->_next(); + $p2_ = $dataset->_next(); + $p3_ = $dataset->_next(); + $plast_ = false; + if ($p3_) { + while ($p = $dataset->_next()) { + $plast_ = $p; + } + } + + if ($plast_ === false) { + $plast_ = $p3_; + } + $dataset->_reset(); + while ($p1 = $dataset->_next()) { + $p0 = $dataset->_nearby(-2); + $p2 = $dataset->_nearby(0); + $p3 = $dataset->_nearby(1); + + if ($p0 === false) { + $p0 = $plast_; + } + + if ($p2 === false) { + $p2 = $p1_; + $p3 = $p2_; + } elseif ($p3 === false) { + $p3 = $p1_; + } + + + $cp = $this->_getControlPoints($p1, $p0, $p2, $p3); + $this->_canvas->addSpline( + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ); + + $next2last = $p0; + $last = $p1; + } + + $cp = $this->_getControlPoints($p1_, $plast_, $p2_, $p3_); + $this->_canvas->addSpline( + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ); + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + } + unset($keys); + } + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup($this->_title); + return parent::_done(); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plot/Step.php b/config/archive/dspam/pear/Image/Graph/Plot/Step.php new file mode 100644 index 00000000..bc9267fe --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plot/Step.php @@ -0,0 +1,200 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot/Bar.php + */ +require_once 'Image/Graph/Plot/Bar.php'; + +/** + * Step chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Step extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 3; + $dy = abs($y1 - $y0) / 3; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y1)); + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y0 + $dy)); + + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y0 + $dy)); + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y0)); + + $this->_canvas->addVertex(array('x' => $x0 + 2*$dx, 'y' => $y0)); + $this->_canvas->addVertex(array('x' => $x0 + 2*$dx, 'y' => $y0 + 2*$dy)); + + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y0 + 2*$dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * PlotType [Constructor] + * + * A 'normal' step chart is 'stacked' + * + * @param Dataset $dataset The data set (value containter) to plot + * @param string $multiType The type of the plot + * @param string $title The title of the plot (used for legends, + * {@link Image_Graph_Legend}) + */ + function Image_Graph_Plot_Step(& $dataset, $multiType = 'stacked', $title = '') + { + $multiType = strtolower($multiType); + if (($multiType != 'stacked') && ($multiType != 'stacked100pct')) { + $multiType = 'stacked'; + } + parent::Image_Graph_Plot($dataset, $multiType, $title); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (Image_Graph_Plot::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + + if ($this->_parent->_horizontal) { + $width = $this->height() / ($this->_maximumX() + 2) / 2; + } + else { + $width = $this->width() / ($this->_maximumX() + 2) / 2; + } + + reset($this->_dataset); + $key = key($this->_dataset); + $dataset =& $this->_dataset[$key]; + + $first = $dataset->first(); + $last = $dataset->last(); + + $point = array ('X' => $first['X'], 'Y' => '#min_pos#'); + $firstY = $this->_pointY($point) + ($this->_parent->_horizontal ? $width : 0); + $base[] = $firstY; + $firstX = $this->_pointX($point) - ($this->_parent->_horizontal ? 0 : $width); + $base[] = $firstX; + + $point = array ('X' => $last['X'], 'Y' => '#min_pos#'); + $base[] = $this->_pointY($point) - ($this->_parent->_horizontal ? $width : 0); + $base[] = $this->_pointX($point) + ($this->_parent->_horizontal ? 0 : $width); + + $first = ($this->_parent->_horizontal ? $firstY : $firstX); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $polygon = array_reverse($base); + unset ($base); + $last = $first; + while ($point = $dataset->_next()) { + $x = $point['X']; + $p = $point; + + if (!isset($current[$x])) { + $current[$x] = 0; + } + + if ($this->_multiType == 'stacked100pct') { + $p['Y'] = 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x]; + } else { + $p['Y'] += $current[$x]; + } + $current[$x] += $point['Y']; + $point = $p; + + if ($this->_parent->_horizontal) { + $x0 = $this->_pointX($point); + $y0 = $last; + $x1 = $this->_pointX($point); + $last = $y1 = $this->_pointY($point) - $width; + } + else { + $x0 = $last; + $y0 = $this->_pointY($point); + $last = $x1 = $this->_pointX($point) + $width; + $y1 = $this->_pointY($point); + } + $polygon[] = $x0; $base[] = $y0; + $polygon[] = $y0; $base[] = $x0; + $polygon[] = $x1; $base[] = $y1; + $polygon[] = $y1; $base[] = $x1; + } + + while (list(, $x) = each($polygon)) { + list(, $y) = each($polygon); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plotarea.php b/config/archive/dspam/pear/Image/Graph/Plotarea.php new file mode 100644 index 00000000..42aeb26a --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plotarea.php @@ -0,0 +1,1145 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Layout.php + */ +require_once 'Image/Graph/Layout.php'; + +/** + * Plot area used for drawing plots. + * + * The plotarea consists of an x-axis and an y-axis, the plotarea can plot multiple + * charts within one plotares, by simply adding them (the axis' will scale to the + * plots automatically). A graph can consist of more plotareas + * + * @category Images + * @package Image_Graph + * @subpackage Plotarea + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plotarea extends Image_Graph_Layout +{ + + /** + * The left most pixel of the 'real' plot area on the canvas + * @var int + * @access private + */ + var $_plotLeft = 0; + + /** + * The top most pixel of the 'real' plot area on the canvas + * @var int + * @access private + */ + var $_plotTop = 0; + + /** + * The right most pixel of the 'real' plot area on the canvas + * @var int + * @access private + */ + var $_plotRight = 0; + + /** + * The bottom most pixel of the 'real' plot area on the canvas + * @var int + * @access private + */ + var $_plotBottom = 0; + + /** + * The X axis + * @var Axis + * @access private + */ + var $_axisX = null; + + /** + * The Y axis + * @var Axis + * @access private + */ + var $_axisY = null; + + /** + * The secondary Y axis + * @var Axis + * @access private + */ + var $_axisYSecondary = null; + + /** + * The border style of the 'real' plot area + * @var LineStyle + * @access private + */ + var $_plotBorderStyle = null; + + /** + * Does any plot have any data? + * @var bool + * @access private + */ + var $_hasData = false; + + /** + * Is the plotarea horizontal? + * @var bool + * @access private + */ + var $_horizontal = false; + + /** + * Image_Graph_Plotarea [Constructor] + * + * @param string $axisX The class of the X axis (if omitted a std. axis is created) + * @param string $axisY The class of the Y axis (if omitted a std. axis is created) + * @param string $direction The direction of the plotarea - 'horizontal' or 'vertical' (default) + */ + function Image_Graph_Plotarea($axisX = 'Image_Graph_Axis_Category', $axisY = 'Image_Graph_Axis', $direction = 'vertical') + { + parent::Image_Graph_Layout(); + + $this->_padding = array('left' => 5, 'top' => 5, 'right' => 5, 'bottom' => 5);; + + include_once 'Image/Graph.php'; + + $this->_axisX =& Image_Graph::factory($axisX, IMAGE_GRAPH_AXIS_X); + $this->_axisX->_setParent($this); + + $this->_axisY =& Image_Graph::factory($axisY, IMAGE_GRAPH_AXIS_Y); + $this->_axisY->_setParent($this); + $this->_axisY->_setMinimum(0); + + $this->_fillStyle = false; + + if ($direction == 'horizontal') { + $this->_horizontal = true; + $this->_axisX->_transpose = true; + $this->_axisY->_transpose = true; + } + } + + /** + * Sets the parent. The parent chain should ultimately be a GraPHP object + * + * @see Image_Graph_Common + * @param Image_Graph_Common $parent The parent + * @access private + */ + function _setParent(& $parent) + { + parent::_setParent($parent); + if ($this->_axisX !== null) { + $this->_axisX->_setParent($this); + } + if ($this->_axisY !== null) { + $this->_axisY->_setParent($this); + } + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setParent($this); + } + } + + /** + * Sets the plot border line style of the element. + * + * @param Image_Graph_Line $lineStyle The line style of the border + * @deprecated 0.3.0dev2 - 2004-12-16 + */ + function setPlotBorderStyle(& $plotBorderStyle) + { + } + + /** + * Adds an element to the plotarea + * + * @param Image_Graph_Element $element The element to add + * @param int $axis The axis to associate the element with, either + * IMAGE_GRAPH_AXIS_X, IMAGE_GRAPH_AXIS_Y, IMAGE_GRAPH_AXIS_Y_SECONDARY + * or the shorter string notations 'x', 'y' or 'ysec' (defaults to + * IMAGE_GRAPH_AXIS_Y) + * @return Image_Graph_Element The added element + * @see Image_Graph_Common::add() + */ + function &add(& $element, $axis = IMAGE_GRAPH_AXIS_Y) + { + if ($axis == 'x') { + $axis = IMAGE_GRAPH_AXIS_X; + } + if ($axis == 'y') { + $axis = IMAGE_GRAPH_AXIS_Y; + } + if ($axis == 'ysec') { + $axis = IMAGE_GRAPH_AXIS_Y_SECONDARY; + } + if (($axis == IMAGE_GRAPH_AXIS_Y_SECONDARY) && + ($this->_axisYSecondary == null)) + { + $this->_axisYSecondary =& Image_Graph::factory('axis', IMAGE_GRAPH_AXIS_Y_SECONDARY); + $this->_axisYSecondary->_setMinimum(0); + if ($this->_horizontal) { + $this->_axisYSecondary->_transpose = true; + } + } + + parent::add($element); + + if (is_a($element, 'Image_Graph_Plot')) { + $element->_setAxisY($axis); + // postpone extrema calculation until we calculate coordinates + //$this->_setExtrema($element); + } elseif (is_a($element, 'Image_Graph_Grid')) { + switch ($axis) { + case IMAGE_GRAPH_AXIS_X: + if ($this->_axisX != null) { + $element->_setPrimaryAxis($this->_axisX); + if ($this->_axisY != null) { + $element->_setSecondaryAxis($this->_axisY); + } + } + break; + case IMAGE_GRAPH_AXIS_Y: + if ($this->_axisY != null) { + $element->_setPrimaryAxis($this->_axisY); + if ($this->_axisX != null) { + $element->_setSecondaryAxis($this->_axisX); + } + } + break; + case IMAGE_GRAPH_AXIS_Y_SECONDARY: + if ($this->_axisYSecondary != null) { + $element->_setPrimaryAxis($this->_axisYSecondary); + if ($this->_axisX != null) { + $element->_setSecondaryAxis($this->_axisX); + } + } + break; + } + } elseif (is_a($element, 'Image_Graph_Axis')) { + switch ($element->_type) { + case IMAGE_GRAPH_AXIS_X: + $this->_axisX =& $element; + break; + + case IMAGE_GRAPH_AXIS_Y: + $this->_axisY =& $element; + break; + + case IMAGE_GRAPH_AXIS_Y_SECONDARY: + $this->_axisYSecondary =& $element; + break; + + } + if ($element->_getMinimum() == $element->_getMaximum()) { + $element->_setMinimum(0); + $element->_setMaximum(1); + } + } + return $element; + } + + /** + * Get the width of the 'real' plotarea + * + * @return int The width of the 'real' plotarea, ie not including space occupied by padding and axis + * @access private + */ + function _plotWidth() + { + return abs($this->_plotRight - $this->_plotLeft); + } + + /** + * Get the height of the 'real' plotarea + * + * @return int The height of the 'real' plotarea, ie not including space + * occupied by padding and axis + * @access private + */ + function _plotHeight() + { + return abs($this->_plotBottom - $this->_plotTop); + } + + /** + * Set the extrema of the axis + * + * @param Image_Graph_Plot $plot The plot that 'hold' the values + * @access private + */ + function _setExtrema(& $plot) + { + if (($this->_axisX != null) && ($this->_axisX->_isNumeric())) { + $this->_axisX->_setMinimum($plot->_minimumX()); + $this->_axisX->_setMaximum($plot->_maximumX()); + } + + if (($plot->_axisY == IMAGE_GRAPH_AXIS_Y_SECONDARY) && + ($this->_axisYSecondary !== null) && + ($this->_axisYSecondary->_isNumeric())) + { + $this->_axisYSecondary->_setMinimum($plot->_minimumY()); + $this->_axisYSecondary->_setMaximum($plot->_maximumY()); + } elseif (($this->_axisY != null) && ($this->_axisY->_isNumeric())) { + $this->_axisY->_setMinimum($plot->_minimumY()); + $this->_axisY->_setMaximum($plot->_maximumY()); + } + + $datasets =& $plot->dataset(); + if (!is_array($datasets)) { + $datasets = array($datasets); + } + + $keys = array_keys($datasets); + foreach ($keys as $key) { + $dataset =& $datasets[$key]; + if ($dataset->count() > 0) { + $this->_hasData = true; + } + + if (is_a($dataset, 'Image_Graph_Dataset')) { + if (($this->_axisX != null) && (!$this->_axisX->_isNumeric())) { + $this->_axisX->_applyDataset($dataset); + } + + if (($plot->_axisY == IMAGE_GRAPH_AXIS_Y_SECONDARY) && + ($this->_axisYSecondary !== null) && + (!$this->_axisYSecondary->_isNumeric())) + { + $this->_axisYSecondary->_applyDataset($dataset); + } elseif (($this->_axisY != null) && (!$this->_axisY->_isNumeric())) { + $this->_axisY->_applyDataset($dataset); + } + } + } + unset($keys); + } + + /** + * Left boundary of the background fill area + * + * @return int Leftmost position on the canvas + * @access private + */ + function _fillLeft() + { + return $this->_plotLeft; + } + + /** + * Top boundary of the background fill area + * + * @return int Topmost position on the canvas + * @access private + */ + function _fillTop() + { + return $this->_plotTop; + } + + /** + * Right boundary of the background fill area + * + * @return int Rightmost position on the canvas + * @access private + */ + function _fillRight() + { + return $this->_plotRight; + } + + /** + * Bottom boundary of the background fill area + * + * @return int Bottommost position on the canvas + * @access private + */ + function _fillBottom() + { + return $this->_plotBottom; + } + + /** + * Get the point from the x-axis + * @param array $value The value array + * @param int $min The minimum pixel position possible + * @param int $max The maximum pixel position possible + * @return int The pixel position from the axis + * @access private + */ + function _axisPointX($value, $min, $max) + { + if (($this->_axisX == null) || (!isset($value['X']))) { + return false; + } + + if ($value['X'] === '#min#') { + return $min; + } + if ($value['X'] === '#max#') { + return $max; + } + + return $this->_axisX->_point($value['X']); + } + + /** + * Get the point from the x-axis + * @param array $value The value array + * @param int $min The minimum pixel position possible + * @param int $max The maximum pixel position possible + * @return int The pixel position from the axis + * @access private + */ + function _axisPointY($value, $min, $max) + { + if (!isset($value['Y'])) { + return false; + } + + if (($value['Y'] === '#min_pos#') || ($value['Y'] === '#max_nex#')) { + // return the minimum (bottom) position or if negative then zero + // or the maxmum (top) position or if positive then zero + if ((isset($value['AXIS_Y'])) && + ($value['AXIS_Y'] == IMAGE_GRAPH_AXIS_Y_SECONDARY) && + ($this->_axisYSecondary !== null) + ) { + $axisY =& $this->_axisYSecondary; + } else { + $axisY =& $this->_axisY; + } + if ($value['Y'] === '#min_pos#') { + return $axisY->_point(max(0, $axisY->_getMinimum())); + } else { + return $axisY->_point(min(0, $axisY->_getMaximum())); + } + } + + if ($value['Y'] === '#min#') { + return $min; + } + if ($value['Y'] === '#max#') { + return $max; + } + + if ((isset($value['AXIS_Y'])) && + ($value['AXIS_Y'] == IMAGE_GRAPH_AXIS_Y_SECONDARY) + ) { + if ($this->_axisYSecondary !== null) { + return $this->_axisYSecondary->_point($value['Y']); + } + } else { + if ($this->_axisY !== null) { + return $this->_axisY->_point($value['Y']); + } + } + return false; + } + + /** + * Get the X pixel position represented by a value + * + * @param double Value the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointX($value) + { + if ($this->_horizontal) { + return $this->_axisPointY($value, $this->_plotLeft, $this->_plotRight); + } + else { + return $this->_axisPointX($value, $this->_plotLeft, $this->_plotRight); + } + } + + /** + * Get the Y pixel position represented by a value + * + * @param double Value the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointY($value) + { + if ($this->_horizontal) { + return $this->_axisPointX($value, $this->_plotBottom, $this->_plotTop); + } + else { + return $this->_axisPointY($value, $this->_plotBottom, $this->_plotTop); + } + } + + /** + * Return the minimum value of the specified axis + * + * @param int $axis The axis to return the minimum value of (see {$link + * Image_Graph_Plotarea::getAxis()}) + * @return double The minimum value of the axis + * @access private + */ + function _getMinimum($axis = IMAGE_GRAPH_AXIS_Y) + { + $axis =& $this->getAxis($axis); + if ($axis !== null) { + return $axis->_getMinimum(); + } else { + return 0; + } + } + + /** + * Return the maximum value of the specified axis + * + * @param int $axis The axis to return the maximum value of(see {$link + * Image_Graph_Plotarea::getAxis()}) + * @return double The maximum value of the axis + * @access private + */ + function _getMaximum($axis = IMAGE_GRAPH_AXIS_Y) + { + $axis =& $this->getAxis($axis); + if ($axis !== null) { + return $axis->_getMaximum(); + } else { + return 0; + } + } + + /** + * Return the label distance for the specified axis. + * + * @param int $axis The axis to return the label distance for + * @return int The distance between 2 adjacent labels + * @access private + */ + function _labelDistance($axis) + { + $axis =& $this->getAxis($axis); + if ($axis !== null) { + return $axis->_labelDistance(); + } + + return false; + } + + /** + * Hides the axis + */ + function hideAxis($axis = false) + { + if (((!$axis) || ($axis === $this->_axisX) || ($axis === 'x')) && ($this->_axisX != null)) { + $this->_axisX->hide(); + } + if (((!$axis) || ($axis === $this->_axisY) || ($axis === 'y')) && ($this->_axisY != null)) { + $this->_axisY->hide(); + } + if (((!$axis) || ($axis === $this->_axisYSecondary) || ($axis === 'y_sec')) && ($this->_axisYSecondary != null)) { + $this->_axisYSecondary->hide(); + } + } + + /** + * Clears/removes the axis + */ + function clearAxis() + { + $this->_axisX = $this->_axisY = $this->_axisYSecondary = null; + } + + /** + * Get axis. + * + * Possible values are IMAGE_GRAPH_AXIS_X, IMAGE_GRAPH_AXIS_Y, + * IMAGE_GRAPH_AXIS_Y_SECONDARY or a short hand notation using + * string identifiers: 'x', 'y', 'ysec' + * + * @param int $axis The axis to return + * @return Image_Graph_Axis The axis + */ + function &getAxis($axis = IMAGE_GRAPH_AXIS_X) + { + switch ($axis) { + case IMAGE_GRAPH_AXIS_X: + case 'x': + return $this->_axisX; + + case IMAGE_GRAPH_AXIS_Y: + case 'y': + return $this->_axisY; + + case IMAGE_GRAPH_AXIS_Y_SECONDARY: + case 'ysec': + return $this->_axisYSecondary; + + } + return null; + } + + /** + * Update coordinates + * + * @access private + */ + function _updateCoords() + { + if (is_array($this->_elements)) { + $keys = array_keys($this->_elements); + foreach ($keys as $key) { + $element =& $this->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + if (((is_a($element, 'Image_Graph_Plot_Bar')) || + (is_a($element, 'Image_Graph_Plot_Step')) || + (is_a($element, 'Image_Graph_Plot_Dot')) || + (is_a($element, 'Image_Graph_Plot_CandleStick')) || + (is_a($element, 'Image_Graph_Plot_BoxWhisker')) || + (is_a($element, 'Image_Graph_Plot_Impulse'))) && + ($this->_axisX != null) && + (strtolower(get_class($this->_axisX)) != 'image_graph_axis') // do not push plot if x-axis is linear + ) + { + $this->_axisX->_pushValues(); + } + $this->_setExtrema($element); + } + } + unset($keys); + } + + $this->_calcEdges(); + + $pctWidth = (int) ($this->width() * 0.05); + $pctHeight = (int) ($this->height() * 0.05); + + $left = $this->_left + $this->_padding['left']; + $top = $this->_top + $this->_padding['top']; + $right = $this->_right - $this->_padding['right']; + $bottom = $this->_bottom - $this->_padding['bottom']; + + // temporary place holder for axis point calculations + $axisPoints['x'] = array($left, $top, $right, $bottom); + $axisPoints['y'] = $axisPoints['x']; + $axisPoints['y2'] = $axisPoints['x']; + + if ($this->_axisX !== null) { + $intersectX = $this->_axisX->_getAxisIntersection(); + $sizeX = $this->_axisX->_size(); + $this->_axisX->_setCoords($left, $top, $right, $bottom); + $this->_axisX->_updateCoords(); + } + + if ($this->_axisY !== null) { + $intersectY = $this->_axisY->_getAxisIntersection(); + $sizeY = $this->_axisY->_size(); + $this->_axisY->_setCoords($left, $top, $right, $bottom); + $this->_axisY->_updateCoords(); + } + + if ($this->_axisYSecondary !== null) { + $intersectYsec = $this->_axisYSecondary->_getAxisIntersection(); + $sizeYsec = $this->_axisYSecondary->_size(); + $this->_axisYSecondary->_setCoords($left, $top, $right, $bottom); + $this->_axisYSecondary->_updateCoords(); + } + + $axisCoordAdd = array('left' => 0, 'right' => 0, 'top' => 0, 'bottom' => 0); + + if ($this->_axisY != null) { + if ($this->_axisX != null) { + $pos = $this->_axisX->_intersectPoint($intersectY['value']); + } else { + $pos = ($this->_horizontal ? $bottom : $left); + } + + if ($this->_horizontal) { + if (($pos + $sizeY) > $bottom) { + $axisCoordAdd['bottom'] = ($pos + $sizeY) - $bottom; + // the y-axis position needs to be recalculated! + } else { + // top & bottom may need to be adjusted when the x-axis has been + // calculated! + $this->_axisY->_setCoords( + $left, + $pos, + $right, + $pos + $sizeY + ); + $this->_axisY->_updateCoords(); + } + } + else { + if (($pos - $sizeY) < $left) { + $axisCoordAdd['left'] = $left - ($pos - $sizeY); + // the y-axis position needs to be recalculated! + } else { + // top & bottom may need to be adjusted when the x-axis has been + // calculated! + $this->_axisY->_setCoords( + $pos - $sizeY, + $top, + $pos, + $bottom + ); + $this->_axisY->_updateCoords(); + } + } + } + + if ($this->_axisYSecondary != null) { + if ($this->_axisX != null) { + $pos = $this->_axisX->_intersectPoint($intersectYsec['value']); + } else { + $pos = ($this->_horizontal ? $top : $right); + } + + if ($this->_horizontal) { + if (($pos - $sizeYsec) < $top) { + $axisCoordAdd['top'] = $top - ($pos - $sizeYsec); + // the secondary y-axis position need to be recalculated + } else { + // top & bottom may need to be adjusted when the x-axis has been + // calculated! + $this->_axisYSecondary->_setCoords( + $left, + $pos - $sizeY, + $right, + $pos + ); + $this->_axisYSecondary->_updateCoords(); + } + } + else { + if (($pos + $sizeYsec) > $right) { + $axisCoordAdd['right'] = ($pos + $sizeYsec) - $right; + // the secondary y-axis position need to be recalculated + } else { + // top & bottom may need to be adjusted when the x-axis has been + // calculated! + $this->_axisYSecondary->_setCoords( + $pos, + $top, + $pos + $sizeY, + $bottom + ); + $this->_axisYSecondary->_updateCoords(); + } + } + } + + if ($this->_axisX != null) { + if (($intersectX['axis'] == IMAGE_GRAPH_AXIS_Y_SECONDARY) && + ($this->_axisYSecondary !== null) + ) { + $axis =& $this->_axisYSecondary; + } elseif ($this->_axisY !== null) { + $axis =& $this->_axisY; + } else { + $axis = false; + } + + if ($axis !== false) { + $pos = $axis->_intersectPoint($intersectX['value']); + } else { + $pos = ($this->_horizontal ? $left : $bottom); + } + + if ($this->_horizontal) { + if (($pos - $sizeX) < $left) { + $axisCoordAdd['left'] = $left - ($pos - $sizeX); + $pos = $left + $sizeX; + } + + $this->_axisX->_setCoords( + $pos - $sizeX, + $top + $axisCoordAdd['top'], + $pos, + $bottom - $axisCoordAdd['bottom'] + ); + $this->_axisX->_updateCoords(); + } + else { + if (($pos + $sizeX) > $bottom) { + $axisCoordAdd['bottom'] = ($pos + $sizeX) - $bottom; + $pos = $bottom - $sizeX; + } + + $this->_axisX->_setCoords( + $left + $axisCoordAdd['left'], + $pos, + $right - $axisCoordAdd['right'], + $pos + $sizeX + ); + $this->_axisX->_updateCoords(); + } + } + + if ($this->_horizontal) { + if (($this->_axisX !== null) && + (($axisCoordAdd['top'] != 0) || + ($axisCoordAdd['bottom'] != 0)) + ) { + // readjust y-axis for better estimate of position + if ($this->_axisY !== null) { + $pos = $this->_axisX->_intersectPoint($intersectY['value']); + $this->_axisY->_setCoords( + false, + $pos, + false, + $pos + $sizeY + ); + $this->_axisY->_updateCoords(); + } + + if ($this->_axisYSecondary !== null) { + $pos = $this->_axisX->_intersectPoint($intersectYsec['value']); + $this->_axisYSecondary->_setCoords( + false, + $pos - $sizeYsec, + false, + $pos + ); + $this->_axisYSecondary->_updateCoords(); + } + } + + // adjust top and bottom of y-axis + if ($this->_axisY !== null) { + $this->_axisY->_setCoords( + $left + $axisCoordAdd['left'], + false, + $right - $axisCoordAdd['right'], + false + ); + $this->_axisY->_updateCoords(); + } + + // adjust top and bottom of y-axis + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setCoords( + $left + $axisCoordAdd['left'], + false, + $right - $axisCoordAdd['right'], + false + ); + $this->_axisYSecondary->_updateCoords(); + } + + if ($this->_axisX !== null) { + $this->_plotTop = $this->_axisX->_top; + $this->_plotBottom = $this->_axisX->_bottom; + } else { + $this->_plotTop = $top; + $this->_plotBottom = $bottom; + } + + if ($this->_axisY !== null) { + $this->_plotLeft = $this->_axisY->_left; + $this->_plotRight = $this->_axisY->_right; + } elseif ($this->_axisYSecondary !== null) { + $this->_plotLeft = $this->_axisYSecondary->_left; + $this->_plotRight = $this->_axisYSecondary->_right; + } else { + $this->_plotLeft = $this->_left; + $this->_plotRight = $this->_right; + } + } + else { + if (($this->_axisX !== null) && + (($axisCoordAdd['left'] != 0) || + ($axisCoordAdd['right'] != 0)) + ) { + // readjust y-axis for better estimate of position + if ($this->_axisY !== null) { + $pos = $this->_axisX->_intersectPoint($intersectY['value']); + $this->_axisY->_setCoords( + $pos - $sizeY, + false, + $pos, + false + ); + $this->_axisY->_updateCoords(); + } + + if ($this->_axisYSecondary !== null) { + $pos = $this->_axisX->_intersectPoint($intersectYsec['value']); + $this->_axisYSecondary->_setCoords( + $pos, + false, + $pos + $sizeYsec, + false + ); + $this->_axisYSecondary->_updateCoords(); + } + } + + // adjust top and bottom of y-axis + if ($this->_axisY !== null) { + $this->_axisY->_setCoords( + false, + $top + $axisCoordAdd['top'], + false, + $bottom - $axisCoordAdd['bottom'] + ); + $this->_axisY->_updateCoords(); + } + + // adjust top and bottom of y-axis + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setCoords( + false, + $top + $axisCoordAdd['top'], + false, + $bottom - $axisCoordAdd['bottom'] + ); + $this->_axisYSecondary->_updateCoords(); + } + + if ($this->_axisX !== null) { + $this->_plotLeft = $this->_axisX->_left; + $this->_plotRight = $this->_axisX->_right; + } else { + $this->_plotLeft = $left; + $this->_plotRight = $right; + } + + if ($this->_axisY !== null) { + $this->_plotTop = $this->_axisY->_top; + $this->_plotBottom = $this->_axisY->_bottom; + } elseif ($this->_axisYSecondary !== null) { + $this->_plotTop = $this->_axisYSecondary->_top; + $this->_plotBottom = $this->_axisYSecondary->_bottom; + } else { + $this->_plotTop = $this->_top; + $this->_plotBottom = $this->_bottom; + } + } + + Image_Graph_Element::_updateCoords(); +/* + if ($this->_axisX != null) { + $this->_axisX->_updateCoords(); + } + if ($this->_axisY != null) { + $this->_axisY->_updateCoords(); + } + if ($this->_axisYSecondary != null) { + $this->_axisYSecondary->_updateCoords(); + }*/ + } + + /** + * Set the axis padding for a specified position. + * + * The axis padding is padding "inside" the plotarea (i.e. to put some space + * between the axis line and the actual plot). + * + * This can be specified in a number of ways: + * + * 1) Specify an associated array with 'left', 'top', 'right' and 'bottom' + * indices with values for the paddings. Leave out 2nd parameter. + * + * 2) Specify an overall padding as the first parameter + * + * 3) Specify the padding and position with position values as mentioned + * above + * + * Normally you'd only consider applying axis padding to a category x-axis. + * + * @param mixed $value The value/padding + * @param mixed $position The "position" of the padding + */ + function setAxisPadding($value, $position = false) + { + if ($position === false) { + if (is_array($value)) { + if ($this->_horizontal) { + if ((isset($value['top'])) && ($this->_axisX !== null)) { + $this->_axisX->_setAxisPadding('low', $value['top']); + } + if ((isset($value['bottom'])) && ($this->_axisX !== null)) { + $this->_axisX->_setAxisPadding('high', $value['bottom']); + } + if ((isset($value['left'])) && ($this->_axisY !== null)) { + $this->_axisY->_setAxisPadding('low', $value['left']); + } + if ((isset($value['right'])) && ($this->_axisY !== null)) { + $this->_axisY->_setAxisPadding('high', $value['right']); + } + if ((isset($value['left'])) && ($this->_axisYSecondary !== null)) { + $this->_axisYSecondary->_setAxisPadding('low', $value['left']); + } + if ((isset($value['right'])) && ($this->_axisYSecondary !== null)) { + $this->_axisYSecondary->_setAxisPadding('high', $value['right']); + } + } + else { + if ((isset($value['left'])) && ($this->_axisX !== null)) { + $this->_axisX->_setAxisPadding('low', $value['left']); + } + if ((isset($value['right'])) && ($this->_axisX !== null)) { + $this->_axisX->_setAxisPadding('high', $value['right']); + } + if ((isset($value['bottom'])) && ($this->_axisY !== null)) { + $this->_axisY->_setAxisPadding('low', $value['bottom']); + } + if ((isset($value['top'])) && ($this->_axisY !== null)) { + $this->_axisY->_setAxisPadding('high', $value['top']); + } + if ((isset($value['bottom'])) && ($this->_axisYSecondary !== null)) { + $this->_axisYSecondary->_setAxisPadding('low', $value['bottom']); + } + if ((isset($value['top'])) && ($this->_axisYSecondary !== null)) { + $this->_axisYSecondary->_setAxisPadding('high', $value['top']); + } + } + } else { + if ($this->_axisX !== null) { + $this->_axisX->_setAxisPadding('low', $value); + $this->_axisX->_setAxisPadding('high', $value); + } + if ($this->_axisY !== null) { + $this->_axisY->_setAxisPadding('low', $value); + $this->_axisY->_setAxisPadding('high', $value); + } + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setAxisPadding('low', $value); + $this->_axisYSecondary->_setAxisPadding('high', $value); + } + } + } else { + switch ($position) { + case 'left': + if ($this->_horizontal) { + if ($this->_axisY !== null) { + $this->_axisY->_setAxisPadding('low', $value); + } + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setAxisPadding('low', $value); + } + } + else if ($this->_axisX !== null) { + $this->_axisX->_setAxisPadding('low', $value); + } + break; + + case 'right': + if ($this->_horizontal) { + if ($this->_axisY !== null) { + $this->_axisY->_setAxisPadding('high', $value); + } + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setAxisPadding('high', $value); + } + } + else if ($this->_axisX !== null) { + $this->_axisX->_setAxisPadding('high', $value); + } + break; + + case 'top': + if (!$this->_horizontal) { + if ($this->_axisY !== null) { + $this->_axisY->_setAxisPadding('high', $value); + } + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setAxisPadding('high', $value); + } + } + else if ($this->_axisX !== null) { + $this->_axisX->_setAxisPadding('high', $value); + } + break; + + case 'bottom': + if (!$this->_horizontal) { + if ($this->_axisY !== null) { + $this->_axisY->_setAxisPadding('low', $value); + } + if ($this->_axisYSecondary !== null) { + $this->_axisYSecondary->_setAxisPadding('low', $value); + } + } + else if ($this->_axisX !== null) { + $this->_axisX->_setAxisPadding('low', $value); + } + break; + } + } + } + + /** + * Output the plotarea to the canvas + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if ($this->_hasData) { + $this->_canvas->startGroup(get_class($this)); + + if ($this->_axisX != null) { + $this->add($this->_axisX); + } + if ($this->_axisY != null) { + $this->add($this->_axisY); + } + if ($this->_axisYSecondary != null) { + $this->add($this->_axisYSecondary); + } + + $this->_getFillStyle(); + $this->_canvas->rectangle( + array( + 'x0' => $this->_plotLeft, + 'y0' => $this->_plotTop, + 'x1' => $this->_plotRight, + 'y1' => $this->_plotBottom + ) + ); + $result = parent::_done(); + $this->_canvas->endGroup(); + return $result; + } else { + // no data -> do nothing at all! + return true; + } + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plotarea/Element.php b/config/archive/dspam/pear/Image/Graph/Plotarea/Element.php new file mode 100644 index 00000000..a7d1b8d2 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plotarea/Element.php @@ -0,0 +1,87 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Element.php + */ +require_once 'Image/Graph/Element.php'; + +/** + * Representation of a element on a plotarea. + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Plotarea_Element extends Image_Graph_Element +{ + + /** + * Get the X pixel position represented by a value + * + * @param double $point the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointX($point) + { + return $this->_parent->_pointX($point); + } + + /** + * Get the Y pixel position represented by a value + * + * @param double $point the value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointY($point) + { + return $this->_parent->_pointY($point); + } + + /** + * Get the X and Y pixel position represented by a value + * + * @param array $point the values to get the pixel-point for + * @return array The (x, y) pixel position along the axis + * @access private + */ + function _pointXY($point) + { + return array ('X' => $this->_pointX($point), 'Y' => $this->_pointY($point)); + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plotarea/Map.php b/config/archive/dspam/pear/Image/Graph/Plotarea/Map.php new file mode 100644 index 00000000..888d3384 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plotarea/Map.php @@ -0,0 +1,304 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plotarea.php + */ +require_once 'Image/Graph/Plotarea.php'; + +/** + * Plot area used for map plots. + * + * A map plot is a chart that displays a map (fx. a world map) in the form of . + * png file. The maps must be located in the /Images/Maps folder and a + * corresponding .txt files mush also exist in this location where named + * locations are mapped to an (x, y) coordinate of the map picture (this text + * file is tab separated with 'Name' 'X' 'Y' values, fx 'Denmark 378 223'). The + * x-values in the dataset are then the named locations (fx 'Denmark') and the + * y-values are then the data to plot. Currently the best (if not only) use is + * to combine a map plot area with a {@link Image_Graph_Plot_Dot} using {@link + * Image_Graph_Marker_PercentageCircle} as marker. + * + * @category Images + * @package Image_Graph + * @subpackage Plotarea + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plotarea_Map extends Image_Graph_Plotarea +{ + + /** + * The GD image for the map + * @var string + * @access private + */ + var $_imageMap; + + /** + * The value for scaling the width and height to fit into the layout boundaries + * @var int + * @access private + */ + var $_scale; + + /** + * The (x,y)-points for the named point + * @var array + * @access private + */ + var $_mapPoints; + + /** + * The original size of the image map + * @var array + * @access private + */ + var $_mapSize; + + /** + * PlotareaMap [Constructor] + * + * @param string $map The name of the map, i.e. the [name].png and [name]. + * txt files located in the Images/maps folder + */ + function Image_Graph_Plotarea_Map($map) + { + parent::Image_Graph_Plotarea(); + + $this->_imageMap = dirname(__FILE__)."/../Images/Maps/$map.png"; + $points = file(dirname(__FILE__)."/../Images/Maps/$map.txt"); + list($width, $height) = getimagesize($this->_imageMap); + $this->_mapSize['X'] = $width; + $this->_mapSize['Y'] = $height; + + if (is_array($points)) { + unset($this->_mapPoints); + foreach ($points as $line) { + list($country, $x, $y) = explode("\t", $line); + $this->_mapPoints[$country] = array('X' => $x, 'Y' => $y); + } + } + } + + /** + * Left boundary of the background fill area + * + * @return int Leftmost position on the canvas + * @access private + */ + function _fillLeft() + { + return $this->_left + $this->_padding['left']; + } + + /** + * Top boundary of the background fill area + * + * @return int Topmost position on the canvas + * @access private + */ + function _fillTop() + { + return $this->_top + $this->_padding['top']; + } + + /** + * Right boundary of the background fill area + * + * @return int Rightmost position on the canvas + * @access private + */ + function _fillRight() + { + return $this->_right - $this->_padding['right']; + } + + /** + * Bottom boundary of the background fill area + * + * @return int Bottommost position on the canvas + * @access private + */ + function _fillBottom() + { + return $this->_bottom - $this->_padding['bottom']; + } + + /** + * Set the extrema of the axis + * + * @param Image_Graph_Plot $plot The plot that 'hold' the values + * @access private + */ + function _setExtrema(& $plot) + { + } + + /** + * Get the X pixel position represented by a value + * + * @param double $value The value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointX($value) + { + $country = $value['X']; + return $this->_plotLeft+$this->_mapPoints[$country]['X']*$this->_scale; + } + + /** + * Get the Y pixel position represented by a value + * + * @param double $value The value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointY($value) + { + $country = $value['X']; + return $this->_plotTop+$this->_mapPoints[$country]['Y']*$this->_scale; + } + + /** + * Hides the axis + */ + function hideAxis() + { + } + + /** + * Add a point to the maps + * + * @param int $latitude The latitude of the point + * @param int $longiude The longitude of the point + * @param string $name The name of the plot + */ + function addMappoint($latitude, $longitude, $name) + { + $x = (($longitude + 180) * ($this->_mapSize['X'] / 360)); + $y = ((($latitude * -1) + 90) * ($this->_mapSize['Y'] / 180)); + $this->_mapPoints[$name] = array('X' => $x, 'Y' => $y); + } + + /** + * Add a point to the maps + * + * @param int $x The latitude of the point + * @param int $y The longitude of the point + * @param string $name The name of the plot + */ + function addPoint($x, $y, $name) + { + $this->_mapPoints[$name] = array('X' => $x, 'Y' => $y); + } + + /** + * Update coordinates + * + * @access private + */ + function _updateCoords() + { + parent::_updateCoords(); + + $mapAspectRatio = $this->_mapSize['X']/$this->_mapSize['Y']; + $plotAspectRatio = ($width = $this->_fillWidth())/($height = $this->_fillHeight()); + + $scaleFactorX = ($mapAspectRatio > $plotAspectRatio); + + if ((($this->_mapSize['X'] <= $width) && ($this->_mapSize['Y'] <= $height)) || + (($this->_mapSize['X'] >= $width) && ($this->_mapSize['Y'] >= $height))) + { + if ($scaleFactorX) { + $this->_scale = $width / $this->_mapSize['X']; + } else { + $this->_scale = $height / $this->_mapSize['Y']; + } + } elseif ($this->_mapSize['X'] < $width) { + $this->_scale = $height / $this->_mapSize['Y']; + } elseif ($this->_mapSize['Y'] < $height) { + $this->_scale = $width / $this->_mapSize['X']; + } + + $this->_plotLeft = ($this->_fillLeft() + $this->_fillRight() - + $this->_mapSize['X']*$this->_scale)/2; + + $this->_plotTop = ($this->_fillTop() + $this->_fillBottom() - + $this->_mapSize['Y']*$this->_scale)/2; + + $this->_plotRight = ($this->_fillLeft() + $this->_fillRight() + + $this->_mapSize['X']*$this->_scale)/2; + + $this->_plotBottom = ($this->_fillTop() + $this->_fillBottom() + + $this->_mapSize['Y']*$this->_scale)/2; + } + + /** + * Output the plotarea to the canvas + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $this->_getFillStyle(); + $this->_canvas->rectangle( + array( + 'x0' => $this->_fillLeft(), + 'y0' => $this->_fillTop(), + 'x1' => $this->_fillRight(), + 'y1' => $this->_fillBottom() + ) + ); + + $scaledWidth = $this->_mapSize['X']*$this->_scale; + $scaledHeight = $this->_mapSize['Y']*$this->_scale; + + $this->_canvas->image( + array( + 'x' => $this->_plotLeft, + 'y' => $this->_plotTop, + 'filename' => $this->_imageMap, + 'width' => $scaledWidth, + 'height' => $scaledHeight + ) + ); + + return Image_Graph_Layout::_done(); + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Plotarea/Radar.php b/config/archive/dspam/pear/Image/Graph/Plotarea/Radar.php new file mode 100644 index 00000000..cfb200ea --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Plotarea/Radar.php @@ -0,0 +1,243 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plotarea.php + */ +require_once 'Image/Graph/Plotarea.php'; + +/** + * Plot area used for radar plots. + * + * @category Images + * @package Image_Graph + * @subpackage Plotarea + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plotarea_Radar extends Image_Graph_Plotarea +{ + + /** + * Create the plotarea, implicitely creates 2 normal axis + */ + function Image_Graph_Plotarea_Radar() + { + parent::Image_Graph_Element(); + $this->_padding = array('left' => 10, 'top' => 10, 'right' => 10, 'bottom' => 10); + $this->_axisX =& Image_Graph::factory('Image_Graph_Axis_Radar'); + $this->_axisX->_setParent($this); + $this->_axisY =& Image_Graph::factory('Image_Graph_Axis', IMAGE_GRAPH_AXIS_Y); + $this->_axisY->_setParent($this); + $this->_axisY->_setMinimum(0); + } + + /** + * Get the width of the 'real' plotarea + * + * @return int The width of the 'real' plotarea, ie not including space occupied by padding and axis + * @access private + */ + function _plotWidth() + { + return (min($this->height(), $this->width())) * 0.80; + } + + /** + * Get the height of the 'real' plotarea + * + * @return int The height of the 'real' plotarea, ie not including space occupied by padding and axis + * @access private + */ + function _plotHeight() + { + return (min($this->height(), $this->width())) * 0.80; + } + + /** + * Left boundary of the background fill area + * + * @return int Leftmost position on the canvas + * @access private + */ + function _fillLeft() + { + return (int) (($this->_left + $this->_right - $this->_plotWidth()) / 2); + } + + /** + * Top boundary of the background fill area + * + * @return int Topmost position on the canvas + * @access private + */ + function _fillTop() + { + return (int) (($this->_top + $this->_bottom - $this->_plotHeight()) / 2); + } + + /** + * Right boundary of the background fill area + * + * @return int Rightmost position on the canvas + * @access private + */ + function _fillRight() + { + return (int) (($this->_left + $this->_right + $this->_plotWidth()) / 2); + } + + /** + * Bottom boundary of the background fill area + * + * @return int Bottommost position on the canvas + * @access private + */ + function _fillBottom() + { + return (int) (($this->_top + $this->_bottom + $this->_plotHeight()) / 2); + } + + /** + * Get the X pixel position represented by a value + * + * @param double $value The value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointX($value) + { + if (is_array($value)) { + if ($value['Y'] == '#min#') { + $radius = 0; + } elseif (($value['Y'] == '#max#') || ($value['Y'] === false)) { + $radius = 1; + } else { + $radius = ($value['Y'] - $this->_axisY->_getMinimum()) / + ($this->_axisY->_getMaximum() - $this->_axisY->_getMinimum()); + } + $x = ($this->_left + $this->_right) / 2 - + $radius * ($this->_plotWidth() / 2) * + cos(deg2rad($this->_axisX->_point($value['X']))); + } + return max($this->_plotLeft, min($this->_plotRight, $x)); + } + + /** + * Get the Y pixel position represented by a value + * + * @param double $value The value to get the pixel-point for + * @return double The pixel position along the axis + * @access private + */ + function _pointY($value) + { + if (is_array($value)) { + if ($value['Y'] == '#min#') { + $radius = 0; + } elseif (($value['Y'] == '#max#') || ($value['Y'] === false)) { + $radius = 1; + } else { + $radius = ($value['Y'] - $this->_axisY->_getMinimum()) / + ($this->_axisY->_getMaximum() - $this->_axisY->_getMinimum()); + } + + $y = ($this->_top + $this->_bottom) / 2 - + $radius * ($this->_plotHeight() / 2) * + sin(deg2rad($this->_axisX->_point($value['X']))); + } + return max($this->_plotTop, min($this->_plotBottom, $y)); + } + + /** + * Update coordinates + * + * @access private + */ + function _updateCoords() + { + if (is_array($this->_elements)) { + $keys = array_keys($this->_elements); + foreach ($keys as $key) { + $element =& $this->_elements[$key]; + if (is_a($element, 'Image_Graph_Plot')) { + $this->_setExtrema($element); + } + } + unset($keys); + } + + $this->_calcEdges(); + + $centerX = (int) (($this->_left + $this->_right) / 2); + $centerY = (int) (($this->_top + $this->_bottom) / 2); + $radius = min($this->_plotHeight(), $this->_plotWidth()) / 2; + + if (is_object($this->_axisX)) { + $this->_axisX->_setCoords( + $centerX - $radius, + $centerY - $radius, + $centerX + $radius, + $centerY + $radius + ); + } + + if (is_object($this->_axisY)) { + $this->_axisY->_setCoords( + $centerX, + $centerY, + $centerX - $radius, + $centerY - $radius + ); + } + + $this->_plotLeft = $this->_fillLeft(); + $this->_plotTop = $this->_fillTop(); + $this->_plotRight = $this->_fillRight(); + $this->_plotBottom = $this->_fillBottom(); + + Image_Graph_Element::_updateCoords(); + + if (is_object($this->_axisX)) { + $this->_axisX->_updateCoords(); + } + + if (is_object($this->_axisY)) { + $this->_axisY->_updateCoords(); + } + + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Simple.php b/config/archive/dspam/pear/Image/Graph/Simple.php new file mode 100644 index 00000000..9d14c4da --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Simple.php @@ -0,0 +1,121 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph.php + */ +require_once 'Image/Graph.php'; + +/** + * Class for simple creation of graphs + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Simple extends Image_Graph +{ + + /** + * Image_Graph_Simple [Constructor] + * + * @param int $width The width of the graph in pixels + * @param int $height The height of the graph in pixels + */ + function Image_Graph_Simple($width, $height, $plotType, $data, $title, $lineColor = 'black', $fillColor = 'white', $font = false) + { + parent::Image_Graph($width, $height); + + $plotarea =& Image_Graph::factory('plotarea'); + + $dataset =& Image_Graph::factory('dataset', array($data)); + + if ($font === false) { + $font =& Image_Graph::factory('Image_Graph_Font'); + } elseif (is_string($font)) { + $font =& Image_Graph::factory('ttf_font', $font); + $font->setSize(8); + } + + $this->setFont($font); + + $this->add( + Image_Graph::vertical( + Image_Graph::factory('title', + array( + $title, + array('size_rel' => 2) + ) + ), + $plotarea, + 10 + ) + ); + + $plotarea->addNew('line_grid', array(), IMAGE_GRAPH_AXIS_Y); + + $plot =& $plotarea->addNew($plotType, array(&$dataset)); + $plot->setLineColor($lineColor); + $plot->setFillColor($fillColor); + + $axisX =& $plotarea->getAxis(IMAGE_GRAPH_AXIS_X); + $axisX->showLabel( + IMAGE_GRAPH_LABEL_MINIMUM + + IMAGE_GRAPH_LABEL_ZERO + + IMAGE_GRAPH_LABEL_MAXIMUM + ); + + } + + /** + * Factory method to create the Image_Simple_Graph object. + */ + function &factory($width, $height, $plotType, $data, $title, $lineColor = 'black', $fillColor = 'white', $font = false) + { + $obj =& Image_Graph::factory('Image_Graph_Simple', + array( + $width, + $height, + $plotType, + $data, + $title, + $lineColor, + $fillColor, + $font + ) + ); + return $obj; + } + +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Title.php b/config/archive/dspam/pear/Image/Graph/Title.php new file mode 100644 index 00000000..2cffe5f3 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Title.php @@ -0,0 +1,194 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Layout.php + */ +require_once 'Image/Graph/Layout.php'; + +/** + * Title + * + * @category Images + * @package Image_Graph + * @subpackage Text + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Title extends Image_Graph_Layout +{ + + /** + * The text to print + * @var string + * @access private + */ + var $_text; + + /** + * The font to use + * @var Font + * @access private + */ + var $_font; + + /** + * The alignment of the title + * @var int + * @access private + */ + var $_alignment = IMAGE_GRAPH_ALIGN_CENTER_X; + + /** + * Create the title. + * + * Pass a Image_Graph_Font object - preferably by-ref (&) as second + * parameter, the font size in pixels or an associated array with some or + * all of the followin keys: + * + * 'size' The size of the title + * + * 'angle' The angle at which to write the title (in degrees or 'vertical') + * + * 'color' The font-face color + * + * @param sting $text The text to represent the title + * @param mixed $fontOptions The font to use in the title + */ + function Image_Graph_Title($text, $fontOptions = false) + { + parent::Image_Graph_Layout(); + if (is_object($fontOptions)) { + $this->_font =& $fontOptions; + } else { + if (is_array($fontOptions)) { + $this->_fontOptions = $fontOptions; + } else { + $this->_fontOptions['size'] = $fontOptions; + } + } + $this->setText($text); + } + + /** + * Set the text + * + * @param string $text The text to display + */ + function setText($text) + { + $this->_text = $text; + } + + /** + * Returns the calculated "auto" size + * + * @return int The calculated auto size + * @access private + */ + function _getAutoSize() + { + if ($this->_defaultFontOptions !== false) { + $this->_canvas->setFont($this->_defaultFontOptions); + } else { + $this->_canvas->setFont($this->_getFont()); + } + + return $this->_canvas->textHeight($this->_text); + } + + /** + * Set the alignment of the legend + * + * @param int $alignment The alignment + */ + function setAlignment($alignment) + { + $this->_alignment = $alignment & 0x7; + } + + /** + * Output the text + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if ($this->_defaultFontOptions !== false) { + $this->_canvas->setFont($this->_defaultFontOptions); + } else { + $this->_canvas->setFont($this->_getFont()); + } + + if (is_a($this->_parent, 'Image_Graph_Plotarea')) { + $this->_setCoords( + $this->_parent->_left, + $this->_parent->_top, + $this->_parent->_right, + $this->_parent->_top + $this->_canvas->textHeight($this->_text) + ); + } elseif (!is_a($this->_parent, 'Image_Graph_Layout')) { + $this->_setCoords( + $this->_parent->_fillLeft(), + $this->_parent->_fillTop(), + $this->_parent->_fillRight(), + $this->_parent->_fillTop() + $this->_canvas->textHeight($this->_text) + ); + } + + if (parent::_done() === false) { + return false; + } + + if ($this->_alignment == IMAGE_GRAPH_ALIGN_CENTER_X) { + $x = ($this->_left + $this->_right) / 2; + } elseif ($this->_alignment == IMAGE_GRAPH_ALIGN_LEFT) { + $x = $this->_left; + } else { + $x = $this->_right; + } + $y = ($this->_top + $this->_bottom) / 2; + + $this->write( + $x, + $y, + $this->_text, + $this->_alignment + IMAGE_GRAPH_ALIGN_CENTER_Y + ); + return true; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pear/Image/Graph/Tool.php b/config/archive/dspam/pear/Image/Graph/Tool.php new file mode 100644 index 00000000..cf245685 --- /dev/null +++ b/config/archive/dspam/pear/Image/Graph/Tool.php @@ -0,0 +1,291 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * This class contains a set of tool-functions. + * + * These functions are all to be called statically + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Tool +{ + + /** + * Return the average of 2 points + * + * @param double P1 1st point + * @param double P2 2nd point + * @return double The average of P1 and P2 + * @static + */ + function mid($p1, $p2) + { + return ($p1 + $p2) / 2; + } + + /** + * Mirrors P1 in P2 by a amount of Factor + * + * @param double $p1 1st point, point to mirror + * @param double $o2 2nd point, mirror point + * @param double $factor Mirror factor, 0 returns $p2, 1 returns a pure + * mirror, ie $p1 on the exact other side of $p2 + * @return double $p1 mirrored in $p2 by Factor + * @static + */ + function mirror($p1, $p2, $factor = 1) + { + return $p2 + $factor * ($p2 - $p1); + } + + /** + * Calculates a Bezier control point, this function must be called for BOTH + * X and Y coordinates (will it work for 3D coordinates!?) + * + * @param double $p1 1st point + * @param double $p2 Point to + * @param double $factor Mirror factor, 0 returns P2, 1 returns a pure + * mirror, i.e. P1 on the exact other side of P2 + * @return double P1 mirrored in P2 by Factor + * @static + */ + function controlPoint($p1, $p2, $factor, $smoothFactor = 0.75) + { + $sa = Image_Graph_Tool::mirror($p1, $p2, $smoothFactor); + $sb = Image_Graph_Tool::mid($p2, $sa); + + $m = Image_Graph_Tool::mid($p2, $factor); + + $pC = Image_Graph_Tool::mid($sb, $m); + + return $pC; + } + + /** + * Calculates a Bezier point, this function must be called for BOTH X and Y + * coordinates (will it work for 3D coordinates!?) + * + * @param double $t A position between $p2 and $p3, value between 0 and 1 + * @param double $p1 Point to use for calculating control points + * @param double $p2 Point 1 to calculate bezier curve between + * @param double $p3 Point 2 to calculate bezier curve between + * @param double $p4 Point to use for calculating control points + * @return double The bezier value of the point t between $p2 and $p3 using + * $p1 and $p4 to calculate control points + * @static + */ + function bezier($t, $p1, $p2, $p3, $p4) + { + // (1-t)^3*p1 + 3*(1-t)^2*t*p2 + 3*(1-t)*t^2*p3 + t^3*p4 + return pow(1 - $t, 3) * $p1 + + 3 * pow(1 - $t, 2) * $t * $p2 + + 3 * (1 - $t) * pow($t, 2) * $p3 + + pow($t, 3) * $p4; + } + + /** + * For a given point (x,y) return a point rotated by a given angle aroung the center (xy,yc) + * + * @param int $x x coordinate of the point to rotate + * @param int $y y coordinate of the point to rotate + * @param int $xc x coordinate of the center of the rotation + * @param int $yc y coordinate of the center of the rotation + * @param int $angle angle of the rotation + * @return array the coordinate of the new point + * @static + */ + function rotate($x, $y, $xc, $yc, $angle) + { + $cos = cos(deg2rad($angle)); + $sin = sin(deg2rad($angle)); + $xr= $x - $xc; + $yr= $y - $yc; + $x1= $xc + $cos * $xr - $sin * $yr; + $y1= $yc + $sin * $xr + $cos * $yr; + return array((int) $x1,(int) $y1); + } + + /** + * If a number is close 0 zero (i.e. 0 within $decimal decimals) it is rounded down to zero + * + * @param double $value The value to round + * @param int $decimal The number of decimals + * @return double The value or zero if "close enough" to zero + * @static + */ + function close2zero($value, $decimal) + { + if (abs($value) < pow(10, -$decimal)) { + return 0; + } + else { + return $value; + } + } + + /** + * Calculate the dimensions and center point (of gravity) for an arc + * + * @param int $v1 The angle at which the arc starts + * @param int $v2 The angle at which the arc ends + * @return array An array with the dimensions in a fraction of a circle width radius 1 'rx', 'ry' and the + * center point of gravity ('cx', 'cy') + * @static + */ + function calculateArcDimensionAndCenter($v1, $v2) + { + // $v2 always larger than $v1 + $r1x = Image_Graph_Tool::close2zero(cos(deg2rad($v1)), 3); + $r2x = Image_Graph_Tool::close2zero(cos(deg2rad($v2)), 3); + + $r1y = Image_Graph_Tool::close2zero(sin(deg2rad($v1)), 3); + $r2y = Image_Graph_Tool::close2zero(sin(deg2rad($v2)), 3); + + // $rx = how many percent of the x-diameter of the entire ellipse does the arc x-diameter occupy: 1 entire width, 0 no width + // $cx = at what percentage of the diameter does the center lie + + // if the arc passes through 0/360 degrees the "highest" of r1x and r2x is replaced by 1! + if ((($v1 <= 0) && ($v2 >= 0)) || (($v1 <= 360) && ($v2 >= 360))) { + $r1x = min($r1x, $r2x); + $r2x = 1; + } + + // if the arc passes through 180 degrees the "lowest" of r1x and r2x is replaced by -1! + if ((($v1 <= 180) && ($v2 >= 180)) || (($v1 <= 540) && ($v2 >= 540))) { + $r1x = max($r1x, $r2x); + $r2x = -1; + } + + if ($r1x >= 0) { // start between [270; 360] or [0; 90] + if ($r2x >= 0) { + $rx = max($r1x, $r2x) / 2; + $cx = 0; // center lies 0 percent along this "vector" + } + else { + $rx = abs($r1x - $r2x) / 2; + $cx = abs($r2x / 2) / $rx; + } + } + else { // start between ]90; 270[ + if ($r2x < 0) { + $rx = max(abs($r1x), abs($r2x)) / 2; + $cx = $rx; + } + else { + $rx = abs($r1x - $r2x) / 2; + $cx = abs($r1x / 2) / $rx; + } + } + + // $ry = how many percent of the y-diameter of the entire ellipse does the arc y-diameter occupy: 1 entire, 0 none + // $cy = at what percentage of the y-diameter does the center lie + + // if the arc passes through 90 degrees the "lowest" of r1x and r2x is replaced by -1! + if ((($v1 <= 90) && ($v2 >= 90)) || (($v1 <= 450) && ($v2 >= 450))) { + $r1y = min($r1y, $r2y); + $r2y = 1; + } + + // if the arc passes through 270 degrees the "highest" of r1y and r2y is replaced by -1! + if ((($v1 <= 270) && ($v2 >= 270)) || (($v1 <= 630) && ($v2 >= 630))) { + $r1y = max($r1y, $r2y); + $r2y = -1; + } + + if ($r1y >= 0) { // start between [0; 180] + if ($r2y >= 0) { + $ry = max($r1y, $r2y) / 2; + $cy = 0; // center lies 0 percent along this "vector" + } + else { + $ry = abs($r1y - $r2y) / 2; + $cy = abs($r2y / 2) / $ry; + } + } + else { // start between ]180; 360[ + if ($r2y < 0) { + $ry = max(abs($r1y), abs($r2y)) / 2; + $cy = $ry; + } + else { + $ry = abs($r1y - $r2y) / 2; + $cy = abs($r1y / 2) / $ry; + } + } + + return array( + 'rx' => $rx, + 'cx' => $cx, + 'ry' => $ry, + 'cy' => $cy + ); + } + + /** + * Calculate linear regression on a dataset + * @param array $data The data to calculate regression upon + * @return array The slope and intersection of the "best-fit" line + * @static + */ + function calculateLinearRegression(&$data) + { + $sumX = 0; + $sumY = 0; + foreach ($data as $point) { + $sumX += $point['X']; + $sumY += $point['Y']; + } + $meanX = $sumX / count($data); + $meanY = $sumY / count($data); + + $sumXX = 0; + $sumYY = 0; + $sumXY = 0; + foreach ($data as $point) { + $sumXX += ($point['X'] - $meanX) * ($point['X'] - $meanX); + $sumYY += ($point['Y'] - $meanY) * ($point['Y'] - $meanY); + $sumXY += ($point['X'] - $meanX) * ($point['Y'] - $meanY); + } + + $result = array(); + $result['slope'] = ($sumXY / $sumXX); + $result['intersection'] = $meanY - ($result['slope'] * $meanX); + return $result; + } + +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pkg/000.mysql.sh b/config/archive/dspam/pkg/000.mysql.sh new file mode 100644 index 00000000..9c25c370 --- /dev/null +++ b/config/archive/dspam/pkg/000.mysql.sh @@ -0,0 +1,68 @@ +#!/bin/sh +# This file was automatically generated +# by the pfSense service handler + +rc_start() { +test_mysql_user=`cat /etc/passwd | grep mysql` +test_mysql_group=`cat /etc/group | grep mysql` +mysql_user="mysql" +mysql_limits_args="-e -U ${mysql_user}" +pidfile="/var/db/mysql/`/bin/hostname`.pid" +command="/usr/local/bin/mysqld_safe" +command_args="--user=${mysql_user} --datadir=/var/db/mysql --pid-file=${pidfile} --bind-address=127.0.0.1 --set-variable=max_connections=500" +procname="/usr/local/libexec/mysqld" +mysql_install_db="/usr/local/bin/mysql_install_db" +mysql_install_db_args="--ldata=/var/db/mysql" + +/sbin/mount_fdescfs fdescfs /dev/fd + +if [ -z "${test_mysql_group}" ]; then + pw groupadd mysql -g 88 +fi + +if [ -z "${test_mysql_user}" ]; then + pw useradd mysql -u 88 -g 88 -d /nonexistent -s /sbin/nologin -c 'MySQL Daemon' +fi + +if [ ! -d "/var/db/mysql" ]; then + mkdir /var/db/mysql && chown mysql:mysql /var/db/mysql +fi + +if [ ! -d "/var/db/mysql/mysql/." ]; then + eval $mysql_install_db $mysql_install_db_args >/dev/null + [ $? -eq 0 ] && chown -R ${mysql_user}:${mysql_user} /var/db/mysql +fi + +#if checkyesno mysql_limits; then +# eval `/usr/bin/limits ${mysql_limits_args}` 2>/dev/null +#else +# return 0 +#fi + +${command} ${command_args} > /dev/null & +} + +rc_stop() { +/usr/bin/killall mysqld +sleep 2 +} + +rc_restart() { + rc_stop + rc_start +} + +case $1 in + start) + rc_start + ;; + stop) + rc_stop + ;; + restart) + rc_restart + ;; + *) + echo "Usage: $0 " + ;; +esac diff --git a/config/archive/dspam/pkg/010.clamav-clamd.sh b/config/archive/dspam/pkg/010.clamav-clamd.sh new file mode 100644 index 00000000..aeb23b04 --- /dev/null +++ b/config/archive/dspam/pkg/010.clamav-clamd.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# This file was automatically generated +# by the pfSense service handler + +rc_start() { +test_clamav_group=`cat /etc/group | grep clam` +test_clamav_user=`cat /etc/passwd | grep clam` + +if [ -z "${test_clamav_group}" ]; then + pw groupadd clamav -g 106 +fi + +if [ -z "${test_clamav_user}" ]; then + pw useradd clamav -u 106 -g 106 -d /nonexistent -s /sbin/nologin -c 'Clam Antivirus' +fi + +if [ ! -d "/usr/local/share/clamav" ]; then + mkdir /usr/local/share/clamav && chown clamav:clamav /usr/local/share/clamav +fi + +if [ ! -d "/var/log/clamav" ]; then + mkdir /var/log/clamav && chown clamav:clamav /var/log/clamav +fi + +if [ ! -d "/var/run/clamav" ]; then + mkdir /var/run/clamav && chown clamav:clamav /var/run/clamav +fi + + /sbin/mount_fdescfs fdescfs /dev/fd + /usr/local/sbin/clamd +} + +rc_stop() { + /usr/bin/killall clamd + sleep 2 +} + +rc_restart() { + rc_stop + rc_start +} + +case $1 in + start) + rc_start + ;; + stop) + rc_stop + ;; + restart) + rc_restart + ;; + *) + echo "Usage: $0 " + ;; +esac diff --git a/config/archive/dspam/pkg/020.clamav-freshclam.sh b/config/archive/dspam/pkg/020.clamav-freshclam.sh new file mode 100644 index 00000000..4332d757 --- /dev/null +++ b/config/archive/dspam/pkg/020.clamav-freshclam.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# This file was automatically generated +# by the pfSense service handler + +rc_start() { + /sbin/mount_fdescfs fdescfs /dev/fd + /usr/local/bin/freshclam --daemon +} + +rc_stop() { + /usr/bin/killall freshclam + sleep 2 +} + +rc_restart() { + rc_stop + rc_start +} + +case $1 in + start) + rc_start + ;; + stop) + rc_stop + ;; + restart) + rc_restart + ;; + *) + echo "Usage: $0 " + ;; +esac diff --git a/config/archive/dspam/pkg/030.p3scan.sh b/config/archive/dspam/pkg/030.p3scan.sh new file mode 100644 index 00000000..ffd08abf --- /dev/null +++ b/config/archive/dspam/pkg/030.p3scan.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# This file was automatically generated +# by the pfSense service handler + +rc_start() { +test_p3scan_user=`cat /etc/passwd | grep p3scan` +test_p3scan_group=`cat /etc/passwd | grep p3scan` + +if [ -z "${test_p3scan_group}" ]; then + pw groupadd p3scan -g 108 +fi + +if [ -z "${test_p3scan_user}" ]; then + pw useradd p3scan -u 108 -g p3scan -d /var/spool/p3scan -s /sbin/nologin -c 'P3Scan Daemon' +fi + +if [ ! -d "/var/spool/p3scan" ]; then + mkdir /var/spool/p3scan && chown p3scan:p3scan /var/spool/p3scan +fi + +if [ ! -d "/var/spool/p3scan/children" ]; then + mkdir /var/spool/p3scan/children && chown p3scan:p3scan /var/spool/p3scan/children +fi + +if [ ! -d "/var/spool/p3scannotify" ]; then + mkdir /var/spool/p3scannotify && chown p3scan:p3scan /var/spool/p3scannotify +fi + +if [ ! -d "/var/run/p3scan" ]; then + mkdir /var/run/p3scan && chown p3scan:p3scan /var/run/p3scan +fi + + /sbin/mount_fdescfs fdescfs /dev/fd + /usr/local/sbin/p3scan --configfile=/usr/local/etc/p3scan/p3scan.conf & +} + +rc_stop() { + /usr/bin/killall p3scan + sleep 2 +} + +rc_restart() { + rc_stop + rc_start +} + +case $1 in + start) + rc_start + ;; + stop) + rc_stop + ;; + restart) + rc_restart + ;; + *) + echo "Usage: $0 " + ;; +esac diff --git a/config/archive/dspam/pkg/clamd.conf b/config/archive/dspam/pkg/clamd.conf new file mode 100644 index 00000000..3ce0402f --- /dev/null +++ b/config/archive/dspam/pkg/clamd.conf @@ -0,0 +1,299 @@ +## +## Example config file for the Clam AV daemon +## Please read the clamd.conf(5) manual before editing this file. +## + + +# Comment or remove the line below. +#Example + +# Uncomment this option to enable logging. +# LogFile must be writable for the user running daemon. +# A full path is required. +# Default: disabled +#LogFile /tmp/clamd.log +LogFile /var/log/clamav/clamd.log + +# By default the log file is locked for writing - the lock protects against +# running clamd multiple times (if want to run another clamd, please +# copy the configuration file, change the LogFile variable, and run +# the daemon with --config-file option). +# This option disables log file locking. +# Default: no +#LogFileUnlock yes + +# Maximal size of the log file. +# Value of 0 disables the limit. +# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes) +# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size +# in bytes just don't use modifiers. +# Default: 1M +#LogFileMaxSize 2M + +# Log time with each message. +# Default: no +#LogTime yes + +# Also log clean files. Useful in debugging but drastically increases the +# log size. +# Default: no +#LogClean yes + +# Use system logger (can work together with LogFile). +# Default: no +#LogSyslog yes +LogSyslog yes + +# Specify the type of syslog messages - please refer to 'man syslog' +# for facility names. +# Default: LOG_LOCAL6 +#LogFacility LOG_MAIL + +# Enable verbose logging. +# Default: no +#LogVerbose yes + +# This option allows you to save a process identifier of the listening +# daemon (main thread). +# Default: disabled +#PidFile /var/run/clamd.pid +PidFile /var/run/clamav/clamd.pid + +# Optional path to the global temporary directory. +# Default: system specific (usually /tmp or /var/tmp). +#TemporaryDirectory /var/tmp + +# Path to the database directory. +# Default: hardcoded (depends on installation options) +#DatabaseDirectory /var/lib/clamav +DatabaseDirectory /usr/local/share/clamav + +# The daemon works in a local OR a network mode. Due to security reasons we +# recommend the local mode. + +# Path to a local socket file the daemon will listen on. +# Default: disabled (must be specified by a user) +#LocalSocket /tmp/clamd + +# Remove stale socket after unclean shutdown. +# Default: no +FixStaleSocket yes + +# TCP port address. +# Default: no +TCPSocket 3310 + +# TCP address. +# By default we bind to INADDR_ANY, probably not wise. +# Enable the following to provide some degree of protectiyes +# from the outside world. +# Default: no +TCPAddr 127.0.0.1 + +# Maximum length the queue of pending connections may grow to. +# Default: 15 +#MaxConnectionQueueLength 30 + +# Clamd uses FTP-like protocol to receive data from remote clients. +# If you are using clamav-milter to balance load between remote clamd daemons +# on firewall servers you may need to tune the options below. + +# Close the connection when the data size limit is exceeded. +# The value should match your MTA's limit for a maximal attachment size. +# Default: 10M +#StreamMaxLength 20M + +# Limit port range. +# Default: 1024 +#StreamMinPort 30000 +# Default: 2048 +#StreamMaxPort 32000 + +# Maximal number of threads running at the same time. +# Default: 10 +#MaxThreads 20 + +# Waiting for data from a client socket will timeout after this time (seconds). +# Value of 0 disables the timeout. +# Default: 120 +#ReadTimeout 300 + +# Waiting for a new job will timeout after this time (seconds). +# Default: 30 +#IdleTimeout 60 + +# Maximal depth directories are scanned at. +# Default: 15 +#MaxDirectoryRecursion 20 + +# Follow directory symlinks. +# Default: no +#FollowDirectorySymlinks yes + +# Follow regular file symlinks. +# Default: no +#FollowFileSymlinks yes + +# Perform internal sanity check (database integrity and freshness). +# Default: 1800 (30 min) +#SelfCheck 600 + +# Execute a command when virus is found. In the command string %v will +# be replaced by a virus name. +# Default: no +#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %v" + +# Run as a selected user (clamd must be started by root). +# Default: don't drop privileges +User clamav + +# Initialize supplementary group access (clamd must be started by root). +# Default: no +AllowSupplementaryGroups yes + +# Stop daemon when libclamav reports out of memory condition. +#ExitOnOOM yes + +# Don't fork into background. +# Default: no +#Foreground yes + +# Enable debug messages in libclamav. +# Default: no +#Debug yes + +# Do not remove temporary files (for debug purposes). +# Default: no +#LeaveTemporaryFiles yes + +## +## Executable files +## + +# PE stands for Portable Executable - it's an executable file format used +# in all 32-bit versions of Windows operating systems. This option allows +# ClamAV to perform a deeper analysis of executable files and it's also +# required for decompression of popular executable packers such as UPX, FSG, +# and Petite. +# Default: yes +#ScanPE yes + +# With this option clamav will try to detect broken executables and mark +# them as Broken.Executable +# Default: no +#DetectBrokenExecutables yes + + +## +## Documents +## + +# This option enables scanning of Microsoft Office document macros. +# Default: yes +#ScanOLE2 yes + +## +## Mail files +## + +# Enable internal e-mail scanner. +# Default: yes +#ScanMail yes + +# If an email contains URLs ClamAV can download and scan them. +# WARNING: This option may open your system to a DoS attack. +# Never use it on loaded servers. +# Default: no +#MailFollowURLs no + + +## +## HTML +## + +# Perform HTML normalisation and decryption of MS Script Encoder code. +# Default: yes +#ScanHTML yes + + +## +## Archives +## + +# ClamAV can scan within archives and compressed files. +# Default: yes +#ScanArchive yes + +# The options below protect your system against Denial of Service attacks +# using archive bombs. + +# Files in archives larger than this limit won't be scanned. +# Value of 0 disables the limit. +# Default: 10M +#ArchiveMaxFileSize 15M + +# Nested archives are scanned recursively, e.g. if a Zip archive contains a RAR +# file, all files within it will also be scanned. This options specifies how +# deep the process should be continued. +# Value of 0 disables the limit. +# Default: 8 +#ArchiveMaxRecursion 10 + +# Number of files to be scanned within an archive. +# Value of 0 disables the limit. +# Default: 1000 +#ArchiveMaxFiles 1500 + +# If a file in an archive is compressed more than ArchiveMaxCompressionRatio +# times it will be marked as a virus (Oversized.ArchiveType, e.g. Oversized.Zip) +# Value of 0 disables the limit. +# Default: 250 +#ArchiveMaxCompressionRatio 300 + +# Use slower but memory efficient decompression algorithm. +# only affects the bzip2 decompressor. +# Default: no +#ArchiveLimitMemoryUsage yes + +# Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR). +# Default: no +#ArchiveBlockEncrypted no + +# Mark archives as viruses (e.g. RAR.ExceededFileSize, Zip.ExceededFilesLimit) +# if ArchiveMaxFiles, ArchiveMaxFileSize, or ArchiveMaxRecursion limit is +# reached. +# Default: no +#ArchiveBlockMax no + + +## +## Clamuko settings +## WARNING: This is experimental software. It is very likely it will hang +## up your system!!! +## + +# Enable Clamuko. Dazuko (/dev/dazuko) must be configured and running. +# Default: no +#ClamukoScanOnAccess yes + +# Set access mask for Clamuko. +# Default: no +#ClamukoScanOnOpen yes +#ClamukoScanOnClose yes +#ClamukoScanOnExec yes + +# Set the include paths (all files in them will be scanned). You can have +# multiple ClamukoIncludePath directives but each directory must be added +# in a seperate line. +# Default: disabled +#ClamukoIncludePath /home +#ClamukoIncludePath /students + +# Set the exclude paths. All subdirectories are also excluded. +# Default: disabled +#ClamukoExcludePath /home/bofh + +# Don't scan files larger than ClamukoMaxFileSize +# Value of 0 disables the limit. +# Default: 5M +#ClamukoMaxFileSize 10M diff --git a/config/archive/dspam/pkg/default.prefs.sample b/config/archive/dspam/pkg/default.prefs.sample new file mode 100644 index 00000000..d9be27ed --- /dev/null +++ b/config/archive/dspam/pkg/default.prefs.sample @@ -0,0 +1,43 @@ +# $Id$ +# default.prefs v3.2 +# Default preferences for DSPAM + +# This file serves two purposes. First, it sets the default preferences each +# user will see when using the preferences section of the DSPAM Control +# Center. Second, it may be symbolically linked (or copied) into DSPAM_HOME to +# set the system-wide default preferences, overriding any commandline or +# dspam.conf parameters. If symlinked, an administrator can edit these options +# in the DSPAM Administrative Suite. + +# Training Mode: TEFT, TOE, TUM, NOTRAIN +trainingMode=TEFT + +# Spam Action: quarantine, tag +spamAction=quarantine + +# Spam Subject: the text to be prepended onto the subject line of tagged spams +spamSubject=[SPAM] + +# Bayesian Noise Reduction: on/off +enableBNR=on + +# Automatic Whitelisting: on/off +enableWhitelist=on + +# Statistical Sedation: 0-10 +statisticalSedation=5 + +# Signature Location: message, headers, attachment +signatureLocation=message + +# Whitelist Threshold: the minimum number of innocent hits from a recipient to +# be automatically whitelisted. Do not set this value too low! +whitelistThreshold=10 + +# showFactors: when set to on, the determining factors for each message will +# be added to a X-DSPAM-Factors message header. +showFactors=off + +# optIn/optOut: Depending on the opt mode set, you can also use one of these. +#optIn=on +#optOut=off diff --git a/config/archive/dspam/pkg/dspam-config.inc b/config/archive/dspam/pkg/dspam-config.inc new file mode 100644 index 00000000..211bee51 --- /dev/null +++ b/config/archive/dspam/pkg/dspam-config.inc @@ -0,0 +1,42 @@ + '/var/db/dspam', + 'DSPAM_BIN' => '/usr/local/bin', + 'DSPAM' => '/usr/local/bin/dspam', + 'DSPAM_STATS' => '/usr/local/bin/dspam_stats', + 'DSPAM_WWW' => '/usr/local/pkg', + 'DSPAM_ARGS' => '--deliver=innocent --class=innocent ' . + '--source=error --user %CURRENT_USER% -d %u', + 'DSPAM_ADMIN_GROUP' => 'dspam_admins', + 'ALL_PROCS' => 'ps auxw', + 'MAIL_QUEUE' => 'mailq | grep \'^[0-9,A-F]\' | wc -l', + 'HISTORY_SIZE' => 799, + 'HISTORY_PER_PAGE' => 100, + 'QUARANTINE_PER_PAGE' => 100, + 'HISTORY_DUPLICATES' => 'yes', + 'MAX_COL_LEN' => 26, + 'QNAV_BUTTONS' => 20, + 'HNAV_BUTTONS' => 22, + 'SORT_DEFAULT' => 'Rating', + '3D_GRAPHS' => 1, + 'USE_MAILPARSE' => 1, + 'OPTMODE' => 'NONE', + 'LOCAL_DOMAIN' => 'localhost', + 'AUTODETECT' => 1, + 'OPENSOURCE' => 0, + /* Is there a website which provides dedicated infos? */ + 'PACKAGE_WEBSITE' => 'http://www.pfsense.com/', + /* Is there a forum which provides dedicated infos? */ + 'PACKAGE_FORUM' => 'http://www.pfsense.com/', + /* + * Is there a issue tracker which allows to fill a + * support request or a bug report? + */ + 'PACKAGE_TRACKER' => 'http://www.pfsense.com/', + /* 'DATE_FORMAT' => '%d.%m.%Y %H:%M' */ + 'DATE_FORMAT' => '%b %d %H:%M' + ); + +?> diff --git a/config/archive/dspam/pkg/dspam-guifunc.inc b/config/archive/dspam/pkg/dspam-guifunc.inc new file mode 100644 index 00000000..121bc8b5 --- /dev/null +++ b/config/archive/dspam/pkg/dspam-guifunc.inc @@ -0,0 +1,2606 @@ +&1", "r"); + + while (!feof($pd)) { + $line = chop( fgets($pd, 4096) ); + + if ($b == "qrowEven") { + $b = "qrowOdd"; + } else { + $b = "qrowEven"; + } + + $line = preg_replace('/:/', ' ', $line); + + list($username, , $sl, , $il, , $fp, , $sm, , $sc, , $ic) + = (preg_split('/\s+/', $line)); + if ($username == "" && $sl == "") { + /* we do not want to display data that + * does not bleong to any user + */ + continue; + } else if ($sl == "") { + $line = fgets($pd, 4096); + $line = preg_replace('/:/', ' ', $line); + list(, , $sl, , $il, , $fp, , $sm, , $sc, , $ic) + = (preg_split('/\s+/', $line)); + } + + $PREFS =& GetPrefs($username, GetPath($username).".prefs"); + if ($PREFS['enableBNR'] == "on") { $PREFS['enableBNR'] = "OFF"; } + if ($PREFS['enableWhitelist'] == "on") { $PREFS['enableWhitelist'] = "OFF"; } + $PREFS['spamAction'] = ucfirst($PREFS['spamAction']); + $PREFS['enableBNR'] = strtoupper($PREFS['enableBNR']); + $PREFS['enableWhitelist'] = strtoupper($PREFS['enableWhitelist']); + + $mailbox = GetPath($username).".mbox"; + if ( file_exists($mailbox) ) { + $mailbox_size = filesize($mailbox); + $mailbox_display = sprintf("%2.1f KB", ($mailbox_size / 1024)); + $mailbox_total += $mailbox_size; + } + else { + $mailbox_display = "--"; + } + + $sl_total += $sl; + $il_total += $il; + $sm_total += $sm; + $fp_total += $fp; + $sc_total += $sc; + $ic_total += $ic; + + $DATA['TABLE'] .= "{$username}" . + " {$mailbox_display}" . + " {$sl}" . + " {$il}" . + " {$fp}" . + " {$sm}" . + " {$sc}" . + " {$ic}" . + " {$PREFS['trainingMode']}" . + " {$PREFS['spamAction']}" . + " {$PREFS['enableBNR']}" . + " {$PREFS['enableWhitelist']}" . + " {$PREFS['statisticalSedation']}" . + " {$PREFS['signatureLocation']}" . + "\n"; + } + pclose($pd); + + $mailbox_total_display = sprintf("%2.1f KB", ($mailbox_total / 1024)); + + $b = "listhdrr"; + $DATA['TABLE'] .= "Total". + " {$mailbox_total_display}". + " {$sl_total}". + " {$il_total}". + " {$sm_total}". + " {$fp_total}". + " {$sc_total}". + " {$ic_total}". + "  ". + "  ". + "  ". + "  ". + "  ". + "  ". + "\n"; +} + +function &DisplayStatus() { + global $CONFIG, $DATA; + + $LOG = "{$CONFIG['DSPAM_HOME']}/system.log"; + $spam_daily = array(); + $nonspam_daily = array(); + $period_daily = array(); + $fp_daily = array(); + $sm_daily = array(); + $inoc_daily = array(); + $whitelist_daily = array(); + $spam_weekly = array(); + $nonspam_weekly = array(); + $period_weekly = array(); + $fp_weekly = array(); + $sm_weekly = array(); + $inoc_weekly = array(); + $$whitelist_weekly = array(); + $msgpersecond = array(); + $classes = array(); + + list (, $min, $hour, $mday, $mon, $year, , ,) = (localtime(time())); + $hmstart = time() - 60; + $daystart = mktime(0, 0, 0, $mon, $mday, $year); + $periodstart = $daystart - (3600*24*24); /* 2 Weeks ago */ + $dailystart = time() - (3600*23); + $c_weekly = 0; /* Cursor to most recent time slot */ + $c_daily = 0; + + if (! file_exists($LOG)) { + return $input_errors[] = "No historical data is available (log file »{$LOG}« does not exist)."; + } + + /* Initialize each individual time period */ + + for ($i = 0; $i <= 23; $i++) { + $h = To12Hour($hour - (23-$i)); + $period_daily[$i] = $h; + $spam_daily[$i] = 0; + $nonspam_daily[$i] = 0; + $sm_daily[$i] = 0; + $fp_daily[$i] = 0; + $inoc_daily[$i] = 0; + } + + for ($i = 0; $i <= 23; $i++) { + $d = $daystart - (3600 * 24 * (24 - $i)); + list (, , , $lday, $lmon, $lyear, , ,) = (localtime($d)); + $lmon++; + $lyear += 1900; + $period_weekly[$i] = "{$lmon}/{$lday}/{$lyear}"; + $spam_weekly[$i] = 0; + $nonspam_weekly[$i] = 0; + $sm_weekly[$i] = 0; + $fp_weekly[$i] = 0; + $inoc_weekly[$i] = 0; + } + + if($fd = @fopen("{$LOG}", "r")) { + while (!feof($fd)) { + $line = fgets($fd, 4096); + list ($t_log, $c_log, , $signature, , $e_log) = preg_split('/\t/', $line); + if ($t_log > time()) { continue; } + + $last_message = $t_log; + + /* Only Parse Log Data in our Time Period */ + if ($t_log >= $periodstart) { + list (, $tmin, $thour, $tday, $tmon, $tyear) = (localtime($t_log)); + $tmon++; + $tyear += 1900; + + /* Weekly Graph */ + $c_weekly = 0; + while($period_weekly[$c_weekly] <> "{$tmon}/{$tday}/{$tyear}" && $c_weekly < 24) { + $c_weekly++; + } + + if ($c_log == "E") { + if ($classes[$signature] == "S") { + $spam_weekly[$c_weekly]--; + if ($spam_weekly[$c_weekly] < 0) { $spam_weekly[$c_weekly] = 0; } + } else if ($classes[$signature] == "I") { + $nonspam_weekly[$c_weekly]--; + if ($nonspam_weekly[$c_weekly] < 0) { $nonspam_weekly[$c_weekly] = 0; } + } else if ($classes[$signature] == "W") { + $whitelist_weekly[$c_weekly]--; + if ($whitelist_weekly[$c_weekly] < 0) { $whitelist_weekly[$c_weekly] = 0; } + } else if ($classes[$signature] == "F") { + $spam_weekly[$c_weekly]++; $fp_weekly[$c_weekly]--; + if ($fp_weekly[$c_weekly] < 0) { $fp_weekly[$c_weekly] = 0; } + } else if ($classes[$signature] == "M") { + $sm_weekly[$c_weekly]--; $nonspam_weekly[$c_weekly]++; + if ($sm_weekly[$c_weekly] < 0) { $sm_weekly[$c_weekly] = 0; } + } else if ($classes[$signature] == "N") { + $inoc_weekly[$c_weekly]--; + if ($inoc_weekly[$c_weekly] < 0) { $inoc_weekly[$c_weekly] = 0; } + } + } else { + $classes[$signature] = $c_log; + } + + if ($c_log == "S") { $spam_weekly[$c_weekly]++; } + if ($c_log == "I") { $nonspam_weekly[$c_weekly]++; } + if ($c_log == "W") { $whitelist_weekly[$c_weekly]++; } + if ($c_log == "F") + { $spam_weekly[$c_weekly]--; $fp_weekly[$c_weekly]++; + if ($spam_weekly[$c_weekly] < 0) { $spam_weekly[$c_weekly] = 0; } + } + if ($c_log == "M") + { $sm_weekly[$c_weekly]++; $nonspam_weekly[$c_weekly]--; + if ($nonspam_weekly[$c_weekly] < 0) { $nonspam_weekly[$c_weekly] = 0; } + } + if ($c_log == "N") { $inoc_weekly[$c_weekly]++; } + + + /* Daily Graph */ + if ($t_log >= $dailystart) { + while($period_daily[$c_daily] <> To12Hour($thour) && $c_daily < 24) { + $c_daily++; + } + + if ($c_log == "E") { + if ($classes[$signature] == "S") { + $spam_daily[$c_daily]--; + if ($spam_daily[$c_daily] < 0) { $spam_daily[$c_daily] = 0; } + } else if ($classes[$signature] == "I") { + $nonspam_daily[$c_daily]--; + if ($nonspam_daily[$c_daily] < 0) { $nonspam_daily[$c_daily] = 0; } + } else if ($classes[$signature] == "W") { + $whitelist_daily[$c_daily]--; + if ($whitelist_daily[$c_daily] < 0) { $whitelist_daily[$c_daily] = 0; } + } else if ($classes[$signature] == "F") { + $spam_daily[$c_daily]++; $fp_daily[$c_daily]--; + if ($fp_daily[$c_daily] < 0) { $fp_daily[$c_daily] = 0; } + } else if ($classes[$signature] == "M") { + $sm_daily[$c_daily]--; $nonspam_daily[$c_daily]++; + if ($sm_daily[$c_daily] < 0) { $sm_daily[$c_daily] = 0; } + } else if ($classes[$signature] == "N") { + $inoc_daily[$c_daily]--; + if ($inoc_daily[$c_daily] < 0) { $inoc_daily[$c_daily] = 0; } + } + } + + if ($c_log == "S") { $spam_daily[$c_daily]++; } + if ($c_log == "I") { $nonspam_daily[$c_daily]++; } + if ($c_log == "W") { $whitelist_daily[$c_daily]++; } + if ($c_log == "F") + { $spam_daily[$c_daily]--; $fp_daily[$c_daily]++; + if ($spam_daily[$c_daily] < 0) { $spam_daily[$c_daily] = 0; } + } + if ($c_log == "M") + { $sm_daily[$c_daily]++; $nonspam_daily[$c_daily]--; + if ($nonspam_daily[$c_daily] < 0) { $nonspam_daily[$c_daily] = 0; } + } + if ($c_log == "N") { $inoc_daily[$c_daily]++; } + } + + /* Last Half-Minute */ + if ($t_log >= $hmstart) { + $msgpersecond[$t_log]++; + $DATA['AVG_PROCESSING_TIME'] += $e_log; + $keycount_exectime++; + } + } + } // end while + + fclose($fd); + } else { + return $input_errors[] = "Unable to open logfile: {$LOG}."; + } // end if + + /* Calculate Avg. Messages Per Second */ + foreach(array_values($msgpersecond) as $el) { + $DATA['AVG_MSG_PER_SECOND'] += $el; + } + $DATA['AVG_MSG_PER_SECOND'] /= 60; + $DATA['AVG_MSG_PER_SECOND'] = sprintf("%2.2f", $DATA['AVG_MSG_PER_SECOND']); + + /* Calculate Avg. Processing Time */ + if ($keycount_exectime == 0) { + $DATA['AVG_PROCESSING_TIME'] = 0; + } else { + $DATA['AVG_PROCESSING_TIME'] /= $keycount_exectime; + } + $DATA['AVG_PROCESSING_TIME'] = sprintf("%01.6f", $DATA['AVG_PROCESSING_TIME']); + + /* Calculate Number of processes, Uptime and Mail Queue length */ + $pd = popen("{$CONFIG['ALL_PROCS']} | grep dspam | grep -v grep | grep -v cgi | grep -v sock | wc -l", "r"); + $DATA['DSPAM_PROCESSES'] = fgets($pd, 4096); + pclose($pd); + + $pd = popen("uptime", "r"); + $DATA['UPTIME'] = fgets($pd, 4096); + pclose($pd); + + $pd = popen("{$CONFIG['MAIL_QUEUE']}", "r"); + $DATA['MAIL_QUEUE'] = fgets($pd, 4096); + pclose($pd); + + /* Calculate Graphs */ + $DATA['SPAM_TODAY'] = $spam_weekly[24]; + $DATA['NONSPAM_TODAY'] = $nonspam_weekly[24]; + $DATA['SM_TODAY'] = $sm_weekly[24]; + $DATA['FP_TODAY'] = $fp_weekly[24]; + $DATA['INOC_TODAY'] = $inoc_weekly[24]; + $DATA['TOTAL_TODAY'] = $DATA['SPAM_TODAY'] + $DATA['NONSPAM_TODAY'] + $DATA['SM_TODAY'] + + $DATA['FP_TODAY'] + $DATA['INOC_TODAY']; + + $DATA['SPAM_THIS_HOUR'] = $spam_daily[23]; + $DATA['NONSPAM_THIS_HOUR'] = $nonspam_daily[23]; + $DATA['SM_THIS_HOUR'] = $sm_daily[23]; + $DATA['FP_THIS_HOUR'] = $fp_daily[23]; + $DATA['INOC_THIS_HOUR'] = $inoc_daily[23]; + $DATA['TOTAL_THIS_HOUR'] = $DATA['SPAM_THIS_HOUR'] + + + $DATA['NONSPAM_THIS_HOUR'] + + $DATA['SM_THIS_HOUR'] + + $DATA['FP_THIS_HOUR'] + + $DATA['INOC_THIS_HOUR']; + + if (is_array($spam_daily) && + is_array($nonspam_daily) && + is_array($sm_daily) && + is_array($fp_daily) && + is_array($inoc_daily) && + is_array($whitelist_daily) && + is_array($period_daily)) { + $DATA['DATA_DAILY'] = join(",", $spam_daily) + . "_" + . join(",", $nonspam_daily) + . "_" + . join(",", $sm_daily) + . "_" + . join(",", $fp_daily) + . "_" + . join(",", $inoc_daily) + . "_" + . join(",", $whitelist_daily) + . "_" + . join(",", $period_daily); + + foreach($spam_daily as $el){ $DATA['TS_DAILY'] += $el; }; + foreach($nonspam_daily as $el){ $DATA['TI_DAILY'] += $el; } + foreach($sm_daily as $el){ $DATA['SM_DAILY'] += $el; } + foreach($fp_daily as $el){ $DATA['FP_DAILY'] += $el; } + foreach($inoc_daily as $el){ $DATA['INOC_DAILY'] += $el; } + foreach($whitelist_daily as $el){ $DATA['TI_DAILY'] += $el; } + } + + if (is_array($spam_weekly) && + is_array($nonspam_weekly) && + is_array($sm_weekly) && + is_array($fp_weekly) && + is_array($inoc_weekly) && + is_array($whitelist_weekly) && + is_array($period_weekly)) { + $DATA['DATA_WEEKLY'] = join(",", $spam_weekly) + . "_" + . join(",", $nonspam_weekly) + . "_" + . join(",", $sm_weekly) + . "_" + . join(",", $fp_weekly) + . "_" + . join(",", $inoc_weekly) + . "_" + . join(",", $whitelist_weekly) + . "_" + . join(",", $period_weekly); + + foreach($spam_weekly as $el){ $DATA['TS_WEEKLY'] += $el; } + foreach($nonspam_weekly as $el){ $DATA['TI_WEEKLY'] += $el; } + foreach($sm_weekly as $el){ $DATA['SM_WEEKLY'] += $el; } + foreach($fp_weekly as $el){ $DATA['FP_WEEKLY'] += $el; } + foreach($inoc_weekly as $el){ $DATA['INOC_WEEKLY'] += $el; } + foreach($whitelist_weekly as $el){ $DATA['TI_WEEKLY'] += $el; } + } +} + +function &DisplayInfos() { + global $CONFIG, $DATA, $g; + $validity = "valide"; + + $pd = @popen("{$CONFIG['DSPAM']} --version", "r"); + fgets($pd, 4096); // ignore 1st line + $DATA['DSPAM_VERSION'] = fgets($pd, 4096); + fgets($pd, 4096); // ignore next line + $DATA['DSPAM_COPYRIGHT'] = fgets($pd, 4096); + $DATA['DSPAM_WEBSITE'] = fgets($pd, 4096); + fgets($pd, 4096); // ignore next line + $DATA['DSPAM_COPYRIGHT_TEXT'] = fgets($pd, 4096); + $DATA['DSPAM_COPYRIGHT_TEXT'] .= " " . fgets($pd, 4096); + fgets($pd, 4096); // ignore next line + $DATA['DSPAM_CONFIGURE_ARGS'] = str_replace("Configuration parameters: ", "", fgets($pd, 4096)); + + pclose($pd); + + if (file_exists("{$g['conf_path']}/nione.lic") && + file_exists("{$g['conf_path']}/nione.lic.sha1")) { + if ($fd = @fopen("{$g['conf_path']}/nione.lic", "r")) { + $owneru = str_replace("Licensed User: ", "", fgets($fd, 4096)); + if ($owneru == "") { $validity = "invalide (owner data not found)"; } + $ownerc = str_replace("Company: ", "", fgets($fd, 4096)); + if ($ownerc == "") { $validity = "invalide (company not found)"; } + $lkey = str_replace("License Key: ", "", fgets($fd, 4096)); + if ($lkey == "") { $validity = "invalide (license key not found)"; } + $pdate = strtotime( str_replace("Purchase Date: ", "", fgets($fd, 4096)) ); + if ($pdate == "") { $validity = "invalide (purchase date not found)"; } + + fclose($fd); + } else { + $validity = "invalide (license files not found)"; + } + + if(! extension_loaded( 'bcompiler' )) { + if(@dl( 'bcompiler.so' )) { + require_once ("knione"); + $gen_lkey = getNIONEKey(trim($owneru), trim($ownerc)); + if (trim($lkey) <> $gen_lkey) { $validity = "invalide (wrong license key)"; } + + $cdate = mktime(0, 0, 0, date("m"), + date("d"), + date("Y")); + + $edate = mktime(0, 0, 0, date("m", $pdate), + date("d", $pdate), + date("Y", $pdate)+1); + + if ($edate < $cdate || + $pdate > $cdate) { + $validity = "invalide (license expired)"; + } + + if ($fd = @fopen("{$g['conf_path']}/nione.lic.sha1", "r")) { + $chksum = str_replace("SHA1 (nione.lic) = ", "", fgets($fd, 4096)); + $chksum_new = sha1_file("{$g['conf_path']}/nione.lic"); + + if (trim($chksum) !== trim($chksum_new)) { + $validity = "invalide (wrong license file checksum)"; + } + + fclose($fd); + } else { + $validity = "invalide (license files not found)"; + } + } else { + $validity = "invalide (extension missing, which is necessary to validate license data.)"; + } + } + } else { + $validity = "invalide (license files not found)"; + } + + $DATA['OWNER'] = $owneru; + $DATA['COMPANY'] = $ownerc; + $DATA['LICENSE_KEY'] = $lkey; + $DATA['LICENSE_VALIDITY'] = $validity; + $DATA['PURCHASE_DATE'] = date("F j, Y", $pdate); + $DATA['EXPIRY_DATE'] = date("F j, Y", $edate); +} + +/* ========================================================================== */ +/* = H I S T O R Y F U N C T I O N S = */ +/* ========================================================================== */ + +function &DisplayFragment($sigID = "", + $from = "", + $subject = "", + $info = "", + $time = "") { + global $DATA, $USER; + + $sigID = preg_replace('/\/', '///', $sigID); + + $DATA['FROM'] = $from; + $DATA['SUBJECT'] = $subject; + $DATA['INFO'] = $info; + $DATA['TIME'] = $time; + + if($fd = @fopen("{$USER}.frag/{$sigID}.frag", "r")) { + while (!feof($fd)) { + /* sanitize HTML markup */ + $line = preg_replace("//e", "'>'", $line); + $DATA['MESSAGE'] .= $line; + } + fclose($fd); + } else { + return $input_errors[] = "Unable to open file {$USER}.frag/{$sigID}.frag."; + } +} + +function &DisplayHistory($command = "", + $sigID= "", + $retrainChecked = array(), + $username = "", + $retrainParam = "", + $currentPage = 1, + $hPerPage = 0) { + global $CONFIG, $USER, $CURRENT_USER, $DATA; + + $buffer = array(); + $history = array(); + $rec = array(); + $rowclass = "rowEven"; + + if ($command == "retrainChecked" && count ($retrainChecked) > 0) { + foreach($retrainChecked as $el) { + list ($retrain, $signature) = split(":", $el); + if ($retrain == "innocent") { + ProcessFalsePositive(quotemeta($signature)); + } else if ($retrain == "innocent" || $retrain == "spam") { + system("{$CONFIG['DSPAM']} --source=error --class=" . quotemeta($retrain) . + " --signature=" . quotemeta($signature) . + " --user " . quotemeta($CURRENT_USER)); + } + } + // TODO: Do we need the other params which were submited during the current + // POS/GET request? + pfSenseHeader("/dspam-history.php?user={$username}&page={$currentPage}&hperpage={$hPerPage}"); + } else { + if ($retrainParam <> "") { + if ($retrainParam == "innocent") { + ProcessFalsePositive(); + } else { + system("{$CONFIG['DSPAM']} --source=error --class=" . quotemeta($retrainParam) . + " --signature=" . quotemeta($sigID) . + " --user " . quotemeta($CURRENT_USER)); + } + // TODO: Do we need the other params which were submited during the current + // POS/GET request? + pfSenseHeader("/dspam-history.php?user={$username}&page={$currentPage}&hperpage={$hPerPage}"); + } + } + + $LOG = "{$USER}.log"; + if (! file_exists($LOG)) { + return $input_errors[] = "No historical data is available (log file »{$USER}.log« does not exist)."; + } + + /* Preseed retraining information and delivery errors */ + + $fd = fopen($LOG, "r"); + while (!feof($fd)) { + /* TODO: If the subject line contains a , the below array would + * contain more then seven elements and thus would be invalide. + * + * The below code is some kind of a bug fix. + */ + $cline = fgets($fd, 4096); + $log_columns = preg_split("/\t/", $cline); + list($time, $class, $from, $signature, $subject, $info, $messageid) = $log_columns; + if (count ($log_columns) > 7) { + /* get values from the array beginning */ + $time = array_shift($log_columns); + $class = array_shift($log_columns); + $from = array_shift($log_columns); + $signature = array_shift($log_columns); + /* get msgid and info from the array end */ + $messageid = array_pop($log_columns); + $info = array_pop($log_columns); + /* the remaining parts are belonging to the subject */ + $subject = implode(" ", $log_columns); + } + + if ($signature == "") { continue; } + if ($class == "M" || $class == "F" || $class == "E") { + if ($class == "E") { + $rec[$signature]['info'] = $info; + } else if ($class == "F" || $class == "M") { + $rec[$signature]['class'] = $class; + $rec[$signature]['count']++; + if ($rec[$signature]['info'] == "") + { $rec[$signature]['info'] = $info; } + } + /* filter out resents if there are any. Since it's the same + * message we only allow retraining on the 1st occurence of it. + */ + } else if ($messageid == "" || + $rec[$signature]['messageid'] != $messageid || + $CONFIG['HISTORY_DUPLICATES'] <> "no") { + $rec[$signature]['time'] = $time; + $rec[$signature]['class'] = $class; + $rec[$signature]['from'] = $from; + $rec[$signature]['signature'] = $signature; + $rec[$signature]['subject'] = $subject; + $rec[$signature]['info'] = $info; + $rec[$signature]['messageid'] = $messageid; + + array_unshift($buffer, $rec[$signature]); + } + } // end while + fclose($fd); + + /* if the page size wasn't specified, set a default one */ + if ($CONFIG['HISTORY_PER_PAGE'] == 0) { + $CONFIG['HISTORY_PER_PAGE'] = 50; + } + + if (isset($hPerPage) && $hPerPage > 0) { + $CONFIG['HISTORY_PER_PAGE'] = $hPerPage; + } + + if (isset($currentPage) && isset($CONFIG['HISTORY_PER_PAGE'])) { + $pages = ceil( (count ($buffer) / $CONFIG['HISTORY_PER_PAGE']) ); + $begin = (($currentPage - 1) * $CONFIG['HISTORY_PER_PAGE']); + $ranges = ceil ($pages / $CONFIG['HNAV_BUTTONS']); + + /* Now lets just keep the information that we really need. */ + $buffer = array_splice($buffer, $begin, $CONFIG['HISTORY_PER_PAGE']); + } + + $retrain_checked_msg_no = 0; + while ($rec = array_pop($buffer)) { + $time = $rec['time']; + $class = $rec['class']; + $from = $rec['from']; + $signature = $rec['signature']; + $subject = $rec['subject']; + $info = $rec['info']; + $messageid = $rec['messageid']; + + if ($signature == "") { continue; } + if ($rec[$signature]['displayed'] <> "") { continue; } + if ($class == "E") { continue; } + $rec[$signature]['displayed'] = 1; + + /* Resends of retrained messages will need the original from/subject line */ + if ($messageid <> "") { + if ($from == "") { $from = $rec[$messageid]['from']; } + if ($subject == "") { $subject = $rec[$messageid]['subject']; } + + + if ($rec[$messageid]['from'] == "") { $rec[$messageid]['from'] = $from; } + if ($rec[$messageid]['subject'] == "") { $rec[$messageid]['subject'] = $subject; } + } + + if ($from == "") { $from = ""; } + if ($subject == "") { $subject = ""; } + + $ctime = ""; + if(isset($CONFIG["DATE_FORMAT"])) { + $ctime = strftime($CONFIG["DATE_FORMAT"], localtime($time)); + } else { + /* date format was taken from ctime.pl */ + $ctime = date ("D M d H:i:s TY",$time); + $ttmp = preg_split("/\s+/", $ctime); + $t = preg_split("/\:/", $ttmp[3]); + $xtmp = preg_split("/\s+/", $ctime); + $x = $xtmp[0]; + $m = "a"; + if ($t[0] > 12) { $t[0] -= 12; $m = "p"; } + if ($t[0] == 0) { $t[0] = 12; } + $ctime = "{$x} {$t[0]}:{$t[1]}{$m}"; + } + + /* Set the appropriate type and label for this message */ + + $cl = ""; + $cllabel = ""; + if ($rec[$signature]['class'] <> "") { $class = $rec[$signature]['class']; } + if ($class == "S") { $cl = "spam"; $cllabel="SPAM"; } + else if ($class == "I") { $cl = "innocent"; $cllabel="Good"; } + else if ($class == "F") { + if (fmod($rec[$signature]['count'], 2) != 0) { + $cl = "false"; $cllabel="Miss"; + } else { + $cl = "innocent"; $cllabel="Good"; + } + } + else if ($class == "M") { + if (fmod($rec[$signature]['count'], 2) != 0) { + $cl = "missed"; $cllabel="Miss"; + } else { + $cl = "spam"; $cllabel="SPAM"; + } + } + else if ($class == "N") { $cl = "inoculation"; $cllabel="Spam"; } + else if ($class == "C") { $cl = "blacklisted"; $cllabel="RBL"; } + else if ($class == "W") { $cl = "whitelisted"; $cllabel="Whitelist"; } + if ($messageid <> "") { + if ($rec[$messageid]['resend'] <> "") { + $cl = "relay"; + $cllabel = "Resend"; + } + $rec[$messageid]['resend'] = $signature; + } + + if ($rec[$signature]['info'] <> "") { $info = $rec[$signature]['info']; } + + /* sanitize HTML markup */ + $from = preg_replace("//e", "'>'", $from); + $subject = preg_replace('//e', "'>'", $subject); + + if (strlen($from) > $CONFIG['MAX_COL_LEN']) { $from = substr($from, 0, $CONFIG['MAX_COL_LEN']) . "..."; } + if (strlen($subject) > $CONFIG['MAX_COL_LEN']) { $subject = substr($subject, 0, $CONFIG['MAX_COL_LEN']) . "..."; } + + $rclass = ""; + if ($class == "I" || $class == "W" || $class == "F") { $rclass = "spam"; } + if ($class == "S" || $class == "M") { $rclass = "innocent"; } + + $retrain = ""; + if (preg_match('/^(M|F)$/', $rec[$signature]['class']) > 0 && + fmod($rec[$signature]['count'], 2) != 0) { + $retrain = "Retrained"; + } + + if ($retrain == "") { + $retrain = "As " . ucfirst($rclass) . ""; + } else { + $retrain .= "(Undo)"; + } + + $path = "{$USER}.frag/{$signature}.frag"; + if (file_exists($path)) { + $pairs = array(); + $pairs['template'] = "fragment"; + $pairs['signatureID'] = $signature; + $sub = $subject; + $sub = preg_replace('/#/e', '//', $sub); + $sub = preg_replace("/(['])/e", '/\\$1/', $sub); + $pairs['subject'] = $sub; + $pairs['from'] = $from; + $pairs['info'] = $info; + $pairs['time'] = $ctime; + $pairs['user'] = $username; + $pairs['page'] = $currentPage; + $pairs['hperpage'] = $hPerPage; + $url = SafeVars($pairs); + $from = "{$from}"; + } + + $entry = << + {$cllabel} + + + + + + + {$ctime} + {$from} + {$subject} + {$info} + + +EOD; + + $retrain_checked_msg_no++; + array_push($history, $entry); + + if ($rowclass == "qrowEven") { + $rowclass = "qrowOdd"; + } else { + $rowclass = "qrowEven"; + } + $hurtz++; + } // end while + + $entry = << + +EOD; + array_push($history, $entry); + + while($line = array_pop($history)) { $DATA['HISTORY'] .= $line; } + + if ($CONFIG['HISTORY_PER_PAGE'] > 0) { + /* prepare quarantine navbar */ + if (($currentPage - 1) >= 1) { $previousPage = $currentPage - 1; } + else { $previousPage = 1; } + + if (($currentPage + 1) <= $pages) { $nextPage = $currentPage + 1; } + else { $nextPage = $pages; } + + $historyFooterBegin = << + + |<  + <  + +EOD; + + $historyFooterEnd = <<>  + >| + + + +EOD; + + $ranges_array = array(); + $rpages = $pages; + for ($i = 0; $i < $ranges; $i++) { + $range = array(); + $range['start'] = (($i + 1)* $CONFIG['HNAV_BUTTONS']) - ($CONFIG['HNAV_BUTTONS'] - 1); + + if (($i + 1) == $ranges) { + $range['end'] = ($range['start'] + $rpages) - 1; + } else { + $range['end'] = (($i + 1)* $CONFIG['HNAV_BUTTONS']); + $rpages -= $CONFIG['HNAV_BUTTONS']; + } + + $ranges_array[$i] = $range; + } + + /* generate nav buttons */ + foreach($ranges_array as $range){ + if ($currentPage >= $range['start'] && $currentPage <= $range['end']) { + for ($i = $range['start']; ; $i++) { + if ($i > $range['end']) { + break; + } else { + if ($i == $currentPage) { + $historyFooter .= "{$i} \n"; + } else { + $historyFooter .= "{$i} \n"; + } + } + } + } + } + + $DATA['HISTORY_FOOTER'] = $historyFooterBegin . $historyFooter .$historyFooterEnd; + $DATA['HPAGES'] = $pages; + $DATA['HPAGE'] = $currentPage; + +/* + $DATA['HISTORY'] .= "

["; + if (($history_pages > 1) && ($history_page > 1)) { + $i = $history_page - 1; + $DATA['HISTORY'] .= " < "; + } + for($i = 1; $i <= $history_pages; $i++) { + if ($i == $history_page) { + $DATA['HISTORY'] .= " $i "; + } else { + $DATA['HISTORY'] .= " {$i} "; + } + } + if (($history_pages > 1) && ($history_page < $history_pages)) { + $i = $history_page + 1; + $DATA['HISTORY'] .= " > "; + } + $DATA['HISTORY'] .= "]
"; +*/ + } // end if +} + +/* ========================================================================== */ +/* = A N A L Y S I S F U N C T I O N S = */ +/* ========================================================================== */ + +function &DisplayAnalysis() { + global $USER, $CURRENT_USER, $CONFIG, $DATA; + $LOG = "{$USER}.log"; + + $Stats = array( + "daily" => array(), + "weekly" => array() + ); + + list(, $min, $hour, $mday, $mon, $year, , ,) = (localtime(time())); + $daystart = mktime(0, 0, 0, $mon, $mday, $year); + $periodstart = $daystart - (3600 * 24 * 13); /* 2 Weeks ago */ + $dailystart = time() - (3600 * 23); + + /* TODO: There's an issue that the Perl timelocal returns + * different values compared to PHP's mktime. There's a + * difference of 2678400, which will be added manually below. + */ + $daystart += 2678400; + $periodstart += 2678400; + + if (file_exists($LOG)) { + if ($fd = @fopen($LOG, "r")) { + $scount = 0; + $icount = 0; + $wcount = 0; + $fcount = 0; + $mcount = 0; + + while(!feof($fd)) { + $buffer = fgets($fd, 4096); + /* drop blank lines */ + if (strlen($buffer) == 0) { continue; } + list($t_log, $c_log) = preg_split("/\t/", $buffer); + + /* Only Parse Log Data in our Time Period */ + /* TODO: The below if should evaluate to true at least for some data */ + if ($t_log >= $periodstart) { + list(, $tmin, $thour, $tday, $tmon, , , ,) = (localtime($t_log)); + $tmon++; + + foreach (array('weekly', 'daily') as $period) { + $idx = 0; + if ($period == "weekly") { + $idx= "{$tmon}/{$tday}"; + } else { + if ($t_log <= $dailystart) { continue; } + $idx = To12Hour($thour); + } + if (is_array($Stats[$period]) && ! array_key_exists ($idx, $Stats[$period])) { + $Stats[$period][$idx] = array( + 'nonspam' => 0, + 'spam' => 0, + 'title' => $idx, + 'idx' => $t_log); + } + /* TODO: Is passing by reference here correct? */ + $hr =& $Stats[$period][$idx]; + /* S => spam */ + if ($c_log== "S") { + $hr['spam']++; + $scount++; + } + /* I => innocent W => whitelisted */ + if ($c_log == "I" || $c_log == "W") { + $hr['nonspam']++; + if ($c_log == "I") { $icount++; } + else { $wcount++; } + } + /* F => false positive */ + if ($c_log == "F") { + $hr['spam']--; + if ($hr['spam'] < 0) { $hr['spam'] = 0; } + $hr['nonspam']++; + $fcount++; + } + /* M => spam miss */ + if ($c_log == "M") { + $hr['nonspam']--; + if ($hr['nonspam'] < 0) { $hr['nonspam'] = 0; } + $hr['spam']++; + $mcount++; + } + } + } + } + + fclose($fd); + } else { + return $input_errors[] = "Unable to open log file: {$LOG}."; + } + + usort ((array_values ($Stats[$period])), "cmpArrayValues"); + + foreach (array('weekly', 'daily') as $period) { + $uc_period = strtoupper($period); + $hk = "DATA_{$uc_period}"; + $lst = array(); + + foreach (array_values($Stats[$period]) as $hr) { + foreach (array('spam', 'nonspam', 'title') as $type ) { + + if (empty($lst[$type])) { + $lst[$type] = array(); + } + + /* populate (newly) created array */ + $lst[$type][] = $hr[$type]; + + $totk=""; + + if ($type == "spam") { $totk="S"; } + else if ($type == "nonspam") { $totk="I"; } + + if ($totk == "") { continue; } + + $sk="T{$totk}_{$uc_period}"; + if (empty($DATA[$sk])) { $DATA[$sk] = 0; } + + $DATA[$sk] += $hr[$type]; + } + } // end foreach + $DATA[$hk] = + @join(",",$lst['spam']) . "_" . + @join(",",$lst['nonspam']) . "_" . + @join(",",$lst['title']); + } // end foreach + } else { + return $input_errors[] = "No historical data is available (log file »{$LOG}« does not exist)."; + } // end if +} + +function cmpArrayValues($a, $b) { + if ($a['idx'] == $b['idx']) + return 0; + + return ($a['idx'] < $b['idx']) ? -1 : 1; +} + +/* ========================================================================== */ +/* = P E R E F E R E N C E S F U N C T I O N S = */ +/* ========================================================================== */ + +function &DisplayPreferences($mode = "", &$statusmsg){ + global $USER, $CURRENT_USER, $CONFIG, $DATA; + $FILE = "{$USER}.prefs"; + $username = $CURRENT_USER; + + if ($_POST) { + $pconfig = $_POST; + + if ($pconfig['chk_feature_nr'] <> "on") { + $pconfig['chk_feature_nr'] = "off"; + } + + if ($pconfig['chk_feature_optin'] <> "on") { + $pconfig['chk_feature_optin'] = "off"; + } + + if ($pconfig['chk_feature_optout'] <> "on") { + $pconfig['chk_feature_optout'] = "off"; + } + + if ($pconfig['chk_feature_at'] <> "on") { + $pconfig['chk_feature_at'] = "off"; + } + + if ($pconfig['chk_feature_aw'] <> "on") { + $pconfig['chk_feature_aw'] = "off"; + } + + if ($CONFIG['PREFERENCES_EXTENSION'] == 1) { + if ($pconfig['msgtag'] == "") { + $pconfig['msgtag'] = "''"; + } else { + $pconfig['msgtag'] = quotemeta($pconfig['msgtag']); + } + + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " trainingMode " . quotemeta($pconfig['rad_train']) . " > /dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " spamAction " . quotemeta($pconfig['rad_train_action']) . " > /dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " signatureLocation " . quotemeta($pconfig['signatureLocation']) . " > /dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " spamSubject " . quotemeta($pconfig['msgtag']) . " > /dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " statisticalSedation " . quotemeta($pconfig['rad_filter_sens']) . " > /dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " enableBNR " . quotemeta($pconfig['chk_feature_nr']) . " > /dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " optOut " . quotemeta($pconfig['chk_feature_optout']) . " >/dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " optIn " . quotemeta($pconfig['chk_feature_optin']) . " >/dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " showFactors " . quotemeta($pconfig['chk_feature_at']) . " > /dev/null"); + exec("{$CONFIG['DSPAM_BIN']}/dspam_admin ch pref " . quotemeta($username) . + " enableWhitelist " . quotemeta($pconfig['chk_feature_aw']) . " > /dev/null"); + } else { + $prefsstr = << 0) { + if ($mode == 0) { $mode = 1; } + else { continue; } + } + + $buff = array_shift($buffer); + if (preg_match('/^From /', $buff) == 0) { + array_push($temp, $buff); + } + + continue; + } + + foreach($temp as $tempel) { + if ($tempel == "") { break; } + list($key, $val) = preg_split('/\: ?/', $tempel, 2); + $head[$key] = $val; + } + if ($head['X-DSPAM-Signature'] == $sigID) { + $found = 1; + $old_erep = error_reporting(E_ALL); + if ($pd = @popen("|{$CONFIG['DSPAM']} {$CONFIG['DSPAM_ARGS']} >{$TMPFILE} 2>&1", "w")) { + $pdresult = fread($handle, 2096); + + foreach($temp as $tempel) { + fwrite($pd, "{$tempel}\n"); + } + + pclose($pd); + error_reporting($old_erep); + } else { + $error = true; + $input_errors[] = "Unable to ope process pipe in function ProcessFalsePositive."; + } + } + } + + /* Couldn't find the message, so just retrain on signature */ + if (!$found) { + system("$CONFIG{'DSPAM'} --source=error --class=innocent --signature=" . quotemeta($sigID) . + " --user " . quotemeta($CURRENT_USER)); + } + + if ($error) { + $log = array(); + $fd = fopen("{$TMPFILE}", "r"); + while (!feof($handle)) { + $log .= fgets($fd, 4096); + } + fclose($fd); + unlink("{$TMPFILE}"); + return $input_errors[] = $log; + } + + unlink("{$TMPFILE}"); + $signatures[$sigID] = "on"; + return QuarantineDeleteSpam("", $signatures, $sortBy, $currentPage, $qPerPage); +} + +function &QuarantineManyNotSpam($signatures = array(), $sortBy = "Rating", $currentPage = 1, $qPerPage = 0){ + global $MAILBOX, $USER; + $buffer = array(); + $errors = array(); + + /* read the user's mailbox line by line into a buffer */ + $fd = fopen("{$MAILBOX}", "r"); + while (!feof($fd)) { + $line = chop(fgets($fd, 4096)); + array_push($buffer, $line); + } + fclose ($fd); + + if ($fd_FILE = @fopen("{$MAILBOX}", "w")) { + $fd_RETRAIN = fopen("{$USER}.retrain.log", "a"); + + /* iterate over the mailbox buffer */ + reset($buffer); + $i = 0; + while ($i < count($buffer)) { + $temp = array(); + $head = array(); + $mode = 0; + $buff = ""; + + /* this while tries to iterate over one single mesage including + * the message header and the message body. + */ + while((preg_match('/^From /', $buff) == 0) && ($i < count($buffer))) { + $buff = $buffer[0]; + + /* switch mode if we are hitting DSPAMs + * pseudo From QUARANTINE line (without a + * colon after the From). + */ + if (preg_match('/^From /', $buff) > 0) { + if ($mode == 0) { + $mode = 1; + $buff = array_shift($buffer); + array_push($temp, $buff); + $buff = ""; + continue; + } else { + continue; + } + } + + $buff = array_shift($buffer); + array_push($temp, $buff); + + continue; + } + + /* populate the header array with header fields */ + foreach($temp as $tempel) { + if ($tempel == "") { break; } + list($key, $val) = preg_split('/\: ?/', $tempel, 2); + $head[$key] = $val; + } + + $delivered = 0; + if ($signatures["chkmsg-{$head['X-DSPAM-Signature']}"] <> "") { + $err = Deliver($temp); + if ($err == "") { + $delivered = 1; + } else { + array_push($errors, $err); + } + } + if (!$delivered) { + foreach($temp as $tempel) { + fwrite($fd_FILE, "{$tempel}\n"); + } + } else { + fwrite($fd_RETRAIN, strval(time()) . "\t{$head['X-DSPAM-Signature']}\tinnocent\n"); + } + + $i++; + } // end while + + fclose($fd_FILE); + fclose($fd_RETRAIN); + } else { + return $input_errors[] = "Unable to open mailbox file: {$MAILBOX}."; + } + + if (count($errors) > 0) { + return $errors; + } + + return DisplayQuarantine($sortBy, $currentPage, $qPerPage); +} + +function Deliver($temp = array()) { + global $CONFIG; + + if (! file_exists("/tmp/dspam-error-output.txt")) { + touch("/tmp/dspam-error-output.txt"); + } + $descriptorspec = array( + 0 => array("pipe", "r"), // stdin is a pipe that the child will read from + 1 => array("pipe", "w"), // stdout is a pipe that the child will write to + 2 => array("file", "/tmp/dspam-error-output.txt", "a") // stderr is a file to write to + ); + + list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizeb, + $atime,$mtimeb,$ctime,$blksize,$blocks) + = stat("/tmp/dspam-error-output.txt"); + clearstatcache(); + + $cwd = '/tmp'; + $process = @proc_open("{$CONFIG['DSPAM']} {$CONFIG['DSPAM_ARGS']}", + $descriptorspec, + $pipes); + + if (is_resource($process)) { + foreach($temp as $tempel) { + if (! @fwrite($pipes[0], "{$tempel}\n")) { + return "error while writting to pipe."; + } + } + + fclose($pipes[0]); + fclose($pipes[1]); + $return_value = proc_close($process); + + /* this isn't an elegant solution to determine whether + * DSPAM did report some errors, but it works for now + */ + list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizea, + $atime,$mtimea,$ctime,$blksize,$blocks) + = stat("/tmp/dspam-error-output.txt"); + + if ($mtimeb <> $mtimea) { return "DSPAM did report some errors to /tmp/dspam-error-output.txt.\n" . + "Please check this particular file."; } + } else { + return "process is not a resource type."; + } + + return ""; +} + +function getLayoutedMessage($msgbuffer = "", $sigID = "", $showpart = 0, $ctype = 0){ + + if ($msgbuffer == "") { + return 'An error occured while parsing the message (no message).'; + } + if ($sigID == "") { + return 'An error occured while parsing the message (no signature).'; + } + + if( extension_loaded( 'mailparse' ) ) { + $msgdate = "N/A"; + $msgfrom = "N/A"; + $msgsub = "N/A"; + $msgto = "N/A"; + + $mime = mailparse_msg_create(); + mailparse_msg_parse($mime, $msgbuffer); + /* return an array of message parts - this contsists of the + * names of the parts only. + */ + $struct = mailparse_msg_get_structure($mime); + $htmlstr = << + Message Infos + + + Date: + %MSGDATE% + + + From: + %MSGFROM% + + + Subject: + %MSGSUB% + + + To: + %MSGTO% + + +   + + + Message Part + Part Type + Part Encoding + + + +EOD; + + /* print a choice of sections */ + foreach($struct as $st) { + + /* get a handle on the message resource for a subsection */ + $section = mailparse_msg_get_part($mime, $st); + /* get content-type, encoding and header information for that section */ + $info = mailparse_msg_get_part_data($section); + + /* replace placeholder with real data */ + if ($info['headers']['date'] <> "") { + $htmlstr = str_replace("%MSGDATE%", $info['headers']['date'], $htmlstr); + } + if ($info['headers']['from'] <> "") { + $htmlstr = str_replace("%MSGFROM%", $info['headers']['from'], $htmlstr); + } + if ($info['headers']['subject'] <> "") { + $htmlstr = str_replace("%MSGSUB%", $info['headers']['subject'], $htmlstr); + } + if ($info['headers']['to'] <> "") { + $htmlstr = str_replace("%MSGTO%", $info['headers']['to'], $htmlstr); + } + + $fontStyle = ""; + if ($showpart && $showpart == $st) { $fontStyle = " style=\"font-weight: bolder;\""; } + + if ($info["content-type"] == "text/html") { + $htmlstr .= "" . + "{$st}" . + "\n"; + } else { + $htmlstr .= "" . + "{$st}" . + "\n"; + } + + $htmlstr .= <<{$info["content-type"]} + {$info["charset"]} + + +EOD; + } // end foreach + + /* if we were called to display a part, do so now */ + if ($showpart) { + /* get a handle on the message resource for the desired part */ + $sec = mailparse_msg_get_part($mime, $showpart); + + $htmlstr .= << +   + + + Section {$showpart} + + + +EOD; + + ob_start(); + mailparse_msg_extract_part($sec, $msgbuffer); + $contents = ob_get_contents(); + ob_end_clean(); + $contents = wordwrap( str_replace(">", ">\n", $contents), 100, "\n" ); + /* quote the message for safe display in a browser */ + if ($ctype = 1) { + /* a html email message */ + $htmlstr .= "
" . $contents . "
\n\n"; + } else { + /* an ASCII (text) email message */ + $htmlstr .= htmlentities($contents) . "\n\n"; + } + } + + return $htmlstr; + } else { + return 'Could not load mailparse extension.'; + } +} + +function &QuarantineViewMessage($sigID = "", + $showpart = 0, + $ctype = 0, + $sortBy = "Rating", + $currentPage = 1, + $qPerPage = 0) { + global $MAILBOX, $DATA; + $buffer = array(); // mailbox buffer + + if ($sigID == "") { + return $input_errors[] = "No Message ID Specified."; + } + + /* save data to be displayed as HTML form data */ + $DATA['MESSAGE_ID'] = $sigID; + $DATA['SHOWPART'] = $showpart; + $DATA['CONTENT_TYPE'] = $ctype; + $DATA['QPAGE'] = $currentPage; + $DATA['SORTBY'] = $sortBy; + + if ($qPerPage > 0) { $CONFIG['QUARANTINE_PER_PAGE'] = $qPerPage; } + + /* read the user's mailbox line by line into a buffer */ + $fd = fopen("{$MAILBOX}", "r"); + while (!feof($fd)) { + $line = chop(fgets($fd, 4096)); + array_push($buffer, $line); + } + fclose ($fd); + + /* iterate over the mailbox buffer */ + reset($buffer); + $i = 0; + while ($i < count($buffer)) { + $temp = array(); + $head = array(); + $mode = 0; + $buff = ""; + + /* this while tries to iterate over one single mesage including + * the message header and the message body. + */ + while((preg_match('/^From /', $buff) == 0) && ($i < count($buffer))) { + $buff = $buffer[0]; + + /* switch mode if we are hitting DSPAMs + * pseudo From QUARANTINE line (without a + * colon after the From). + */ + if (preg_match('/^From /', $buff) > 0) { + if ($mode == 0) { $mode = 1; } + else { continue; } + } + + $buff = array_shift($buffer); + if (preg_match('/^From /', $buff) == 0) { + array_push($temp, $buff); + } + + continue; + } + + /* populate the header array with header fields */ + foreach($temp as $tempel) { + if ($tempel == "") { break; } + list($key, $val) = preg_split('/\: ?/', $tempel, 2); + $head[$key] = $val; + } + if ($head['X-DSPAM-Signature'] == $sigID) { + foreach($temp as $tempel) { + $tempel = preg_replace("//e", "'>'", $tempel); + $DATA['MESSAGE'] .= "{$tempel}\n"; + } + } + + $i ++; + } // end while +} + +function QuarantineDeleteSpam($deleteAll = "", $signatures = array(), $sortBy = "Rating", $currentPage = 1, $qPerPage = 0){ + global $USER, $MAILBOX; + $buffer = array(); + + /* this is the most easiest operation: If the user wants + * to completly delete any quarantined message, simply + * open his mailbox in write mode, which empties the + * user's mailbox file. + */ + if ($deleteAll <> "") { + + list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, + $atime,$mtime,$ctime,$blksize,$blocks) = stat("{$USER}.mbox"); + + $fd = fopen("{$USER}.mbox.size", "r"); + $sz = chop(fgets($fd, 4096)); + fclose($fd); + + if ($sz == $size) { + $fd = fopen("{$MAILBOX}", "w"); + fclose($fd); + unlink("{$USER}.mbox.size"); + unlink("{$USER}.mboxwarn"); + } else { + return DisplayQuarantine($sortBy, $currentPage, $qPerPage); + } + + //$FORM{'template'} = "performance"; + CheckQuarantine(); + return DisplayIndex(); + } + + /* iterate over the user's mailbox and store its contents in a buffer */ + $fd = fopen("{$MAILBOX}", "r"); + while (!feof($fd)) { + $line = chop(fgets($fd, 4096)); + array_push($buffer, $line); + } + fclose($fd); + + /* open the user's mailbox in write mode. This empties the mailbox! */ + fopen("{$MAILBOX}", "w"); + + /* iterate over the mailbox buffer */ + reset($buffer); + $i = 0; + while ($i < count($buffer)) { + $temp = array(); + $head = array(); + $mode = 0; + + /* this while tries to iterate over one single mesage including + * the message header and the message body. + */ + while((preg_match('/^From /', $buff) == 0) && ($i < count($buffer))) { + $buff = $buffer[0]; + + /* switch mode if we are hitting DSPAMs + * pseude From QUARANTINE line (without a + * colon after the From). + */ + if (preg_match('/^From /', $buff) > 0) { + if ($mode == 0) { + $mode = 1; + $buff = array_shift($buffer); + array_push($temp, $buff); + $buff = ""; + continue; + } else { + continue; + } + } + $buff = array_shift($buffer); + array_push($temp, $buff); + + continue; + } + + /* populate the header array with header fields */ + foreach($temp as $tempel) { + if ($tempel == "") { break; } + list($key, $val) = preg_split('/\: ?/', $tempel, 2); + $head[$key] = $val; + } + + /* if the current DSPAM signature wasn't selected by the + * user to be deleted, write it back to the user's mailbox. + */ + if ($signatures["chkmsg-{$head['X-DSPAM-Signature']}"] == "") { + foreach($temp as $tempel) { + fwrite($fd, "{$tempel}\n"); + } + } + + $i++; + } // end while + fclose($fd); + + return; +} + +function sortBySubject($a, $b){ + $lca = strtolower ($a['Subject']); + $lcb = strtolower ($b['Subject']); + + return strcmp($lca, $lcb); +} + +function sortByFrom($a, $b){ + $lca = strtolower ($a['From']); + $lcb = strtolower ($b['From']); + + return strcmp($lca, $lcb); +} + +function &DisplayQuarantine($sortBy = "Rating", $currentPage = 1, $qPerPage = 0) { + global $USER, $CURRENT_USER, $CONFIG, $DATA, $MAILBOX; + $alertcfg = &$config['installedpackages']['dspamalerts']['config']; + $alerts = array(); + + if (file_exists("{$USER}.mbox")) { + list($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, + $atime,$mtime,$ctime,$blksize,$blocks) = stat("{$USER}.mbox"); + + $fd = fopen("{$USER}.mbox.size", "w"); + fwrite($fd, "{$size}"); + fclose($fd); + + $fd = fopen("{$MAILBOX}.stamp", "a+"); + fclose($fd); + chmod("{$MAILBOX}.stamp", 0660); + + /* process alert names */ + if (is_array($alertcfg)) { + $alert_counter = 0; + + foreach ($alertcfg as $alert) { + $alerts[$alert_counter] = $alert['alertname']; + $alert_counter++; + } + } + + $mode = ""; + $buffer = array(); + $headings = array(); + $rowclass = "qrowEven"; + $fd = fopen("{$MAILBOX}", "r"); + + while (!feof($fd)) { + $mbxline = chop(fgets($fd, 4096)); + + if ($mbxline <> "") { + if (($mode == "")) { + if (preg_match('/^From /', $mbxline) > 0) { + $mode = 1; + } else { + continue; + } + } + + array_push($buffer, $mbxline); + continue; + } + + if ($mode == "") { continue; } + + $alert = 0; + $new = array(); + + foreach($buffer as $buf_element){ + foreach($alerts as $al){ + if (preg_match("/{$al}/i", $buf_element) > 0) { + $alert = 1; + } + } + + if (preg_match('/^From /', $buf_element) > 0) { + $a = split(' ', $buf_element); + $x = 2; + + for ($i = 0; $i < count ($a); $i++) { + if ((preg_match('/\@|>/', $a[$i]) > 0) && $i > $x) { + $x = $i + 1; + } + } + + for ($i = 1; $i < $x; $i++) { array_shift($a); } + $start = join(" ", $a); + } else { + list($key, $val) = preg_split('/\: ?/', $buf_element, 2); + $new[$key] = $val; + } + } + + if ($rowclass == "qrowEven") { + $rowclass = "qrowOdd"; + } else { + $rowclass = "qrowEven"; + } + + $new['alert'] = $alert; + + if ($alert) { $rowclass="qrowAlert"; } + + $new['Sub2'] = $new['X-DSPAM-Signature']; + if (strlen($new['Subject']) > $CONFIG['MAX_COL_LEN']) { + $new['Subject'] = substr($new['Subject'], 0, $CONFIG['MAX_COL_LEN']) . "..."; + } + + if (strlen($new['From']) > $CONFIG['MAX_COL_LEN']) { + $new['From'] = substr($new['From'], 0, $CONFIG['MAX_COL_LEN']) . "..."; + } + + if ($new['Subject'] == "") { + $new['Subject'] = ""; + } + + //$new->{'rating'} = $new->{'X-DSPAM-Probability'} * $new->{'X-DSPAM-Confidence'}; + $new['rating'] = $new['X-DSPAM-Confidence']; + + foreach(array_keys($new) as $key) { + if ($key == "X-DSPAM-Signature") { continue; } + preg_replace('//', '/\>\;/', $new[$key]); + } + + array_push($headings, $new); + + $buffer = array(); + $mode = ""; + continue; + } // end while (!feof($fd)) + + if (! isset($sortBy) || $sortBy == "") { + $sortBy = $CONFIG['SORT_DEFAULT']; + } + if ($sortBy == "Rating") { + usort($headings, "sortByRating"); + } + if ($sortBy == "Subject") { + usort($headings, "sortBySubject"); + } + if ($sortBy == "From") { + usort($headings, "sortByFrom"); + } + if ($sortBy == "Date") { + array_reverse ($headings); + } + + /* + + +   + Rating + Date + From + Subject + + + */ + + $DATA['SORTBY'] = $sortBy; + $DATA['SORT_SELECTOR'] .= << +   + +EOD; + + if ($sortBy == "Rating") { + $DATA{'SORT_SELECTOR'} .= "Rating  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "Rating"; + } + if ($sortBy == "Date") { + $DATA{'SORT_SELECTOR'} .= "Date  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "Date"; + } + if ($sortBy == "Subject") { + $DATA{'SORT_SELECTOR'} .= "Subject  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "Subject"; + } + if ($sortBy == "From") { + $DATA{'SORT_SELECTOR'} .= "From  ◊"; + } else { + $DATA{'SORT_SELECTOR'} .= "From"; + } + + $DATA{'SORT_SELECTOR'} .= "\n "; + + if (isset($qPerPage) && $qPerPage > 0) { + $CONFIG['QUARANTINE_PER_PAGE'] = $qPerPage; + } + + if (isset($currentPage) && isset($CONFIG['QUARANTINE_PER_PAGE'])) { + $pages = ceil( (count ($headings) / $CONFIG['QUARANTINE_PER_PAGE']) ); + $begin = (($currentPage - 1) * $CONFIG['QUARANTINE_PER_PAGE']); + $ranges = ceil ($pages / $CONFIG['QNAV_BUTTONS']); + + /* Now lets just keep the information that we really need. */ + $headings = array_splice ($headings, $begin, $CONFIG['QUARANTINE_PER_PAGE']); + } + + $rowclass = "qrowEven"; + foreach ($headings as $row) { + $rating = sprintf("%3.0f%%", $row['rating'] * 100.0); + if ($row['rating'] > 0.8) { + $markclass = "high"; + } else { + if ($row['rating'] < 0.7) { + $markclass = "low"; + } else { + $markclass = "medium"; + } + } + + $PAIRS = array(); + + $PAIRS['signatureID'] = $row['X-DSPAM-Signature']; + $PAIRS['command'] = "viewMessage"; + $PAIRS['user'] = $CURRENT_USER; + $PAIRS['page'] = $currentPage; + $PAIRS['sortby'] = $sortBy; + $PAIRS['qperpage'] = $CONFIG['QUARANTINE_PER_PAGE']; + // $PAIRS['template'] = "quarantine"; + + $url = SafeVars($PAIRS); + $sender = htmlentities ($row['From']); + $rsubject = htmlentities ($row['Subject']); + + if ($row['alert']) { + $outclass = "qrowAlert"; + } else { + $outclass = $rowclass; + } + + $ptfields = preg_split('/\s+/', $row['X-DSPAM-Processed']); + $times = preg_split('/\:/', $ptfields[3]); + $ptime = ""; + if($CONFIG["DATE_FORMAT"]) { + $month = array(); + $month['Jan'] = 0; + $month['Feb'] = 1; + $month['Mar'] = 2; + $month['Apr'] = 3; + $month['May'] = 4; + $month['Jun'] = 5; + $month['Jul'] = 6; + $month['Aug'] = 7; + $month['Sep'] = 8; + $month['Oct'] = 9; + $month['Nov'] = 10; + $month['Dec'] = 11; + $ptime = strftime($CONFIG["DATE_FORMAT"], + mktime($times[2], + $times[1], + $times[0], + $ptfields[2], + $month[$ptfields[1]], + $ptfields[4] - 1900)); + } else { + $mer = "a"; + if ($times[0] > 12) { $times[0] -= 12; $mer = "p"; } + if ($times[0] == 0) { $times[0] = "12"; } + $ptime = "{$ptfields[1]} {$ptfields[2]} {$times[0]}:{$times[1]}{$mer}"; + } + + /* + + + + + + + 50% + + Apr 1 05:59a + Mar 30 11:08a + + Last chance to register for Frankfurt, 4 April BEA... + + + + + + + + + {$rating} + + {$ptime} + {$row['From']} + + {$row['Subject']} + + + */ + + $DATA['QUARANTINE'] .= << + + + + + {$rating} + + {$ptime} + {$sender} + + {$rsubject} + + + +EOD; + + if ($rowclass == "qrowEven") { + $rowclass = "qrowOdd"; + } else { + $rowclass = "qrowEven"; + } + } // end foreach ($headings as $row) + + /* prepare quarantine navbar */ + if (($currentPage - 1) >= 1) { $previousPage = $currentPage - 1; } + else { $previousPage = 1; } + + if (($currentPage + 1) <= $pages) { $nextPage = $currentPage + 1; } + else { $nextPage = $pages; } + + $quarantineFooterBegin = << + + + + + + |<  + <  + +EOD; + + $quarantineFooterEnd = <<>  + >| + + + +EOD; + + $ranges_array = array(); + $rpages = $pages; + for ($i = 0; $i < $ranges; $i++) { + $range = array(); + $range['start'] = (($i + 1)* $CONFIG['QNAV_BUTTONS']) - ($CONFIG['QNAV_BUTTONS'] - 1); + + if (($i + 1) == $ranges) { + $range['end'] = ($range['start'] + $rpages) - 1; + } else { + $range['end'] = (($i + 1)* $CONFIG['QNAV_BUTTONS']); + $rpages -= $CONFIG['QNAV_BUTTONS']; + } + + $ranges_array[$i] = $range; + } + + /* generate nav buttons */ + foreach($ranges_array as $range){ + if ($currentPage >= $range['start'] && $currentPage <= $range['end']) { + for ($i = $range['start']; ; $i++) { + if ($i > $range['end']) { + break; + } else { + if ($i == $currentPage) { + $quarantineFooter .= "{$i} \n"; + } else { + $quarantineFooter .= "{$i} \n"; + } + } + } + } + } + + $DATA['QUARANTINE_FOOTER'] = $quarantineFooterBegin . $quarantineFooter .$quarantineFooterEnd; + $DATA['QPAGES'] = $pages; + $DATA['QPAGE'] = $currentPage; + } else { + $input_errors[] = "Unable to open DSPAM quarantine mailbox at »{$USER}.mbox«. " . + "If you are a DSPAM admin user you can savely " . + "ignore this error because such users usually do not " . + "have a DSPAM mailbox/quarantine."; + } + + return $input_errors; +} + +/* ========================================================================== */ +/* = P E R F O R M A N C E F U N C T I O N S = */ +/* ========================================================================== */ + +function ResetStats() { + global $USER; + + $fd = fopen("{$USER}.stats", "r"); + $ts = chop(fgets($fd, 4096)); + $group = chop(fgets($fd, 4096)); + fclose($fd); + list($ts, $ti, $tm, $fp, $sc, $ic) = split(",", $ts); + + if ($group <> "") { + $GROUP = GetPath($group) . ".stats"; + $fd = fopen("{$GROUP}", "r"); + $gts = chop(fgets($fd, 4096)); + fclose($fd); + list ($gts, $gti, $gtm, $gfp, $gsc, $gic) = split(",", $gts); + $ts -= $gts; + $ti -= $gti; + $tm -= $gtm; + $fp -= $gfp; + $sc -= $gsc; + $ic -= $gic; + } + + $fd = fopen("{$USER}.rstats", "w"); + fputs($fd, "{$ts}" . "," . "{$ti}" . "," . "{$tm}" . "," . + "{$fp}" . "," . "{$sc}" . "," . "{$ic}\n"); + fclose($fd); +} + +function Tweak() { + global $USER; + + $fd = fopen("{$USER}.rstats", "r"); + $ts = chop(fgets($fd, 4096)); + $group = chop($fgets($fd, 4096)); + fclose($fd); + list($ts, $ti, $tm, $fp, $sc, $ic) = split(",", $ts); + $tm++; + + $fd = fopen("{$USER}.rstats", "w"); + fputs($fd, "{$ts},{$ti},{$tm},{$fp},{$sc},{$ic}\n"); + fclose($fd); +} + +function &DisplayIndex() { + global $USER, $CONFIG, $DATA, $CURRENT_STORE, $CURRENT_USER; + + if (strpos ($CURRENT_USER, "@") === false) { + if (GetDomain($CURRENT_STORE) <> "") + $domain = GetDomain($CURRENT_STORE); + else + $domain = $config['system']['domain']; + + $spamalias = "spam-{$CURRENT_USER}@{$domain}"; + } else { + $spamalias = "spam-{$CURRENT_USER}"; + } + + if ($handle = @fopen ("{$USER}.stats", "r")) { + $spam .= chop(fgets($handle, 4096)); + $group .= chop(fgets($handle, 4096)); + fclose($handle); + list($spam, $innocent, $misses, $fp, $sc, $ic) = split(",", $spam); + + if ($group <> "") { + $GROUP = GetPath($group) . ".stats"; + $fd = fopen("{$GROUP}", "r"); + $gspam = chop(fgets($fd, 4096)); + fclose($fd); + + list($gspam, $ginnocent, $gfp, $gmisses, $gsc, $gic) = preg_split('/\,/', $gspam); + $spam -= $gspam; + $innocent -= $ginnocent; + $misses -= $gmisses; + $fp -= $gfp; + $sc -= $gsc; + $ic -= $gic; + } + + if ($spam + $innocent > 0) { + $ratio = sprintf("%2.3f", + (($spam+$misses)/($spam+$misses+$fp+$innocent)*100)); + } else { + $ratio = 0; + } + + if (file_exists("{$USER}.rstats")) { + $handle = fopen ("{$USER}.rstats", "r"); + $buffer = chop(fgets($handle, 4096)); + + fclose ($handle); + + list($rts, $rti, $rtm, $rfp) = split(",", $buffer); + + $real_missed = $misses - $rtm; + $real_caught = $spam - $rts; + $real_fp = $fp - $rfp; + + if ($real_fp < 0) { $real_fp = 0; } + + $real_innocent = $innocent - $rti; + + if (($spam - $rts > 0) && ($spam - $rts + $misses - $rtm != 0) && + ($real_caught + $real_missed > 0) && ($real_fp + $real_innocent > 0)) { + $monthly = sprintf("%2.3f", + (100.0-(($real_missed)/($real_caught+$real_missed))*100.0)); + $overall = sprintf("%2.3f", + (100-((($real_missed+$real_fp) / + ($real_fp+$real_innocent+$real_caught+$real_missed))*100))); + } else { + if ($real_caught == 0 && $real_missed > 0) { + $monthly = 0; + $overall = 0; + } else { + $monthly = 100; + $overall = 100; + } + } + + if ($real_fp + $real_innocent > 0) { + $fpratio = sprintf("%2.3f", ($real_fp/($real_fp+$real_innocent)*100)); + } else { + $fpratio = 0; + } + + } else { + $rts = $spam + $misses; + $rti = $innocent; + $rtm = $misses; + $rfp = $fp; + + $handle = fopen ("{$USER}.rstats", "w"); + fwrite("{$rts},{$rti},{$rtm},{$rfp}\n"); + fclose($handle); + + $monthly = "N/A"; + $fpratio = "N/A"; + $overall = "N/A"; + } + + $DATA['TIME'] = $time; + $DATA['TOTAL_SPAM_SCANNED'] = $spam; + $DATA['TOTAL_SPAM_LEARNED'] = $misses; + $DATA['TOTAL_NONSPAM_SCANNED'] = $innocent; + $DATA['TOTAL_NONSPAM_LEARNED'] = $fp; + $DATA['SPAM_RATIO'] = $ratio; + $DATA['SPAM_ACCURACY'] = $monthly; + $DATA['NONSPAM_ERROR_RATE'] = $fpratio; + $DATA['OVERALL_ACCURACY'] = $overall; + $DATA['TOTAL_SPAM_CORPUSFED'] = $sc; + $DATA['TOTAL_NONSPAM_CORPUSFED'] = $ic; + $DATA['TOTAL_SPAM_MISSED'] = $real_missed; + $DATA['TOTAL_SPAM_CAUGHT'] = $real_caught; + $DATA['TOTAL_NONSPAM_MISSED'] = $real_fp; + $DATA['TOTAL_NONSPAM_CAUGHT'] = $real_innocent; + $DATA['SPAM_ALIAS'] = $spamalias; + + $DATA['LOCAL_DOMAIN'] = $CONFIG['LOCAL_DOMAIN']; + } else { + $DATA['SPAM_ACCURACY'] = "N/A"; + $DATA['NONSPAM_ERROR_RATE'] = "N/A"; + $DATA['OVERALL_ACCURACY'] = "N/A"; + $DATA['SPAM_RATIO'] = "N/A"; + $DATA['TOTAL_SPAM_MISSED'] = 0; + $DATA['TOTAL_SPAM_CAUGHT'] = 0; + $DATA['SPAM_RATIO'] = "N/A"; + $DATA['TOTAL_NONSPAM_MISSED'] = 0; + $DATA['TOTAL_NONSPAM_CAUGHT'] = 0; + $DATA['NONSPAM_ERROR_RATE'] = "N/A"; + $DATA['TOTAL_SPAM_LEARNED'] = 0; + $DATA['TOTAL_SPAM_SCANNED'] = 0; + $DATA['TOTAL_NONSPAM_LEARNED'] = 0; + $DATA['TOTAL_NONSPAM_SCANNED'] = 0; + $DATA['TOTAL_SPAM_CORPUSFED'] = 0; + $DATA['TOTAL_NONSPAM_CORPUSFED'] = 0; + $DATA['SPAM_ALIAS'] = $spamalias; + + $input_errors[] = "Unable to open DSPAM stats at »{$USER}.stats«. " . + "If you are a DSPAM admin user you can savely " . + "ignore this error because such users usually do not " . + "have a DSPAM mailbox/quarantine."; + } + + return $input_errors; +} + +function getJScriptFunction($whichOne = 0) { + $changeuser_msg = gettext("Do you realy want to change the current user?") . "\\n" . + gettext("This requires a logout followed by a login."); + + switch ($whichOne) { + case 0: + $scriptstr = ' + + /* applicable for almost any dspam related page */ + function changeuser() { + check = confirm("' . $changeuser_msg . '"); + + if (check == true) + window.location.href = "/index.php?logout=true"; + } + '; + + break; + case 1: + $scriptstr = ' + + /* applicable for dspam-quarantine.php */ + function checkallmsgs(enable) { + var endis = (document.iform.checkall.checked || enable); + var elem = document.iform.elements.length; + + for (i = 0; i < elem; i++) { + if (document.iform.elements[i].name.indexOf("chkmsg") >= 0) { + document.iform.elements[i].checked = endis; + } + } + } + '; + + break; + case 2: + $scriptstr = ' + + /* applicable for dspam-quarantine.php */ + function sortmsg(criterion) { + var baseURL = "/dspam-quarantine.php?page=" + document.iform.qpage.value; + var qperpage = document.getElementsByName("qperpage")[0].value; + + window.location.href = baseURL + "&qperpage=" + qperpage + "&sortby=" + criterion; + } + '; + + break; + case 3: + $scriptstr = ' + + /* applicable for dspam-quarantine.php */ + function processmsg(what) { + var elem = document.iform.elements.length; + var checked = false; + + switch (what) { + case 0: + for (i = 0; i < elem; i++) { + if (document.iform.elements[i].name.indexOf("chkmsg") >= 0 && + document.iform.elements[i].checked == true) { + checked = true; + break; + } + } + + if (checked) { + document.iform.processAction.value = "manyNotSpam"; + } else { + alert("You did not select any message that should be processed as not beeing Spam."); + return false; + } + break; + case 1: + for (i = 0; i < elem; i++) { + if (document.iform.elements[i].name.indexOf("chkmsg") >= 0 && + document.iform.elements[i].checked == true) { + checked = true; + break; + } + } + + if (checked) { + if (confirm("Are you sure you want to delete SELECTED messages in quarantine?") == false) { + return false; + } else { + document.iform.processAction.value = "manySpam"; + } + } else { + alert("You did not select any message that should be processed as beeing Spam."); + return false; + } + break; + case 2: + if (confirm("Are you sure you want to delete ALL messages in quarantine?") == false) { + return false; + } else { + document.iform.processAction.value = "deleteAll"; + } + break; + } + + document.iform.submit(); + } + '; + + break; + case 4: + $scriptstr = ' + + /* applicable for dspam-quarantine.php nad dspam-history.php */ + function changeQPerPage(originator) { + var elementName = ""; + var baseURL = ""; + + if (originator.name == "qperpage") { + baseURL = "/dspam-quarantine.php?page=" + document.iform.qpage.value; + elementName = "qperpage"; + } else { + baseURL = "/dspam-history.php?page=" + document.iform.hpage.value; + elementName = "hperpage"; + } + + for (var i = 0; i < 2; i++) { + document.getElementsByName(elementName)[i].value = originator.value; + } + + if (originator.name == "qperpage") + window.location.href = baseURL + "&qperpage=" + originator.value; + else + window.location.href = baseURL + "&hperpage=" + originator.value; + } + '; + + break; + case 5: + $scriptstr = ' + + /* applicable for dspam-settings.php */ + + function fadeTableRow(rowid, fadeType, opts){ + if(!opts){ + opts = {}; + } + + var row = $(rowid); + var cells= row.childNodes; + for(i=0;i diff --git a/config/archive/dspam/pkg/dspam-pkgfunc.inc b/config/archive/dspam/pkg/dspam-pkgfunc.inc new file mode 100644 index 00000000..31a7fa06 --- /dev/null +++ b/config/archive/dspam/pkg/dspam-pkgfunc.inc @@ -0,0 +1,548 @@ + "dspam.sh", + "start" => $start, + "stop" => $stop + ) + ); + conf_mount_ro(); + config_unlock(); + + if (! file_exists("/usr/local/etc/dspam.conf")) { + mwexec("ln -s /etc/dspam.conf /usr/local/etc/dspam.conf"); + } + + mwexec("/usr/local/etc/rc.d/dspam.sh stop"); + mwexec("/usr/local/etc/rc.d/dspam.sh start"); + + return 0; +} + +function dspam_configure() { + global $config, $g; + + $dspamcfg = $config['installedpackages']['dspam']['config'][0]; + + if ($g['booting']) + echo "Starting DSPAM service... "; + else + sleep(1); + + /* write dhcpd.conf */ + $fd = fopen("/usr/local/etc/dspam.conf", "w"); + if (!$fd) { + printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n"); + return 1; + } + + $dspamconf = << 0) { + $dspamconf .= "Algorithm\t\t"; + + foreach ($t_algos as $algo) { + $dspamconf .= "{$algo['name']} "; + } + + $dspamconf .= "\n"; + } + + $dspamconf .= "PValue\t\t\t{$dspamcfg['pvalue']}\n"; + isset($dspamcfg['improbability-drive']) ? $dspamconf .= "ImprobabilityDrive\ton\n" : $dspamconf .= "ImprobabilityDrive\toff\n"; + + $t_prefs = &$dspamcfg['preference']; + + foreach ($t_prefs as $pref) { + $dspamconf .= "Preference\t\t{$pref['value']}\n"; + } + + $t_overr = &$dspamcfg['override']; + + foreach ($t_overr as $over) { + $dspamconf .= "AllowOverride\t\t{$over['value']}\n"; + } + + if (isset($dspamcfg['ldap-enable'])) { + $dspamconf .= << "") { + $dspamconf .= << "") { + $dspamconf .= "ClientPort\t\t{$dspamcfg['dspam-client-port']}\n"; + } + } + + $dspamconf .= "## EOF\n"; + + fwrite($fd, $dspamconf); + fclose($fd); + + /* fire up dspam --daemon */ + mwexec("/usr/local/etc/rc.d/dspam.sh stop"); + mwexec("/usr/local/etc/rc.d/dspam.sh start"); + + if ($g['booting']) { + print "done.\n"; + } + + return 0; +} + +function custom_php_install_command() { + global $config, $g; + /* create a default config */ + sync_package_dspam(); +} + +function custom_php_deinstall_command() { + global $config, $g; + conf_mount_rw(); + unlink_if_exists("/usr/local/etc/rc.d/dspam.sh"); + unlink_if_exists("/usr/local/etc/dspam.conf"); + unlink_if_exists("/usr/local/bin/dspam_spamfeed"); + unlink_if_exists("/usr/local/bin/dspam_innocentfeed"); + conf_mount_ro(); +} + +function checkForLDAPSupport() { + $pd = popen("ldd /usr/local/bin/dspam", "r"); + while (!feof($pd)) { + $dspamstr .= fgets($pd, 4096); + } + pclose($pd); + + if (strpos($dspamstr, "libldap") !== false && + file_exists("/usr/local/lib/libldap.so") && + file_exists("/usr/local/lib/liblber.so")) { + return true; + } + + return false; +} + +function checkForPgSQLSupport() { + if (file_exists("/usr/local/lib/libpgsql_drv.so") && + file_exists("/usr/local/lib/libpq.so")) { + return true; + } + + return false; +} + +function checkForMySQLSupport() { + if (file_exists("/usr/local/lib/libmysql_drv.so") && + file_exists("/usr/local/lib/mysql/libmysqlclient.so")) { + return true; + } + + return false; +} + +function checkForSQLiteSupport() { + if (file_exists("/usr/local/lib/libsqlite3_drv.so") && + file_exists("/usr/local/lib/mysql/libsqlite3.so")) { + return true; + } + + return false; +} + +function checkForClamAVSupport() { + if (file_exists("/usr/local/bin/clamdscan") && + file_exists("/usr/local/bin/clamscan") && + file_exists("/usr/local/sbin/clamd")) { + return true; + } + + return false; +} + +?> diff --git a/config/archive/dspam/pkg/dspam-utilfunc.inc b/config/archive/dspam/pkg/dspam-utilfunc.inc new file mode 100644 index 00000000..903790b8 --- /dev/null +++ b/config/archive/dspam/pkg/dspam-utilfunc.inc @@ -0,0 +1,458 @@ + $value ) { + if( is_array( $value ) ){ + $new_convention = sprintf( $convention, $key ) . '[%s]'; + $query .= http_parse_query( $value, $new_convention ); + } else { + $key = urlencode( $key ); + $value = urlencode( $value ); + $query .= sprintf( $convention, $key ) . "=$value&"; + } + } + } + + return $query; + } +} + +/* just a wrapper function */ +function SafeVars($PAIRS) { + $url = http_parse_query($PAIRS); + return $url; +} + +function To12Hour($h) { + if ($h < 0) { $h += 24; } + if ($h > 11) { if ($h > 12) { $h -= 12; } $h .= "p"; } + else { if ($h == 0) { $h = "12"; } $h .= "a"; } + return $h; +} + +function GetPath($store) { + global $CONFIG, $USER; + $PATH = ""; + + /* Domain-scalen */ + if ($CONFIG['DOMAIN_SCALE'] == 1) { + $splittmp = (split('@', $store)); + $VPOPUSERNAME = $splittmp[0]; + $VPOPDOMAIN = $splittmp[1]; + if ($VPOPDOMAIN == "") {$VPOPDOMAIN = "local";} + + $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$VPOPDOMAIN}/{$VPOPUSERNAME}/" . + "{$VPOPUSERNAME}"; + return $PATH; + + /* Normal scale */ + } else if ($CONFIG['LARGE_SCALE'] == 0) { + $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}/{$USER}"; + return $PATH; + + /* Large-scale */ + } else { + if (strlen($USER) > 1) { + $PATH = "{$CONFIG['DSPAM_HOME']}/data/" . substr($USER, 0, 1) . + "/". substr($USER, 1, 1) . "/{$USER}/{$USER}"; + } else { + $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}/{$USER}"; + } + return $PATH; + } +} + +function GetUserDir($store) { + global $CONFIG, $USER; + $PATH = ""; + + /* Domain-scalen */ + if ($CONFIG['DOMAIN_SCALE'] == 1) { + $splittmp = (split('@', $store)); + $VPOPUSERNAME = $splittmp[0]; + $VPOPDOMAIN = $splittmp[1]; + if ($VPOPDOMAIN == "") {$VPOPDOMAIN = "local";} + + $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$VPOPDOMAIN}/{$VPOPUSERNAME}"; + return $PATH; + + /* Normal scale */ + } else if ($CONFIG['LARGE_SCALE'] == 0) { + $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}/"; + return $PATH; + + /* Large-scale */ + } else { + if (strlen($USER) > 1) { + $PATH = "{$CONFIG['DSPAM_HOME']}/data/" . substr($USER, 0, 1) . + "/". substr($USER, 1, 1) . "/{$USER}/{$USER}"; + } else { + $PATH = "{$CONFIG['DSPAM_HOME']}/data/{$USER}"; + } + return $PATH; + } +} + +function GetDomain($store) { + global $CONFIG, $USER; + $PATH = ""; + + /* Domain-scalen */ + if ($CONFIG['DOMAIN_SCALE'] == 1) { + $splittmp = (split('@', $store)); + $VPOPUSERNAME = $splittmp[0]; + $VPOPDOMAIN = $splittmp[1]; + if ($VPOPDOMAIN == "") {$VPOPDOMAIN = "local";} + + return $VPOPDOMAIN; + } +} + +function isDSPAMAdmin($username = "") { + global $config, $CONFIG; + + $groupindex = index_groups(); + $userindex = index_users(); + + if ($username == "") { return 0; } + + $gname = $config['system']['group'][$groupindex[$config['system']['user'][$userindex[$username]]['groupname']]]['name']; + + if (isset($gname)) { + return ($gname === $CONFIG['DSPAM_ADMIN_GROUP']); + } + + return 0; +} + +function createUserNotificationMessages() { + global $config, $CONFIG, $USER, $CURRENT_USER, $CURRENT_STORE; + + $firstrun = "{$USER}.firstrun"; + $firstspam = "{$USER}.firstspam"; + $quarantinefull = "{$USER}.quarantinefull"; + $savemsg = ""; + + if (isset($config['installedpackages']['dspam']['config'][0]['dspam-domain'])) + $domain = $config['installedpackages']['dspam']['config'][0]['dspam-domain']; + else + $domain = $config['system']['domain']; + + if (GetDomain($CURRENT_STORE) <> "") + $user_domain = GetDomain($CURRENT_STORE); + else + $user_domain = $config['system']['domain']; + + $userdir = GetUserDir($CURRENT_STORE); + $hostname = $config['system']['hostname']; + $support_user = $config['installedpackages']['dspam']['config'][0]['dspam-contact']; + + /* return if there are no sample files */ + if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample") || + ! file_exists("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample") || + ! file_exists("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample") || + ! file_exists($userdir)) { + return; + } + + /* create firstrun.txt */ + if (! file_exists("{$firstrun}")) { + $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample"); + + $sample_msg = str_replace("support", $support_user, $sample_msg); + $sample_msg = str_replace("configureme.com", $user_domain, $sample_msg); + $sample_msg = str_replace("http://www.yourdomain.com/dspam/", + "http://{$hostname}.{$domain}/dspam.php", + $sample_msg); + + @file_put_contents("{$firstrun}", $sample_msg); + $savemsg .= " »{$firstrun}«, "; + } + + /* create firstspam.txt */ + if (! file_exists("{$firstspam}")) { + $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample"); + + $sample_msg = str_replace("support", $support_user, $sample_msg); + $sample_msg = str_replace("configureme.com", $user_domain, $sample_msg); + $sample_msg = str_replace("http://www.yourdomain.com/dspam/", + "http://{$hostname}.{$domain}/dspam.php", + $sample_msg); + + @file_put_contents("{$firstspam}", $sample_msg); + $savemsg .= " »{$firstspam}«, "; + } + + /* create quarantinefull.txt */ + if (! file_exists("{$quarantinefull}")) { + $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample"); + + $sample_msg = str_replace("support", $support_user, $sample_msg); + $sample_msg = str_replace("configureme.com", $user_domain, $sample_msg); + $sample_msg = str_replace("http://www.yourdomain.com/dspam/", + "http://{$hostname}.{$domain}/dspam.php", + $sample_msg); + + @file_put_contents("{$quarantinefull}", $sample_msg); + $savemsg .= " »{$quarantinefull}«."; + } + + if ($savemsg <> "") { + $savemsg = gettext("The following files were created: ") . $savemsg; + return $savemsg; + } + + return; +} + +function createNotificationMessages() { + global $config, $CONFIG, $USER, $CURRENT_USER; + + $firstrun = "{$CONFIG['DSPAM_HOME']}/firstrun.txt"; + $firstspam = "{$CONFIG['DSPAM_HOME']}/firstspam.txt"; + $quarantinefull = "{$CONFIG['DSPAM_HOME']}/quarantinefull.txt"; + $savemsg = ""; + + if (isset($config['installedpackages']['dspam']['config'][0]['dspam-domain'])) + $domain = $config['installedpackages']['dspam']['config'][0]['dspam-domain']; + else + $domain = $config['system']['domain']; + + $hostname = $config['system']['hostname']; + $support_user = $config['installedpackages']['dspam']['config'][0]['dspam-contact']; + + /* return if there are no sample files */ + if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample") || + ! file_exists("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample") || + ! file_exists("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample")) { + return; + } + + /* create firstrun.txt */ + if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstrun.txt")) { + $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstrun.txt.sample"); + + $sample_msg = str_replace("support", $support_user, $sample_msg); + $sample_msg = str_replace("configureme.com", $domain, $sample_msg); + $sample_msg = str_replace("http://www.yourdomain.com/dspam/", + "http://{$hostname}.{$domain}/dspam.php", + $sample_msg); + + @file_put_contents("{$firstrun}", $sample_msg); + $savemsg .= " »{$firstrun}«, "; + } + + /* create firstspam.txt */ + if (! file_exists("{$CONFIG['DSPAM_HOME']}/firstspam.txt")) { + $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/firstspam.txt.sample"); + + $sample_msg = str_replace("support", $support_user, $sample_msg); + $sample_msg = str_replace("configureme.com", $domain, $sample_msg); + $sample_msg = str_replace("http://www.yourdomain.com/dspam/", + "http://{$hostname}.{$domain}/dspam.php", + $sample_msg); + + @file_put_contents("{$firstspam}", $sample_msg); + $savemsg .= " »{$firstspam}«, "; + } + + /* create quarantinefull.txt */ + if (! file_exists("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt")) { + $sample_msg = file_get_contents("{$CONFIG['DSPAM_HOME']}/quarantinefull.txt.sample"); + + $sample_msg = str_replace("support", $support_user, $sample_msg); + $sample_msg = str_replace("configureme.com", $domain, $sample_msg); + $sample_msg = str_replace("http://www.yourdomain.com/dspam/", + "http://{$hostname}.{$domain}/dspam.php", + $sample_msg); + + @file_put_contents("{$quarantinefull}", $sample_msg); + $savemsg .= " »{$quarantinefull}«."; + } + + if ($savemsg <> "") { + $savemsg = gettext("The following files were created: ") . $savemsg; + return $savemsg; + } + + return; +} + +function &check_dspam_installation() { + global $config; + + /* create RC files if necessary */ + if (! file_exists("/usr/local/etc/rc.d")) { + @mkdir("/usr/local/etc/rc.d"); + } + if (! file_exists("/usr/local/etc/rc.d/000.mysql.sh")) { + @copy("/usr/local/pkg/000.mysql.sh", "/usr/local/etc/rc.d/000.mysql.sh"); + @chmod("/usr/local/etc/rc.d/000.mysql.sh", 0755); + } + if (! file_exists("/usr/local/etc/rc.d/010.clamav-clamd.sh")) { + @copy("/usr/local/pkg/010.clamav-clamd.sh", + "/usr/local/etc/rc.d/010.clamav-clamd.sh"); + @chmod("/usr/local/etc/rc.d/010.clamav-clamd.sh", 0755); + } + if (! file_exists("/usr/local/etc/rc.d/020.clamav-freshclam.sh")) { + @copy("/usr/local/pkg/020.clamav-freshclam.sh", + "/usr/local/etc/rc.d/020.clamav-freshclam.sh"); + @chmod("/usr/local/etc/rc.d/020.clamav-freshclam.sh", 0755); + } + if (! file_exists("/usr/local/etc/rc.d/030.p3scan.sh")) { + @copy("/usr/local/pkg/030.p3scan.sh", + "/usr/local/etc/rc.d/030.p3scan.sh"); + @chmod("/usr/local/etc/rc.d/030.p3scan.sh", 0755); + } + + /* create conf files for those packages DSPAM depends on */ + if (! file_exists("/usr/local/etc/clamd.conf")) { + @copy("/usr/local/pkg/clamd.conf", + "/usr/local/etc/clamd.conf"); + } + if (! file_exists("/usr/local/etc/freshclam.conf")) { + @copy("/usr/local/pkg/freshclam.conf", + "/usr/local/etc/freshclam.conf"); + } + + if (! is_service_running("dspam")) { + $input_errors[] = "The DSPAM daemon process is not running. " . + "If you are certain that you did configure DSPAM " . + "appropriatly, you can start the corresponding process " . + "using the service control panel which is part of the " . + "»Status« menu item."; + } + if (! is_service_running("p3scan")) { + $input_errors[] = "The POP3 proxy process is not running. " . + "If you are certain that you did configure the POP3 proxy " . + "appropriatly, you can start the corresponding process " . + "using the service control panel which is part of the " . + "»Status« menu item."; + } + if (! is_service_running("clamd")) { + $input_errors[] = "The ClamAV daemon process is not running. " . + "If you are certain that you did configure DSPAM " . + "appropriatly, you can start the corresponding process " . + "using the service control panel which is part of the " . + "»Status« menu item (ClamAV does not need any configuration)."; + } + if (! is_service_running("freshclam")) { + $input_errors[] = "The freshclam daemon process is not running. " . + "If you are certain that you did configure DSPAM " . + "appropriatly, you can start the corresponding process " . + "using the service control panel which is part of the " . + "»Status« menu item (freshclam does not need any configuration)."; + } + if (! is_service_running("mysql")) { + $input_errors[] = "The MySQL daemon process is not running. " . + "If you are certain that you did configure DSPAM " . + "appropriatly, you can start the corresponding process " . + "using the service control panel which is part of the " . + "»Status« menu item (MySQL does not need any configuration)."; + } + + if (empty($config['installedpackages']['dspam']['config']) || + empty($config['installedpackages']['dspam']['config'][0]['storage-driver']) || + (file_exists('/usr/local/etc/dspam.conf') == false)) { + /* create default config files etc. */ + sync_package_dspam(); + + $input_errors[] = "It seems that you are using DSPAM for the very first time. " . + "Please run the DSPAM wizard from the »Services« menu " . + "if you would like to configure DSPAM right now. " . + "If you are not eligible to administer DSPAM you may contact " . + "your local DSPAM admin personal to solve this issue."; + } + + return $input_errors; +} + +?> diff --git a/config/archive/dspam/pkg/dspam.inc b/config/archive/dspam/pkg/dspam.inc new file mode 100644 index 00000000..9a821e6a --- /dev/null +++ b/config/archive/dspam/pkg/dspam.inc @@ -0,0 +1,360 @@ + + + Unauthorized Access + + + +

Unauthorized Access - You will be redirected shortly!

+ + +EOD; + print $htmlstr; + exit; + } +} + +/* + * only DSPAM admins can change the current user without logging out + * and logging in as another user again. + */ +if ($_POST) { + if (! empty($_POST['username']) && $CONFIG['ADMIN'] == 1) { + $CURRENT_USER = $_POST['username']; + } +} +if ($_GET) { + if (! empty($_GET['user']) && $CONFIG['ADMIN'] == 1) { + $CURRENT_USER = $_GET['user']; + } +} + +if ($CURRENT_USER == "") { + $input_errors[] = "System Error. I was unable to determine your identity."; +} + +preg_replace('/%CURRENT_USER%/', $CURRENT_USER, $CONFIG['DSPAM_ARGS']); + +/* current store */ +$PREF =& GetPrefs($CURRENT_USER); +$CURRENT_STORE = $PREF['localStore']; +if ($CURRENT_STORE == "") {$CURRENT_STORE = $CURRENT_USER; } + +$USER = GetPath($CURRENT_STORE); +$MAILBOX = $USER . ".mbox"; +$TMPFILE = $USER . ".tmp"; + +/* + * Set up initial display variables + */ +CheckQuarantine(); +$DATA['REMOTE_USER'] = $CURRENT_USER; + +/* + * Check whether DSPAM is already configured. + */ +$install_errors =& check_dspam_installation(); +$input_errors = array_merge($input_errors, $install_errors); + +/* + * Check whether we should generate notification messages + */ +if (isset($config['installedpackages']['dspam']['config'][0]['notification-email'])) { + $tmpmsg = createNotificationMessages(); + if (! empty($tmpmsg)) + $tmpmsg .= "\n" . createUserNotificationMessages(); + else + $tmpmsg = createUserNotificationMessages(); + + $savemsg =& $tmpmsg; +} + +/* + * Process Commands + */ +if (isset($pgtitle) && is_array($pgtitle)) { + /* Performance */ + if (basename($_SERVER['SCRIPT_NAME']) == "dspam-perf.php") { + if ($_GET) { + if ($GET['command'] == "resetStats") { + ResetStats(); + } else if ($GET['command'] == "tweak") { + Tweak(); + } + } + + $display_errors =& DisplayIndex(); + $input_errors = array_merge($input_errors, $display_errors); + } + + /* Preferences */ + else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-prefs.php") { + $savemsg = ""; + $prefs_errors =& DisplayPreferences(NULL, $savemsg); + $input_errors = array_merge($input_errors, $prefs_errors); + } + + /* Quarantine */ + else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-quarantine.php") { + if ($_GET) { + if ($_GET['command'] == "viewMessage") { + $showpart = 0; + $ctype = 0; + $sortby = "Rating"; + $currentPage = 1; + $qPerPage = 0; + + if (isset($_GET['showpart'])) { $showpart = $_GET['showpart']; } + if (isset($_GET['ctype'])) { $ctype = intval($_GET['ctype']); } + if (isset($_GET['sortby'])) { $sortby = $_GET['sortby']; } + if (isset($_GET['page'])) { $currentPage = $_GET['page']; } + if (isset($_GET['qperpage'])) { $qPerPage = $_GET['qperpage']; } + + $quarantine_errors =& QuarantineViewMessage($_GET['signatureID'], + $showpart, + $ctype, + $sortby, + $currentPage, + $qPerPage); + $input_errors = array_merge($input_errors, $quarantine_errors); + } else if (isset($_GET['sortby'])) { + $qperpage = $CONFIG['QUARANTINE_PER_PAGE']; + if (isset($_GET['qperpage'])) { $qperpage = $_GET['qperpage']; } + $page = 1; + if (isset($_GET['page'])) { $page = $_GET['page']; } + + $quarantine_errors =& DisplayQuarantine($_GET['sortby'], + intval($page), + intval($qperpage)); + $input_errors = array_merge($input_errors, $quarantine_errors); + } else if (isset($_GET['qperpage'])) { + if (isset($_GET['page'])) { + $quarantine_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'], + intval($_GET['page']), + intval($_GET['qperpage'])); + $input_errors = array_merge($input_errors, $quarantine_errors); + } else { + $quarantine_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'], + 1, + intval($_GET['qperpage'])); + $input_errors = array_merge($input_errors, $quarantine_errors); + } + } else { + $displayq_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'], 1); + $input_errors = array_merge($input_errors, $displayq_errors); + } + } else if ($_POST) { + if ($_POST['command'] == "processQuarantine") { + $signatures = array(); + + while (list($key, $val) = each($_POST)) { + if (strpos($key, "chkmsg") !== false) { + $signatures[$key] = $val; + } + } + if ($_POST['processAction']) { + $processq_errors =& ProcessQuarantine($signatures, + $_POST['processAction'], + $_POST['sortby'], + intval($_POST['qpage']), + intval($_POST['qperpage'])); + $input_errors = array_merge($input_errors, $processq_errors); + } else { + $processq_errors =& ProcessQuarantine($signatures, + "None", + $_POST['sortby'], + intval($_POST['qpage']), + intval($_POST['qperpage'])); + $input_errors = array_merge($input_errors, $processq_errors); + } + } else if ($_POST['command'] == "processFalsePositive") { + $processfp_errors =& ProcessFalsePositive($_POST['signatureID'], + $_POST['sortby'], + intval($_POST['qpage']), + intval($_POST['qperpage'])); + $input_errors = array_merge($input_errors, $processfp_errors); + $displayq_errors =& DisplayQuarantine($_POST['sortby'], + intval($_POST['qpage']), + intval($_POST['qperpage'])); + $input_errors = array_merge($input_errors, $displayq_errors); + } + } else { + /* usually this particular line of code should not be hit because + * the user always triggers a GET or POST action. Unfortunatly at + * the time, the alerts page is implemented in a way that neither + * triggers a GET nor a POST action if initially accessed via the + * tab. Hence this final catch all else. + */ + $displayq_errors =& DisplayQuarantine($CONFIG['SORT_DEFAULT'], 1); + $input_errors = array_merge($input_errors, $displayq_errors); + } + } + + /* Analysis */ + else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-analysis.php") { + $displaya_errors =& DisplayAnalysis(); + $input_errors = array_merge($input_errors, $displaya_errors); + } + + /* History */ + else if (in_array(gettext("History"), $pgtitle)) { + if ($_POST) { + /* Form fields that may be submited via POST: + * - command + * - username + * - msgid$retrain_checked_msg_no (checkbox, multible times) + */ + $checked = array(); + + while (list($key, $val) = each($_POST)) { + if (strpos($key, "msgid") !== false) { + $checked[] = $val; + } + } + + $displayh_errors =& DisplayHistory($_POST['command'], + "", + $checked, + $_POST['username'], + "", + $_POST['hpage'], + $_POST['hperpage']); + $input_errors = array_merge($input_errors, $displayh_errors); + } else if ($_GET) { + /* Form fields that may be submited via GET: + * - history_page + * - command + * - signatureID + * - retrain + * - user + */ + $displayh_errors =& DisplayHistory($_GET['command'], + $_GET['signatureID'], + NULL, + $_GET['user'], + $_GET['retrain'], + isset($_GET['page']) ? intval($_GET['page']) : 1, + isset($_GET['hperpage']) ? $_GET['hperpage'] : $CONFIG['QUARANTINE_PER_PAGE']); + $input_errors = array_merge($input_errors, $displayh_errors); + } else { + $displayh_errors =& DisplayHistory("", // command + "", // signature ID + NULL, // signatures to be retrained + $CURRENT_USER); + $input_errors = array_merge($input_errors, $displayh_errors); + } + } else if (in_array(gettext("Fragment"), $pgtitle)) { + if ($_GET) { + $displayf_errors =& DisplayFragment($_GET['signatureID'], + $_GET['from'], + $_GET['subject'], + $_GET['info'], + $_GET['time']); + $input_errors = array_merge($input_errors, $displayf_errors); + } + } + + /* Info Page */ + else if (basename($_SERVER['SCRIPT_NAME']) == "dspam.php") { + $info_errors =& DisplayInfos(); + $input_errors = array_merge($input_errors, $info_errors); + } + +/* ========================================================================== */ +/* = A D M I N R E L A T E D F U N C T I O N C A L L S = */ +/* ========================================================================== */ + + /* Status */ + else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-admin.php" && $CONFIG['ADMIN']) { + $displays_errors =& DisplayStatus(); + $input_errors = array_merge($input_errors, $displays_errors); + } + + /* User Statistics */ + else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-admin-stats.php" && $CONFIG['ADMIN']) { + $displayus_errors =& DisplayUserStatistics(); + $input_errors = array_merge($input_errors, $displayus_errors); + } + + /* Preferences */ + else if (basename($_SERVER['SCRIPT_NAME']) == "dspam-admin-prefs.php" && $CONFIG['ADMIN']) { + $savemsg = ""; + $displayap_errors =& DisplayAdminPreferences($savemsg); + $input_errors = array_merge($input_errors, $displayap_errors); + } +} else { + $input_errors[] = "The page you did request can't be processed by dspam.inc."; +} + +?> \ No newline at end of file diff --git a/config/archive/dspam/pkg/dspam.xml b/config/archive/dspam/pkg/dspam.xml new file mode 100644 index 00000000..59740ae1 --- /dev/null +++ b/config/archive/dspam/pkg/dspam.xml @@ -0,0 +1,342 @@ + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + dspam + 1.0 + Services: DSPAM: Main + /usr/local/pkg/dspam.inc + + + dspam +
Services
+ dspam.xml + /dspam-perf.php +
+ + DSPAM Legacy WebGUI + Original Perl-based GUI +
Services
+ /vhosts/dspam/dspam.cgi +
+ + dspam + /usr/local/etc/rc.d/dspam.sh + + + + Overview + /dspam.php + + + + Performance + /dspam-perf.php + + + Preferences + /dspam-prefs.php + + + Alerts + /pkg.php?xml=dspam_alerts.xml + + + Quarantine + /dspam-quarantine.php + + + Analysis + /dspam-analysis.php + + + History + /dspam-history.php + + + + ['installedpackages']['dspam']['config'] + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-perf.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-admin.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-admin-graph.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-admin-prefs.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-admin-stats.php + + + /usr/local/pkg/ + 0755 + http://www.abyssworld.de/packages/config/dspam_settings.xml + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-settings.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-settings-algo.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-settings-bmta.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-settings-feat.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-header.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-overr.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-settings-prefs.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-spwd.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-tuser.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-train.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/dspam-viewmsg.php + + + /usr/local/www/ + 0755 + http://www.abyssworld.de/packages/config/verdana.ttf + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-prefs.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-quarantine.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-analysis.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-analysis-graph.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-hfragment.php + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/dspam-history.php + + + + /usr/local/pkg/ + 0755 + http://www.abyssworld.de/packages/config/dspam_alerts.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/dspam.inc + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/dspam-config.inc + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/dspam-guifunc.inc + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/dspam-pkgfunc.inc + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/dspam-utilfunc.inc + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/000.mysql.sh + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/010.clamav-clamd.sh + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/020.clamav-freshclam.sh + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/030.p3scan.sh + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/clamd.conf + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/default.prefs.sample + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/freshclam.conf + + + + /usr/local/www/wizards/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/wizards/dspam_wizard.xml + + + /usr/local/www/wizards/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-lda-proxy.png + + + /usr/local/www/wizards/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-pop-proxy.png + + + /usr/local/www/wizards/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-smtp-relay.png + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/dspam/pkg/verdana.ttf + + + /usr/local/www/themes/metallic/ + 0755 + http://www.pfsense.com/packages/config/dspam/www/themes/metallic/dspam.css + + + + + sync_package_dspam(); + + + custom_php_install_command(); + + + custom_php_deinstall_command(); + +
diff --git a/config/archive/dspam/pkg/dspam_alerts.xml b/config/archive/dspam/pkg/dspam_alerts.xml new file mode 100644 index 00000000..ea59cfd2 --- /dev/null +++ b/config/archive/dspam/pkg/dspam_alerts.xml @@ -0,0 +1,147 @@ + + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + dspamalerts + 1.0 + Services: DSPAM: Alerts + /usr/local/pkg/dspam.inc + + + + Performance + /dspam-perf.php + + + Preferences + /dspam-prefs.php + + + Alerts + /pkg.php?xml=dspam_alerts.xml + + + + Quarantine + /dspam-quarantine.php + + + Analysis + /dspam-analysis.php + + + History + /dspam-history.php + + + Train Filter + /dspam-train.php + + + Admin Suite + /dspam-admin.php + + + + ['installedpackages']['dspam']['config']['alerts'] + + + Alert Name + alertname + + + Description + description + + + + + + Alert Name + alertname + Name of an alert that should be raised + input + 30 + + + + Description + description + You may enter a description here for your reference (not parsed). + input + 30 + + + + + dspam_configure(); + + + dspam_configure(); + + \ No newline at end of file diff --git a/config/archive/dspam/pkg/freshclam.conf b/config/archive/dspam/pkg/freshclam.conf new file mode 100644 index 00000000..173d97bf --- /dev/null +++ b/config/archive/dspam/pkg/freshclam.conf @@ -0,0 +1,110 @@ +## +## Example config file for freshclam +## Please read the freshclam.conf(5) manual before editing this file. +## This file may be optionally merged with clamd.conf. +## + + +# Comment or remove the line below. +#Example + +# Path to the database directory. +# WARNING: It must match clamd.conf's directive! +# Default: hardcoded (depends on installation options) +#DatabaseDirectory /var/lib/clamav +DatabaseDirectory /var/db/clamav + +# Path to the log file (make sure it has proper permissions) +# Default: disabled +#UpdateLogFile /var/log/freshclam.log +UpdateLogFile /var/log/clamav/freshclam.log + +# Enable verbose logging. +# Default: no +#LogVerbose yes + +# Use system logger (can work together with UpdateLogFile). +# Default: no +#LogSyslog yes + +# Specify the type of syslog messages - please refer to 'man syslog' +# for facility names. +# Default: LOG_LOCAL6 +#LogFacility LOG_MAIL + +# This option allows you to save the process identifier of the daemyes +# Default: disabled +#PidFile /var/run/freshclam.pid +PidFile /var/run/clamav/freshclam.pid + +# By default when started freshclam drops privileges and switches to the +# "clamav" user. This directive allows you to change the database owner. +# Default: clamav (may depend on installation options) +DatabaseOwner clamav + +# Initialize supplementary group access (freshclam must be started by root). +# Default: no +AllowSupplementaryGroups yes + +# Use DNS to verify virus database version. Freshclam uses DNS TXT records +# to verify database and software versions. With this directive you can change +# the database verification domain. +# WARNING: Do not touch it unless you're configuring freshclam to use your +# own database verification domain. +# Default: current.cvd.clamav.net +#DNSDatabaseInfo current.cvd.clamav.net + +# Uncomment the following line and replace XY with your country +# code. See http://www.iana.org/cctld/cctld-whois.htm for the full list. +#DatabaseMirror db.XY.clamav.net + +# database.clamav.net is a round-robin record which points to our most +# reliable mirrors. It's used as a fall back in case db.XY.clamav.net is +# not working. DO NOT TOUCH the following line unless you know what you +# are doing. +DatabaseMirror database.clamav.net + +# How many attempts to make before giving up. +# Default: 3 (per mirror) +#MaxAttempts 5 + +# Number of database checks per day. +# Default: 12 (every two hours) +#Checks 24 + +# Proxy settings +# Default: disabled +#HTTPProxyServer myproxy.com +#HTTPProxyPort 1234 +#HTTPProxyUsername myusername +#HTTPProxyPassword mypass + +# Use aaa.bbb.ccc.ddd as client address for downloading databases. Useful for +# multi-homed systems. +# Default: Use OS'es default outgoing IP address. +#LocalIPAddress aaa.bbb.ccc.ddd + +# Send the RELOAD command to clamd. +# Default: no +NotifyClamd /usr/local/etc/clamd.conf + +# Run command after successful database update. +# Default: disabled +#OnUpdateExecute command + +# Run command when database update process fails. +# Default: disabled +#OnErrorExecute command + +# Run command when freshclam reports outdated version. +# In the command string %v will be replaced by the new version number. +# Default: disabled +#OnOutdatedExecute command + +# Don't fork into background. +# Default: no +#Foreground yes + +# Enable debug messages in libclamav. +# Default: no +#Debug yes diff --git a/config/archive/dspam/pkg/p3scan-pf-emer.xml b/config/archive/dspam/pkg/p3scan-pf-emer.xml new file mode 100644 index 00000000..7475e23c --- /dev/null +++ b/config/archive/dspam/pkg/p3scan-pf-emer.xml @@ -0,0 +1,127 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfemer + 1.0 + Services: POP3 Proxy: Emergency Contact + /usr/local/pkg/p3scan.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config']['contacts'] + + + + Email Address + emailaddress + + + Description + description + + + + + + Email Address + emailaddress + + In the event p3scan encounters a catastrophic problem and has to terminate, + it will send an email to these email addresses just before setting up to + close down on the next iteration of a child process. + + input + + + Description + description + Description. + input + + + + + sync_package_p3scan(); + + + sync_package_p3scan(); + + diff --git a/config/archive/dspam/pkg/p3scan-pf-msg.xml b/config/archive/dspam/pkg/p3scan-pf-msg.xml new file mode 100644 index 00000000..b2144fe6 --- /dev/null +++ b/config/archive/dspam/pkg/p3scan-pf-msg.xml @@ -0,0 +1,198 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfmsg + 1.0 + Services: POP3 Proxy: Message Processing + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + /usr/local/pkg/p3scan.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config']['messaging'] + + + + Just Delete + justdelete + + Instead of keeping an infected message in the Virus Directory, delete it + after reporting it to the user. + + checkbox + true + + + Bytes Free + bytesfree + The number of KB's there must be free before processing any mail. + input + + 10000 + + + Broken Email Clients + brokenec + + Some email clients may require special processing. + + checkbox + true + + + ISP Spam + ispspam + + This option allows you to set the string your <acronym title="Internet Service Provider">ISP</acronym> uses if it processes + your email for SPAM. Leave this field blank if you are not going to use + this option. + + input + -- Spam -- + + + Subject + subject + + This option can be used to change the default subject line when + reporting a virus infected message. + + input + 60 + + Subject: "[Virus] found in a mail to you:" <virus name> + + + Notify + notify + + This option can be used to change the default file deleted notification + that is displayed in the virus notification message when the + "justdelete" option is used. + + input + 60 + + Per instruction, the message has been deleted. + + + SMTP Reject + smtpreject + + This option can be used to change the default lt;acronym title="Simple Mail Transfer Protocol">SMTP</acronym> Reject message that + is sent to the client in the event a message is rejected due to a virus. + The error message will have a prefix of "554". + + input + 60 + + Virus detected! P3scan rejected message! + + + Check SMTP size + checksize + + This option can be used to set the maximum message size (in KBytes) + that p3scan will use to determine if it should scan an smtp submission. + Leave this field blank if you are not going to use this option. + + input + 1024 + + + Footer + footer + + This option is used to add the virus definition info from your scanner + to an SMTP message. Leave this field blank if you are not going to use + this option. + + input + 40 + /usr/local/bin/clamdscan -V + + + + + sync_package_p3scan(); + + diff --git a/config/archive/dspam/pkg/p3scan-pf-spam.xml b/config/archive/dspam/pkg/p3scan-pf-spam.xml new file mode 100644 index 00000000..eae78a0f --- /dev/null +++ b/config/archive/dspam/pkg/p3scan-pf-spam.xml @@ -0,0 +1,119 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfspam + 1.0 + Services: POP3 Proxy: SPAM Settings + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + /usr/local/pkg/p3scan.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Message Processing + pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + + ['installedpackages']['p3scanpf']['config']['spam'] + + + + Enable Spam Checking + checkspam + + If set, will scan for Spam before scanning for a virus. + + checkbox + true + spamcheck + + + SPAM Executable Command + spamcheck + The command (plus arguments) that should be invoked to check for SPAM messages. + input + 70 + + /usr/local/bin/dspam --user dspamuser --mode=teft --stdout --deliver=innocent,spam --feature=ch,no,wh + + + + + + sync_package_p3scan(); + + diff --git a/config/archive/dspam/pkg/p3scan-pf-vir.xml b/config/archive/dspam/pkg/p3scan-pf-vir.xml new file mode 100644 index 00000000..ed68b8cf --- /dev/null +++ b/config/archive/dspam/pkg/p3scan-pf-vir.xml @@ -0,0 +1,162 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfvir + 1.0 + Services: POP3 Proxy: Virus Scanner Settings + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + /usr/local/pkg/p3scan.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config']['virus'] + + + + Scanner Type + scannertype + Select here which type of scanner you want to use. + select + 1 + clamd + + + + + + + + + + + Virusscanner + scanner + Depends on scannertype. + input + + 127.0.0.1:3310 + + + Scanner Returncode + viruscode + + Specify the returncode(s) which the scanner returns when + the mail is infected. + + input + 1 + + + Good Scanner return codes + goodcode + + Some scanners can report more than good or infected. Place valid return + codes here that will enable the message to be delivered without a warning. + + input + + + Regular Expression for Virusname + virusregexp + + Specify here a regular expression which describes where the name of + the virus can be found. + + input + .*: (.*) FOUND + + + deMIME Setting + demime + + Tick this if we should parse all lt;acronym title="Multipurpose Internet Mail Extensions">MIME</acronym>-sections instead of passing the + message as-is to the scanner. + + checkbox + true + + + + + sync_package_p3scan(); + + diff --git a/config/archive/dspam/pkg/p3scan-pf.xml b/config/archive/dspam/pkg/p3scan-pf.xml new file mode 100644 index 00000000..f78c3912 --- /dev/null +++ b/config/archive/dspam/pkg/p3scan-pf.xml @@ -0,0 +1,211 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + p3scanpf + 1.0 + Services: POP3 Proxy: Main + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf.xml&id=0 + /usr/local/pkg/p3scan.inc + + + p3scan + A transparent POP3-Proxy with virus-scanning capabilities +
Services
+ p3scan.xml +
+ + p3scan-pf + /usr/local/etc/rc.d/030.p3scan.sh + + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config'] + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf-msg.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf-emer.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf-vir.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf-spam.xml + + + /usr/local/www/ + 0755 + http://www.pfsense.com/packages/config/p3scan_rules.php + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan.inc + + + + + Max Child's + maxchilds + The maximum number of connections we will handle at once. + input + 10 + + + IP Address + ipaddr + The <acronym title="Internet Protocol">IP</acronym> Address we listen on. + input + + 0.0.0.0 + + + Port + port + The <acronym title="Transmission Control Protocol">TCP</acronym> port on we should listen. + input + + 8110 + + + SSL Port + sslport + The TCP <acronym title="Secure Sockets Layer">SSL</acronym> port on we should listen. + input + + 995 + + + Target IP + targetip + Target IP is the IP to connect (0.0.0.0 enables transparent mode). + input + + 0.0.0.0 + + + Target Port + targetport + Target Port is the port to connect. + input + + 8110 + + + Email Port + emailport + The port we should listen on to scan outgoing email messages. + input + + 25 + + + Daemon User + daemonuser + The username the daemon should run as. + input + + root + + + + + sync_package_p3scan(); + + + sync_package_p3scan(); + + + custom_php_install_command(); + + + custom_php_deinstall_command(); + +
diff --git a/config/archive/dspam/pkg/p3scan.inc b/config/archive/dspam/pkg/p3scan.inc new file mode 100644 index 00000000..7d675050 --- /dev/null +++ b/config/archive/dspam/pkg/p3scan.inc @@ -0,0 +1,277 @@ + "") + fwrite($fd, "maxchilds = {$cfg['maxchilds']}\n"); + else + fwrite($fd, "maxchilds = 10\n"); + if (isset($cfg['ipaddr']) && $cfg['ipaddr'] <> "") + fwrite($fd, "ip = {$cfg['ipaddr']}\n"); + else + fwrite($fd, "ip = 0.0.0.0\n"); + /* TODO: Even if the port is configurable, it is + hardcoded in p3scan.c. This needs to be + changed for the sake of flexebility. + */ + if (isset($cfg['port']) && $cfg['port'] <> "") + fwrite($fd, "port = {$cfg['port']}\n"); + else + fwrite($fd, "port = 8110\n"); + if (isset($cfg['sslport']) && $cfg['sslport'] <> "") + fwrite($fd, "sslport = {$cfg['sslport']}\n"); + else + fwrite($fd, "sslport = 995\n"); + if (isset($cfg['targetip']) && $cfg['targetip'] <> "") + fwrite($fd, "targetip = {$cfg['targetip']}\n"); + else + fwrite($fd, "targetip = 0.0.0.0\n"); + if (isset($cfg['targetport']) && $cfg['targetport'] <> "") + fwrite($fd, "targetport = {$cfg['targetport']}\n"); + else + fwrite($fd, "targetport = 8110\n"); + if (isset($cfg['emailport']) && $cfg['emailport'] <> "") + fwrite($fd, "emailport = {$cfg['emailport']}\n"); + else + fwrite($fd, "emailport = 25\n"); + if (isset($cfg['daemonuser']) && $cfg['daemonuser'] <> "") + fwrite($fd, "user = {$cfg['daemonuser']}\n"); + else + fwrite($fd, "user = root\n"); + fwrite($fd, "notifydir = /var/spool/p3scan/notify\n"); + fwrite($fd, "virusdir = /var/spool/p3scan\n"); + fwrite($fd, "template = /usr/local/etc/p3scan/p3scan.mail\n"); + + /* ================================================================ */ + /* == Tab: Message Processing == */ + /* ================================================================ */ + fwrite($fd, "## Message Processing Settings.\n"); + if (isset($cfgmsg['justdelete']) && $cfgmsg['justdelete'] <> "") + fwrite($fd, "justdelete\n"); + if (isset($cfgmsg['bytesfree']) && $cfgmsg['bytesfree'] <> "") + fwrite($fd, "bytesfree = {$cfgmsg['bytesfree']}\n"); + else + fwrite($fd, "bytesfree = 10000\n"); + if (isset($cfgmsg['broken']) && $cfgmsg['broken'] <> "") + fwrite($fd, "broken\n"); + if (isset($cfgmsg['timeout']) && $cfgmsg['timeout'] <> "") + fwrite($fd, "timeout = {$cfgmsg['timeout']}\n"); + else + fwrite($fd, "timeout = 30\n"); + if (isset($cfgmsg['ispspam']) && $cfgmsg['ispspam'] <> "") + fwrite($fd, "ispspam = {$cfg['ispspam']}\n"); + if (file_exists("/usr/local/bin/renattach")) + fwrite($fd, "renattach = /usr/local/bin/renattach\n"); + if (isset($cfgmsg['subject']) && $cfgmsg['subject'] <> "") + fwrite($fd, "subject = {$cfgmsg['subject']}\n"); + else + fwrite($fd, "subject = Subject: \"[Virus] found in a mail to you:\" \n"); + if (isset($cfgmsg['notify']) && $cfgmsg['notify'] <> "") + fwrite($fd, "notify = {$cfgmsg['notify']}\n"); + else + fwrite($fd, "notify = Per instruction, the message has been deleted.\n"); + if (isset($cfgmsg['smtpreject']) && $cfgmsg['smtpreject'] <> "") + fwrite($fd, "smtprset = {$cfgmsg['smtpreject']}\n"); + else + fwrite($fd, "smtprset = Virus detected! P3scan rejected message!\n"); + if (isset($cfgmsg['checksize']) && $cfgmsg['checksize'] <> "") + fwrite($fd, "checksize = {$cfgmsg['checksize']}\n"); + if (isset($cfgmsg['footer']) && $cfgmsg['footer'] <> "") + fwrite($fd, "footer = {$cfgmsg['footer']}\n"); + + /* ================================================================ */ + /* == Tab: Emergency Contact == */ + /* ================================================================ */ + fwrite($fd, "## Emergency Contacts.\n"); + if (is_array($cfgemer)) { + foreach ($cfgemer as $addr) { + $contact .= "{$addr['emailaddress']} "; + } + if (isset($contact) && $contact <> "") + fwrite($fd, "emergcon = {$contact}\n"); + } + + /* ================================================================ */ + /* == Tab: Virus Scanner Settings == */ + /* ================================================================ */ + fwrite($fd, "## Virus Scanner Settings.\n"); + if (isset($cfgvir['scannertype']) && $cfgvir['scannertype'] <> "") + fwrite($fd, "scannertype = {$cfgvir['scannertype']}\n"); + else + fwrite($fd, "scannertype = clamd\n"); + if (isset($cfgvir['scanner']) && $cfgvir['scanner'] <> "") + fwrite($fd, "scanner = {$cfgvir['scanner']}\n"); + else + fwrite($fd, "scanner = 127.0.0.1:3310\n"); + if (isset($cfgvir['viruscode']) && $cfgvir['viruscode'] <> "") + fwrite($fd, "viruscode = {$cfgvir['viruscode']}\n"); + else + fwrite($fd, "viruscode = 1\n"); + if (isset($cfgvir['goodcode']) && $cfgvir['goodcode'] <> "") + fwrite($fd, "goodcode = {$cfgvir['goodcode']}\n"); + if (isset($cfgvir['virusregexp']) && $cfgvir['virusregexp'] <> "") + fwrite($fd, "virusregexp = {$cfgvir['virusregexp']}\n"); + if (isset($cfgvir['demime']) && $cfgvir['demime'] <> "") + fwrite($fd, "demime\n"); + + /* ================================================================ */ + /* == Tab: SPAM Settings == */ + /* ================================================================ */ + if (isset($cfgspam['checkspam']) && $cfgpam['checkspam'] <> "") { + fwrite($fd, "## SPAM Settings.\n"); + fwrite($fd, "checkspam\n"); + if (isset($cfgvir['spamcheck']) && $cfgvir['spamcheck'] <> "") + fwrite($fd, "spamcheck = {$cfgspam['spamcheck']}\n"); + else + fwrite($fd, "spamcheck = /usr/local/bin/dspam --user dspamuser --mode=teft --stdout --deliver=innocent,spam --feature=ch,no,wh\n"); + } + + fclose($fd); + + /* NOTE: The following code requires the p3scan.inc file to be saved with + UNIX Linefeeds. LF that is and NOT CR LF. + */ + $start = << "030.p3scan.sh", + "start" => $start, + "stop" => $stop + ) + ); + + conf_mount_ro(); + config_unlock(); + + if (! file_exists("/usr/local/etc/p3scan")) { + mkdir("/usr/local/etc/p3scan"); + } + if (! file_exists("/usr/local/etc/p3scan/p3scan.conf")) { + mwexec("ln -s /etc/p3scan.conf /usr/local/etc/p3scan/p3scan.conf"); + } + if (! file_exists("/usr/local/etc/p3scan/p3scan.mail")) { + $fd = fopen("/usr/local/etc/p3scan/p3scan.mail","w"); + + $p3scanmail = << + +EOD; + + fwrite($fd, $p3scanmail); + fclose($fd); + } + + mwexec("/usr/local/etc/rc.d/030.p3scan.sh stop"); + mwexec("/usr/local/etc/rc.d/030.p3scan.sh start"); + + return 0; +} + +function custom_php_install_command() { + global $config, $g; + sync_package_p3scan(); +} + +function custom_php_deinstall_command() { + global $config, $g; + conf_mount_rw(); + unlink_if_exists("/usr/local/pkg/pf/p3scan_rules.php"); + unlink_if_exists("/usr/local/www/p3scan_rules.php"); + unlink_if_exists("/usr/local/etc/p3scan/p3scan.conf"); + unlink_if_exists("/usr/local/etc/p3scan/p3scan.mail"); + unlink_if_exists("/usr/local/etc/rc.d/030.p3scan.sh"); + rmdir("/usr/local/etc/p3scan"); + conf_mount_ro(); +} +?> \ No newline at end of file diff --git a/config/archive/dspam/pkg/verdana.ttf b/config/archive/dspam/pkg/verdana.ttf new file mode 100644 index 00000000..754a9b7b Binary files /dev/null and b/config/archive/dspam/pkg/verdana.ttf differ diff --git a/config/archive/dspam/www/dspam-admin-graph.php b/config/archive/dspam/www/dspam-admin-graph.php new file mode 100644 index 00000000..508824e2 --- /dev/null +++ b/config/archive/dspam/www/dspam-admin-graph.php @@ -0,0 +1,201 @@ + 725, + 'height' => 450, + 'antialias' => 'native')); + +// create the graph +$Graph =& Image_Graph::factory('graph', $Canvas); +// add a TrueType font +$Font =& $Graph->addNew('font', 'Verdana'); +// set the font size to 8 pixels +$Font->setSize(8); + +$Graph->setFont($Font); + +// setup the plotarea, legend and their layout +$Graph->add( + Image_Graph::vertical( + Image_Graph::factory('title', array('', 12)), + Image_Graph::horizontal( + $Plotarea = Image_Graph::factory('plotarea'), + $Legend = Image_Graph::factory('legend'), + 80 + ), + 0 + ) +); + +// add grids +$Grid =& $Plotarea->addNew('line_grid', IMAGE_GRAPH_AXIS_Y); +$Grid->setLineColor('silver'); + +// link the legend with the plotares +$Legend->setPlotarea($Plotarea); + +// create the two datasets +$i = 0; +$spamds =& Image_Graph::factory('dataset'); +foreach($spam as $el){ + $spamds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +$i = 0; +$hamds =& Image_Graph::factory('dataset'); +foreach($nonspam as $el){ + $hamds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +$i = 0; +$smds =& Image_Graph::factory('dataset'); +foreach($sm as $el){ + $smds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +$i = 0; +$fpds =& Image_Graph::factory('dataset'); +foreach($fp as $el){ + $fpds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +$i = 0; +$inocds =& Image_Graph::factory('dataset'); +foreach($inoc as $el){ + $inocds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +$i = 0; +$whds =& Image_Graph::factory('dataset'); +foreach($wh as $el){ + $whds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +// set the name/title of each dataset +$spamds->setName('SPAM'); +$hamds->setName('Nonspam'); +$smds->setName('Spam Misses'); +$fpds->setName('False Positives'); +$inocds->setName('Inoculations'); +$whds->setName('Auto-Whitelisted'); + +// put each dataset in a singel ds array +$Datasets = array($inocds, $whds, $spamds, $hamds, $smds, $fpds); + +// create the plot as line chart using the dataset +$Plot =& $Plotarea->addNew('Image_Graph_Plot_Bar', array($Datasets,'stacked')); + +// set a fill color +$FillArray =& Image_Graph::factory('Image_Graph_Fill_Array'); +$FillArray->addColor('#000000'); +$FillArray->addColor('#BF00BF'); +$FillArray->addColor('#BF0000'); +$FillArray->addColor('#00BF00'); +$FillArray->addColor('#BFBF00'); +$FillArray->addColor('#FF7F00'); + +// set a standard fill style +$Plot->setFillStyle($FillArray); + +/* set axis labels */ +$XAxis =& $Plotarea->getAxis(IMAGE_GRAPH_AXIS_X); +$XAxis->setTitle("{$FORM['x_label']}", array('size' => 8, 'angle' => 0)); +$XAxis->setFontAngle(60); +$XAxis->setLabelOptions(array('offset' => intval($FORM['offset']), + 'showtext' => true, + 'position' => 'outside'), 1); + + +$YAxis =& $Plotarea->getAxis(IMAGE_GRAPH_AXIS_Y); +$YAxis->setTitle('Number of Messages', array('size' => 8, 'angle' => 90)); + +// create a Y data value marker +$Marker =& $Plot->addNew('Image_Graph_Marker_Value', IMAGE_GRAPH_VALUE_Y); +$Marker->setFontSize(6); + +// and use the marker on the 1st plot +$Plot->setMarker($Marker); +$Plot->setDataSelector(Image_Graph::factory('Image_Graph_DataSelector_NoZeros')); + +// output the Graph +$Graph->done(); + +function &ReadParse($URI = "") { + if ($URI == "") { + return NULL; + } + + $pairs = preg_split('/&/', $URI); + $FORM = array(); + + foreach($pairs as $pair){ + list($name, $value) = preg_split('/\=/', $pair); + $pattern = '/%([a-fA-F0-9][a-fA-F0-9])/'; + + $name = preg_replace('/\+/', ' ', $name); + $name = preg_replace_callback( + $pattern, + create_function( + '$matches', + 'return pack("C", hexdec($matches[1]));' + ), + $name + ); + + $value = preg_replace('/\+/', ' ', $value); + $value = preg_replace_callback( + $pattern, + create_function( + '$matches', + 'return pack("C", hexdec($matches[1]));' + ), + $value + ); + + $FORM[$name] = $value; + } // end foreach + + return $FORM; +} +?> diff --git a/config/archive/dspam/www/dspam-admin-prefs.php b/config/archive/dspam/www/dspam-admin-prefs.php new file mode 100644 index 00000000..324d961f --- /dev/null +++ b/config/archive/dspam/www/dspam-admin-prefs.php @@ -0,0 +1,249 @@ + + + +EOD; + + $pfSenseHead->addScript($jscriptstr); + echo $pfSenseHead->getHTML(); + +?> + + + +
+ + +

+ + This page lets you configure how the filter will handle your messages. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
+ Training – Configure how the filter learns as it processes messages +
+

DSPAM should train:

+ value="TEFT" type="radio" class="formfld" title="On every new message scanned by the filter" alt="On every new message scanned by the filter" name="rad_train" id="rad_train_one" /> + +
+ value="TOE" type="radio" class="formfld" title="Only when the filter makes a mistake" alt="Only when the filter makes a mistake" name="rad_train" id="rad_train_two" /> + +
+ value="TUM" type="radio" class="formfld" title=";Only with new data or if the filter makes a mistake" alt=";Only with new data or if the filter makes a mistake" name="rad_train" id="rad_train_three" /> + +
+

When I train DSPAM, I prefer:

+ value="message" type="radio" class="formfld" title="To forward my spams (signature appears in message body)" alt="To forward my spams (signature appears in message body)" name="rad_train_action" id="rad_train_action_one" /> + +
+ value="headers" type="radio" class="formfld" title="To bounce my spams (signature appears in message headers)" alt="To bounce my spams (signature appears in message headers)" name="rad_train_action" id="rad_train_action_two" /> + +
+

+ Filter sensitivity during the training period: +

+

+ + + Catch SPAM (More in Quarantine)  + /> + /> + /> + /> + /> + » + /> + « + /> + /> + /> + /> + /> +  Assume Good (Fewer in Quarantine) + + +

+
 
+ Message Handling – Configure how SPAM is handled +
+

When a SPAM message is identified:

+

+ type="radio" class="formfld" title="Quarantine the message" alt="Quarantine the message" name="rad_ident_action" id="rad_ident_action_one" /> + +
+ type="radio" class="formfld" title="Tag the Subject header with" alt="Tag the Subject header with" name="rad_ident_action" id="rad_ident_action_two" /> + + " name="msgtag" /> +
+ type="radio" class="formfld" title="Deliver the message normally with a X-DSPAM-Result header" alt="Deliver the message normally with a X-DSPAM-Result header" name="rad_ident_action" id="rad_ident_action_three" /> + +

+
 
+ Features – Tuning SPAM filtering +
+

+ type="checkbox" class="formbtn" title="Enable noise reduction, which usually improves filtering accuracy" alt="Enable noise reduction, which usually improves filtering accuracy" name="chk_feature_nr" id="chk_feature_nr" /> + +
+ type="checkbox" class="formbtn" title="Enable automatic whitelisting to record frequent correspondence" alt="Enable automatic whitelisting to record frequent correspondence" name="chk_feature_aw" id="chk_feature_aw" /> + +
+ type="checkbox" class="formbtn" title="Add the factoring tokens in each email into the message's full headers" alt="Add the factoring tokens in each email into the message's full headers" name="chk_feature_at" id="chk_feature_at" /> + + +

+
 
  + " /> +
+
+
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-admin-stats.php b/config/archive/dspam/www/dspam-admin-stats.php new file mode 100644 index 00000000..82b91831 --- /dev/null +++ b/config/archive/dspam/www/dspam-admin-stats.php @@ -0,0 +1,123 @@ +getHTML(); + +?> + + + +
+ + +

+ + The following table shows the number of messages processed for each user + along with their current preference settings. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + +
 
NameQ.SizeTPTNFPFNSCICModeOn SpamBNRWhitelistSedSig Loc
+
+
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-admin.php b/config/archive/dspam/www/dspam-admin.php new file mode 100644 index 00000000..45b33b55 --- /dev/null +++ b/config/archive/dspam/www/dspam-admin.php @@ -0,0 +1,207 @@ +getHTML(); + +?> + + + +
+ + +

+ + The following graphs and tables summarize the processing done by the filter. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + +
 
+ Overview +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MessagesTodayThis Hour StatusCurrent Value
Spam Average message processing time sec.
Good Average throughput messages/sec.
Spam Misses DSPAM instances process(es)
False Positives System uptime
Inoculations Mail queue length messages
Total   
+
 
+ 24 Hour Activity – 125 SPAM, 601 Good, 2 Spam Misses, 0 False Positives, 2 Inoculations +
+ + 24 Hour Activity + + &offset=20" alt="24 Hour Activity" border="0" /> + +
 
+ Daily Activity – 2457 SPAM, 10772 Good, 35 Spam Misses, 0 False Positives, 33 Inoculations +
+ + + + + +
+
+
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-analysis-graph.php b/config/archive/dspam/www/dspam-analysis-graph.php new file mode 100644 index 00000000..67262564 --- /dev/null +++ b/config/archive/dspam/www/dspam-analysis-graph.php @@ -0,0 +1,137 @@ +addNew('font', 'Verdana'); +// set the font size to 11 pixels +$Font->setSize(8); + +$Graph->setFont($Font); + +// setup the plotarea, legend and their layout +$Graph->add( + Image_Graph::vertical( + Image_Graph::factory('title', array('', 12)), + Image_Graph::vertical( + $Plotarea = Image_Graph::factory('plotarea'), + $Legend = Image_Graph::factory('legend'), + 88 + ), + 5 + ) +); + +// link the legend with the plotares +$Legend->setPlotarea($Plotarea); + +// create the two datasets +$i = 0; +$spamds =& Image_Graph::factory('dataset'); +foreach($spam_day as $el){ + $spamds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +$i = 0; +$hamds =& Image_Graph::factory('dataset'); +foreach($nonspam_day as $el){ + $hamds->addPoint(strval($period[$i]), intval($el)); + $i++; +} + +// set the name/title of each dataset +$spamds->setName('SPAM'); +$hamds->setName('Good'); + +// put each dataset in a singel ds array +$Datasets = array($spamds, $hamds); + +// create the plot as line chart using the dataset +$Plot =& $Plotarea->addNew('Image_Graph_Plot_Line', array($Datasets,'normal')); + +// set a line color +$LineArray =& Image_Graph::factory('Image_Graph_Line_Array'); +$LineArray->addColor('red'); +$LineArray->addColor('green'); + +// set a standard line style +$Plot->setLineStyle($LineArray); + +/* set axis labels */ +$XAxis =& $Plotarea->getAxis(IMAGE_GRAPH_AXIS_X); +$XAxis->setTitle("{$FORM['x_label']}"); +$YAxis =& $Plotarea->getAxis(IMAGE_GRAPH_AXIS_Y); +$YAxis->setTitle('Number of Messages', 'vertical'); + +// output the Graph +$Graph->done(); + +function &ReadParse($URI = "") { + if ($URI == "") { + return NULL; + } + + $pairs = preg_split('/&/', $URI); + $FORM = array(); + + foreach($pairs as $pair){ + list($name, $value) = preg_split('/\=/', $pair); + $pattern = '/%([a-fA-F0-9][a-fA-F0-9])/'; + + $name = preg_replace('/\+/', ' ', $name); + $name = preg_replace_callback( + $pattern, + create_function( + '$matches', + 'return pack("C", hexdec($matches[1]));' + ), + $name + ); + + $value = preg_replace('/\+/', ' ', $value); + $value = preg_replace_callback( + $pattern, + create_function( + '$matches', + 'return pack("C", hexdec($matches[1]));' + ), + $value + ); + + $FORM[$name] = $value; + } // end foreach + + return $FORM; +} +?> diff --git a/config/archive/dspam/www/dspam-analysis.php b/config/archive/dspam/www/dspam-analysis.php new file mode 100644 index 00000000..f80bd54b --- /dev/null +++ b/config/archive/dspam/www/dspam-analysis.php @@ -0,0 +1,147 @@ + + + +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + +

+ + Graphs showing the number of messages that have been processed are shown below. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
+ 24 Hour Activity SPAM, Good +
+ + 24 Hour Activity + + " alt="24 Hour Activity" border="0" /> + +
 
+ 14 Day Activity SPAM, Good +
+ + 24 Hour Activity + + 24 Hour Activity + +
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-hfragment.php b/config/archive/dspam/www/dspam-hfragment.php new file mode 100644 index 00000000..36152a00 --- /dev/null +++ b/config/archive/dspam/www/dspam-hfragment.php @@ -0,0 +1,90 @@ +getHTML(); + +?> + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + +
+
+
+
+ ()

+
+
 
+
+            
+            
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-history.php b/config/archive/dspam/www/dspam-history.php new file mode 100644 index 00000000..cb5e4f2c --- /dev/null +++ b/config/archive/dspam/www/dspam-history.php @@ -0,0 +1,172 @@ + + + +EOD; + +$pfSenseHead->addScript($jscriptstr); +$pfSenseHead->addLink("\n"); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + + + +

+ + The messages that have been processed by the filter are shown below. The + most recent messages are shown first. Use the retrain options to correct + errors and deliver any false positives that are still in your quarantine. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
+ + + + + +
 
TypeActionDay/TimeFromSubjectAdditional Info
 
+ + + + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-perf.php b/config/archive/dspam/www/dspam-perf.php new file mode 100644 index 00000000..8b69319f --- /dev/null +++ b/config/archive/dspam/www/dspam-perf.php @@ -0,0 +1,222 @@ + + + +EOD; + +$pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + +

+ + If you receive a message in your e-mail application that was not caught by + the filter, please forward it to + so that it can be analyzed and learned as SPAM. + This will improve the filter's accuracy in the future. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
+ Performance Statistics +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
MetricCalculated as
+ Overall accuracy (since last reset) + + % + (SPAM messages caught + Good messages delivered) / Total number of messages 
+ Spam identification (since last reset) + + % + (Spam catch rate only) 
+ Spam ratio (of total processed) + + % + Total SPAM messages (both caught & missed) / Total number of messages 
+
  + + + + + + + + + + + + + + + + + + + + + +
 SPAM messagesGood messages
Since last reset + missed
+ caught
+ % caught
+
+ missed
+ delivered
+ % missed
+
Total processed by filter + missed
+ caught
+
+ missed
+ delivered
+
From corpus + feed
+
+ feed
+
+
+
+

+ Reset | Tweak -1 +

+
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-prefs.php b/config/archive/dspam/www/dspam-prefs.php new file mode 100644 index 00000000..4e6b0f90 --- /dev/null +++ b/config/archive/dspam/www/dspam-prefs.php @@ -0,0 +1,234 @@ + + + +EOD; + +$pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + +

+ + This page lets you configure how the filter will handle your messages. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
+ Training – Configure how the filter learns as it processes messages +
+

DSPAM should train:

+ value="TEFT" type="radio" class="formfld" title="On every new message scanned by the filter" alt="On every new message scanned by the filter" name="rad_train" id="rad_train_one" /> + +
+ value="TOE" type="radio" class="formfld" title="Only when the filter makes a mistake" alt="Only when the filter makes a mistake" name="rad_train" id="rad_train_two" /> + +
+ value="TUM" type="radio" class="formfld" title=";Only with new data or if the filter makes a mistake" alt=";Only with new data or if the filter makes a mistake" name="rad_train" id="rad_train_three" /> + +
+

When I train DSPAM, I prefer:

+ value="message" type="radio" class="formfld" title="To forward my spams (signature appears in message body)" alt="To forward my spams (signature appears in message body)" name="rad_train_action" id="rad_train_action_one" /> + +
+ value="headers" type="radio" class="formfld" title="To bounce my spams (signature appears in message headers)" alt="To bounce my spams (signature appears in message headers)" name="rad_train_action" id="rad_train_action_two" /> + +
+

+ Filter sensitivity during the training period: +

+

+ + + Catch SPAM (More in Quarantine)  + /> + /> + /> + /> + /> + » + /> + « + /> + /> + /> + /> + /> +  Assume Good (Fewer in Quarantine) + + +

+
 
+ Message Handling – Configure how SPAM is handled +
+

When a SPAM message is identified:

+

+ type="radio" class="formfld" title="Quarantine the message" alt="Quarantine the message" name="rad_ident_action" id="rad_ident_action_one" /> + +
+ type="radio" class="formfld" title="Tag the Subject header with" alt="Tag the Subject header with" name="rad_ident_action" id="rad_ident_action_two" /> + + " name="msgtag" /> +
+ type="radio" class="formfld" title="Deliver the message normally with a X-DSPAM-Result header" alt="Deliver the message normally with a X-DSPAM-Result header" name="rad_ident_action" id="rad_ident_action_three" /> + +

+
 
+ Features – Tuning SPAM filtering +
+

+ type="checkbox" class="formbtn" title="Enable noise reduction, which usually improves filtering accuracy" alt="Enable noise reduction, which usually improves filtering accuracy" name="chk_feature_nr" id="chk_feature_nr" /> + +
+ type="checkbox" class="formbtn" title="Enable automatic whitelisting to record frequent correspondence" alt="Enable automatic whitelisting to record frequent correspondence" name="chk_feature_aw" id="chk_feature_aw" /> + +
+ type="checkbox" class="formbtn" title="Add the factoring tokens in each email into the message's full headers" alt="Add the factoring tokens in each email into the message's full headers" name="chk_feature_at" id="chk_feature_at" /> + + +

+
 
  + " /> +
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-quarantine.php b/config/archive/dspam/www/dspam-quarantine.php new file mode 100644 index 00000000..bc205a50 --- /dev/null +++ b/config/archive/dspam/www/dspam-quarantine.php @@ -0,0 +1,178 @@ + + + +EOD; + +$pfSenseHead->addScript($jscriptstr); +$pfSenseHead->addLink("\n"); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + + + + + +

+ + The messages below have not been delivered to your normal e-mail application + because they are believed to be spam. Click on the Subject line to view the + message or choose a sort option to change how messages are sorted. Use the + checkboxes and Deliver Checked to deliver messages you want + to read, or use Delete All to empty the quarantine. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
+ +   +   + + + + + +
 
 
+ +   +   + + + + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-settings-algo.php b/config/archive/dspam/www/dspam-settings-algo.php new file mode 100644 index 00000000..58ffb247 --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-algo.php @@ -0,0 +1,204 @@ + + foo + foo desc + + + bar + bar desc + +*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['algorithm'])) { + $config['installedpackages']['dspam']['config'][0]['algorithm'] = array(); +} + +$t_algos = &$config['installedpackages']['dspam']['config'][0]['algorithm']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_algos[$id]) { + $pconfig['name'] = $t_algos[$id]['name']; + $pconfig['descr'] = $t_algos[$id]['descr']; +} else { + $pconfig['name'] = $_GET['aname']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "aname"); + $reqdfieldsn = explode(",", "DSPAM Algorithm Name"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_algos as $algo) { + if (isset($id) && ($t_algos[$id]) && ($t_algos[$id] === $algo)) { + continue; + } + if ($algo['name'] == $_POST['aname']) { + $input_errors[] = gettext("This algorithm name already exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $algo = array(); + $algo['name'] = $_POST['aname']; + $algo['descr'] = $_POST['descr']; + + if (isset($id) && $t_algos[$id]) + $t_algos[$id] = $algo; + else + $t_algos[] = $algo; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ + +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings-bmta.php b/config/archive/dspam/www/dspam-settings-bmta.php new file mode 100644 index 00000000..c670085d --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-bmta.php @@ -0,0 +1,202 @@ + + foo + foo desc + + + bar + bar desc + +*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['bmta'])) { + $config['installedpackages']['dspam']['config'][0]['bmta'] = array(); +} + +$t_bmtas = &$config['installedpackages']['dspam']['config'][0]['bmta']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_bmtas[$id]) { + $pconfig['name'] = $t_bmtas[$id]['name']; + $pconfig['descr'] = $t_bmtas[$id]['descr']; +} else { + $pconfig['name'] = $_GET['oname']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "oname"); + $reqdfieldsn = explode(",", "Broken MTA Option Name"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_bmtas as $bmta) { + if (isset($id) && ($t_bmtas[$id]) && ($t_bmtas[$id] === $bmta)) { + continue; + } + if ($bmta['name'] == $_POST['oname']) { + $input_errors[] = gettext("This option name already exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $bmta = array(); + $bmta['name'] = $_POST['oname']; + $bmta['descr'] = $_POST['descr']; + + if (isset($id) && $t_bmtas[$id]) + $t_bmtas[$id] = $bmta; + else + $t_bmtas[] = $bmta; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ + +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings-feat.php b/config/archive/dspam/www/dspam-settings-feat.php new file mode 100644 index 00000000..7805fa43 --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-feat.php @@ -0,0 +1,203 @@ + + foo + foo desc + + + bar + bar desc + +*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['feature'])) { + $config['installedpackages']['dspam']['config'][0]['feature'] = array(); +} + +$t_features = &$config['installedpackages']['dspam']['config'][0]['feature']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_features[$id]) { + $pconfig['name'] = $t_features[$id]['name']; + $pconfig['descr'] = $t_features[$id]['descr']; +} else { + $pconfig['name'] = $_GET['fname']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "fname"); + $reqdfieldsn = explode(",", "DSPAM Feature Name"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_features as $feature) { + if (isset($id) && ($t_features[$id]) && ($t_features[$id] === $feature)) { + continue; + } + if ($feature['name'] == $_POST['fname']) { + $input_errors[] = gettext("This feature name already exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $feature = array(); + $feature['name'] = $_POST['fname']; + $feature['descr'] = $_POST['descr']; + + if (isset($id) && $t_features[$id]) + $t_features[$id] = $feature; + else + $t_features[] = $feature; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ + +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings-header.php b/config/archive/dspam/www/dspam-settings-header.php new file mode 100644 index 00000000..d0a5dd9c --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-header.php @@ -0,0 +1,197 @@ + + foo + foo desc + +
+ bar + foo desc +
+*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['header'])) { + $config['installedpackages']['dspam']['config'][0]['header'] = array(); +} + +$t_headers = &$config['installedpackages']['dspam']['config'][0]['header']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_headers[$id]) { + $pconfig['name'] = $t_headers[$id]['name']; + $pconfig['descr'] = $t_headers[$id]['descr']; +} else { + $pconfig['name'] = $_GET['hname']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "hname"); + $reqdfieldsn = explode(",", "Header Name"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_headers as $header) { + if (isset($id) && ($t_headers[$id]) && ($t_headers[$id] === $header)) { + continue; + } + if ($header['name'] == $_POST['hname']) { + $input_errors[] = gettext("This header name already exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $header = array(); + $header['name'] = $_POST['hname']; + $header['descr'] = $_POST['descr']; + + if (isset($id) && $t_headers[$id]) + $t_headers[$id] = $header; + else + $t_headers[] = $header; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings-overr.php b/config/archive/dspam/www/dspam-settings-overr.php new file mode 100644 index 00000000..d938b313 --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-overr.php @@ -0,0 +1,197 @@ + + foo + foo desc + + + bar + bar desc + +*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['override'])) { + $config['installedpackages']['dspam']['config'][0]['override'] = array(); +} + +$t_overr = &$config['installedpackages']['dspam']['config'][0]['override']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_overr[$id]) { + $pconfig['value'] = $t_overr[$id]['value']; + $pconfig['descr'] = $t_overr[$id]['descr']; +} else { + $pconfig['value'] = $_GET['ovalue']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "ovalue"); + $reqdfieldsn = explode(",", "DSPAM Override Value"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_overr as $over) { + if (isset($id) && ($t_overr[$id]) && ($t_overr[$id] === $over)) { + continue; + } + if ($over['value'] == $_POST['ovalue']) { + $input_errors[] = gettext("This override value exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $over = array(); + $over['value'] = $_POST['ovalue']; + $over['descr'] = $_POST['descr']; + + if (isset($id) && $t_overr[$id]) + $t_overr[$id] = $over; + else + $t_overr[] = $over; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings-prefs.php b/config/archive/dspam/www/dspam-settings-prefs.php new file mode 100644 index 00000000..c30cb7bd --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-prefs.php @@ -0,0 +1,197 @@ + + foo + foo desc + + + bar + bar desc + +*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['preference'])) { + $config['installedpackages']['dspam']['config'][0]['preference'] = array(); +} + +$t_prefs = &$config['installedpackages']['dspam']['config'][0]['preference']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_prefs[$id]) { + $pconfig['value'] = $t_prefs[$id]['value']; + $pconfig['descr'] = $t_prefs[$id]['descr']; +} else { + $pconfig['value'] = $_GET['pvalue']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "pvalue"); + $reqdfieldsn = explode(",", "DSPAM Algorithm Name"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_prefs as $pref) { + if (isset($id) && ($t_prefs[$id]) && ($t_prefs[$id] === $pref)) { + continue; + } + if ($pref['value'] == $_POST['pvalue']) { + $input_errors[] = gettext("This preference value already exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $pref = array(); + $pref['value'] = $_POST['pvalue']; + $pref['descr'] = $_POST['descr']; + + if (isset($id) && $t_prefs[$id]) + $t_prefs[$id] = $pref; + else + $t_prefs[] = $pref; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings-spwd.php b/config/archive/dspam/www/dspam-settings-spwd.php new file mode 100644 index 00000000..7912b0f6 --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-spwd.php @@ -0,0 +1,197 @@ + + foo + foo desc + + + bar + bar desc + +*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['server-pwd'])) { + $config['installedpackages']['dspam']['config'][0]['server-pwd'] = array(); +} + +$t_spwds = &$config['installedpackages']['dspam']['config'][0]['server-pwd']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_spwds[$id]) { + $pconfig['value'] = $t_spwds[$id]['value']; + $pconfig['descr'] = $t_spwds[$id]['descr']; +} else { + $pconfig['value'] = $_GET['pwdvalue']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "pwdvalue"); + $reqdfieldsn = explode(",", "Server Password Value"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_spwds as $spwd) { + if (isset($id) && ($t_spwds[$id]) && ($t_spwds[$id] === $spwd)) { + continue; + } + if ($spwd['value'] == $_POST['pwdvalue']) { + $input_errors[] = gettext("This password value already exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $pwd = array(); + $pwd['value'] = $_POST['pwdvalue']; + $pwd['descr'] = $_POST['descr']; + + if (isset($id) && $t_spwds[$id]) + $t_spwds[$id] = $pwd; + else + $t_spwds[] = $pwd; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings-tuser.php b/config/archive/dspam/www/dspam-settings-tuser.php new file mode 100644 index 00000000..57e9ec71 --- /dev/null +++ b/config/archive/dspam/www/dspam-settings-tuser.php @@ -0,0 +1,195 @@ + + foo + + + bar + +*/ + +if (!is_array($config['installedpackages']['dspam']['config'][0]['tuser'])) { + $config['installedpackages']['dspam']['config'][0]['tuser'] = array(); +} + +$t_users = &$config['installedpackages']['dspam']['config'][0]['tuser']; + +/* ID is only set if the user wants to edit an existing entry */ +$id = $_GET['id']; +$sectionid = $_GET['sectionid']; +if (isset($_POST['id'])) + $id = $_POST['id']; +if (isset($_POST['sectionid'])) + $sectionid = $_POST['sectionid']; + +if (isset($id) && $t_users[$id]) { + $pconfig['name'] = $t_users[$id]['name']; + $pconfig['descr'] = $t_users[$id]['descr']; +} else { + $pconfig['name'] = $_GET['uuname']; + $pconfig['descr'] = $_GET['descr']; +} + +if ($_POST) { + + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + $reqdfields = explode(" ", "uuname"); + $reqdfieldsn = explode(",", "Unix username"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + + /* check for overlaps */ + foreach ($t_users as $user) { + if (isset($id) && ($t_users[$id]) && ($t_users[$id] === $user)) { + continue; + } + if ($user['name'] == $_POST['uuname']) { + $input_errors[] = gettext("This username already exists."); + break; + } + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $user = array(); + $user['name'] = $_POST['uuname']; + $user['descr'] = $_POST['descr']; + + if (isset($id) && $t_users[$id]) + $t_users[$id] = $user; + else + $t_users[] = $user; + + write_config(); + + $retval = 0; + config_lock(); + $retval = dspam_configure(); + config_unlock(); + + $savemsg = get_std_save_message($retval); + + isset($sectionid) ? $header = "dspam-settings.php?sectionid={$sectionid}" : $header = "dspam-settings.php"; + pfSenseHeader($header); + exit; + } +} + +/* if ajax is calling, give them an update message */ +if(isAjax()) + print_info_box_np($savemsg); + +include("head.inc"); +/* put your custom HTML head content here */ +/* using some of the $pfSenseHead function calls */ +echo $pfSenseHead->getHTML(); + +?> + + + + +
+
+ + + + + + + + + + + + + +
+ +
+ +
  + "> " onclick="history.back()"> + + + + + + +
+
+ +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + diff --git a/config/archive/dspam/www/dspam-settings.php b/config/archive/dspam/www/dspam-settings.php new file mode 100644 index 00000000..05662a6e --- /dev/null +++ b/config/archive/dspam/www/dspam-settings.php @@ -0,0 +1,2955 @@ + "") { + $error_bucket[] = array("error" => "You must specify a valid MySQL server name value.", + "field" => "msqlserver"); + } else { + if (strpos($_POST['msqlserver'], '/') === false) { + foreach (explode(' ', $_POST['msqlserver']) as $ts) { + if (!is_domain($ts)) { + $error_bucket[] = array("error" => "A MySQL server name may only contain the characters a-z, 0-9, '-' and '.'.", + "field" => "msqlserver"); + break; + } + } + } + } + /* if we are going to use a TCP/IP base MySQL connection, a port value is required */ + if (! is_port($_POST['msqlport']) && strpos($_POST['msqlserver'], '/') === false) { + $error_bucket[] = array("error" => "You must specify a valid MySQL port value.", + "field" => "msqlport"); + } + if (! $_POST['msqluser'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid MySQL username value.", + "field" => "msqluser"); + } + if (! $_POST['msqlpwd'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid MySQL password value.", + "field" => "msqlpwd"); + } + if (! $_POST['msqldb'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid MySQL database value.", + "field" => "msqldb"); + } + if ($_POST['msqlccache'] && !is_numericint($_POST['msqlccache'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a connection cache value.", + "field" => "msqlccache"); + } + } else if($_POST['sdriver'] == "sqlite") { + /* NOP */ + } else if($_POST['sdriver'] == "bdb") { + /* NOP */ + } else if($_POST['sdriver'] == "pgsql") { + if (! $_POST['pgserver'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid PostgreSQL server name value.", + "field" => "pgserver"); + } else { + foreach (explode(' ', $_POST['pgserver']) as $ts) { + if (!is_domain($ts)) { + $error_bucket[] = array("error" => "A PostgreSQL server name may only contain the characters a-z, 0-9, '-' and '.'.", + "field" => "pgserver"); + break; + } + } + } + if (! is_port($_POST['pgport'])) { + $error_bucket[] = array("error" => "You must specify a valid PostgreSQL port value.", + "field" => "pgport"); + } + if (! $_POST['pguser'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid PostgreSQL username value.", + "field" => "pguser"); + } + if (! $_POST['pgpwd'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid PostgreSQL password value.", + "field" => "pgpwd"); + } + if (! $_POST['pgdb'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid PostgreSQL database value.", + "field" => "pgdb"); + } + if ($_POST['pgccache'] && !is_numericint($_POST['pgccache'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a connection cache value.", + "field" => "pgccache"); + } + } else if($_POST['sdriver'] == "oracle") { + if (! $_POST['oraserver'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid Oracle server connection string.", + "field" => "oraserver"); + } + if (! $_POST['orauser'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid Oracle username value.", + "field" => "orauser"); + } + if (! $_POST['orapwd'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid Oracle password value.", + "field" => "orapwd"); + } + if (! $_POST['orasch'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid Oracle schema value.", + "field" => "orasch"); + } + } else if($_POST['sdriver'] == "hash") { + if ($_POST['hsrmax'] && !is_numericint($_POST['hsrmax'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a number for the initial records to be created.", + "field" => "hsrmax"); + } + if ($_POST['hsmxex'] && !is_numericint($_POST['hsmxex'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a number for the maximum extends.", + "field" => "hsmxex"); + } + if ($_POST['hsexsz'] && !is_numericint($_POST['hsexsz'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a number for the record size.", + "field" => "hsexsz"); + } + if ($_POST['hsmxse'] && !is_numericint($_POST['hsmxse'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a number for the maximum number of records to seek.", + "field" => "hsmxse"); + } + if ($_POST['hscoca'] && !is_numericint($_POST['hscoca'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a number for hash connection cache.", + "field" => "hscoca"); + } + } + + if ($_POST['tcpipdel'] == "yes") { + if (! $_POST['dhost'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid server name value for the DSPAM deliver host.", + "field" => "dhost"); + } else { + foreach (explode(' ', $_POST['dhost']) as $ts) { + if (!is_domain($ts)) { + $error_bucket[] = array("error" => "A DSPAM delivery host name may only contain the characters a-z, 0-9, '-' and '.'.", + "field" => "dhost"); + break; + } + } + } + if (! is_port($_POST['dport'])) { + $error_bucket[] = array("error" => "You must specify a valid port value for the DSPAM delivery host.", + "field" => "dport"); + } + if (! $_POST['dident'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid identification string for the DSPAM delivery host.", + "field" => "dident"); + } + } + + if ($_POST['enabledbg'] == "yes") { + if (! $_POST['debug'] <> "") { + $error_bucket[] = array("error" => "You must specify a non-zero value for the debug parameter.", + "field" => "debug"); + } + if (! $_POST['dopt'] <> "") { + $error_bucket[] = array("error" => "You must specify a non-zero value for the debug options.", + "field" => "dopt"); + } + } + + if ($_POST['enableldap'] == "yes") { + if (! $_POST['ldaphost'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid server name value for the LDAP host.", + "field" => "ldaphost"); + } else { + foreach (explode(' ', $_POST['ldaphost']) as $ts) { + if (!is_domain($ts)) { + $error_bucket[] = array("error" => "A LDAP host name may only contain the characters a-z, 0-9, '-' and '.'.", + "field" => "ldaphost"); + break; + } + } + } + if (! $_POST['ldapfilter'] <> "") { + $error_bucket[] = array("error" => "You must specify a non-zero value for the LDAP filter option or you may not be able to get any query result.", + "field" => "ldapfilter"); + } + if (! $_POST['ldapbase'] <> "") { + $error_bucket[] = array("error" => "You must specify a non-zero value for the LDAP base option or you may not be able to get any query result.", + "field" => "ldapbase"); + } + } + + /* misc settings */ + if ($_POST['foatt'] && !is_numericint($_POST['foatt'])) { + $error_bucket[] = array("error" => "You must specify a integer based value for the number of failover attempts.", + "field" => "foatt"); + } + if ($_POST['enablesbl'] == "yes") { + if (! $_POST['sblhost'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid server name value for the SBL host.", + "field" => "sblhost"); + } else { + foreach (explode(' ', $_POST['sblhost']) as $ts) { + if (!is_domain($ts)) { + $error_bucket[] = array("error" => "A SBL host name may only contain the characters a-z, 0-9, '-' and '.'.", + "field" => "sblhost"); + break; + } + } + } + } + if(isset($_POST['enablenoti'])) { + if($_POST['dspamcontact'] == "") { + $error_bucket[] = array("error" => "It is necessary to provide a support contact, if you want DSPAM to send notification messages.", + "field" => "dspamcontact"); + } + if(empty($_POST['whichdomain'])) { + if ($_POST['dspamdomain'] == "") { + $error_bucket[] = array("error" => "You must specify a valid domain name that should be used while sending DSPAM related mail messages.", + "field" => "dspamdomain"); + } else { + if (!is_domain($_POST['dspamdomain'])) { + $error_bucket[] = array("error" => "You must specify a valid domain name that should be used while sending DSPAM related mail messages.", + "field" => "dspamdomain"); + } + } + } + } + + /* Maintanance Settings */ + if (! $_POST['psig'] || $_POST['psig'] == "") { + $error_bucket[] = array("error" => "You must specify a value for the number of signatures to be purged.", + "field" => "psig"); + } else if (! $_POST['psig'] == "off") { + if (!is_numericint($_POST['psig'])) { + $error_bucket[] = array("error" => "You must specify a valide integer value for the number of signatures to be purged.", + "field" => "psig"); + } + } + if (! $_POST['pneut'] || $_POST['pneut'] == "") { + $error_bucket[] = array("error" => "You must specify a value for the number of neutrals to be purged.", + "field" => "pneut"); + } else if (! $_POST['pneut'] == "off") { + if (!is_numericint($_POST['pneut'])) { + $error_bucket[] = array("error" => "You must specify a valide integer value for the number of neutrals to be purged.", + "field" => "pneut"); + } + } + if (! $_POST['punu'] || $_POST['punu'] == "") { + $error_bucket[] = array("error" => "You must specify a value for the number of unused tokens to be purged.", + "field" => "punu"); + } else if (! $_POST['punu'] == "off") { + if (!is_numericint($_POST['punu'])) { + $error_bucket[] = array("error" => "You must specify a valide integer value for the number of unused tokens to be purged.", + "field" => "punu"); + } + } + if (! $_POST['phapa'] || $_POST['phapa'] == "") { + $input_errors[] = "You must specify a value for the number of hapaxes to be purged."; + $input_error_fields[] = "phapa"; + } else if (! $_POST['phapa'] == "off") { + if (!is_numericint($_POST['phapa'])) { + $error_bucket[] = array("error" => "You must specify a valide integer value for the number of hapaxes to be purged.", + "field" => "phapa"); + } + } + if (! $_POST['pones'] || $_POST['pones'] == "") { + $error_bucket[] = array("error" => "You must specify a value for the number of tokens with only 1 spam hit to be purged.", + "field" => "pones"); + } else if (! $_POST['pones'] == "off") { + if (!is_numericint($_POST['pones'])) { + $error_bucket[] = array("error" => "You must specify a valide integer value for the number of tokens with only 1 spam hit to be purged.", + "field" => "pones"); + } + } + if (! $_POST['ponei'] || $_POST['ponei'] == "") { + $error_bucket[] = array("error" => "You must specify a value for the number of tokens with only 1 innocent hit to be purged.", + "field" => "ponei"); + } else if (! $_POST['ponei'] == "off") { + if (!is_numericint($_POST['ponei'])) { + $error_bucket[] = array("error" => "You must specify a valide integer value for the number of tokens with only 1 innocent hit to be purged.", + "field" => "ponei"); + } + } + + /* System Settings */ + if (! is_ipaddr($_POST['locmx'])) { + $error_bucket[] = array("error" => "You must specify a valid IP address for the local MX parameter.", + "field" => "locmx"); + } + if ($_POST['maxmsgs'] && !is_numericint($_POST['maxmsgs'])) { + $error_bucket[] = array("error" => "You must specify a integer based value for the maximum message size.", + "field" => "maxmsgs"); + } + + /* ClamAV Settings */ + if ($_POST['enableclam'] == "yes") { + if (! is_port($_POST['clamport'])) { + $error_bucket[] = array("error" => "You must specify a valid port value for the ClamAV host.", + "field" => "clamport"); + } + if (! $_POST['clamhost'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid server name value for the ClamAV host.", + "field" => "clamhost"); + } else { + foreach (explode(' ', $_POST['clamhost']) as $ts) { + if (!is_domain($ts)) { + $error_bucket[] = array("error" => "A ClamAV host name may only contain the characters a-z, 0-9, '-' and '.'.", + "field" => "clamhost"); + break; + } + } + } + } + + /* */ + /* DSPAM Daemon Settings (Server) */ + /* */ + + /* at least the DSPAM thin client (dspamc) + * should force the user to configure the + * DSPAM daemon. + */ + if (isset($_POST['dsthinc'])) { + if (! is_port($_POST['dsport'])) { + $error_bucket[] = array("error" => "You must specify a valid port value for the DSPAM host.", + "field" => "dsport"); + } + if ($_POST['dsqsize'] && !is_numericint($_POST['dsqsize'])) { + $error_bucket[] = array("error" => "You must specify a valid integer value as a number for the server queue size.", + "field" => "dsqsize"); + } + if (! $_POST['dspid'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid value as PID file for the DSPAM server.", + "field" => "dspid"); + } + if ($_POST['dssmode'] == "standard") { + if (! $_POST['serverparam'] <> "") { + $error_bucket[] = array("error" => "You must specify some valid parameters to be passed to the LMTP server.", + "field" => "serverparam"); + } + if (! $_POST['serverid'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid identification string to be passed to the LMTP server.", + "field" => "serverid"); + } + if ($_POST['serversock'] && $_POST['serversock'] <> "") { + if (strpos($_POST['serversock'], '/') === false) { + $error_bucket[] = array("error" => "You must specify a valid value for the location of a Unix domain socket.", + "field" => "serversock"); + } + } + } + } + + /* DSPAM Daemon Settings (Client) */ + if ($_POST['enabledsclient'] == "yes") { + if (! $_POST['dsclhost'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid server name value for the DSPAM client host.", + "field" => "dsclhost"); + } else { + foreach (explode(' ', $_POST['dsclhost']) as $ts) { + if (!is_domain($ts)) { + $error_bucket[] = array("error" => "A DSPAM client host name may only contain the characters a-z, 0-9, '-' and '.'.", + "field" => "dsclhost"); + break; + } + } + } + if (! is_port($_POST['dsclport'])) { + $error_bucket[] = array("error" => "You must specify a valid port value for the DSPAM client host.", + "field" => "dsclport"); + } + if (! $_POST['dsclident'] <> "") { + $error_bucket[] = array("error" => "You must specify a valid value as identification string for the DSPAM client.", + "field" => "dsclident"); + } + } + + if (is_array($error_bucket)) + foreach($error_bucket as $elem) + $input_errors[] =& $elem["error"]; + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + exit; + } + + if (!$input_errors) { + $config['installedpackages']['dspam']['config'][0]['storage-driver'] = $_POST['sdriver']; + unset($config['installedpackages']['dspam']['config'][0]['dbsettings']); + + if($_POST['sdriver'] == "mysql") { + /* ====================================================================== */ + /* == String and integer values == */ + /* ====================================================================== */ + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-server'] = $_POST['msqlserver']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-port'] = $_POST['msqlport']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-user'] = $_POST['msqluser']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-password'] = $_POST['msqlpwd']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-database'] = $_POST['msqldb']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-ccache'] = $_POST['msqlccache']; + /* ====================================================================== */ + /* == Boolean values == */ + /* ====================================================================== */ + if($_POST['msqlcomp'] == "yes") + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-compress'] = $_POST['msqlcomp']; + else + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-compress']); + if($_POST['msqlsuqt'] == "yes") + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-squote'] = $_POST['msqlsuqt']; + else + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-squote']); + if($_POST['msqluid'] == "yes") + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-uid'] = $_POST['msqluid']; + else + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-uid']); + } else if($_POST['sdriver'] == "sqlite") { + /* ====================================================================== */ + /* == String and integer values == */ + /* ====================================================================== */ + if ($_POST['slitepr']) + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['sqlite-pragma'] = $_POST['slitepr']; + } else if($_POST['sdriver'] == "bdb") { + /* NOP */ + } else if($_POST['sdriver'] == "pgsql") { + /* ====================================================================== */ + /* == String and integer values == */ + /* ====================================================================== */ + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-server'] = $_POST['pgserver']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-port'] = $_POST['pgport']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-user'] = $_POST['pguser']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-password'] = $_POST['pgpwd']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-database'] = $_POST['pgdb']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-ccache'] = $_POST['pgccache']; + /* ====================================================================== */ + /* == Boolean values == */ + /* ====================================================================== */ + if($_POST['pguid'] == "yes") + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-uid'] = $_POST['pguid']; + else + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-uid']); + } else if($_POST['sdriver'] == "oracle") { + /* ====================================================================== */ + /* == String and integer values == */ + /* ====================================================================== */ + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-server'] = $_POST['oraserver']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-user'] = $_POST['orauser']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-password'] = $_POST['orapwd']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-schema'] = $_POST['orasch']; + } else if($_POST['sdriver'] == "hash") { + /* ====================================================================== */ + /* == String and integer values == */ + /* ====================================================================== */ + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-rec-max'] = $_POST['hsrmax']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-ext'] = $_POST['hsmxex']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-ext-size'] = $_POST['hsexsz']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-seek'] = $_POST['hsmxse']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-user'] = $_POST['hsccus']; + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-cache'] = $_POST['hscoca']; + /* ====================================================================== */ + /* == Boolean values == */ + /* ====================================================================== */ + if($_POST['hsatex'] == "yes") + $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-auto-ex'] = $_POST['hsatex']; + else + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-auto-ex']); + } + + $config['installedpackages']['dspam']['config'][0]['tdelivery-agent'] = $_POST['dagent']; + $config['installedpackages']['dspam']['config'][0]['thin-client'] = $_POST['dsthinc']; + + if($_POST['tcpipdel'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery'] = $_POST['tcpipdel']; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-host'] = $_POST['dhost']; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-port'] = $_POST['dport']; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-ident'] = $_POST['dident']; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-proto'] = $_POST['delproto']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['tcpip-delivery']); + unset($config['installedpackages']['dspam']['config'][0]['tcpip-delivery-host']); + unset($config['installedpackages']['dspam']['config'][0]['tcpip-delivery-port']); + unset($config['installedpackages']['dspam']['config'][0]['tcpip-delivery-ident']); + unset($config['installedpackages']['dspam']['config'][0]['tcpip-delivery-proto']); + } + + $config['installedpackages']['dspam']['config'][0]['delivery-onfail'] = $_POST['onfail']; + + if($_POST['enabledbg'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['debug-enable'] = $_POST['enabledbg']; + $config['installedpackages']['dspam']['config'][0]['debug-whom'] = $_POST['debug']; + $config['installedpackages']['dspam']['config'][0]['debug-options'] = $_POST['dopt']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['debug-enable']); + unset($config['installedpackages']['dspam']['config'][0]['debug-whom']); + unset($config['installedpackages']['dspam']['config'][0]['debug-options']); + } + + /* DSPAM engine settings */ + $config['installedpackages']['dspam']['config'][0]['training-mode'] = $_POST['tmode']; + if($_POST['testct'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['test-cond-training'] = $_POST['testct']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['test-cond-training']); + } + $config['installedpackages']['dspam']['config'][0]['pvalue'] = $_POST['pvalue']; + if($_POST['ipdrive'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['improbability-drive'] = $_POST['ipdrive']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['improbability-drive']); + } + + /* LDAP related settings */ + if($_POST['enableldap'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['ldap-enable'] = $_POST['enableldap']; + $config['installedpackages']['dspam']['config'][0]['ldap-mode'] = $_POST['ldapmode']; + $config['installedpackages']['dspam']['config'][0]['ldap-host'] = $_POST['ldaphost']; + $config['installedpackages']['dspam']['config'][0]['ldap-filter'] = $_POST['ldapfilter']; + $config['installedpackages']['dspam']['config'][0]['ldap-base'] = $_POST['ldapbase']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['ldap-enable']); + unset($config['installedpackages']['dspam']['config'][0]['ldap-mode']); + unset($config['installedpackages']['dspam']['config'][0]['ldap-host']); + unset($config['installedpackages']['dspam']['config'][0]['ldap-filter']); + unset($config['installedpackages']['dspam']['config'][0]['ldap-base']); + } + + /* misc settings */ + $config['installedpackages']['dspam']['config'][0]['failover-attempts'] = $_POST['foatt']; + if($_POST['enablesbl'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['sbl-enable'] = $_POST['enablesbl']; + $config['installedpackages']['dspam']['config'][0]['sbl-host'] = $_POST['sblhost']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['sbl-enable']); + unset($config['installedpackages']['dspam']['config'][0]['sbl-host']); + } + if($_POST['enablerbl'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['rbl-inoculate'] = $_POST['enablerbl']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['rbl-inoculate']); + } + if($_POST['enablenoti'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['notification-email'] = $_POST['enablenoti']; + $config['installedpackages']['dspam']['config'][0]['dspam-contact'] = $_POST['dspamcontact']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['notification-email']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-domain']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-contact']); + } + if($_POST['whichdomain'] == "yes") { + unset($config['installedpackages']['dspam']['config'][0]['dspam-domain']); + } else { + $config['installedpackages']['dspam']['config'][0]['dspam-domain'] = $_POST['dspamdomain']; + } + + /* Maintainance Settings */ + $config['installedpackages']['dspam']['config'][0]['purge-signatures'] = $_POST['psig']; + $config['installedpackages']['dspam']['config'][0]['purge-neutral'] = $_POST['pneut']; + $config['installedpackages']['dspam']['config'][0]['purge-unused'] = $_POST['punu']; + $config['installedpackages']['dspam']['config'][0]['purge-hapaxes'] = $_POST['phapa']; + $config['installedpackages']['dspam']['config'][0]['purge-hits-1s'] = $_POST['pones']; + $config['installedpackages']['dspam']['config'][0]['purge-hits-1i'] = $_POST['ponei']; + + /* System Settings */ + $config['installedpackages']['dspam']['config'][0]['local-mx'] = $_POST['locmx']; + $config['installedpackages']['dspam']['config'][0]['local-mx'] = $_POST['locmx']; + if($_POST['enablesysl'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['system-log'] = $_POST['enablesysl']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['system-log']); + } + if($_POST['enableusel'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['user-log'] = $_POST['enableusel']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['user-log']); + } + $config['installedpackages']['dspam']['config'][0]['filter-opt'] = $_POST['optinout']; + if($_POST['enableptoh'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['parse-to-headers'] = $_POST['enableptoh']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['parse-to-headers']); + } + if($_POST['enablecmop'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['change-mode-on-parse'] = $_POST['enablecmop']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['change-mode-on-parse']); + } + if($_POST['enablecuop'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['change-user-on-parse'] = $_POST['enablecuop']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['change-user-on-parse']); + } + if($_POST['enablecuop'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['change-user-on-parse'] = $_POST['enablecuop']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['change-user-on-parse']); + } + if($_POST['enablebmta'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['broken-mta-settings'] = $_POST['enablebmta']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['broken-mta-settings']); + } + $config['installedpackages']['dspam']['config'][0]['max-message-size'] = $_POST['maxmsgs']; + if($_POST['procbias'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['processor-bias'] = $_POST['procbias']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['processor-bias']); + } + + /* ClamAV related settings */ + if($_POST['enableclam'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['clamav-enable'] = $_POST['enableclam']; + $config['installedpackages']['dspam']['config'][0]['clamav-port'] = $_POST['clamport']; + $config['installedpackages']['dspam']['config'][0]['clamav-host'] = $_POST['clamhost']; + $config['installedpackages']['dspam']['config'][0]['clamav-response'] = $_POST['clamresp']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['clamav-enable']); + unset($config['installedpackages']['dspam']['config'][0]['clamav-port']); + unset($config['installedpackages']['dspam']['config'][0]['clamav-host']); + unset($config['installedpackages']['dspam']['config'][0]['clamav-response']); + } + + /* DSPAM daemon settings */ + $config['installedpackages']['dspam']['config'][0]['dspam-server-port'] = $_POST['dsport']; + $config['installedpackages']['dspam']['config'][0]['dspam-server-queue-size'] = $_POST['dsqsize']; + $config['installedpackages']['dspam']['config'][0]['dspam-server-pid'] = $_POST['dspid']; + $config['installedpackages']['dspam']['config'][0]['dspam-server-mode'] = $_POST['dssmode']; + $config['installedpackages']['dspam']['config'][0]['dspam-server-params'] = $_POST['serverparam']; + $config['installedpackages']['dspam']['config'][0]['dspam-server-id'] = $_POST['serverid']; + $config['installedpackages']['dspam']['config'][0]['dspam-server-socket'] = $_POST['serversock']; + + /* DSPAM client settings */ + if($_POST['enabledsclient'] == "yes") { + $config['installedpackages']['dspam']['config'][0]['dspam-client-enable'] = $_POST['enabledsclient']; + $config['installedpackages']['dspam']['config'][0]['dspam-client-host'] = $_POST['dsclhost']; + $config['installedpackages']['dspam']['config'][0]['dspam-client-port'] = $_POST['dsclport']; + $config['installedpackages']['dspam']['config'][0]['dspam-client-id'] = $_POST['dsclident']; + } else { + unset($config['installedpackages']['dspam']['config'][0]['dspam-client-enable']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-client-host']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-client-port']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-client-id']); + } + + write_config(); + + $retval = 0; + conf_mount_rw(); + config_lock(); + $retval = dspam_configure(); + config_unlock(); + $savemsg = get_std_save_message($retval); + conf_mount_ro(); + } +} + +/* did the user send a request to delete an item? */ +if ($_GET['act'] == "del") { + if ($_GET['what'] == "tuser" && $t_users[$_GET['id']]) { + unset($t_users[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } else if ($_GET['what'] == "feat" && $t_features[$_GET['id']]) { + unset($t_features[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } else if ($_GET['what'] == "algo" && $t_algos[$_GET['id']]) { + unset($t_algos[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } else if ($_GET['what'] == "pref" && $t_prefs[$_GET['id']]) { + unset($t_prefs[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } else if ($_GET['what'] == "overr" && $t_overr[$_GET['id']]) { + unset($t_overr[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } else if ($_GET['what'] == "header" && $t_headers[$_GET['id']]) { + unset($t_headers[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } else if ($_GET['what'] == "bmta" && $t_bmtas[$_GET['id']]) { + unset($t_bmtas[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } else if ($_GET['what'] == "spwd" && $t_spwds[$_GET['id']]) { + unset($t_spwds[$_GET['id']]); + write_config(); + pfSenseHeader("dspam-settings.php"); + exit; + } +} + + /* if ajax is calling, give them an update message */ + if(isAjax()) + print_info_box_np($savemsg); + + include("head.inc"); + /* put your custom HTML head content here */ + /* using some of the $pfSenseHead function calls */ + $jscriptstr = << + + +EOD; + + $pfSenseHead->addScript($jscriptstr); + echo $pfSenseHead->getHTML();?> + +> + +
+ + + +

+ + + Note: + + the options on this page are intended for use by advanced users only. + Any setting found on this page is directly going into dspam.conf. + Make sure you do not mess with settings, you do not understand. + +

+

+ If you submit this page, the DSPAM daemon process will be restarted. +

+
+ + + + + + + +
+ +
+
+ + + + + + + +
+

Settings

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Database Settings
Storage Driver + + Specifies the storage driver backend (library) to use. +

+ + IMPORTANT: Switching storage drivers requires more than merely changing this option. + If you do not wish to lose all of your data, you will need to migrate it to the new + backend before making this change. + +

+
  + + " onclick="document.iform.sectionid.value = 'db';" /> +
 
 Delivery Settings
Trusted Delivery Agent + + Specifies the local delivery agent DSPAM should call when delivering mail as a trusted user. +

+ + Note: Use %u to specify the user DSPAM is processing mail for. It is generally a good idea to + allow the MTA to specify the pass-through arguments at run-time, but they may also be specified + here. + +

+
DSPAM Thin Client + /> + Use dspamc instead of the dspam binary. +

+ + Note: This requires to enable the dspam daemon as well (section: DSPAM Daemon Settings (Server)). + +

+
TCP/IP Based Delivery + onClick="enable_change(false, 5);" /> + Use TCP/IP based delivery. +

+ + Note: This option needs to be ticked if you are going to deliver via LMTP or SMTP. + +

+
Deliver Host + name="dhost" id="dhost" value="" /> + Alternatively, you may wish to use SMTP or LMTP delivery to deliver your message to the mail server. +

+ + Note: You will need to configure with --enable-daemon to use host delivery, + however you do not need to operate in daemon mode. Specify an IP address or UNIX path to a + domain socket below as a host. + +

+
Deliver Port + name="dport" id="dport" value="" /> + Port number of a particular host. +
Deliver Ident + name="dident" id="dident" value="" /> + A particular identification string +
TCP/IP Delivery Protocol + + A particular protocol typ. Either SMTP + or LMTP. +
On Fail + + What to do if local delivery or quarantine should fail. +

+ + Note: If set to "unlearn", DSPAM will unlearn the message prior to exiting with an un + successful return code. The default option, "error" will not unlearn the message but + return the appropriate error code. The unlearn option is use-ful on some systems where local + delivery failures will cause the message to be requeued for delivery, and could result in the + message being processed multiple times. During a very large failure, however, this could cause + a significant load increase. + +

+
  + + " onclick="document.iform.sectionid.value = 'del';" /> +
 
 DSPAM Privileges
Trusted Users + Unix users which are allowed to perform certain actions. +

+ + Note: Only the users specified below will be allowed to perform + administrative functions in DSPAM such as setting the active user and + accessing tools. All other users attempting to run DSPAM will be restricted; + their uids will be forced to match the active username and they will not be + able to specify delivery agent privileges or use tools. + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
  + + " onclick="document.iform.sectionid.value = 'priv';" /> +
 
 DSPAM Debugging Options + onClick="enable_change(false, 0);" /> + Enable +
Debug + name="debug" id="debug" value="" /> + Enables debugging for some or all users. +

+ + IMPORTANT: DSPAM must be compiled with debug support in order to use this option. + DSPAM should never be running in production with debug active unless you are + troubleshooting problems. + +

+
Debug Options + name="dopt" id="dopt" value="" /> + One or more of: process, classify, spam, fp, inoculation, corpus +

+ +

+process     standard message processing
+classify    message classification using --classify
+spam        error correction of missed spam
+fp          error correction of false positives
+inoculation message inoculations (source=inoculation)
+corpus      corpusfed messages (source=corpus)
+                        
+ +

+
  + + " onclick="document.iform.sectionid.value = 'dbg';" /> +
 
 DSPAM Engine Settings
Training Mode + + + The default training mode to use for all operations, when one has not been + specified on the commandline or in the user's preferences. + +

+ + Acceptable values are: toe, tum, teft, notrain + +

+
Test Conditional Training + /> + + By default, dspam will retrain certain errors + until the condition is no longer met. + +

+ + Note: This usually accelerates learning. Some people argue that this can increase + the risk of errors, however. + +

+
Features + + Specify features to activate by default; can also be specified + on the commandline. See the documentation for a list of available features. + If _any_ features are specified on the commandline, these are ignored. + +

+ + Note: For standard "CRM114" Markovian weighting, use sbph + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
Algorithms + + Specify the statistical algorithms to use, overriding any + defaults configured in the build. + +

+ + The options are: +

+naive       Naive-Bayesian (All Tokens)
+graham      Graham-Bayesian ("A Plan for Spam")
+burton      Burton-Bayesian (SpamProbe)
+robinson    Robinson's Geometric Mean Test (Obsolete)
+chi-square  Fisher-Robinson's Chi-Square Algorithm
+                        
+ +

+

+ + You may have multiple algorithms active simultaneously, but it is strongly + recommended that you group Bayesian algorithms with other Bayesian + algorithms, and any use of Chi-Square remain exclusive. +

+

+ + NOTE: For standard "CRM114" Markovian weighting, use ‘naive’, or consider + using ‘burton’ for slightly better accuracy. + +

+

+ + Don't mess with this unless you know what you're doing + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
PValue + + + Specify the technique used for calculating PValues, overriding any defaults + configured in the build. + +

+ + These options are: +

+graham      Graham's Technique ("A Plan for Spam")
+robinson    Robinson's Technique
+markov      Markovian Weighted Technique
+                        
+ +

+

+ + Unlike algorithms, you may only have one of these defined. Use of the + chi-square algorithm automatically changes this to robinson. + +

+

+ + Don't mess with this unless you know what you're doing. + +

+
Improbability Drive + /> + + Calculate odds-ratios for ham/spam, and add to X-DSPAM-Improbability headers + +
Preferences + + Specify any preferences to set by default, unless otherwise + overridden by the user (see next section) or a default.prefs file. + +

+ + Note: If user or default.prefs are found, the user's + preferences will override any defaults. + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
Overrides + + Specifies the user preferences which may override + configuration and commandline defaults. + +

+ + Note: Any other preferences supplied by an untrusted user will be ignored. + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
  + + " onclick="document.iform.sectionid.value = 'eng';" /> +
 
 LDAP Settings + onClick="enable_change(false, 1);" /> + Enable +
LDAP Mode + + + Perform various LDAP functions depending on LDAPMode variable. + +

+ + Note: Presently, the only mode supported is 'verify', which will verify the + existence of an unknown user in LDAP prior to creating them as a new user in + the system. This is useful on some systems acting as gateway machines. + +

+
LDAP Host + name="ldaphost" id="ldaphost" value="" /> + + Hostname of the LDAP directory server. + +
LDAP Filter + name="ldapfilter" id="ldapfilter" value="" /> + + A specific query filter, that should be used while querying the LDAP server. + +
LDAP Base + name="ldapbase" id="ldapbase" value="" /> + + A particular distinguish name from where to start LDAP queries. + +
  + + " onclick="document.iform.sectionid.value = 'ldap';" /> +
 
 Miscellaneous Settings
Failover Attempts + name="foatt" id="foatt" value="" /> + + A particular number of attempts. + +

+ + If the storage fails, the agent will follow each profile's failover up to + a maximum number of failover attempts. This should be set to a maximum of + the number of profiles you have, otherwise the agent could loop and try + the same profile multiple times (unless this is your desired behavior). + +

+
Ignore Headers +

+ + If DSPAM is behind other tools which may add a header to + incoming emails, it may be beneficial to ignore these headers - especially + if they are coming from another spam filter. If you are _not_ using one of + these tools, however, leaving the appropriate headers commented out will + allow DSPAM to use them as telltale signs of forged email. + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
SBL Lookup +

+ onClick="enable_change(false, 2);" /> + + Enable checks against a particular SBL host. + +

+

+ name="sblhost" id="sblhost" value="" /> + + A particular SBL hostname. + +

+

+ + Perform lookups on streamlined blackhole list servers (see + http://www.nuclearelephant.com/projects/sbl/). + The streamlined blacklist + server is machine-automated, unsupervised blacklisting system designed to + provide real-time and highly accurate blacklisting based on network spread. + When performing a lookup, DSPAM will automatically learn the inbound message + as spam if the source IP is listed. Until an official public RABL server is + available, this feature is only useful if you are running your own + streamlined blackhole list server for internal reporting among multiple mail + servers. Provide the name of the lookup zone below to use. + +

+

+ + This function performs standard reverse-octet.domain lookups, and while it + will function with many RBLs, it's strongly discouraged to use those + maintained by humans as they're often inaccurate and could hurt filter + learning and accuracy. + +

+
RBL Inoculate + /> + + Enable RBL inoculation support. + +
Enable Notification + onClick="enable_change(false, 2);" /> + + Enable the sending of notification emails to users (first message, quarantine full, etc.) + +
DSPAM Support Contact + name="dspamcontact" id="dspamcontact" value="" /> + + The username of the person who provides DSPAM support for this DSPAM installation + +  (This is the left most part of an email address before the @ sign). +
Email Domain Name + onClick="toggleDSPAMDomain(false, this);" /> + + Use global domain settings while trying to send an email message. + +
  + + " onclick="document.iform.sectionid.value = 'misc';" /> +
 
 Maintainance Settings
  +

+ + Set dspam_clean purge default options, if not + otherwise specified on the commandline. You may set some of + the below values to off, for instance if you are + using a SQL-based database backend for DSPAM. Please consult your + DSPAM manual for any details. + +

+
Purge Signatures + name="psig" id="psig" value="" /> + + Purge stale signatures + +
Purge Neutral + name="pneut" id="pneut" value="" /> + + Purge tokens with neutralish probabilities + +
Purge Unused + name="punu" id="punu" value="" /> + + Purge unused tokens + +
Purge Hapaxes + name="phapa" id="phapa" value="" /> + + Purge tokens with less than 5 hits (hapaxes) + +
Purge Hits 1S + name="pones" id="pones" value="" /> + + Purge tokens with only 1 spam hit + +
Purge Hits 1I + name="ponei" id="ponei" value="" /> + + Purge tokens with only 1 innocent hit + +
  + + " onclick="document.iform.sectionid.value = 'main';" /> +
 
 System Settings
Local MX + name="locmx" id="locmx" value="" /> + + Local Mail Exchangers: Used for source address tracking, tells DSPAM which + mail exchangers are local and therefore should be ignored in the Received: + header when tracking the source of an email. Note: you should use the address + of the host as appears between brackets [ ] in the Received header. + +
  + + Disabling logging for users will make usage graphs unavailable to + them. Disabling system logging will make admin graphs unavailable. + +
Enable System Log + /> + + Enable system logging. + +
Enable User Log + /> + + Enable user logging. + +
Opt Settings + +

+ + Opt: in or out; determines DSPAM's default filtering behavior. If this value + is set to in, users must opt-in to filtering by dropping a .dspam file in + /var/dspam/opt-in/user.dspam (or if you have homedirs configured, a .dspam + folder in their home directory). The default is opt-out, which means all + users will be filtered unless a .nodspam file is dropped in + /var/dspam/opt-out/user.nodspam + +

+
  + + In lieu of setting up individual aliases for each user, + DSPAM can be configured to automatically parse the To: address for spam and + false positive forwards. From there, it can be configured to either set the + DSPAM user based on the username specified in the header and/or change the + training class and source accordingly. The options below can be used to + customize most common types of header parsing behavior to avoid the need for + multiple aliases, or if using LMTP, aliases entirely.. + +
Parse To Headers + /> + + Parse the To: headers of an incoming message. + +

+ + This must be set to ‘on’ to use either of the following features. + +

+
Change Mode On Parse + /> + + Automatically change the class (to spam or innocent). + +

+ + This depends on whether spam- or notspam- was specified, and change + the source to ‘error’. This is convenient if you're not + using aliases at all, but are delivering via LMTP. + +

+
Change User On Parse + /> + + Automatically change the username to match that specified in the To: header. + +

+ + For example, spam-bob@domain.tld will set the username + to bob, ignoring any --user passed in. This may not always be desirable if + you are using virtual email addresses as usernames. Options: + on or user take the portion before the @ sign only + full take everything after the initial {spam,notspam}-. + +

+
Broken MTA Settings + /> + + Enable broken MTA settings. + +

+ + Broken MTA Options: Some MTAs don't support the proper functionality + necessary. In these cases you can activate certain features in DSPAM to + compensate. ‘returnCodes’ causes DSPAM to return an exit code of 99 if + the message is spam, 0 if not, or a negative code if an error has occured. + Specifying ‘case’ causes DSPAM to force the input usernames to lowercase. + Spceifying ‘lineStripping’ causes DSPAM to strip ˆM's from messages passed + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
Max Message Size + name="maxmsgs" id="maxmsgs" value="" /> + + You may specify a maximum message size for DSPAM to process. + +

+ + If the message is larger than the maximum size, it will be delivered + without processing. Value is in bytes. + +

+
Processor Bias + /> + + Bias causes the filter to lean more toward ‘innocent’, and + usually greatly reduces false positives. It is the default behavior of + most Bayesian filters (including dspam). + +

+ + Note: You probably DONT want this if you're using Markovian Weighting, + unless you are paranoid about false positives. + +

+
  + + " onclick="document.iform.sectionid.value = 'sys';" /> +
 
 ClamAV Engine Settings + onClick="enable_change(false, 3);" /> + Enable +
  +

+ + If you are running clamd, DSPAM can perform stream-based + virus checking using TCP. Uncomment the values below to enable virus + checking. + +

+

+ + ClamAVResponse: +

+
reject
+
(reject or drop the message with a permanent failure)
+
accept
+
(accept the message and quietly drop the message)
+
spam
+
(treat as spam and quarantine/tag/whatever)
+
+ +

+
ClamAV Port +

+ name="clamport" id="clamport" value="" /> + + A number that specifies the port the ClamAV daemon is listening to. + +

+

+ + If the message is larger than the maximum size, it will be delivered + without processing. Value is in bytes. + +

+
ClamAV Host + name="clamhost" id="clamhost" value="" /> + + An IP address that points to the host the ClamAV daemon is running on. + +
ClamAV Response + + + The action that should take place, if ClamAV reports a positive. + +
  + + " onclick="document.iform.sectionid.value = 'clam';" /> +
 
 DSPAM Daemon Settings (Server)
  + + If you are running DSPAM as a daemonized server using + --daemon, the following parameters will override the default. Use the + ServerPass option to set up accounts for each client machine. The DSPAM + server will process and deliver the message based on the parameters + specified. If you want the client machine to perform delivery, use + the --stdout option in conjunction with a local setup. + +
Server Port +

+ name="dsport" id="dsport" value="" /> + + A number that specifies the port the DSPAM daemon is listening to. + +

+
Server Queue Size +

+ name="dsqsize" id="dsqsize" value="" /> + + A number that specifies the server's queue size. + +

+
Server PID +

+ name="dspid" id="dspid" value="" /> + + Keep this is sync with /usr/local/etc/rc.d/dspam.rc script. + +

+

+ + Note: Don't change this value unless you know what you are doing. + +

+
Server Mode +

+ + + Specifies the type of LMTP server to start. + +

+ + This can be one of: +

+
dspam
+
DSPAM-proprietary DLMTP server, for communicating with dspamc
+
standard
+
Standard LMTP server, for communicating with Postfix or other MTA
+
auto
+
Speak both DLMTP and LMTP; auto-detect by ServerPass.IDENT
+
+ +

+

+
  +

+ + If supporting DLMTP (dspam) mode, dspam clients will require authentication + as they will be passing in parameters. The idents below will be used to + determine which clients will be speaking DLMTP, so if you will be using + both LMTP and DLMTP from the same host, be sure to use something other + than the server's hostname below (which will be sent by the MTA during a + standard LMTP LHLO). + +

+ + + + + + + + + ""): ?> + + + + + + + + + + + + + + +
+ + +   + + + + + + +
')">
+
+ + + + +
+
+
+

+ + If supporting standard LMTP mode, server parameters will need to be specified + here, as they will not be passed in by the mail server. The ServerIdent + specifies the 250 response code ident sent back to connecting clients and + should be set to the hostname of your server, or an alias. + +

+

+ + Note: If you specify --user in ServerParameters, the RCPT TO will be used + only for delivery, and not set as the active user for processing. + +

+
Server Parameters +

+ + + Parameters which will be passed to the LMTP server. + +

+
Server Ident +

+ name="serverid" id="serverid" value="" /> + + An identification string which will be used to be passed to the LMTP server. + +

+
Server Domain Socket Path +

+ name="serversock" id="serversock" value="" /> + + A local Unix domain socket. + +

+

+ + If you wish to use a local domain socket instead of a TCP socket, uncomment + the following. It is strongly recommended you use local domain sockets if + you are running the client and server on the same machine, as it eliminates + much of the bandwidth overhead. + +

+

+ + Keep this is sync with /usr/local/etc/rd.d/dspam.rc script + +

+
  + + " onclick="document.iform.sectionid.value = 'srv';" /> +
 
 DSPAM Daemon Settings (Client) + onClick="enable_change(false, 4);" /> + Enable +
  +

+ + If you are running DSPAM in client/server mode, uncomment and + set these variables. A ClientHost beginning with a / + will be treated as a domain socket. + +

Client Host +

+ name="dsclhost" id="dsclhost" value="" /> + + A IP address or a Unix domain socket. + +

+
Client Port +

+ name="dsclport" id="dsclport" value="" /> + + Will be only used if this client uses TCP/IP communication. + +

+
Client Ident +

+ name="dsclident" id="dsclident" value="" /> + + A string that will be used to identify the client against a server. + +

+
  + + " onclick="document.iform.sectionid.value = 'cli';" /> +
+
+
+
+
+
+ + +getHTML(); +?> + + + + + + + + +
Access denied for:
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-train.php b/config/archive/dspam/www/dspam-train.php new file mode 100644 index 00000000..bc0bc087 --- /dev/null +++ b/config/archive/dspam/www/dspam-train.php @@ -0,0 +1,284 @@ + + + +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
Archive Type + + +  Mailbox format (like it is used for example by Mozilla Thunderbird) +
+ + +  Maildir format (like it was initially introduced by qmail) +

+ + : + +
+ +
+

+
Compression Type + +  Archive was compressed using a ZIP algorithm. +
+ +  Archive was compressed using a GNU ZIP algorithm. +
+ +  Archive was compressed using a bzip2 algorithm +
+
Message Type + +  Archive to be uploaded contains Spam messages. +
+ +  Archive to be uploaded contains Ham messages. +
+
  +

+ +

+

+ +

+

+ " /> +

+

+ + : + +
+ +
+

+
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam-viewmsg.php b/config/archive/dspam/www/dspam-viewmsg.php new file mode 100644 index 00000000..e56b081f --- /dev/null +++ b/config/archive/dspam/www/dspam-viewmsg.php @@ -0,0 +1,158 @@ + + + +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + + + + + + +

+ + The contents of the message in the quarantine is shown below. + +

+ + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
+ + +
 
Mail Message
+ +
Mail Message
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/dspam.php b/config/archive/dspam/www/dspam.php new file mode 100644 index 00000000..1f2d7df7 --- /dev/null +++ b/config/archive/dspam/www/dspam.php @@ -0,0 +1,264 @@ + + + +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + + + +
+ + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Statistical SPAM Protection for...
Username + + /> + + + +   + + /> +
 
DSPAM Version
DSPAM Copyright
DSPAM Copyright Text
DSPAM Website + +
DSPAM Configure Args + +
 
License User
Company
License Key
License Validity + + +  Renew License + +
Purchase Date
Expiry Date
Ni-ONE Website + http://www.niefert.net/nione.php +
Support Request + Issue a support request +
Ni-ONE Customer Forum + Visit Ni-ONE Customer Forum +
License File (nione.lic) + +
License Checksum (nione.lic.sha1) + +
License Disclaimer +

+ The Ni-ONE appliance solution is based on open source software. Hence you + are allowed to use the corresponding software components (i.e. DSPAM and + its dependencies) under the terms of the accompanying open source license. +

+

+ The Ni-ONE license provides 1st class priority support for a period + of one year starting from the day you did purchase a valide license option. If the + license is marked as expired, you may consider to purchase a renewal license + option using the renew license button that will be provided by the web + interface in such circumstances. +

+
  + " /> +

+ + : + +
+ +
+

+
+
+
+
+ + + + \ No newline at end of file diff --git a/config/archive/dspam/www/themes/metallic/dspam.css b/config/archive/dspam/www/themes/metallic/dspam.css new file mode 100644 index 00000000..5b39ba32 --- /dev/null +++ b/config/archive/dspam/www/themes/metallic/dspam.css @@ -0,0 +1,115 @@ +.qrowEven { + background-color: #DDDDDD; + padding-right: 20px; + padding-left: 8px; + border-bottom: 1px solid #999999; +} +.qrowOdd { + background-color: #FFFFFF; + padding-right: 20px; + padding-left: 8px; + border-bottom: 1px solid #999999; +} +.qrowAlert { + background-color: yellow; + padding-right: 20px; + padding-left: 8px; + border-bottom: 1px solid #999999; +} +.qrowHighlight { + background-color: white; + font-weight: bold; + padding-right: 20px; + padding-left: 8px; + border-bottom: 1px solid #999999; +} +.qrowDivider { + padding-right: 20px; + padding-left: 8px; + border-left: 1px solid black; + border-bottom: 1px solid #999999; +} + +.innocent {color: limegreen; background-color: green;} +.whitelisted {color: magenta; background-color: purple;} +.spam {color: red; background-color: darkred;} +.false {color: white; font-weight: bold; background-color: green;} +.missed {color: white; font-weight: bold; background-color: darkred;} +.inoculation {color: dodgerblue; background-color: darkblue;} +.corpus {color: black; background-color: white;} +.relay {color: white; background-color: #994400;} +.low {color: darkblue; font-weight: bold;} +.medium {color: steelblue; font-weight: bold;} +.high {color: darkorange; font-weight: bold;} + +.small { font-size: 9px;} +.hollow { border: 0px; } + +.qnavtd { + border: 1px solid #CCCCCC; +} +.qnavtdl { + border-top: 1px solid #CCCCCC; + border-bottom: 1px solid #CCCCCC; + border-left: 1px solid #CCCCCC; +} +.qnavtdr { + border-top: 1px solid #CCCCCC; + border-bottom: 1px solid #CCCCCC; + border-right: 1px solid #CCCCCC; +} +.qnavbtnhl { + font-size: 9px !important; + border-right: 1px solid #FF7F7F; + border-bottom: 1px solid #FF7F7F; + border-left: 1px solid #5F0000; + border-top: 1px solid #5F0000; + padding-left: 3px; + padding-right: 3px; + padding-bottom: 2px; + padding-top: 2px; + background-color: #FF7F7F; +} +.qnavbtn { + font-size: 9px !important; + border-right: 1px solid #FF7F7F; + border-bottom: 1px solid #FF7F7F; + border-left: 1px solid #5F0000; + border-top: 1px solid #5F0000; + padding-left: 3px; + padding-right: 3px; + padding-bottom: 2px; + padding-top: 2px; + background-color: #507DCD; + cursor: pointer; +} +.qnavbtn a:link { + font-size: 9px !important; + font-weight: bold; + color: #FFFFFF; + text-decoration:none; +} +.qnavbtn a:visited { + font-size: 9px !important; + font-weight: bold; + color: #FFFFFF; + text-decoration:none; +} +.qnavbtn a:focus { + font-size: 9px !important; + font-weight: bold; + color: #FFFFFF; + text-decoration:underline; +} +.qnavbtn a:hover { + font-size: 9px !important; + font-weight: bold; + color: #FFFFFF; + text-decoration:none; +} +.qnavbtn a:active { + font-size: 9px !important; + font-weight: bold; + color: #FFFFFF; + text-decoration:underline; +} \ No newline at end of file diff --git a/config/archive/dspam/www/wizards/dspam-lda-proxy.png b/config/archive/dspam/www/wizards/dspam-lda-proxy.png new file mode 100644 index 00000000..7a4565ec Binary files /dev/null and b/config/archive/dspam/www/wizards/dspam-lda-proxy.png differ diff --git a/config/archive/dspam/www/wizards/dspam-pop-proxy.png b/config/archive/dspam/www/wizards/dspam-pop-proxy.png new file mode 100644 index 00000000..fa373385 Binary files /dev/null and b/config/archive/dspam/www/wizards/dspam-pop-proxy.png differ diff --git a/config/archive/dspam/www/wizards/dspam-smtp-relay.png b/config/archive/dspam/www/wizards/dspam-smtp-relay.png new file mode 100644 index 00000000..07f554c8 Binary files /dev/null and b/config/archive/dspam/www/wizards/dspam-smtp-relay.png differ diff --git a/config/archive/dspam/www/wizards/dspam_wizard.xml b/config/archive/dspam/www/wizards/dspam_wizard.xml new file mode 100644 index 00000000..4ac96a4c --- /dev/null +++ b/config/archive/dspam/www/wizards/dspam_wizard.xml @@ -0,0 +1,1848 @@ + + + + + + +15 +Services: DSPAM: DSPAM Wizard + + 1 + dspam.inc + DSPAM Setup Wizard + true + This wizard will guide you through the initial configuration of the DSPAM filter. + + + Next + submit + + + + + 2 + dspam.inc + DSPAM Profile Selection + true + DSPAM can be used in different network environment. Hence we are providing three distinct profiles to suit different DSPAM use cases. Please select a particular profile from the below profile selection. + + + dspamprofile + radio + installedpackages->dspam->config->0->dspam-profile + + <center> + <p> +When your mail server gets ready to deliver mail to a user's mailbox it calls +a delivery agent of some sort. On most UNIX systems, this is procmail, maildrop, +mail.local, or a similar tool. When used as a delivery proxy, the DSPAM agent +is called in place of your existing agent - or better put, it can masquerade +as the local delivery agent. DSPAM then processes the message and will call +the /real/ delivery agent to pass the good mail into the user's mailbox, +quarantining the bad mail. DSPAM can optionally tag and deliver both spam +and legitimate mail. + </p> + <p> +In the diagram below, MTA refers to Mail Transfer Agent, or your mail server +software: Postfix, Sendmail, Exim, etc. LDA refers to the Local Delivery +Agent: Procmail, Maildrop, etc.. + </p> + </center> + + lda + + <center><img src="/wizards/dspam-lda-proxy.png" alt="DSPAM acts as a LDA proxy" border="0" /></center> + + + dspamprofile + radio + installedpackages->dspam->config->0->dspam-profile + + <center> +If you don't want to tinker with your existing mail server setup, DSPAM can +be combined with one of a few open source programs designed to act as a POP3 +proxy. This means spam is filtered whenever the user checks their mail, +rather than when it is delivered. The benefit to this is that you can set up +a small machine on your network that will connect to your existing mail server, +so no integration is needed. It also allows your users to arbitarily point their +mail client at it if they desire filtering. The drawback to this approach is +that the POP3 protocol has no way to tell the mail client that a message is +spam, and so the user will have to download the spam (tagged, of course). + </center> + + pop + + <center><img src="/wizards/dspam-pop-proxy.png" alt="DSPAM will be invoked by a POP3 proxy" border="0" /></center> + + + dspamprofile + radio + installedpackages->dspam->config->0->dspam-profile + + <center> +Newer versions of DSPAM have seen features that allow it to function more +easily as an SMTP relay. An SMTP relay sits in front of your existing mail +server (requiring no integration). To use an SMTP relay, the MX records for +your domains are repointed to the relay machine running DSPAM. DSPAM then +relays the good (and optionally bad) mail to the existing SMTP server. This +allows you to use DSPAM with even a Windows-based destination mail server +as no integration is necessary. See doc/relay.txt for one example of how to +do this with Postfix. + </center> + + smtp + + <center><img src="/wizards/dspam-smtp-relay.png" alt="DSPAM acts as a SMTP realy" border="0" /></center> + + + Next + submit + + + + + + + + 3 + dspam.inc + Database Settings + + On this screen you will set the storage driver type that will be used to store + DSPAM tokens. After having completed this wizard you have to configure the + database that you did select herein. + + + + storagedriver + select + installedpackages->dspam->config->0->storage-driver + Specifies the storage driver backend (library) to use. + mysql + toggleDBSettings(); + 1 + + + + + + + + + + + msqlserver + input + installedpackages->dspam->config->0->dbsettings->0->mysql-server + Either a reference to a Unix domain socket or a reference to a specific host. + /tmp/mysql.sock + ^[a-z0-9.|/]+$ + Server name field is invalid + + + + msqlport + input + installedpackages->dspam->config->0->dbsettings->0->mysql-port + Use this variable if you are going to a MySQL server instance using TCP/IP instead of a socket connection. + 3306 + ^[0-9]+$ + Port field is invalid + + + + msqluser + input + installedpackages->dspam->config->0->dbsettings->0->mysql-user + Username, that will be used to connect to a MySQL server instance. + dspam + + + + msqlpwd + input + installedpackages->dspam->config->0->dbsettings->0->mysql-password + Password, that will be used to connect to a MySQL server instance. + dspam + + + + msqldb + input + installedpackages->dspam->config->0->dbsettings->0->mysql-database + Database name, that contains DSPAM data. + dspam + + + + msqlcomp + checkbox + installedpackages->dspam->config->0->dbsettings->0->mysql-compress + Indicates whether communication data between DSPAM and MySQL should be compressed. + on + + + msqlsuqt + checkbox + installedpackages->dspam->config->0->dbsettings->0->mysql-squote + Use this if you have the 4.1 quote bug (see doc/mysql.txt). + + + msqlccache + input + installedpackages->dspam->config->0->dbsettings->0->mysql-ccache + Conection cache default set to 10. + 10 + ^[0-9]+$ + Connection cache field is invalid + + + + msqluid + checkbox + installedpackages->dspam->config->0->dbsettings->0->mysql-uid + Insert user id into the DSPAM signature. + on + + + slitepr + input + installedpackages->dspam->config->0->dbsettings->0->sqlite-pragma + A particular SQLite pragma command to be used. + + + pgserver + input + installedpackages->dspam->config->0->dbsettings->0->pgsql-server + A reference to a specific host that is running a PostgreSQL instance. + 127.0.0.1 + ^[a-z0-9.|-]+$ + Server name field is invalid + + + + pgport + input + installedpackages->dspam->config->0->dbsettings->0->pgsql-port + A number that represents the port a specific PostgreSQL instance is listening to. + 5432 + ^[0-9]+$ + Port field is invalid + + + + pguser + input + installedpackages->dspam->config->0->dbsettings->0->pgsql-user + Username, that will be used to connect to a PostgreSQL server instance. + dspam + + + + pgpwd + input + installedpackages->dspam->config->0->dbsettings->0->pgsql-password + Password, that will be used to connect to a PostgreSQL server instance. + dspam + + + + pgdb + input + installedpackages->dspam->config->0->dbsettings->0->pgsql-database + Database name, that contains DSPAM data. + dspam + + + + pgccache + input + installedpackages->dspam->config->0->dbsettings->0->pgsql-ccache + Conection cache default set to 3. + 3 + ^[0-9]+$ + Connection cache field is invalid + + + + pguid + checkbox + installedpackages->dspam->config->0->dbsettings->0->pgsql-uid + Insert user id into the DSPAM signature. + on + + + oraserver + input + installedpackages->dspam->config->0->dbsettings->0->ora-server + A reference to a specific host that is running an Oracle database instance. + 50 + "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SID=PROD)))" + + + + orauser + input + installedpackages->dspam->config->0->dbsettings->0->ora-user + Username, that will be used to connect to a Oracle database server instance. + dspam + + + + orapwd + input + installedpackages->dspam->config->0->dbsettings->0->ora-password + Password, that will be used to connect to a Oracle database server instance. + dspam + + + + orasch + input + installedpackages->dspam->config->0->dbsettings->0->ora-schema + Schema name, that contains DSPAM data. + dspam + + + + hsrmax + input + installedpackages->dspam->config->0->dbsettings->0->hash-rec-max + Default number of records to create in the initial segment when building hash files. + 98317 + ^[0-9]+$ + Default number of record field is invalid + + + + hsatex + checkbox + installedpackages->dspam->config->0->dbsettings->0->hash-auto-ex + Autoextend hash databases when they fill up. This allows them to continue to train by adding extents (extensions) to the file. + on + + + + hsmxex + input + installedpackages->dspam->config->0->dbsettings->0->hash-max-ext + The maximum number of extents that may be created in a single hash file. + 0 + ^[0-9]+$ + Default number of record field is invalid + + + + hsexsz + input + installedpackages->dspam->config->0->dbsettings->0->hash-ext-size + The record size for newly created extents. + 49157 + ^[0-9]+$ + Default number of record field is invalid + + + + hsmxse + input + installedpackages->dspam->config->0->dbsettings->0->hash-max-seek + The maximum number of records to seek to insert a new record before failing or adding a new extent. + 100 + ^[0-9]+$ + Default number of record field is invalid + + + + hsccus + input + installedpackages->dspam->config->0->dbsettings->0->hash-co-user + If you are using a single, stateful hash database in daemon mode, specifying a concurrent user will cause the user to be permanently mapped into memory and shared via rwlocks. + user + + + + hscoca + input + installedpackages->dspam->config->0->dbsettings->0->hash-co-cache + If running in daemon mode, this is the max # of concurrent connections that will be supported. + 10 + ^[0-9]+$ + Default number of record field is invalid + + + + Next + submit + + + + + + + + + + + 4 + dspam.inc + Delivery Settings + + On this page you will specify how DSPAM should deliver email messages to + their final destination. This could be either a local delivery method or + a TCP/IP based delivery method. + + + + dagent + Specifies the local delivery agent DSPAM should call when delivering mail as a trusted user. + select + + + + + + + + + installedpackages->dspam->config->0->tdelivery-agent + + + true + dspamc + Use <code>dspamc</code> instead of <code>dspam</code> to locally deliver mails from the MTA to the user's mailbox (this pulls in DSPAM client/server settings). + checkbox + installedpackages->dspam->config->0->thin-client + + + true + tcpipdel + Use TCP/IP based delivery. This option needs to be ticked if you are going to deliver via LMTP or SMTP. + checkbox + installedpackages->dspam->config->0->tcpip-delivery + dhost,dport,dident,delproto + + + dhost + input + false + installedpackages->dspam->config->0->tcpip-delivery-host + Alternatively, you may wish to use SMTP or LMTP delivery to deliver your message to the mail server. + ^[a-z0-9.|-]+$ + Host name field is invalid + + + dport + input + installedpackages->dspam->config->0->tcpip-delivery-port + Port number of a particular host. + ^[0-9]+$ + Port field is invalid + + + dident + input + installedpackages->dspam->config->0->tcpip-delivery-ident + A particular identification string. + + + delproto + A particular protocol typ. Either SMTP or LMTP. + select + + + + + installedpackages->dspam->config->0->tcpip-delivery-proto + + + onfail + What to do if local delivery or quarantine should fail. + select + + + + + installedpackages->dspam->config->0->delivery-onfail + + + Next + submit + + + + + + + + 5 + dspam.inc + DSPAM Debugging Options + + Usually the DSPAM binary that ships with pfSense does not contain debugging symbols. + Hence it makes little sense to enable debugging options. If you are quite certain that + your DSPAM distribution comes with debugging enabled you may tweak the below debugging + options. + + + + true + enabledbg + Enable debugging. + checkbox + installedpackages->dspam->config->0->debug-enable + debug,dopt + + + debug + input + installedpackages->dspam->config->0->debug-whom + Enables debugging for some or all users. + + + dopt + input + installedpackages->dspam->config->0->debug-options + One or more of: process, classify, spam, fp, inoculation, corpus + + + Next + submit + + + + + 6 + dspam.inc + DSPAM Engine Settings + + On this page you will find some specific options required to operate the DSPAM engine. Please + consult your <code>dspam.conf</code> for a detailed explanation of each option. + If you are unsure about the meaning of a particular option, please use the default values. + + + + tmode + + The default training mode to use for all operations, when one has not + been specified on the commandline or in the user's preferences (default: teft). + + select + teft + + + + + + + installedpackages->dspam->config->0->training-mode + + + true + testct + on + + By default, dspam will retrain certain errors until the condition is + no longer met (default: enabled). + + checkbox + installedpackages->dspam->config->0->test-cond-training + + + pvalue + + Specify the technique used for calculating PValues, overriding any + defaults configured in the build (default: graham). + + select + teft + + + + + + installedpackages->dspam->config->0->pvalue + + + true + ipdrive + on + + Calculate odds-ratios for ham/spam, and add to X-DSPAM-Improbability + headers (default: disabled). + + checkbox + installedpackages->dspam->config->0->improbability-drive + + + Next + submit + + + + + 7 + dspam.inc + LDAP Settings + + DSPAM comes with the ability to verify users agains user records stored within a LDAP directory. + If using this option, it would be for example possible to verify mail users against Windows + user entries stored within an Active Directory. Please consider this feature as somewhat experimental. + + + + true + enableldap + Enable checks against a LDAP directory. + checkbox + installedpackages->dspam->config->0->ldap-enable + ldapmode,ldaphost,ldapfilter,ldapbase + + + ldapmode + + Perform various LDAP functions depending on LDAPMode variable. + + select + verify + + + + installedpackages->dspam->config->0->ldap-mode + + + ldaphost + input + installedpackages->dspam->config->0->ldap-host + Hostname of the LDAP directory server. + + + ldapfilter + input + installedpackages->dspam->config->0->ldap-filter + A specific query filter, that should be used while querying the LDAP server. + + + ldapbase + input + installedpackages->dspam->config->0->ldap-base + A particular distinguish name from where to start LDAP queries. + + + Next + submit + + + + + 8 + dspam.inc + Miscellaneous Settings + + On this page we will give you an opertunity to fine-tune the DSPAM engine. As mentioned earlier, + if you are unsure about the meaning of a particular option, use its default value. + + + + foatt + input + installedpackages->dspam->config->0->failover-attempts + A particular number of attempts (default: 1). + + + true + enablesbl + Enable checks against a particular SBL host (default: disabled). + checkbox + installedpackages->dspam->config->0->sbl-enable + sblhost + + + sblhost + input + installedpackages->dspam->config->0->sbl-host + A particular SBL hostname (default: none). + 30 + + + true + enablerbl + Enable RBL inoculation support (default: disabled). + checkbox + installedpackages->dspam->config->0->rbl-inoculate + + + true + enablenoti + Enable the sending of notification emails to users (first message, quarantine full, etc. default: disabled). + checkbox + installedpackages->dspam->config->0->notification-email + + + Next + submit + + + + + 9 + dspam.inc + Maintainance Settings + + DSPAM stores token data etc. in some kind of a database (e.g. a RDBMS or flat files). + Over time, this token data may consume lots of space. Hence it makes sense to run + certain routines to clean up unused data. + + + + psig + input + installedpackages->dspam->config->0->purge-signatures + Purge stale signatures (default: 14). + + + pneut + input + installedpackages->dspam->config->0->purge-neutral + Purge tokens with neutralish probabilities (default: 90). + + + punu + input + installedpackages->dspam->config->0->purge-unused + Purge unused tokens (default: 90). + + + phapa + input + installedpackages->dspam->config->0->purge-hapaxes + Purge tokens with less than 5 hits (hapaxes - default: 30). + + + pones + input + installedpackages->dspam->config->0->purge-hits-1s + Purge tokens with only 1 spam hit (default: 15). + + + ponei + input + installedpackages->dspam->config->0->purge-hits-1i + Purge tokens with only 1 innocent hit (default: 15). + + + Next + submit + + + + + 10 + dspam.inc + System Settings + + This page contains additional settings related to the DSPAM system such as logging, + message processing behaviour et cetera. + + + + locmx + input + installedpackages->dspam->config->0->local-mx + + Local Mail Exchangers: Used for source address tracking, tells DSPAM + which mail exchangers are local and therefore should be ignored in the + Received: header when tracking the source of an email. Note: you should + use the address of the host as appears between brackets [ ] in the + Received header (default: 127.0.0.1). + + + + true + enablesysl + Enable system logging (default: enabled). + checkbox + installedpackages->dspam->config->0->system-log + + + true + enableusel + Enable per user logging (default: enabled). + checkbox + installedpackages->dspam->config->0->user-log + + + optinout + + Opt: in or out; determines DSPAM's default filtering behavior (default: out). + + select + out + + + + + installedpackages->dspam->config->0->filter-opt + + + true + enableptoh + Parse the To: headers of an incoming message. (default: disabled). + checkbox + installedpackages->dspam->config->0->parse-to-headers + + + true + enablecmop + Automatically change the class (to spam or innocent - default: disabled). + checkbox + installedpackages->dspam->config->0->change-mode-on-parse + + + true + enablecuop + Automatically change the username to match that specified in the To: header (default: enabled). + checkbox + installedpackages->dspam->config->0->change-user-on-parse + + + maxmsgs + input + installedpackages->dspam->config->0->max-message-size + + You may specify a maximum message size in bytes for DSPAM to process. (default: 307200). + + + + true + procbias + + Bias causes the filter to lean more toward "innocent", and usually + greatly reduces false positives. It is the default behavior of most + Bayesian filters, including dspam (default: enabled). + + checkbox + installedpackages->dspam->config->0->processor-bias + + + Next + submit + + + + + 11 + dspam.inc + ClamAV Engine Settings + + DSPAM comes with an additional feature which allows to scan mail messages + for malicious code (i.e. virii). If you require messages not only to be + classified as Spam/Ham but additionally to be scanned for virii, enable + to appropriate option below. + + + + true + enableclam + Enable ClamAV Engine (default: disabled). + checkbox + installedpackages->dspam->config->0->clamav-enable + clamport,clamhost,clamresp + + + clamport + input + installedpackages->dspam->config->0->clamav-port + A number that specifies the port the ClamAV daemon is listening to (default: none). + + + clamhost + input + installedpackages->dspam->config->0->clamav-host + An IP address that points to the host the ClamAV daemon is running on (default: none). + + + clamresp + The action that should take place, if ClamAV reports a positive (default: none). + select + accept + + + + + + installedpackages->dspam->config->0->clamav-response + + + Next + submit + + + + + 12 + dspam.inc + DSPAM Daemon Settings (Server) + + DSPAM can be either invoked per message (i.e. a thread per message) or it + can be run as a daemon in the background. The latter option enables DSPAM + to maintain database connection pools which may increase overall performance. + Based on the profile, that you did choose initially, some of the below options + may be already set. + + + + dsport + input + installedpackages->dspam->config->0->dspam-server-port + A number that specifies the port the DSPAM daemon is listening to (default: none). + + + dsqsize + input + installedpackages->dspam->config->0->dspam-server-queue-size + A number that specifies the server's queue size (default: none). + + + dspid + input + installedpackages->dspam->config->0->dspam-server-pid + Keep this is sync with <code>/usr/local/etc/rc.d/dspam.rc</code> script (default: none). + 40 + + + dssmode + Specifies the type of LMTP server to start. (default: none). + select + auto + + + + + + installedpackages->dspam->config->0->dspam-server-mode + + + serverparam + input + installedpackages->dspam->config->0->dspam-server-params + Parameters which will be passed to the LMTP server (default: none). + + + serverid + input + installedpackages->dspam->config->0->dspam-server-id + An identification string which will be used to be passed to the LMTP server (default: none). + + + serversock + input + installedpackages->dspam->config->0->dspam-server-socket + A local Unix domain socket (default: none). + 40 + + + Next + submit + + + + + 13 + dspam.inc + DSPAM Daemon Settings (Client) + + If you did configure DSPAM to run in dspam mode, it is required to configure + client settings because DSPAM needs for example to authenticate against its + server counterpart. + + + + true + enabledsclient + Run DSPAM in client mode (default: disabled). + checkbox + installedpackages->dspam->config->0->dspam-client-enable + dsclhost,dsclport,dsclident + + + dsclhost + input + installedpackages->dspam->config->0->dspam-client-host + An IP address or a Unix domain socket (default: none). + + + dsclport + input + installedpackages->dspam->config->0->dspam-client-port + Will be only used if this client uses TCP/IP communication (default: none). + + + dsclident + input + installedpackages->dspam->config->0->dspam-client-id + A string that will be used to identify the client against a server. (default: none). + 40 + + + Next + submit + + + + + 14 + dspam.inc + Reload configuration + true + Click 'Reload' to reload the DSPAM daemon with new changes. + + + Reload + submit + + + + + 15 + dspam.inc + Reload in progress + + A reload is now in progress. Please wait. + <br /> <br /> + The system will automatically try to access DSPAM settings in 120 page seconds. + <br /> <br /> + You can click on the icon above to access the site more quickly. + + + + + + + + + diff --git a/config/archive/p3scan-pf/p3scan-pf-emer.xml b/config/archive/p3scan-pf/p3scan-pf-emer.xml new file mode 100644 index 00000000..da39aef8 --- /dev/null +++ b/config/archive/p3scan-pf/p3scan-pf-emer.xml @@ -0,0 +1,131 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfemer + 1.0 + Services: POP3 Proxy: Emergency Contact + p3scan-pf.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Transparent Proxy Exclusion + /pkg.php?xml=p3scan-pf-transex.xml + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config']['contacts'] + + + + Email Address + emailaddress + + + Description + description + + + + + + Email Address + emailaddress + + In the event p3scan encounters a catastrophic problem and has to terminate, + it will send an email to these email addresses just before setting up to + close down on the next iteration of a child process. + + input + + + Description + description + Description. + input + + + + + sync_package_p3scan(); + + + sync_package_p3scan(); + + diff --git a/config/archive/p3scan-pf/p3scan-pf-msg.xml b/config/archive/p3scan-pf/p3scan-pf-msg.xml new file mode 100644 index 00000000..d3f81aa2 --- /dev/null +++ b/config/archive/p3scan-pf/p3scan-pf-msg.xml @@ -0,0 +1,202 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfmsg + 1.0 + Services: POP3 Proxy: Message Processing + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + p3scan-pf.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Transparent Proxy Exclusion + /pkg.php?xml=p3scan-pf-transex.xml + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config']['messaging'] + + + + Just Delete + justdelete + + Instead of keeping an infected message in the Virus Directory, delete it + after reporting it to the user. + + checkbox + true + + + Bytes Free + bytesfree + The number of KB's there must be free before processing any mail. + input + + 10000 + + + Broken Email Clients + brokenec + + Some email clients may require special processing. + + checkbox + true + + + ISP Spam + ispspam + + This option allows you to set the string your <acronym title="Internet Service Provider">ISP</acronym> uses if it processes + your email for SPAM. Leave this field blank if you are not going to use + this option. + + input + -- Spam -- + + + Subject + subject + + This option can be used to change the default subject line when + reporting a virus infected message. + + input + 60 + + Subject: "[Virus] found in a mail to you:" <virus name> + + + Notify + notify + + This option can be used to change the default file deleted notification + that is displayed in the virus notification message when the + "justdelete" option is used. + + input + 60 + + Per instruction, the message has been deleted. + + + SMTP Reject + smtpreject + + This option can be used to change the default <acronym title="Simple Mail Transfer Protocol">SMTP</acronym> Reject message that + is sent to the client in the event a message is rejected due to a virus. + The error message will have a prefix of "554". + + input + 60 + + Virus detected! P3scan rejected message! + + + Check SMTP size + checksize + + This option can be used to set the maximum message size (in KBytes) + that p3scan will use to determine if it should scan an smtp submission. + Leave this field blank if you are not going to use this option. + + input + 1024 + + + Footer + footer + + This option is used to add the virus definition info from your scanner + to an SMTP message. Leave this field blank if you are not going to use + this option. + + input + 40 + /usr/local/bin/clamdscan -V + + + + + sync_package_p3scan(); + + diff --git a/config/archive/p3scan-pf/p3scan-pf-spam.xml b/config/archive/p3scan-pf/p3scan-pf-spam.xml new file mode 100644 index 00000000..86301a50 --- /dev/null +++ b/config/archive/p3scan-pf/p3scan-pf-spam.xml @@ -0,0 +1,122 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfspam + 1.0 + Services: POP3 Proxy: SPAM Settings + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + p3scan-pf.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Transparent Proxy Exclusion + /pkg.php?xml=p3scan-pf-transex.xml + + + Message Processing + pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + + ['installedpackages']['p3scanpf']['config']['spam'] + + + + Enable Spam Checking + checkspam + + If set, will scan for Spam before scanning for a virus. + + checkbox + true + spamcheck + + + SPAM Executable Command + spamcheck + The command (plus arguments) that should be invoked to check for SPAM messages. + input + 70 + + /usr/local/bin/dspam --user dspamuser --mode=teft --stdout --deliver=innocent,spam --feature=ch,no,wh + + + + + sync_package_p3scan(); + + diff --git a/config/archive/p3scan-pf/p3scan-pf-transex.xml b/config/archive/p3scan-pf/p3scan-pf-transex.xml new file mode 100644 index 00000000..e1b2070a --- /dev/null +++ b/config/archive/p3scan-pf/p3scan-pf-transex.xml @@ -0,0 +1,124 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpftransex + 1.0 + Services: POP3 Proxy: Exclude from Transparent Proxy + + Below you will have the opportunity to define specific IP addresses + which should be exempt from beeing served via transparent proxying. + + p3scan-pf.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Transparent Proxy Exclusion + /pkg.php?xml=p3scan-pf-transex.xml + + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config']['virus'] + + + + Exempted IP + ip + + + Description + description + + + + + + Exempted IP + ip + Enter the IP to exempt from transparent proxy + input + + + Description + description + Enter the description for this item + input + + + + + sync_package_p3scan(); + + diff --git a/config/archive/p3scan-pf/p3scan-pf-vir.xml b/config/archive/p3scan-pf/p3scan-pf-vir.xml new file mode 100644 index 00000000..d96e8a87 --- /dev/null +++ b/config/archive/p3scan-pf/p3scan-pf-vir.xml @@ -0,0 +1,166 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + + p3scanpfvir + 1.0 + Services: POP3 Proxy: Virus Scanner Settings + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + p3scan-pf.inc + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + Transparent Proxy Exclusion + /pkg.php?xml=p3scan-pf-transex.xml + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config']['virus'] + + + + Scanner Type + scannertype + Select here which type of scanner you want to use. + select + 1 + clamd + + + + + + + + + + + Virusscanner + scanner + Depends on scannertype. + input + + 127.0.0.1:3310 + + + Scanner Returncode + viruscode + + Specify the returncode(s) which the scanner returns when + the mail is infected. + + input + 1 + + + Good Scanner return codes + goodcode + + Some scanners can report more than good or infected. Place valid return + codes here that will enable the message to be delivered without a warning. + + input + + + Regular Expression for Virusname + virusregexp + + Specify here a regular expression which describes where the name of + the virus can be found. + + input + .*: (.*) FOUND + + + deMIME Setting + demime + + Tick this if we should parse all <acronym title="Multipurpose Internet Mail Extensions">MIME</acronym>-sections instead of passing the + message as-is to the scanner. + + checkbox + true + + + + + sync_package_p3scan(); + + diff --git a/config/archive/p3scan-pf/p3scan-pf.inc b/config/archive/p3scan-pf/p3scan-pf.inc new file mode 100644 index 00000000..b6f497b2 --- /dev/null +++ b/config/archive/p3scan-pf/p3scan-pf.inc @@ -0,0 +1,395 @@ + + All rights reserved. + + Copyright (C) 2006 Fernando Lemos + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notices, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notices, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* ====================== USAGE NOTE: ====================== */ +/* Depending on your use case scenario, this software may */ +/* depend on the following software packages: */ +/* */ +/* - renatach (part of the FreeBSD ports collection) */ +/* - a virus scanner (e.g. ClamAV) */ +/* - a spam filter (e.g. DSPAM or SpamAssassin) */ +/* ========================================================= */ + + +/* include all configuration functions */ +require_once("functions.inc"); +require_once("notices.inc"); + +function sync_package_p3scan() { + global $config, $g; + conf_mount_rw(); + config_lock(); + $fd = fopen("/etc/p3scan.conf","w"); + + /* shorten the config path */ + $cfg = $config['installedpackages']['p3scanpf']['config'][0]; + $cfgmsg = $config['installedpackages']['p3scanpfmsg']['config'][0]; + $cfgemer = $config['installedpackages']['p3scanpfemer']['config']; + $cfgvir = $config['installedpackages']['p3scanpfvir']['config'][0]; + $cfgspam = $config['installedpackages']['p3scanpfspam']['config'][0]; + + fwrite($fd, "## p3scan-pf config file - generated by pfSense.\n##\n"); + fwrite($fd, "## at: " . date("l dS of F Y h:i:s A") . "\n##\n"); + /* ================================================================ */ + /* == Tab: Daemon Settings == */ + /* ================================================================ */ + fwrite($fd, "## Daemon Settings.\n"); + fwrite($fd, "pidfile = /var/run/p3scan/p3scan.pid\n"); + if (isset($cfg['maxchilds']) && $cfg['maxchilds'] <> "") + fwrite($fd, "maxchilds = {$cfg['maxchilds']}\n"); + else + fwrite($fd, "maxchilds = 10\n"); + if (isset($cfg['ipaddr']) && $cfg['ipaddr'] <> "") + fwrite($fd, "ip = {$cfg['ipaddr']}\n"); + else + fwrite($fd, "ip = 127.0.0.1\n"); + if (isset($cfg['port']) && $cfg['port'] <> "") + fwrite($fd, "port = {$cfg['port']}\n"); + else + fwrite($fd, "port = 8110\n"); + if (isset($cfg['sslport']) && $cfg['sslport'] <> "") + fwrite($fd, "sslport = {$cfg['sslport']}\n"); + else + fwrite($fd, "sslport = 995\n"); + if (isset($cfg['targetip']) && $cfg['targetip'] <> "") { + if ($cfg['targetip'] == "0.0.0.0") + setup_transparency(); + else + remove_transparency(); + fwrite($fd, "targetip = {$cfg['targetip']}\n"); + } else { + setup_transparency(); + fwrite($fd, "targetip = 0.0.0.0\n"); + } + if (isset($cfg['targetport']) && $cfg['targetport'] <> "") + fwrite($fd, "targetport = {$cfg['targetport']}\n"); + else + fwrite($fd, "targetport = 8110\n"); + if (isset($cfg['emailport']) && $cfg['emailport'] <> "") + fwrite($fd, "emailport = {$cfg['emailport']}\n"); + else + fwrite($fd, "emailport = 25\n"); + if (isset($cfg['daemonuser']) && $cfg['daemonuser'] <> "") + fwrite($fd, "user = {$cfg['daemonuser']}\n"); + else + fwrite($fd, "user = root\n"); + fwrite($fd, "notifydir = /var/spool/p3scan/notify\n"); + fwrite($fd, "virusdir = /var/spool/p3scan\n"); + fwrite($fd, "template = /usr/local/etc/p3scan/p3scan.mail\n"); + + /* ================================================================ */ + /* == Tab: Message Processing == */ + /* ================================================================ */ + fwrite($fd, "## Message Processing Settings.\n"); + if (isset($cfgmsg['justdelete']) && $cfgmsg['justdelete'] <> "") + fwrite($fd, "justdelete\n"); + if (isset($cfgmsg['bytesfree']) && $cfgmsg['bytesfree'] <> "") + fwrite($fd, "bytesfree = {$cfgmsg['bytesfree']}\n"); + else + fwrite($fd, "bytesfree = 10000\n"); + if (isset($cfgmsg['broken']) && $cfgmsg['broken'] <> "") + fwrite($fd, "broken\n"); + if (isset($cfgmsg['timeout']) && $cfgmsg['timeout'] <> "") + fwrite($fd, "timeout = {$cfgmsg['timeout']}\n"); + else + fwrite($fd, "timeout = 30\n"); + if (isset($cfgmsg['ispspam']) && $cfgmsg['ispspam'] <> "") + fwrite($fd, "ispspam = {$cfgmsg['ispspam']}\n"); + if (file_exists("/usr/local/bin/renattach")) + fwrite($fd, "renattach = /usr/local/bin/renattach\n"); + if (isset($cfgmsg['subject']) && $cfgmsg['subject'] <> "") + fwrite($fd, "subject = {$cfgmsg['subject']}\n"); + else + fwrite($fd, "subject = Subject: \"[Virus] found in a mail to you:\" \n"); + if (isset($cfgmsg['notify']) && $cfgmsg['notify'] <> "") + fwrite($fd, "notify = {$cfgmsg['notify']}\n"); + else + fwrite($fd, "notify = Per instruction, the message has been deleted.\n"); + if (isset($cfgmsg['smtpreject']) && $cfgmsg['smtpreject'] <> "") + fwrite($fd, "smtprset = {$cfgmsg['smtpreject']}\n"); + else + fwrite($fd, "smtprset = Virus detected! P3scan rejected message!\n"); + if (isset($cfgmsg['checksize']) && $cfgmsg['checksize'] <> "") + fwrite($fd, "checksize = {$cfgmsg['checksize']}\n"); + if (isset($cfgmsg['footer']) && $cfgmsg['footer'] <> "") + fwrite($fd, "footer = {$cfgmsg['footer']}\n"); + + /* ================================================================ */ + /* == Tab: Emergency Contact == */ + /* ================================================================ */ + fwrite($fd, "## Emergency Contacts.\n"); + if (is_array($cfgemer)) { + foreach ($cfgemer as $addr) { + $contact .= "{$addr['emailaddress']} "; + } + if (isset($contact) && $contact <> "") + fwrite($fd, "emergcon = {$contact}\n"); + } + + /* ================================================================ */ + /* == Tab: Virus Scanner Settings == */ + /* ================================================================ */ + fwrite($fd, "## Virus Scanner Settings.\n"); + if (isset($cfgvir['scannertype']) && $cfgvir['scannertype'] <> "") + fwrite($fd, "scannertype = {$cfgvir['scannertype']}\n"); + else + fwrite($fd, "scannertype = clamd\n"); + if (isset($cfgvir['scanner']) && $cfgvir['scanner'] <> "") + fwrite($fd, "scanner = {$cfgvir['scanner']}\n"); + else + fwrite($fd, "scanner = 127.0.0.1:3310\n"); + if (isset($cfgvir['viruscode']) && $cfgvir['viruscode'] <> "") + fwrite($fd, "viruscode = {$cfgvir['viruscode']}\n"); + else + fwrite($fd, "viruscode = 1\n"); + if (isset($cfgvir['goodcode']) && $cfgvir['goodcode'] <> "") + fwrite($fd, "goodcode = {$cfgvir['goodcode']}\n"); + if (isset($cfgvir['virusregexp']) && $cfgvir['virusregexp'] <> "") + fwrite($fd, "virusregexp = {$cfgvir['virusregexp']}\n"); + if (isset($cfgvir['demime']) && $cfgvir['demime'] <> "") + fwrite($fd, "demime\n"); + + /* ================================================================ */ + /* == Tab: SPAM Settings == */ + /* ================================================================ */ + if ((isset($cfgspam['checkspam']) && $cfgspam['checkspam'] <> "") || + $config['installedpackages']['sassassin']['config'][0]['enable'] == 'on') { + fwrite($fd, "## SPAM Settings.\n"); + fwrite($fd, "checkspam\n"); + if (isset($cfgspam['spamcheck']) && $cfgspam['spamcheck'] <> "") { + /* most times the command line for the spam binary becomes + * quite lengthy, which my be the reason that users are + * the XML tag and the command line itself into several + * lines. Thus strip whitespaces. + */ + $cfgspam['spamcheck'] = trim($cfgspam['spamcheck']); + fwrite($fd, "spamcheck = {$cfgspam['spamcheck']}\n"); + } else { + if ($config['installedpackages']['sassassin']['config'][0]['enable'] == 'on') { + fwrite($fd, "spamcheck = /usr/bin/spamc\n"); + } else { + fwrite($fd, "spamcheck = /usr/local/bin/dspam --user dspamuser --mode=teft --stdout --deliver=innocent,spam --feature=ch,no,wh\n"); + } + } + } + + fclose($fd); + + /* NOTE: The following code requires the p3scan-pf.inc file to + * be saved with UNIX Linefeeds. LF that is and NOT CR LF. + */ + $start = << "030.p3scan.sh", + "start" => $start, + "stop" => $stop + ) + ); + } + + /* finally get rid of files that were instaled by the package */ + removePackageLeftovers(); + + conf_mount_ro(); + config_unlock(); + + if (! file_exists("/usr/local/etc/p3scan")) { + mkdir("/usr/local/etc/p3scan"); + } + if (! file_exists("/usr/local/etc/p3scan/p3scan.conf")) { + mwexec("ln -s /etc/p3scan.conf /usr/local/etc/p3scan/p3scan.conf"); + } + if (! file_exists("/usr/local/etc/p3scan/p3scan.mail")) { + $fd = fopen("/usr/local/etc/p3scan/p3scan.mail","w"); + + $p3scanmail = << + +EOD; + + fwrite($fd, $p3scanmail); + fclose($fd); + } + + mwexec("/usr/local/etc/rc.d/030.p3scan.sh stop"); + /* test whether a pid file still exists and remove it if necessary */ + if (! is_service_running("p3scan-pf")) + unlink_if_exists("/var/run/p3scan/p3scan.pid"); + mwexec("/usr/local/etc/rc.d/030.p3scan.sh start"); + + return 0; +} + +function custom_php_install_command() { + global $config, $g; + sync_package_p3scan(); +} + +function custom_php_deinstall_command() { + global $config, $g; + conf_mount_rw(); + + if (is_service_running("p3scan-pf")) + stop_service("p3scan-pf"); + + unlink_if_exists("/usr/local/etc/p3scan/p3scan.conf"); + unlink_if_exists("/usr/local/etc/p3scan/p3scan.mail"); + unlink_if_exists("/usr/local/etc/rc.d/030.p3scan.sh"); + rmdir("/usr/local/etc/p3scan"); + mwexec("rm -rf /var/spool/p3scan"); + mwexec("rm -rf /var/run/p3scan"); + mwexec("rm -rf /var/run/p3scan"); + + conf_mount_ro(); +} + +function removePackageLeftovers() { + unlink_if_exists("/usr/local/etc/rc.d/p3scan.sh"); + unlink_if_exists("/usr/local/etc/p3scan.conf.sample"); + unlink_if_exists("/usr/local/etc/p3scan.mail.sample"); + +} + +function add_trans_table(){ + global $config; + + /* Flush all entries first, and then add them. */ + $p3scan_pf_result = mwexec ('pfctl -a "rdr-package/p3scan" -t p3scan -T flush'); + if($p3scan_pf_result <> 0) { + file_notice("P3SCAN", "There were error(s) flushing the exclude table", "P3SCAN", ""); + } + if($config['installedpackages']['p3scanpftransex']['config'] != ""){ + foreach($config['installedpackages']['p3scanpftransex']['config'] as $tmp) { + $p3scan_pf_result = mwexec ('pfctl -a "rdr-package/p3scan" -t p3scan -T add ' . $tmp['ip']); + if($p3scan_pf_result <> 0) { + file_notice("P3SCAN", "There were error(s) adding the ip " . $tmp['ip'], "P3SCAN", ""); + } + } + } +} + +function remove_transparency() { + $p3scan_pf_result = mwexec ('pfctl -a "rdr-package/p3scan" -t p3scan -T flush'); + if($p3scan_pf_result <> 0) { + file_notice("P3SCAN", "There were error(s) flushing the exclude table", "P3SCAN", ""); + } +} + +function setup_transparency() { + global $config; + $cfg = $config['installedpackages']['p3scanpf']['config'][0]; + $ip = $cfg['ipaddr']; + $port = $cfg['port']; + + if ($ip == "" || $port == "") { return; } + + $trans_file = fopen("/tmp/p3scan_pf.rules","w"); + fwrite($trans_file, "table persist\n"); + fwrite($trans_file, "rdr on " . $config['interfaces']['lan']['if'] . " inet proto tcp from ! to ! " . $config['interfaces']['lan']['ipaddr'] . " port = pop3 -> {$ip} port {$port} \n"); + fclose($trans_file); + $p3scan_pf_result = mwexec ('pfctl -a "rdr-package/p3scan" -f /tmp/p3scan_pf.rules'); + if($p3scan_pf_result <> 0) { + file_notice("P3SCAN", "There were error(s) loading the transparency rules", "P3SCAN", ""); + } + add_trans_table(); +} +?> \ No newline at end of file diff --git a/config/archive/p3scan-pf/p3scan-pf.xml b/config/archive/p3scan-pf/p3scan-pf.xml new file mode 100644 index 00000000..f309cb50 --- /dev/null +++ b/config/archive/p3scan-pf/p3scan-pf.xml @@ -0,0 +1,218 @@ + + + + + + + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + p3scanpf + 1.0 + Services: POP3 Proxy: Main + + This <acronym title="Hypertext Markup Language">HTML</acronym> page uses default values, hence even if each field is + set, you are still required to save this page if you are editing this page + for the very first time! + + pkg_edit.php?xml=p3scan-pf.xml&id=0 + p3scan-pf.inc + + + POP3 Proxy + A transparent POP3-Proxy with virus-scanning capabilities +
Services
+ p3scan-pf.xml + /pkg_edit.php?xml=p3scan-pf.xml&id=0 +
+ + p3scan-pf + 030.p3scan.sh + p3scan + POP3 virus/spam scanner. + + + + Daemon Settings + /pkg_edit.php?xml=p3scan-pf.xml&id=0 + + + + Transparent Proxy Exclusion + /pkg.php?xml=p3scan-pf-transex.xml + + + Message Processing + /pkg_edit.php?xml=p3scan-pf-msg.xml&id=0 + + + Emergency Contact + /pkg.php?xml=p3scan-pf-emer.xml + + + Virus Scanner Settings + /pkg_edit.php?xml=p3scan-pf-vir.xml&id=0 + + + SPAM Settings + /pkg_edit.php?xml=p3scan-pf-spam.xml&id=0 + + + + ['installedpackages']['p3scanpf']['config'] + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf/p3scan-pf-msg.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf/p3scan-pf-transex.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf/p3scan-pf-emer.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf/p3scan-pf-vir.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf/p3scan-pf-spam.xml + + + /usr/local/pkg/ + 0755 + http://www.pfsense.com/packages/config/p3scan-pf/p3scan-pf.inc + + + + + Max Child's + maxchilds + The maximum number of connections we will handle at once. + input + 10 + + + IP Address + ipaddr + The <acronym title="Internet Protocol">IP</acronym> Address we listen on. + input + + 127.0.0.1 + + + Port + port + The <acronym title="Transmission Control Protocol">TCP</acronym> port on we should listen. + input + + 8110 + + + SSL Port + sslport + The TCP <acronym title="Secure Sockets Layer">SSL</acronym> port on we should listen. + input + + 995 + + + Target IP + targetip + Target IP is the IP to connect (0.0.0.0 enables transparent mode). + input + + 0.0.0.0 + + + Target Port + targetport + Target Port is the port to connect. + input + + 8110 + + + Email Port + emailport + The port we should listen on to scan outgoing email messages. + input + + 25 + + + Daemon User + daemonuser + The username the daemon should run as. + input + + root + + + + + sync_package_p3scan(); + + + sync_package_p3scan(); + + + custom_php_install_command(); + + + custom_php_deinstall_command(); + +
diff --git a/config/archive/p3scan.inc b/config/archive/p3scan.inc new file mode 100644 index 00000000..902df50f --- /dev/null +++ b/config/archive/p3scan.inc @@ -0,0 +1,63 @@ + diff --git a/config/archive/p3scan.mail b/config/archive/p3scan.mail new file mode 100644 index 00000000..920e5c8c --- /dev/null +++ b/config/archive/p3scan.mail @@ -0,0 +1,15 @@ +To: %MAILTO% +Date: %MAILDATE% +Subject: *** VIRUS *** %SUBJECT% +Content-Transfer-Encoding: 8bit +Content-Type: text/plain; charset="iso8859-1" +MIME-Version: 1.0 + +Your message was scanned by the pfSense virus scanner for POP3, running on %HOSTNAME%.%DOMAINNAME%, and a virus was found. This email has been sent to you instead of the original infected email. The infected message has been deleted. + +The virus contained in the original message was %VIRUSNAME%. The sender of the email was %MAILFROM%. + +%FILESTATUS% + +Contact the system administrator for further details. This is an automated message, please do not reply to it. +. diff --git a/config/archive/p3scan.xml b/config/archive/p3scan.xml new file mode 100644 index 00000000..9bc438ff --- /dev/null +++ b/config/archive/p3scan.xml @@ -0,0 +1,73 @@ + + + + + + . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + none + none + none + p3scan.inc + + p3scan + p3scan.sh + p3scan + POP3 virus/spam scanner. + + + http://www.pfsense.org/packages/config/p3scan.inc + + + /usr/local/bin/ + 0755 + http://www.pfsense.org/packages/All/p3scan + + + /usr/local/etc/ + http://www.pfsense.org/packages/config/p3scan.mail + + + p3scan_install_command(); + + diff --git a/config/archive/upclient.xml b/config/archive/upclient.xml new file mode 100644 index 00000000..42f71a25 --- /dev/null +++ b/config/archive/upclient.xml @@ -0,0 +1,126 @@ + + + + + + . + All rights reserved. + */ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ +/* ========================================================================== */ + ]]> + + Describe your package here + Describe your package requirements here + Currently there are no FAQ items provided. + upclient + 5.0.b8_2 + upclient: Settings + pkg_edit.php?xml=upclient.xml&id=0 + + upclient + Modify upclient settings. +
Services
+ upclient.xml + /pkg_edit.php?xml=upclient.xml&id=0 +
+ + upclient + upclient.sh + upclient + + installedpackages->package->$packagename->configuration->settings + + + Authorization Key + authkey + This system's uptime authorization key. + input + + + Update Interval + interval + The interval between updates, in seconds (default 550). + input + + + Uptime Server + server + The server this system should send uptime reports to. + input + + + + function sync_package_upclient() { + global $config; + conf_mount_rw(); + config_lock(); + $upclient_conf = $config['installedpackages']['upclient']['config'][0]; + $fout = fopen("/usr/local/etc/upclient.conf", "w"); + if($upclient_conf['authkey'] and $upclient_conf['server']) { + fwrite($fout, "PidFile = /var/run/upclient.pid # Location of pid file\n"); + fwrite($fout, "AuthKey = {$upclient_conf['authkey']}\n"); + $interval = $upclient_conf['interval'] ? $upclient_conf['interval'] : "550"; + fwrite($fout, "Interval = {$interval}\n"); + fwrite($fout, "UptimeServer = {$upclient_conf['server']}\n"); + $static = <<<EOD +SendIdle = 1 # Send CPU idle percent +SendUsage = 1 # Send CPU load percent +SendOSName = 1 # Send name of your Operating System +SendOSVersion = 1 # Send version of your OS +SendCPU = 1 # Send CPU name of your machine +SendCPUDetail = 1 # (BSD, Linux & Solaris only) +SendLoadAvg = 1 # Send 15-minute Load-average (unix only) + +EOD; + fwrite($fout, $static); + fclose($fout); + } + $start = "/usr/local/sbin/upclient &"; + write_rcfile(array( + "file" => "upclient.sh", + "start" => $start + ) + ); + restart_service("upclient"); + conf_mount_ro(); + config_unlock(); + } + + + sync_package_upclient(); + +
+ -- cgit v1.2.3