diff options
Diffstat (limited to 'config/dspam')
164 files changed, 42635 insertions, 0 deletions
diff --git a/config/dspam/conf.default/config.xml b/config/dspam/conf.default/config.xml new file mode 100644 index 00000000..4b33662e --- /dev/null +++ b/config/dspam/conf.default/config.xml @@ -0,0 +1,1020 @@ +<?xml version="1.0"?> +<!-- pfSense default system configuration --> +<pfsense> + <version>2.1</version> + <lastchange></lastchange> + <theme>nione</theme> + <system> + <disablenatreflection/> + <optimization>normal</optimization> + <hostname>nione</hostname> + <domain>local</domain> + <dnsserver></dnsserver> + <dnsallowoverride/> + <timezone>Etc/UTC</timezone> + <time-update-interval>300</time-update-interval> + <timeservers>pool.ntp.org</timeservers> + <group> + <name>admins</name> + <description>System Administrators</description> + <scope>system</scope> + <pages>ANY</pages> + <home>index.php</home> + </group> + <group> + <name>dspam_users</name> + <description>DSPAM Users</description> + <scope>user</scope> + <home>dspam.php</home> + <pages> + <page>dspam.php</page> + <page>wizard.php</page> + <page>system_usermanager.php</page> + <page>license.php</page> + <page>pkg.php</page> + <page>pkg_edit.php</page> + <page>index.php</page> + <page>dspam_alerts.xml</page> + <page>dspam.xml</page> + <page>dspam-perf.php</page> + <page>dspam-prefs.php</page> + <page>dspam-train.php</page> + <page>dspam-quarantine.php</page> + <page>dspam-viewmsg.php</page> + <page>dspam-hfragment.php</page> + <page>dspam-history.php</page> + <page>dspam-analysis-graph.php</page> + <page>dspam-analysis.php</page> + <page>ifstats.php</page> + <page>xmlrpc.php</page> + <page>preload.php</page> + <page>functions.inc.php</page> + <page>javascript.inc.php</page> + <page>sajax.class.php</page> + </pages> + </group> + <group> + <name>dspam_admins</name> + <description>DSPAM Administrators</description> + <scope>user</scope> + <home>dspam.php</home> + <pages> + <page>dspam.php</page> + <page>dspam_wizard.xml</page> + <page>wizard.php</page> + <page>system_usermanager.php</page> + <page>license.php</page> + <page>pkg.php</page> + <page>pkg_edit.php</page> + <page>index.php</page> + <page>status_services.php</page> + <page>dspam-admin-prefs.php</page> + <page>dspam_alerts.xml</page> + <page>dspam.xml</page> + <page>dspam-perf.php</page> + <page>dspam-prefs.php</page> + <page>dspam-train.php</page> + <page>dspam-admin-stats.php</page> + <page>dspam-admin-graph.php</page> + <page>dspam-admin.php</page> + <page>dspam-quarantine.php</page> + <page>dspam-viewmsg.php</page> + <page>dspam-hfragment.php</page> + <page>dspam-history.php</page> + <page>dspam-analysis-graph.php</page> + <page>dspam-analysis.php</page> + <page>dspam-settings-algo.php</page> + <page>dspam-settings-bmta.php</page> + <page>dspam-settings-feat.php</page> + <page>dspam-settings-prefs.php</page> + <page>dspam-settings-header.php</page> + <page>dspam-settings-overr.php</page> + <page>dspam-settings-spwd.php</page> + <page>dspam-settings-tuser.php</page> + <page>dspam-settings.php</page> + <page>p3scan-pf-emer.xml</page> + <page>p3scan-pf.xml</page> + <page>p3scan-pf-msg.xml</page> + <page>p3scan-pf-spam.xml</page> + <page>p3scan-pf-vir.xml</page> + <page>p3scan-pf-transex.xml</page> + <page>ifstats.php</page> + <page>xmlrpc.php</page> + <page>preload.php</page> + <page>functions.inc.php</page> + <page>javascript.inc.php</page> + <page>sajax.class.php</page> + </pages> + </group> + <user> + <name>admin</name> + <fullname>System Administrator</fullname> + <scope>system</scope> + <groupname>admins</groupname> + <password>$1$pHZLmGLm$rtBJza55tMwVbJNkr0qCz/</password> + <priv> + <id>lockwc</id> + <name>Lock webConfigurator</name> + <descr>Indicates whether this user will lock access to the webConfigurator for other users.</descr> + </priv> + <priv> + <id>lock-ipages</id> + <name>Lock individual pages</name> + <descr>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).</descr> + </priv> + <priv> + <id>hasshell</id> + <name>Has shell access</name> + <descr>Indicates whether this user is able to login for example via SSH.</descr> + </priv> + <priv> + <id>isroot</id> + <name>Is root user</name> + <descr>This user is associated with the UNIX root user (you should associate this privilege only with one single user).</descr> + </priv> + </user> + <user> + <name>dspamadm</name> + <fullname>DSPAM Administrator</fullname> + <scope>user</scope> + <groupname>dspam_admins</groupname> + <password>$1$utl.fBcK$ZDnGqMSm2fJHi8vxQ6EfT1</password> + </user> + <webgui> + <protocol>http</protocol> + <!-- + <port></port> + <certificate></certificate> + <private-key></private-key> + <noassigninterfaces/> + <expanddiags/> + <noantilockout></noantilockout> + --> + </webgui> + <!-- <disableconsolemenu/> --> + <!-- <disablefirmwarecheck/> --> + <!-- <shellcmd></shellcmd> --> + <!-- <earlyshellcmd></earlyshellcmd> --> + <!-- <harddiskstandby></harddiskstandby> --> + </system> + <interfaces> + <lan> + <if>sis0</if> + <ipaddr>192.168.1.1</ipaddr> + <subnet>24</subnet> + <media></media> + <mediaopt></mediaopt> + <bandwidth>100</bandwidth> + <bandwidthtype>Mb</bandwidthtype> + <!-- + <wireless> + *see below (opt[n])* + </wireless> + --> + </lan> + <wan> + <if>sis1</if> + <mtu></mtu> + <ipaddr>dhcp</ipaddr> + <!-- *or* ipv4-address *or* 'pppoe' *or* 'pptp' *or* 'bigpond' --> + <subnet></subnet> + <gateway></gateway> + <blockpriv/> + <disableftpproxy/> + <dhcphostname></dhcphostname> + <media></media> + <mediaopt></mediaopt> + <bandwidth>100</bandwidth> + <bandwidthtype>Mb</bandwidthtype> + <!-- + <wireless> + *see below (opt[n])* + </wireless> + --> + </wan> + <!-- + <opt[n]> + <enable/> + <descr></descr> + <if></if> + <ipaddr></ipaddr> + <subnet></subnet> + <media></media> + <mediaopt></mediaopt> + <bridge>lan|wan|opt[n]</bridge> + <wireless> + <mode>hostap *or* bss *or* ibss</mode> + <ssid></ssid> + <channel></channel> + <wep> + <enable/> + <key> + <txkey/> + <value></value> + </key> + </wep> + </wireless> + </opt[n]> + --> + </interfaces> + <!-- + <vlans> + <vlan> + <tag></tag> + <if></if> + <descr></descr> + </vlan> + </vlans> + --> + <staticroutes> + <!-- + <route> + <interface>lan|opt[n]|pptp</interface> + <network>xxx.xxx.xxx.xxx/xx</network> + <gateway>xxx.xxx.xxx.xxx</gateway> + <descr></descr> + </route> + --> + </staticroutes> + <pppoe> + <username></username> + <password></password> + <provider></provider> + <!-- + <ondemand/> + <timeout></timeout> + --> + </pppoe> + <pptp> + <username></username> + <password></password> + <local></local> + <subnet></subnet> + <remote></remote> + <!-- + <ondemand/> + <timeout></timeout> + --> + </pptp> + <bigpond> + <username></username> + <password></password> + <authserver></authserver> + <authdomain></authdomain> + <minheartbeatinterval></minheartbeatinterval> + </bigpond> + <dyndns> + <!-- <enable/> --> + <type>dyndns</type> + <username></username> + <password></password> + <host></host> + <mx></mx> + <!-- <wildcard/> --> + </dyndns> + <dhcpd> + <lan> + <enable/> + <range> + <from>192.168.1.100</from> + <to>192.168.1.199</to> + </range> + <!-- + <winsserver>xxx.xxx.xxx.xxx</winsserver> + <defaultleasetime></defaultleasetime> + <maxleasetime></maxleasetime> + <gateway>xxx.xxx.xxx.xxx</gateway> + <domain></domain> + <dnsserver></dnsserver> + <next-server></next-server> + <filename></filename> + --> + </lan> + <!-- + <opt[n]> + ... + </opt[n]> + --> + <!-- + <staticmap> + <mac>xx:xx:xx:xx:xx:xx</mac> + <ipaddr>xxx.xxx.xxx.xxx</ipaddr> + <descr></descr> + </staticmap> + --> + </dhcpd> + <pptpd> + <mode><!-- off *or* server *or* redir --></mode> + <redir></redir> + <localip></localip> + <remoteip></remoteip> + <!-- <accounting/> --> + <!-- + <user> + <name></name> + <password></password> + </user> + --> + </pptpd> + <ovpn> + <!-- + <server> + <enable/> + <ca_cert></ca_cert> + <srv_cert></srv_cert> + <srv_key></srv_key> + <dh_param></dh_param> + <verb></verb> + <tun_iface></tun_iface> + <port></port> + <bind_iface></bind_iface> + <cli2cli/> + <maxcli></maxcli> + <prefix></prefix> + <ipblock></ipblock> + <crypto></crypto> + <dupcn/> + <psh_options> + <redir></redir> + <redir_loc></redir_loc> + <rte_delay></rte_delay> + <ping></ping> + <pingrst></pingrst> + <pingexit></pingexit> + <inact></inact> + </psh_options> + </server> + <client> + <tunnel></tunnel> + <ca_cert></ca_cert> + <cli_cert></cli_cert> + <cli_key></cli_key> + <type></type> + <tunnel> + <if></if> + <proto></proto> + <cport></cport> + <saddr></saddr> + <sport></sport> + <crypto></crypto> + </tunnel> + </client> + --> + </ovpn> + <dnsmasq> + <enable/> + <!-- + <hosts> + <host></host> + <domain></domain> + <ip></ip> + <descr></descr> + </hosts> + --> + </dnsmasq> + <snmpd> + <!-- <enable/> --> + <syslocation></syslocation> + <syscontact></syscontact> + <rocommunity>public</rocommunity> + </snmpd> + <diag> + <ipv6nat> + <!-- <enable/> --> + <ipaddr></ipaddr> + </ipv6nat> + </diag> + <bridge> + <!-- <filteringbridge/> --> + </bridge> + <syslog> + <!-- + <reverse/> + <enable/> + <remoteserver>xxx.xxx.xxx.xxx</remoteserver> + <filter/> + <dhcp/> + <system/> + <nologdefaultblock/> + --> + </syslog> + <!-- + <captiveportal> + <enable/> + <interface>lan|opt[n]</interface> + <idletimeout>minutes</idletimeout> + <timeout>minutes</timeout> + <page> + <htmltext></htmltext> + <errtext></errtext> + </page> + <httpslogin/> + <httpsname></httpsname> + <certificate></certificate> + <private-key></private-key> + <redirurl></redirurl> + <radiusip></radiusip> + <radiusport></radiusport> + <radiuskey></radiuskey> + <nomacfilter/> + </captiveportal> + --> + <nat> + <ipsecpassthru> + <enable/> + </ipsecpassthru> + <!-- + <rule> + <interface></interface> + <external-address></external-address> + <protocol></protocol> + <external-port></external-port> + <target></target> + <local-port></local-port> + <descr></descr> + </rule> + --> + <!-- + <onetoone> + <interface></interface> + <external>xxx.xxx.xxx.xxx</external> + <internal>xxx.xxx.xxx.xxx</internal> + <subnet></subnet> + <descr></descr> + </onetoone> + --> + <!-- + <advancedoutbound> + <enable/> + <rule> + <interface></interface> + <source> + <network>xxx.xxx.xxx.xxx/xx</network> + </source> + <destination> + <not/> + <any/> + *or* + <network>xxx.xxx.xxx.xxx/xx</network> + </destination> + <target>xxx.xxx.xxx.xxx</target> + <descr></descr> + </rule> + </advancedoutbound> + --> + <!-- + <servernat> + <ipaddr></ipaddr> + <descr></descr> + </servernat> + --> + </nat> + <filter> + <!-- <tcpidletimeout></tcpidletimeout> --> + <rule> + <type>pass</type> + <descr>Default LAN -> any</descr> + <interface>lan</interface> + <source> + <network>lan</network> + </source> + <destination> + <any/> + </destination> + </rule> + <!-- rule syntax: + <rule> + <disabled/> + <type>pass|block|reject</type> + <descr>...</descr> + <interface>lan|opt[n]|wan|pptp</interface> + <protocol>tcp|udp|tcp/udp|...</protocol> + <icmptype></icmptype> + <source> + <not/> + + <address>xxx.xxx.xxx.xxx(/xx) or alias</address> + *or* + <network>lan|opt[n]|pptp</network> + *or* + <any/> + + <port>a[-b]</port> + </source> + <destination> + *same as for source* + </destination> + <frags/> + <log/> + </rule> + --> + </filter> + <shaper> + <!-- <enable/> --> + <!-- <schedulertype>hfsc</schedulertype> --> + <!-- rule syntax: + <rule> + <disabled/> + <descr></descr> + + <targetpipe>number (zero based)</targetpipe> + *or* + <targetqueue>number (zero based)</targetqueue> + + <interface>lan|wan|opt[n]|pptp</interface> + <protocol>tcp|udp</protocol> + <direction>in|out</direction> + <source> + <not/> + + <address>xxx.xxx.xxx.xxx(/xx)</address> + *or* + <network>lan|opt[n]|pptp</network> + *or* + <any/> + + <port>a[-b]</port> + </source> + <destination> + *same as for source* + </destination> + + <iplen>from[-to]</iplen> + <iptos>(!)lowdelay,throughput,reliability,mincost,congestion</iptos> + <tcpflags>(!)fin,syn,rst,psh,ack,urg</tcpflags> + </rule> + <pipe> + <descr></descr> + <bandwidth></bandwidth> + <delay></delay> + <mask>source|destination</mask> + </pipe> + <queue> + <descr></descr> + <targetpipe>number (zero based)</targetpipe> + <weight></weight> + <mask>source|destination</mask> + </queue> + --> + </shaper> + <ipsec> + <preferredoldsa/> + <!-- <enable/> --> + <!-- syntax: + <tunnel> + <disabled/> + <auto/> + <descr></descr> + <interface>lan|wan|opt[n]</interface> + <local-subnet> + <address>xxx.xxx.xxx.xxx(/xx)</address> + *or* + <network>lan|opt[n]</network> + </local-subnet> + <remote-subnet>xxx.xxx.xxx.xxx/xx</remote-subnet> + <remote-gateway></remote-gateway> + <p1> + <mode></mode> + <myident> + <myaddress/> + *or* + <address>xxx.xxx.xxx.xxx</address> + *or* + <fqdn>the.fq.dn</fqdn> + </myident> + <encryption-algorithm></encryption-algorithm> + <hash-algorithm></hash-algorithm> + <dhgroup></dhgroup> + <lifetime></lifetime> + <pre-shared-key></pre-shared-key> + </p1> + <p2> + <protocol></protocol> + <encryption-algorithm-option></encryption-algorithm-option> + <hash-algorithm-option></hash-algorithm-option> + <pfsgroup></pfsgroup> + <lifetime></lifetime> + </p2> + </tunnel> + <mobileclients> + <enable/> + <p1> + <mode></mode> + <myident> + <myaddress/> + *or* + <address>xxx.xxx.xxx.xxx</address> + *or* + <fqdn>the.fq.dn</fqdn> + </myident> + <encryption-algorithm></encryption-algorithm> + <hash-algorithm></hash-algorithm> + <dhgroup></dhgroup> + <lifetime></lifetime> + </p1> + <p2> + <protocol></protocol> + <encryption-algorithm-option></encryption-algorithm-option> + <hash-algorithm-option></hash-algorithm-option> + <pfsgroup></pfsgroup> + <lifetime></lifetime> + </p2> + </mobileclients> + <mobilekey> + <ident></ident> + <pre-shared-key></pre-shared-key> + </mobilekey> + --> + </ipsec> + <aliases> + <!-- + <alias> + <name></name> + <address>xxx.xxx.xxx.xxx(/xx)</address> + <descr></descr> + </alias> + --> + </aliases> + <proxyarp> + <!-- + <proxyarpnet> + <network>xxx.xxx.xxx.xxx/xx</network> + *or* + <range> + <from>xxx.xxx.xxx.xxx</from> + <to>xxx.xxx.xxx.xxx</to> + </range> + </proxyarpnet> + --> + </proxyarp> + <wol> + <!-- + <wolentry> + <interface>lan|opt[n]</interface> + <mac>xx:xx:xx:xx:xx:xx</mac> + <descr></descr> + </wolentry> + --> + </wol> + <installedpackages> + <dspam> + <config> + <!-- ============================================ --> + <!-- == Database Settings == --> + <!-- ============================================ --> + <storage-driver>mysql</storage-driver> + <dbsettings> + <mysql-server>/tmp/mysql.sock</mysql-server> + <mysql-port /> + <mysql-user>dspam</mysql-user> + <mysql-password>dspam</mysql-password> + <mysql-database>dspam</mysql-database> + <mysql-ccache>10</mysql-ccache> + <mysql-compress>yes</mysql-compress> + <mysql-uid>yes</mysql-uid> + </dbsettings> + <!-- ============================================ --> + <!-- == Delivery Settings == --> + <!-- ============================================ --> + <tdelivery-agent>mail</tdelivery-agent> + <tcpip-delivery>yes</tcpip-delivery> + <tcpip-delivery-host>192.168.1.6</tcpip-delivery-host> + <tcpip-delivery-port>24</tcpip-delivery-port> + <tcpip-delivery-ident>localhost</tcpip-delivery-ident> + <tcpip-delivery-proto>smtp</tcpip-delivery-proto> + <delivery-onfail>error</delivery-onfail> + <!-- ============================================ --> + <!-- == DSPAM Privileges == --> + <!-- ============================================ --> + <tuser> + <name>root</name> + <descr>root desc</descr> + </tuser> + <tuser> + <name>mail</name> + <descr>mail desc</descr> + </tuser> + <tuser> + <name>mailnull</name> + <descr>mailnull desc</descr> + </tuser> + <tuser> + <name>smmsp</name> + <descr>smmsp desc</descr> + </tuser> + <tuser> + <name>daemon</name> + <descr>daemon desc</descr> + </tuser> + <!-- ============================================ --> + <!-- == DSPAM Engine Settings == --> + <!-- ============================================ --> + <training-mode>teft</training-mode> + <test-cond-training>yes</test-cond-training> + <feature> + <name>chained</name> + <descr>feat desc</descr> + </feature> + <feature> + <name>whitelist</name> + <descr>whitelist desc</descr> + </feature> + <algorithm> + <name>graham</name> + <descr>naive desc</descr> + </algorithm> + <algorithm> + <name>burton</name> + <descr>naive desc</descr> + </algorithm> + <pvalue>graham</pvalue> + <improbability-drive>yes</improbability-drive> + <preference> + <value>"spamAction=quarantine"</value> + <descr>desc</descr> + </preference> + <preference> + <value>"signatureLocation=message"</value> + <descr>'message' or 'headers'</descr> + </preference> + <preference> + <value>"showFactors=on"</value> + <descr>desc</descr> + </preference> + <override> + <value>trainingMode</value> + <descr>tmode desc</descr> + </override> + <override> + <value>spamAction spamSubject</value> + <descr>desc</descr> + </override> + <override> + <value>statisticalSedation</value> + <descr>desc</descr> + </override> + <override> + <value>enableBNR</value> + <descr>desc</descr> + </override> + <override> + <value>enableWhitelist</value> + <descr>desc</descr> + </override> + <override> + <value>signatureLocation</value> + <descr>desc</descr> + </override> + <override> + <value>showFactors</value> + <descr>desc</descr> + </override> + <override> + <value>optIn optOut</value> + <descr>desc</descr> + </override> + <override> + <value>whitelistThreshold</value> + <descr>desc</descr> + </override> + <!-- ============================================ --> + <!-- == Miscellaneous Settings == --> + <!-- ============================================ --> + <failover-attempts>1</failover-attempts> + <notification-email>yes</notification-email> + <dspam-contact>support</dspam-contact> + <!-- ============================================ --> + <!-- == Maintainance Settings == --> + <!-- ============================================ --> + <purge-signatures>14</purge-signatures> + <purge-neutral>90</purge-neutral> + <purge-unused>90</purge-unused> + <purge-hapaxes>30</purge-hapaxes> + <purge-hits-1s>15</purge-hits-1s> + <purge-hits-1i>15</purge-hits-1i> + <!-- ============================================ --> + <!-- == System Settings == --> + <!-- ============================================ --> + <local-mx>127.0.0.1</local-mx> + <system-log>yes</system-log> + <user-log>yes</user-log> + <filter-opt>out</filter-opt> + <parse-to-headers>yes</parse-to-headers> + <change-mode-on-parse>yes</change-mode-on-parse> + <max-message-size>307200</max-message-size> + <processor-bias>yes</processor-bias> + <!-- ============================================ --> + <!-- == ClamAV Engine Settings == --> + <!-- ============================================ --> + <clamav-enable>yes</clamav-enable> + <clamav-port>3310</clamav-port> + <clamav-host>127.0.0.1</clamav-host> + <clamav-response>accept</clamav-response> + <!-- ============================================ --> + <!-- == DSPAM Daemon Settings (Server) == --> + <!-- ============================================ --> + <dspam-server-port>24</dspam-server-port> + <dspam-server-queue-size>32</dspam-server-queue-size> + <dspam-server-pid>/var/run/dspam/dspam.pid</dspam-server-pid> + <dspam-server-mode>standard</dspam-server-mode> + <dspam-server-params>--deliver=innocent -d %u</dspam-server-params> + <dspam-server-id>abysseleven.abyssworld.de</dspam-server-id> + <dspam-server-socket>/var/run/dspam/dspam.sock</dspam-server-socket> + </config> + </dspam> + <package> + <name>dspam</name> + <website>http://dspam.nuclearelephant.com/</website> + <descr> + 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. + </descr> + <config_file>http://www.abyssworld.de/packages/config/dspam.xml</config_file> + <depends_on_package_base_url>http://www.abyssworld.de/packages/All/</depends_on_package_base_url> + <depends_on_package>dspam-devel-3.6.4.20060315.1518.tbz</depends_on_package> + <version>3.6.6</version> + <status>ALPHA</status> + <maintainer>me@daniel.stefan.haischt.name</maintainer> + <logging> + <facilityname>dspam</facilityname> + </logging> + </package> + <package> + <name>p3scan-pf</name> + <descr>A transparent POP3-Proxy with virus-scanning- and spam-scanning-capabilities.</descr> + <website>http://www.undergroundsecurity.com/p3scan/</website> + <category>Security</category> + <version>0.1</version> + <status>ALPHA</status> + <maintainer>fernando@netfilter.com.br</maintainer> + <depends_on_package_base_url>http://www.pfsense.com/packages/All/</depends_on_package_base_url> + <depends_on_package>p3scan-pf-2.3.2.tbz</depends_on_package> + <config_file>http://www.pfsense.org/packages/config/p3scan-pf/p3scan-pf.xml</config_file> + <configurationfile>p3scan-pf.xml</configurationfile> + </package> + <package> + <name>mysql</name> + <website>http://www.mysql.com/</website> + <descr> + MySQL RDBMS. + </descr> + <config_file>http://www.abyssworld.de/packages/config/mysql.xml</config_file> + <depends_on_package_base_url>http://www.abyssworld.de/packages/All/</depends_on_package_base_url> + <depends_on_package>mysql-server-5.0.21.tbz</depends_on_package> + <version>5.0.21</version> + <status>ALPHA</status> + <maintainer>me@daniel.stefan.haischt.name</maintainer> + <logging> + <facilityname>mysql</facilityname> + </logging> + </package> + <package> + <name>clamav</name> + <website>http://www.clamav.net/</website> + <descr> + Clam Antivirus. + </descr> + <config_file>http://www.abyssworld.de/packages/config/clamav.xml</config_file> + <depends_on_package_base_url>http://www.abyssworld.de/packages/All/</depends_on_package_base_url> + <depends_on_package>clamav-devel-20060503_1.tbz</depends_on_package> + <version>20060503_1</version> + <status>ALPHA</status> + <maintainer>me@daniel.stefan.haischt.name</maintainer> + <logging> + <facilityname>clamav</facilityname> + </logging> + </package> + <package> + <name>sshterm</name> + <descr> + 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. + </descr> + <website>http://sourceforge.net/projects/sshtools/</website> + <category>Security</category> + <version>0.1</version> + <status>ALPHA</status> + <maintainer>me@daniel.stefan.haischt.name</maintainer> + <depends_on_package_base_url>http://www.pfsense.com/packages/All/</depends_on_package_base_url> + <depends_on_package>sshtools-0.2.2.tbz</depends_on_package> + <config_file>http://www.pfsense.org/packages/config/sshterm/sshterm.xml</config_file> + <configurationfile>sshterm.xml</configurationfile> + </package> + <menu> + <name>POP3 Proxy</name> + <section>Services</section> + <configfile>p3scan-pf.xml</configfile> + <url>/pkg_edit.php?xml=p3scan-pf.xml&id=0</url> + <tooltiptext>A transparent POP3-Proxy with virus-scanning capabilities</tooltiptext> + </menu> + <menu> + <name>DSPAM</name> + <section>Services</section> + <configfile>dspam.inc</configfile> + <url>/dspam.php</url> + </menu> + <menu> + <name>DSPAM Wizard</name> + <section>Services</section> + <configfile>dspam.inc</configfile> + <url>/wizard.php?xml=dspam_wizard.xml</url> + </menu> + <menu> + <name>Shell</name> + <section>Diagnostics</section> + <configfile>sshterm.xml</configfile> + <url>/diag_shell.php</url> + </menu> + <service> + <name>dspam</name> + <description>DSPAM content-based spam filter</description> + <rcfile>dspam.sh</rcfile> + <executable>dspam</executable> + </service> + <service> + <name>clamd</name> + <description>Clam AntiVirus Scanner</description> + <rcfile>010.clamav-clamd.sh</rcfile> + <executable>clamd</executable> + </service> + <service> + <description>Deamon that receives new AntiVirus signatures</description> + <name>freshclam</name> + <rcfile>020.clamav-freshclam.sh</rcfile> + <executable>freshclam</executable> + </service> + <service> + <name>mysql</name> + <description>MySQL RDBMS</description> + <rcfile>000.mysql.sh</rcfile> + <executable>mysqld_safe</executable> + </service> + <service> + <name>p3scan-pf</name> + <description> + p3scan is a pop3 antivirus proxy that can be used completely transparently with any pop3 mail client. + </description> + <rcfile>030.p3scan.sh</rcfile> + <executable>p3scan</executable> + </service> + </installedpackages> + <cron> + <item> + <minute>0</minute> + <hour>*</hour> + <mday>*</mday> + <month>*</month> + <wday>*</wday> + <who>root</who> + <command>/usr/bin/nice -n20 newsyslog</command> + </item> + <item> + <minute>1,31</minute> + <hour>0-5</hour> + <mday>*</mday> + <month>*</month> + <wday>*</wday> + <who>root</who> + <command>/usr/bin/nice -n20 adjkerntz -a</command> + </item> + <item> + <minute>1</minute> + <hour>*</hour> + <mday>1</mday> + <month>*</month> + <wday>*</wday> + <who>root</who> + <command>/usr/bin/nice -n20 /etc/rc.update_bogons.sh</command> + </item> + <item> + <minute>*/60</minute> + <hour>*</hour> + <mday>*</mday> + <month>*</month> + <wday>*</wday> + <who>root</who> + <command>/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 sshlockout</command> + </item> + <item> + <minute>1</minute> + <hour>1</hour> + <mday>*</mday> + <month>*</month> + <wday>*</wday> + <who>root</who> + <command>/usr/bin/nice -n20 /etc/rc.dyndns.update</command> + </item> + <item> + <minute>*/5</minute> + <hour>*</hour> + <mday>*</mday> + <month>*</month> + <wday>*</wday> + <who>root</who> + <command>/usr/bin/nice -n20 /etc/ping_hosts.sh</command> + </item> + </cron> +</pfsense> diff --git a/config/dspam/pear/Image/Canvas.php b/config/dspam/pear/Image/Canvas.php new file mode 100644 index 00000000..e669807a --- /dev/null +++ b/config/dspam/pear/Image/Canvas.php @@ -0,0 +1,733 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Canvas + * + * Canvas based creation of images to facilitate different output formats + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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 "<pre>"; var_dump($params, $angle); print "</pre>"; + $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: + * + * <code> + * <?php + * $Canvas =& Image_Graph::factory('png', + * array('width' => 800, 'height' => 600, 'antialias' => 'native') + * ); + * ?> + * </code> + * + * @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/dspam/pear/Image/Canvas/Color.php b/config/dspam/pear/Image/Canvas/Color.php new file mode 100644 index 00000000..0ac78553 --- /dev/null +++ b/config/dspam/pear/Image/Canvas/Color.php @@ -0,0 +1,182 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2003 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stefan Neufeind <pear.neufeind@speedpartner.de> | +// +----------------------------------------------------------------------+ +// +// $Id$ + +/** +* Class for color-handling +* +* @author Stefan Neufeind <pear.neufeind@speedpartner.de> +* @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 <pear.neufeind@speedpartner.de> +* @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/dspam/pear/Image/Canvas/Fonts/README b/config/dspam/pear/Image/Canvas/Fonts/README new file mode 100644 index 00000000..0a836147 --- /dev/null +++ b/config/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/dspam/pear/Image/Canvas/Fonts/fontmap.txt b/config/dspam/pear/Image/Canvas/Fonts/fontmap.txt new file mode 100644 index 00000000..ccec67dd --- /dev/null +++ b/config/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/dspam/pear/Image/Canvas/GD.php b/config/dspam/pear/Image/Canvas/GD.php new file mode 100644 index 00000000..40132899 --- /dev/null +++ b/config/dspam/pear/Image/Canvas/GD.php @@ -0,0 +1,1693 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Canvas + * + * Class for handling output in GD compatible format. + * + * Supported formats are PNG, JPEG, GIF and WBMP. + * + * Requires PHP extension GD + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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 '<img src="' . $params['urlpath'] . $params['filename'] . '"' . + (isset($params['alt']) ? ' alt="' . $params['alt'] . '"' : '') . + (isset($params['cssclass']) ? ' class="' . $params['cssclass'] . '"' : '') . + (isset($params['border']) ? ' border="' . $params['border'] . '"' : '') . + (isset($this->_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("<td[^>]*>GD Version *<\/td><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/dspam/pear/Image/Canvas/GD/JPG.php b/config/dspam/pear/Image/Canvas/GD/JPG.php new file mode 100644 index 00000000..ef78aeca --- /dev/null +++ b/config/dspam/pear/Image/Canvas/GD/JPG.php @@ -0,0 +1,119 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Canvas + * + * Canvas class to handle JPEG format. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Canvas/GD/PNG.php b/config/dspam/pear/Image/Canvas/GD/PNG.php new file mode 100644 index 00000000..75184d8c --- /dev/null +++ b/config/dspam/pear/Image/Canvas/GD/PNG.php @@ -0,0 +1,125 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Canvas + * + * Canvas class to handle PNG format. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Canvas/ImageMap.php b/config/dspam/pear/Image/Canvas/ImageMap.php new file mode 100644 index 00000000..e69f3de2 --- /dev/null +++ b/config/dspam/pear/Image/Canvas/ImageMap.php @@ -0,0 +1,354 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Canvas + * + * Class for handling output as a HTML imagemap + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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[] = + '<area shape="' . $shape . '" coords="' . $coords . '" href="' . $url . '"' . + ($target ? ' target="' . $target . '"' : '') . + ($alt ? ' alt="' . $alt . '"' : '') . + (isset($params['id']) ? ' id="' . $params['id'] . '"' : '') . + $tags . + '>'; + } + } + + /** + * 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 '<map name="' . $params['name'] . '">' . "\n\t" . implode($this->_map, "\n\t") . "\n</map>"; + } + return ''; + } +} + +?>
\ No newline at end of file diff --git a/config/dspam/pear/Image/Canvas/PDF.php b/config/dspam/pear/Image/Canvas/PDF.php new file mode 100644 index 00000000..180263cb --- /dev/null +++ b/config/dspam/pear/Image/Canvas/PDF.php @@ -0,0 +1,1007 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class for handling output in PDF format. + * + * Requires PHP extension PDFlib + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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 '<a href="' . $params['urlpath'] . $params['filename'] . '">' . $params['title'] . '</a>'; + } + + /** + * 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("<td[^>]*>PDFlib GmbH Version *<\/td><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/dspam/pear/Image/Canvas/SVG.php b/config/dspam/pear/Image/Canvas/SVG.php new file mode 100644 index 00000000..3fed62ba --- /dev/null +++ b/config/dspam/pear/Image/Canvas/SVG.php @@ -0,0 +1,918 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class for handling output in SVG format. + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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 . '<a xlink:href="' . $url . '"' . ($target ? ' target="' . $target . '"' : '') . '>' . "\n" . + ' ' . $elementdata . + $this->_indent . '</a>' . "\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( + '<radialGradient id="' . $id . '" cx="' . + $cx .'" cy="' . $cy .'" r="' . $r .'" fx="' . + $fx .'" fy="' . $fy .'">' + ); + $this->_addDefine( + ' <stop offset="0%" style="stop-color:' . + $startColor. ';' . ($startOpacity ? 'stop-opacity:' . + $startOpacity . ';' : ''). '"/>' + ); + $this->_addDefine( + ' <stop offset="100%" style="stop-color:' . + $endColor. ';' . ($endOpacity ? 'stop-opacity:' . + $endOpacity . ';' : ''). '"/>' + ); + $this->_addDefine( + '</radialGradient>' + ); + } elseif (($fillStyle['direction'] == 'vertical_mirror') || + ($fillStyle['direction'] == 'horizontal_mirror')) + { + $this->_addDefine( + '<linearGradient id="' . $id . '" x1="' . + $x1 .'" y1="' . $y1 .'" x2="' . $x2 .'" y2="' . + $y2 .'">' + ); + $this->_addDefine( + ' <stop offset="0%" style="stop-color:' . + $startColor. ';' . ($startOpacity ? 'stop-opacity:' . + $startOpacity . ';' : ''). '"/>' + ); + $this->_addDefine( + ' <stop offset="50%" style="stop-color:' . + $endColor. ';' . ($endOpacity ? 'stop-opacity:' . + $endOpacity . ';' : ''). '"/>' + ); + $this->_addDefine( + ' <stop offset="100%" style="stop-color:' . + $startColor. ';' . ($startOpacity ? 'stop-opacity:' . + $startOpacity . ';' : ''). '"/>' + ); + $this->_addDefine( + '</linearGradient>' + ); + } else { + $this->_addDefine( + '<linearGradient id="' . $id . '" x1="' . + $x1 .'" y1="' . $y1 .'" x2="' . $x2 .'" y2="' . + $y2 .'">' + ); + $this->_addDefine( + ' <stop offset="0%" style="stop-color:' . + $startColor. ';' . ($startOpacity ? 'stop-opacity:' . + $startOpacity . ';' : ''). '"/>' + ); + $this->_addDefine( + ' <stop offset="100%" style="stop-color:' . + $endColor. ';' . ($endOpacity ? 'stop-opacity:' . + $endOpacity . ';' : ''). '"/>' + ); + $this->_addDefine( + '</linearGradient>' + ); + } + + 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<br> + * If 'type' = 'ttf' then the following can be specified<br> + * 'size' = size in pixels<br> + * '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( + '<line ' . + 'x1="' . round($x0) . '" ' . + 'y1="' . round($y0) . '" ' . + 'x2="' . round($x1) . '" ' . + 'y2="' . round($y1) . '" ' . + 'style="' . $style . '"' . + '/>', + $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( + '<path ' . + 'd="' . $points . '" ' . + 'style="' . $style . '"' . + '/>', + $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( + '<rect ' . + 'x="' . round($x0) . '" ' . + 'y="' . round($y0) . '" ' . + 'width="' . round(abs($x1 - $x0)) . '" ' . + 'height="' . round(abs($y1 - $y0)) . '" ' . + 'style="' . $style . '"' . + '/>', + $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( + '<ellipse ' . + 'cx="' . round($x) . '" ' . + 'cy="' . round($y) . '" ' . + 'rx="' . round($rx) . '" ' . + 'ry="' . round($ry) . '" ' . + 'style="' . $style . '"' . + '/>', + $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( + '<path d="' . + 'M' . round($x) . ',' . round($y) . ' ' . + 'L' . round($x1) . ',' . round($y1) . ' ' . + 'A' . round($rx) . ',' . round($ry) . ($dv > 180 ? ' 0 1,1 ' : ' 0 0,1 ') . + round($x2) . ',' . round($y2) . ' ' . + 'Z" ' . + 'style="' . $style . '"' . + '/>', + $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( + '<g transform="translate(' . round($x) . ', ' . round($y) . ')">' . "\n" . + $this->_indent . ' <text ' . + 'x="0" ' . + 'y="0" ' . + (isset($this->_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) . + '</text>' . "\n" . + $this->_indent . '</g>', + $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( + '<image xlink:href="' . $data . '" x="' . $x . '" y="' . $y . '"' . + ($width ? ' width="' . $width . '"' : '') . + ($height ? ' height="' . $height . '"' : '') . + ' preserveAspectRatio="none"/>', + $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('<g id="' . htmlspecialchars($name) . '">'); + $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('</g>'); + } + + /** + * Output the result of the canvas + * + * @param array $param Parameter array + */ + function show($param = false) + { + parent::show($param); + $output = '<?xml version="1.0" encoding="iso-8859-1"?>' . "\n" . + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"' . "\n\t" . + ' "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">' . "\n" . + '<svg width="' . $this->_width . '" height="' . $this->_height . + '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' . "\n" . + ($this->_defs ? + ' <defs>' . "\n" . + $this->_defs . + ' </defs>' . "\n" : + '' + ) . + $this->_elements . + '</svg>'; + + 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 = '<?xml version="1.0" encoding="iso-8859-1"?>' . "\n" . + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"' . "\n\t" . + ' "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">' . "\n" . + '<svg width="' . $this->_width . '" height="' . $this->_height . + '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' . "\n" . + ($this->_defs ? + ' <defs>' . "\n" . + $this->_defs . + ' </defs>' . "\n" : + '' + ) . + $this->_elements . + '</svg>'; + + $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('</g>'); + } + else { + $group = "clipping_" . $this->_id; + $this->_id++; + $this->_addElement('<g clip-path="url(#' . $group . ')">'); + + $this->_addDefine('<clipPath id="' . $group . '">'); + $this->_addDefine(' <path d="' . + 'M' . $this->_getX($params['x0']) . ' ' . $this->_getY($params['y0']) . + ' H' . $this->_getX($params['x1']) . + ' V' . $this->_getY($params['y1']) . + ' H' . $this->_getX($params['x0']) . + ' Z"/>'); + $this->_addDefine('</clipPath>'); + } + } + + /** + * 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 '<embed src="' . $params['urlpath'] . $params['filename'] . '" width=' . $params['width'] . ' height=' . $params['height'] . ' type="image/svg+xml">'; + } + +} + +?>
\ No newline at end of file diff --git a/config/dspam/pear/Image/Canvas/Tool.php b/config/dspam/pear/Image/Canvas/Tool.php new file mode 100644 index 00000000..3b87122c --- /dev/null +++ b/config/dspam/pear/Image/Canvas/Tool.php @@ -0,0 +1,217 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Canvas + * + * Canvas based creation of images to facilitate different output formats + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Canvas/WithMap.php b/config/dspam/pear/Image/Canvas/WithMap.php new file mode 100644 index 00000000..dc43ec4d --- /dev/null +++ b/config/dspam/pear/Image/Canvas/WithMap.php @@ -0,0 +1,278 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Canvas + * + * Canvas based creation of images to facilitate different output formats + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Canvas + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Color.php b/config/dspam/pear/Image/Color.php new file mode 100644 index 00000000..1b20125d --- /dev/null +++ b/config/dspam/pear/Image/Color.php @@ -0,0 +1,719 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Color.php is the implementation of Image_Color. + * + * PHP versions 4 and 5 + * + * LICENSE: This source file is subject to version 3.0 of the PHP license + * that is available through the world-wide-web at the following URI: + * http://www.php.net/license/3_0.txt. If you did not receive a copy of + * the PHP License and are unable to obtain it through the web, please + * send a note to license@php.net so we can mail you a copy immediately. + * + * @category Image + * @package Image_Color + * @author Jason Lotito <jason@lehighweb.com> + * @author Andrew Morton <drewish@katherinehouse.com> + * @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 <jason@lehighweb.com> + * @author Andrew Morton <drewish@katherinehouse.com> + * @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 <jason@lehighweb.com> + * @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 <jason@lehighweb.com> + */ + 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 <jason@lehighweb.com> + */ + 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 <jason@lehighweb.com> + * @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 <jason@lehighweb.com> + * @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 <jason@lehighweb.com> + */ + 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 <jason@lehighweb.com> + */ + 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 <jason@lehighweb.com> + */ + 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 <jason@lehighweb.com> + * @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 <jason@lehighweb.com> + * @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 <jason@lehighweb.com> + * @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 <jurgen@schwietering.com> + * @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 <pear@laurent-laville.org> + * @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 <sb@sebastian-bergmann.de> + */ + 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 <jason@lehighweb.com> + * @author Andrew Morton <drewish@katherinehouse.com> + * @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/dspam/pear/Image/Graph.php b/config/dspam/pear/Image/Graph.php new file mode 100644 index 00000000..d2e2492b --- /dev/null +++ b/config/dspam/pear/Image/Graph.php @@ -0,0 +1,851 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Axis.php b/config/dspam/pear/Image/Graph/Axis.php new file mode 100644 index 00000000..99da305f --- /dev/null +++ b/config/dspam/pear/Image/Graph/Axis.php @@ -0,0 +1,1690 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class for axis handling. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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: + * <ul> + * <li>IMAGE_GRAPH_AXIS_X / IMAGE_GRAPH_AXIS_HORIZONTAL + * <li>IMAGE_GRAPH_AXIS_Y / IMAGE_GRAPH_AXIS_VERTICAL / + * IMAGE_GRAPH_AXIS_Y_SECONDARY + * </ul> + * @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: + * <ul> + * <li>IMAGE_GRAPH_LABEL_MINIMUM + * <li>IMAGE_GRAPH_LABEL_ZERO + * <li>IMAGE_GRAPH_LABEL_MAXIMUM + * </ul> + * 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/dspam/pear/Image/Graph/Axis/Category.php b/config/dspam/pear/Image/Graph/Axis/Category.php new file mode 100644 index 00000000..b6451496 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Axis/Category.php @@ -0,0 +1,437 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class for axis handling. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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 + * + * <b>A minimum cannot be set on this type of axis</b> + * + * 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. <b>Note!</b> 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 + * + * <b>A maximum cannot be set on this type of axis</b> + * + * 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. <b>Note!</b> 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:<p> + * 1: (1, 2, 3, 4, 5, 6)<br> + * 2: (0, 1, 2, 3, 4, 5, 6, 7)<p> + * If they are not ordered, but simply appended, the categories on the axis + * would be:<p> + * X: (1, 2, 3, 4, 5, 6, 0, 7)<p> + * 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:<p> + * 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/dspam/pear/Image/Graph/Axis/Logarithmic.php b/config/dspam/pear/Image/Graph/Axis/Logarithmic.php new file mode 100644 index 00000000..2675ee4c --- /dev/null +++ b/config/dspam/pear/Image/Graph/Axis/Logarithmic.php @@ -0,0 +1,152 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class for axis handling. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Axis/Marker/Area.php b/config/dspam/pear/Image/Graph/Axis/Marker/Area.php new file mode 100644 index 00000000..1931ab48 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Axis/Marker/Area.php @@ -0,0 +1,156 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class file containing a axis marker used for explicitly highlighting a area + * on the graph, based on an interval specified on an axis. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Axis/Marker/Line.php b/config/dspam/pear/Image/Graph/Axis/Marker/Line.php new file mode 100644 index 00000000..0c46c144 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Axis/Marker/Line.php @@ -0,0 +1,124 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class file containing a axis marker used for explicitly highlighting a point + * (line) on the graph, based on an value specified on an axis. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Axis/Radar.php b/config/dspam/pear/Image/Graph/Axis/Radar.php new file mode 100644 index 00000000..7348254c --- /dev/null +++ b/config/dspam/pear/Image/Graph/Axis/Radar.php @@ -0,0 +1,204 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Class for axis handling. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Axis + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Common.php b/config/dspam/pear/Image/Graph/Common.php new file mode 100644 index 00000000..f695cb58 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Common.php @@ -0,0 +1,313 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Config.php b/config/dspam/pear/Image/Graph/Config.php new file mode 100644 index 00000000..ece8a91b --- /dev/null +++ b/config/dspam/pear/Image/Graph/Config.php @@ -0,0 +1,30 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Constants.php b/config/dspam/pear/Image/Graph/Constants.php new file mode 100644 index 00000000..f03674ba --- /dev/null +++ b/config/dspam/pear/Image/Graph/Constants.php @@ -0,0 +1,225 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor.php b/config/dspam/pear/Image/Graph/DataPreprocessor.php new file mode 100644 index 00000000..f135d539 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor.php @@ -0,0 +1,74 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor/Array.php b/config/dspam/pear/Image/Graph/DataPreprocessor/Array.php new file mode 100644 index 00000000..08e62378 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/Array.php @@ -0,0 +1,103 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor/Currency.php b/config/dspam/pear/Image/Graph/DataPreprocessor/Currency.php new file mode 100644 index 00000000..2d3b5e2f --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/Currency.php @@ -0,0 +1,66 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor/Date.php b/config/dspam/pear/Image/Graph/DataPreprocessor/Date.php new file mode 100644 index 00000000..74695264 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/Date.php @@ -0,0 +1,90 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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 <a href = 'http://www.php.net/manual/en/function.date.php'>PHP + * Manual</a> 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/dspam/pear/Image/Graph/DataPreprocessor/Formatted.php b/config/dspam/pear/Image/Graph/DataPreprocessor/Formatted.php new file mode 100644 index 00000000..ff7335a0 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/Formatted.php @@ -0,0 +1,90 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor/Function.php b/config/dspam/pear/Image/Graph/DataPreprocessor/Function.php new file mode 100644 index 00000000..b23a718d --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/Function.php @@ -0,0 +1,92 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor/NumberText.php b/config/dspam/pear/Image/Graph/DataPreprocessor/NumberText.php new file mode 100644 index 00000000..a7d6874e --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/NumberText.php @@ -0,0 +1,89 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor/RomanNumerals.php b/config/dspam/pear/Image/Graph/DataPreprocessor/RomanNumerals.php new file mode 100644 index 00000000..0bfcdb62 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/RomanNumerals.php @@ -0,0 +1,79 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataPreprocessor/Sequential.php b/config/dspam/pear/Image/Graph/DataPreprocessor/Sequential.php new file mode 100644 index 00000000..248f0be9 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataPreprocessor/Sequential.php @@ -0,0 +1,67 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataPreprocessor + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataSelector.php b/config/dspam/pear/Image/Graph/DataSelector.php new file mode 100644 index 00000000..0a81716c --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataSelector.php @@ -0,0 +1,67 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataSelector/EveryNthPoint.php b/config/dspam/pear/Image/Graph/DataSelector/EveryNthPoint.php new file mode 100644 index 00000000..62581222 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataSelector/EveryNthPoint.php @@ -0,0 +1,97 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataSelector/NoZeros.php b/config/dspam/pear/Image/Graph/DataSelector/NoZeros.php new file mode 100644 index 00000000..f32b918e --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataSelector/NoZeros.php @@ -0,0 +1,68 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/DataSelector/Values.php b/config/dspam/pear/Image/Graph/DataSelector/Values.php new file mode 100644 index 00000000..412e6ea9 --- /dev/null +++ b/config/dspam/pear/Image/Graph/DataSelector/Values.php @@ -0,0 +1,90 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage DataSelector + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Dataset.php b/config/dspam/pear/Image/Graph/Dataset.php new file mode 100644 index 00000000..4c349980 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Dataset.php @@ -0,0 +1,483 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Dataset/Function.php b/config/dspam/pear/Image/Graph/Dataset/Function.php new file mode 100644 index 00000000..08174b1d --- /dev/null +++ b/config/dspam/pear/Image/Graph/Dataset/Function.php @@ -0,0 +1,147 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Dataset/Random.php b/config/dspam/pear/Image/Graph/Dataset/Random.php new file mode 100644 index 00000000..0b2d7c68 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Dataset/Random.php @@ -0,0 +1,77 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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</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/dspam/pear/Image/Graph/Dataset/Sequential.php b/config/dspam/pear/Image/Graph/Dataset/Sequential.php new file mode 100644 index 00000000..2605c409 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Dataset/Sequential.php @@ -0,0 +1,114 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Dataset/Trivial.php b/config/dspam/pear/Image/Graph/Dataset/Trivial.php new file mode 100644 index 00000000..84af1c4b --- /dev/null +++ b/config/dspam/pear/Image/Graph/Dataset/Trivial.php @@ -0,0 +1,260 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Dataset/VectorFunction.php b/config/dspam/pear/Image/Graph/Dataset/VectorFunction.php new file mode 100644 index 00000000..4250bbc0 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Dataset/VectorFunction.php @@ -0,0 +1,185 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Dataset + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Element.php b/config/dspam/pear/Image/Graph/Element.php new file mode 100644 index 00000000..7c352ee5 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Element.php @@ -0,0 +1,763 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Figure/Circle.php b/config/dspam/pear/Image/Graph/Figure/Circle.php new file mode 100644 index 00000000..a3f1652e --- /dev/null +++ b/config/dspam/pear/Image/Graph/Figure/Circle.php @@ -0,0 +1,64 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Figure/Ellipse.php b/config/dspam/pear/Image/Graph/Figure/Ellipse.php new file mode 100644 index 00000000..8e42f2b1 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Figure/Ellipse.php @@ -0,0 +1,97 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Figure/Polygon.php b/config/dspam/pear/Image/Graph/Figure/Polygon.php new file mode 100644 index 00000000..5b78f635 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Figure/Polygon.php @@ -0,0 +1,94 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Figure/Rectangle.php b/config/dspam/pear/Image/Graph/Figure/Rectangle.php new file mode 100644 index 00000000..dbca58e0 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Figure/Rectangle.php @@ -0,0 +1,96 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Figure + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Fill.php b/config/dspam/pear/Image/Graph/Fill.php new file mode 100644 index 00000000..f1cd36d7 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Fill.php @@ -0,0 +1,63 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Fill/Array.php b/config/dspam/pear/Image/Graph/Fill/Array.php new file mode 100644 index 00000000..8d0b2dfa --- /dev/null +++ b/config/dspam/pear/Image/Graph/Fill/Array.php @@ -0,0 +1,137 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Fill/Gradient.php b/config/dspam/pear/Image/Graph/Fill/Gradient.php new file mode 100644 index 00000000..9cf23a6b --- /dev/null +++ b/config/dspam/pear/Image/Graph/Fill/Gradient.php @@ -0,0 +1,149 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Fill/Image.php b/config/dspam/pear/Image/Graph/Fill/Image.php new file mode 100644 index 00000000..9b1fb142 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Fill/Image.php @@ -0,0 +1,97 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Fill + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Font.php b/config/dspam/pear/Image/Graph/Font.php new file mode 100644 index 00000000..ad018a27 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Font.php @@ -0,0 +1,158 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Text + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Grid.php b/config/dspam/pear/Image/Graph/Grid.php new file mode 100644 index 00000000..4406dbdd --- /dev/null +++ b/config/dspam/pear/Image/Graph/Grid.php @@ -0,0 +1,175 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Grid/Bars.php b/config/dspam/pear/Image/Graph/Grid/Bars.php new file mode 100644 index 00000000..a75782f2 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Grid/Bars.php @@ -0,0 +1,117 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Grid/Lines.php b/config/dspam/pear/Image/Graph/Grid/Lines.php new file mode 100644 index 00000000..805778ee --- /dev/null +++ b/config/dspam/pear/Image/Graph/Grid/Lines.php @@ -0,0 +1,114 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Grid/Polar.php b/config/dspam/pear/Image/Graph/Grid/Polar.php new file mode 100644 index 00000000..03b1b916 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Grid/Polar.php @@ -0,0 +1,111 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Grid + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Images/Icons/pinpoint.png b/config/dspam/pear/Image/Graph/Images/Icons/pinpoint.png Binary files differnew file mode 100644 index 00000000..d23f0b7d --- /dev/null +++ b/config/dspam/pear/Image/Graph/Images/Icons/pinpoint.png diff --git a/config/dspam/pear/Image/Graph/Images/Icons/pinpointr.png b/config/dspam/pear/Image/Graph/Images/Icons/pinpointr.png Binary files differnew file mode 100644 index 00000000..2455e09b --- /dev/null +++ b/config/dspam/pear/Image/Graph/Images/Icons/pinpointr.png diff --git a/config/dspam/pear/Image/Graph/Images/Maps/README b/config/dspam/pear/Image/Graph/Images/Maps/README new file mode 100644 index 00000000..1b984bbb --- /dev/null +++ b/config/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/dspam/pear/Image/Graph/Layout.php b/config/dspam/pear/Image/Graph/Layout.php new file mode 100644 index 00000000..1561aafa --- /dev/null +++ b/config/dspam/pear/Image/Graph/Layout.php @@ -0,0 +1,219 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Layout/Horizontal.php b/config/dspam/pear/Image/Graph/Layout/Horizontal.php new file mode 100644 index 00000000..414a168c --- /dev/null +++ b/config/dspam/pear/Image/Graph/Layout/Horizontal.php @@ -0,0 +1,186 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Layout/Matrix.php b/config/dspam/pear/Image/Graph/Layout/Matrix.php new file mode 100644 index 00000000..8acec871 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Layout/Matrix.php @@ -0,0 +1,201 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Layout/Vertical.php b/config/dspam/pear/Image/Graph/Layout/Vertical.php new file mode 100644 index 00000000..2dc6f945 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Layout/Vertical.php @@ -0,0 +1,108 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Layout + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Legend.php b/config/dspam/pear/Image/Graph/Legend.php new file mode 100644 index 00000000..d853dad5 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Legend.php @@ -0,0 +1,385 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Legend + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Line/Array.php b/config/dspam/pear/Image/Graph/Line/Array.php new file mode 100644 index 00000000..5d542141 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Line/Array.php @@ -0,0 +1,129 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Line/Dashed.php b/config/dspam/pear/Image/Graph/Line/Dashed.php new file mode 100644 index 00000000..448fb218 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Line/Dashed.php @@ -0,0 +1,76 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Line/Dotted.php b/config/dspam/pear/Image/Graph/Line/Dotted.php new file mode 100644 index 00000000..8574f8da --- /dev/null +++ b/config/dspam/pear/Image/Graph/Line/Dotted.php @@ -0,0 +1,67 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Line/Formatted.php b/config/dspam/pear/Image/Graph/Line/Formatted.php new file mode 100644 index 00000000..e6d0181b --- /dev/null +++ b/config/dspam/pear/Image/Graph/Line/Formatted.php @@ -0,0 +1,90 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Line/Solid.php b/config/dspam/pear/Image/Graph/Line/Solid.php new file mode 100644 index 00000000..e77e62f1 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Line/Solid.php @@ -0,0 +1,105 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Line + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Logo.php b/config/dspam/pear/Image/Graph/Logo.php new file mode 100644 index 00000000..df5fe7e4 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Logo.php @@ -0,0 +1,153 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Logo + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker.php b/config/dspam/pear/Image/Graph/Marker.php new file mode 100644 index 00000000..1c1926fe --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker.php @@ -0,0 +1,123 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Array.php b/config/dspam/pear/Image/Graph/Marker/Array.php new file mode 100644 index 00000000..12fed66c --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Array.php @@ -0,0 +1,105 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Asterisk.php b/config/dspam/pear/Image/Graph/Marker/Asterisk.php new file mode 100644 index 00000000..effde5a5 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Asterisk.php @@ -0,0 +1,109 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Average.php b/config/dspam/pear/Image/Graph/Marker/Average.php new file mode 100644 index 00000000..c4e3e7a4 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Average.php @@ -0,0 +1,91 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Box.php b/config/dspam/pear/Image/Graph/Marker/Box.php new file mode 100644 index 00000000..5602c33d --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Box.php @@ -0,0 +1,76 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Bubble.php b/config/dspam/pear/Image/Graph/Marker/Bubble.php new file mode 100644 index 00000000..180ab4e3 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Bubble.php @@ -0,0 +1,91 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Circle.php b/config/dspam/pear/Image/Graph/Marker/Circle.php new file mode 100644 index 00000000..7eeb5cb6 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Circle.php @@ -0,0 +1,96 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Cross.php b/config/dspam/pear/Image/Graph/Marker/Cross.php new file mode 100644 index 00000000..720f3bb4 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Cross.php @@ -0,0 +1,114 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Diamond.php b/config/dspam/pear/Image/Graph/Marker/Diamond.php new file mode 100644 index 00000000..2a3d68c8 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Diamond.php @@ -0,0 +1,73 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Icon.php b/config/dspam/pear/Image/Graph/Marker/Icon.php new file mode 100644 index 00000000..d9b9456f --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Icon.php @@ -0,0 +1,133 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Pinpoint.php b/config/dspam/pear/Image/Graph/Marker/Pinpoint.php new file mode 100644 index 00000000..7b87f153 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Pinpoint.php @@ -0,0 +1,65 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Plus.php b/config/dspam/pear/Image/Graph/Marker/Plus.php new file mode 100644 index 00000000..0a817cfc --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Plus.php @@ -0,0 +1,98 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Pointing.php b/config/dspam/pear/Image/Graph/Marker/Pointing.php new file mode 100644 index 00000000..05ab94e4 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Pointing.php @@ -0,0 +1,140 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Pointing/Angular.php b/config/dspam/pear/Image/Graph/Marker/Pointing/Angular.php new file mode 100644 index 00000000..93b8b7cf --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Pointing/Angular.php @@ -0,0 +1,105 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Pointing/Radial.php b/config/dspam/pear/Image/Graph/Marker/Pointing/Radial.php new file mode 100644 index 00000000..ce1a0aac --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Pointing/Radial.php @@ -0,0 +1,91 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/ReversePinpoint.php b/config/dspam/pear/Image/Graph/Marker/ReversePinpoint.php new file mode 100644 index 00000000..57e945ab --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/ReversePinpoint.php @@ -0,0 +1,65 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Star.php b/config/dspam/pear/Image/Graph/Marker/Star.php new file mode 100644 index 00000000..67b2b9b3 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Star.php @@ -0,0 +1,88 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Triangle.php b/config/dspam/pear/Image/Graph/Marker/Triangle.php new file mode 100644 index 00000000..626f2589 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Triangle.php @@ -0,0 +1,75 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Marker/Value.php b/config/dspam/pear/Image/Graph/Marker/Value.php new file mode 100644 index 00000000..24f142f3 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Marker/Value.php @@ -0,0 +1,214 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Marker + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot.php b/config/dspam/pear/Image/Graph/Plot.php new file mode 100644 index 00000000..4a6c16d3 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot.php @@ -0,0 +1,824 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Area.php b/config/dspam/pear/Image/Graph/Plot/Area.php new file mode 100644 index 00000000..a5288e1a --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Area.php @@ -0,0 +1,194 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Band.php b/config/dspam/pear/Image/Graph/Plot/Band.php new file mode 100644 index 00000000..3d5b629a --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Band.php @@ -0,0 +1,205 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Bar.php b/config/dspam/pear/Image/Graph/Plot/Bar.php new file mode 100644 index 00000000..3e35f92c --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Bar.php @@ -0,0 +1,307 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/BoxWhisker.php b/config/dspam/pear/Image/Graph/Plot/BoxWhisker.php new file mode 100644 index 00000000..59c1ee44 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/BoxWhisker.php @@ -0,0 +1,298 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/CandleStick.php b/config/dspam/pear/Image/Graph/Plot/CandleStick.php new file mode 100644 index 00000000..b050aea1 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/CandleStick.php @@ -0,0 +1,251 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Dot.php b/config/dspam/pear/Image/Graph/Plot/Dot.php new file mode 100644 index 00000000..19352567 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Dot.php @@ -0,0 +1,99 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Fit/Line.php b/config/dspam/pear/Image/Graph/Plot/Fit/Line.php new file mode 100644 index 00000000..07f3b9cc --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Fit/Line.php @@ -0,0 +1,118 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Impulse.php b/config/dspam/pear/Image/Graph/Plot/Impulse.php new file mode 100644 index 00000000..91372cd1 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Impulse.php @@ -0,0 +1,204 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Line.php b/config/dspam/pear/Image/Graph/Plot/Line.php new file mode 100644 index 00000000..009b4e1f --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Line.php @@ -0,0 +1,171 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Odo.php b/config/dspam/pear/Image/Graph/Plot/Odo.php new file mode 100644 index 00000000..d6bf7969 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Odo.php @@ -0,0 +1,719 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <mdelorme@tennaxia.com> + * @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/dspam/pear/Image/Graph/Plot/Pie.php b/config/dspam/pear/Image/Graph/Plot/Pie.php new file mode 100644 index 00000000..f0e872c3 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Pie.php @@ -0,0 +1,623 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Radar.php b/config/dspam/pear/Image/Graph/Plot/Radar.php new file mode 100644 index 00000000..1bfd9da7 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Radar.php @@ -0,0 +1,118 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Smoothed/Area.php b/config/dspam/pear/Image/Graph/Plot/Smoothed/Area.php new file mode 100644 index 00000000..8ea469dd --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Smoothed/Area.php @@ -0,0 +1,145 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php b/config/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php new file mode 100644 index 00000000..bc21b4c8 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php @@ -0,0 +1,173 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Smoothed/Line.php b/config/dspam/pear/Image/Graph/Plot/Smoothed/Line.php new file mode 100644 index 00000000..00692839 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Smoothed/Line.php @@ -0,0 +1,172 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php b/config/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php new file mode 100644 index 00000000..d505a11f --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php @@ -0,0 +1,142 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plot/Step.php b/config/dspam/pear/Image/Graph/Plot/Step.php new file mode 100644 index 00000000..bc9267fe --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plot/Step.php @@ -0,0 +1,200 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plotarea.php b/config/dspam/pear/Image/Graph/Plotarea.php new file mode 100644 index 00000000..42aeb26a --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plotarea.php @@ -0,0 +1,1145 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plotarea + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plotarea/Element.php b/config/dspam/pear/Image/Graph/Plotarea/Element.php new file mode 100644 index 00000000..a7d1b8d2 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plotarea/Element.php @@ -0,0 +1,87 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plotarea/Map.php b/config/dspam/pear/Image/Graph/Plotarea/Map.php new file mode 100644 index 00000000..888d3384 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plotarea/Map.php @@ -0,0 +1,304 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plotarea + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Plotarea/Radar.php b/config/dspam/pear/Image/Graph/Plotarea/Radar.php new file mode 100644 index 00000000..cfb200ea --- /dev/null +++ b/config/dspam/pear/Image/Graph/Plotarea/Radar.php @@ -0,0 +1,243 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - PEAR PHP OO Graph Rendering Utility. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Plotarea + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Simple.php b/config/dspam/pear/Image/Graph/Simple.php new file mode 100644 index 00000000..9d14c4da --- /dev/null +++ b/config/dspam/pear/Image/Graph/Simple.php @@ -0,0 +1,121 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Title.php b/config/dspam/pear/Image/Graph/Title.php new file mode 100644 index 00000000..2cffe5f3 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Title.php @@ -0,0 +1,194 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @subpackage Text + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pear/Image/Graph/Tool.php b/config/dspam/pear/Image/Graph/Tool.php new file mode 100644 index 00000000..cf245685 --- /dev/null +++ b/config/dspam/pear/Image/Graph/Tool.php @@ -0,0 +1,291 @@ +<?php + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Image_Graph - Main class for the graph creation. + * + * PHP versions 4 and 5 + * + * LICENSE: This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. This library is distributed in the hope that it + * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser + * General Public License for more details. You should have received a copy of + * the GNU Lesser General Public License along with this library; if not, write + * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * @category Images + * @package Image_Graph + * @author Jesper Veggerby <pear.nosey@veggerby.dk> + * @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 <pear.nosey@veggerby.dk> + * @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/dspam/pkg/000.mysql.sh b/config/dspam/pkg/000.mysql.sh new file mode 100644 index 00000000..9c25c370 --- /dev/null +++ b/config/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 <start|stop|restart>" + ;; +esac diff --git a/config/dspam/pkg/010.clamav-clamd.sh b/config/dspam/pkg/010.clamav-clamd.sh new file mode 100644 index 00000000..aeb23b04 --- /dev/null +++ b/config/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 <start|stop|restart>" + ;; +esac diff --git a/config/dspam/pkg/020.clamav-freshclam.sh b/config/dspam/pkg/020.clamav-freshclam.sh new file mode 100644 index 00000000..4332d757 --- /dev/null +++ b/config/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 <start|stop|restart>" + ;; +esac diff --git a/config/dspam/pkg/030.p3scan.sh b/config/dspam/pkg/030.p3scan.sh new file mode 100644 index 00000000..ffd08abf --- /dev/null +++ b/config/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 <start|stop|restart>" + ;; +esac diff --git a/config/dspam/pkg/clamd.conf b/config/dspam/pkg/clamd.conf new file mode 100644 index 00000000..3ce0402f --- /dev/null +++ b/config/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/dspam/pkg/default.prefs.sample b/config/dspam/pkg/default.prefs.sample new file mode 100644 index 00000000..d9be27ed --- /dev/null +++ b/config/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/dspam/pkg/dspam-config.inc b/config/dspam/pkg/dspam-config.inc new file mode 100644 index 00000000..211bee51 --- /dev/null +++ b/config/dspam/pkg/dspam-config.inc @@ -0,0 +1,42 @@ +<?php +/* $Id$ */ +/* Copyright (C) 2006 Daniel S. Haischt */ + +$CONFIG = array('DSPAM_HOME' => '/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/dspam/pkg/dspam-guifunc.inc b/config/dspam/pkg/dspam-guifunc.inc new file mode 100644 index 00000000..121bc8b5 --- /dev/null +++ b/config/dspam/pkg/dspam-guifunc.inc @@ -0,0 +1,2606 @@ +<?php +/* $Id$ */ +/* Copyright (C) 2006 Daniel S. Haischt */ +require_once("functions.inc"); +require_once("dspam.inc"); + +/* ========================================================================== */ +/* = A D M I N S T A T U S F U N C T I O N S = */ +/* ========================================================================== */ + +function DisplayAdminPreferences(&$statusmsg) { + return DisplayPreferences("admin", $statusmsg); +} + +function DisplayUserStatistics() { + global $CONFIG, $DATA; + $b = "rowEven"; + + $sl_total = 0; + $il_total = 0; + $sm_total = 0; + $fp_total = 0; + $sc_total = 0; + $ic_total = 0; + $mailbox_total = 0; + + $pd = popen("{$CONFIG['DSPAM_STATS']} 2>&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'] .= "<tr><td class=\"{$b}\"><a href=\"{$CONFIG['DSPAM_CGI']}?user={$username}\">{$username}</A></td>" . + " <td class=\"{$b} rowDivider\" align=\"right\" nowrap=\"nowrap\">{$mailbox_display}</td>" . + " <td class=\"{$b} rowDivider\">{$sl}</td>" . + " <td class=\"{$b}\">{$il}</td>" . + " <td class=\"{$b}\">{$fp}</td>" . + " <td class=\"{$b}\">{$sm}</td>" . + " <td class=\"{$b}\">{$sc}</td>" . + " <td class=\"{$b}\">{$ic}</td>" . + " <td class=\"{$b} rowDivider\">{$PREFS['trainingMode']}</td>" . + " <td class=\"{$b}\">{$PREFS['spamAction']}</td>" . + " <td class=\"{$b}\">{$PREFS['enableBNR']}</td>" . + " <td class=\"{$b}\">{$PREFS['enableWhitelist']}</td>" . + " <td class=\"{$b}\">{$PREFS['statisticalSedation']}</td>" . + " <td class=\"{$b}\">{$PREFS['signatureLocation']}</td>" . + "</tr>\n"; + } + pclose($pd); + + $mailbox_total_display = sprintf("%2.1f KB", ($mailbox_total / 1024)); + + $b = "listhdrr"; + $DATA['TABLE'] .= "<tr><td class=\"{$b}\">Total</td>". + " <td class=\"{$b} rowDivider\" align=\"right\" nowrap=\"nowrap\">{$mailbox_total_display}</td>". + " <td class=\"{$b} rowDivider\">{$sl_total}</td>". + " <td class=\"{$b}\">{$il_total}</td>". + " <td class=\"{$b}\">{$sm_total}</td>". + " <td class=\"{$b}\">{$fp_total}</td>". + " <td class=\"{$b}\">{$sc_total}</td>". + " <td class=\"{$b}\">{$ic_total}</td>". + " <td class=\"{$b} rowDivider\"> </td>". + " <td class=\"{$b}\"> </td>". + " <td class=\"{$b}\"> </td>". + " <td class=\"{$b}\"> </td>". + " <td class=\"{$b}\"> </td>". + " <td class=\"{$b}\"> </td>". + "</tr>\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", "'<'", fgets($fd, 4096)); + $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 <TAB>, 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 == "<None Specified>") { $from = $rec[$messageid]['from']; } + if ($subject == "<None Specified>") { $subject = $rec[$messageid]['subject']; } + + + if ($rec[$messageid]['from'] == "") { $rec[$messageid]['from'] = $from; } + if ($rec[$messageid]['subject'] == "") { $rec[$messageid]['subject'] = $subject; } + } + + if ($from == "") { $from = "<None Specified>"; } + if ($subject == "") { $subject = "<None Specified>"; } + + $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); + $from = preg_replace("/>/e", "'>'", $from); + $subject = preg_replace('/</e', "'<'", $subject); + $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 = "<b>Retrained</b>"; + } + + if ($retrain == "") { + $retrain = "<A HREF=\"/dspam-history.php?page={$currentPage}&hperpage={$hPerPage}&user={$username}&retrain={$rclass}&signatureID={$signature}\">As " . ucfirst($rclass) . "</A>"; + } else { + $retrain .= "(<A HREF=\"/dspam-history.php?page={$currentPage}&hperpage={$hPerPage}&user={$username}&retrain={$rclass}&signatureID={$signature}\">Undo</A>)"; + } + + $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 = "<a href=\"javascript:openwin(580,400,1,'/dspam-hfragment.php?{$url}')\">{$from}</a>"; + } + + $entry = <<<EOD + <tr> + <td align="left" valign="top" class="{$rowclass} {$cl}" nowrap="true"><small>{$cllabel}</small></td> + <td align="left" valign="top" class="{$rowclass}" nowrap="true"> + <small> + <input class="formfld" name="msgid{$retrain_checked_msg_no}" id="msgid{$retrain_checked_msg_no}" title="Check/Uncheck" type="checkbox" value="{$rclass}:{$signature}"> + <label for="msgid{$retrain_checked_msg_no}">{$retrain}</label> + </small> + </td> + <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$ctime}</small></td> + <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$from}</small></td> + <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$subject}</small></td> + <td align="left" valign="top" class="{$rowclass}" nowrap="true"><small>{$info}</small></td> + </tr> + +EOD; + + $retrain_checked_msg_no++; + array_push($history, $entry); + + if ($rowclass == "qrowEven") { + $rowclass = "qrowOdd"; + } else { + $rowclass = "qrowEven"; + } + $hurtz++; + } // end while + + $entry = <<<EOD + <input name="history_page" type="hidden" value="{$history_page}"> + +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 + <tr> + <td align="right" valign="middle" class="listtopic" colspan="6"> + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="First Page (1)"><a href="/dspam-history.php?page=1&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="First Page (1)">|<</a></span> + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$previousPage}"><a href="/dspam-history.php?page={$previousPage}&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="Page {$previousPage}"><</a></span> + +EOD; + + $historyFooterEnd = <<<EOD + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$nextPage}"><a href="/dspam-history.php?page={$nextPage}&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="Page {$nextPage}">></a></span> + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Last Page ({$pages})"><a href="/dspam-history.php?page={$pages}&qperpage={$CONFIG['HISTORY_PER_PAGE']}" title="Last Page ({$pages})">>|</a></span> + </td> + </tr> + +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 .= "<span class=\"qnavbtnhl\">{$i}</span> \n"; + } else { + $historyFooter .= "<span class=\"qnavbtn\" onmouseover=\"this.style.backgroundColor='#A5B9E1;'\" onmouseout=\"this.style.backgroundColor='#507DCD;'\" title=\"Page {$i}\"><a href=\"/dspam-history.php?page={$i}&hperpage={$CONFIG['HISTORY_PER_PAGE']}\" title=\"Page {$i}\">{$i}</a></span> \n"; + } + } + } + } + } + + $DATA['HISTORY_FOOTER'] = $historyFooterBegin . $historyFooter .$historyFooterEnd; + $DATA['HPAGES'] = $pages; + $DATA['HPAGE'] = $currentPage; + +/* + $DATA['HISTORY'] .= "<tr><td align=\"left\" valign=\"top\" colspan=\"6\"><center>["; + if (($history_pages > 1) && ($history_page > 1)) { + $i = $history_page - 1; + $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\"> < </a>"; + } + for($i = 1; $i <= $history_pages; $i++) { + if ($i == $history_page) { + $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\"><big><strong> $i </strong></big></a>"; + } else { + $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\"> {$i} </a>"; + } + } + if (($history_pages > 1) && ($history_page < $history_pages)) { + $i = $history_page + 1; + $DATA['HISTORY'] .= "<a href=\"/dspam-history.php?user={$username}&history_page={$i}\"> > </a>"; + } + $DATA['HISTORY'] .= "]</center></td></tr>"; +*/ + } // 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 = <<<EOD +trainingMode={$pconfig['rad_train']} +spamAction={$pconfig['rad_ident_action']} +spamSubject={$pconfig['msgtag']} +statisticalSedation={$pconfig['rad_filter_sens']} +enableBNR={$pconfig['chk_feature_nr']} +optIn={$pconfig['chk_feature_optin']} +optOut={$pconfig['chk_feature_optout']} +showFactors={$pconfig['chk_feature_at']} +enableWhitelist={$pconfig['chk_feature_aw']} +signatureLocation={$pconfig['rad_train_action']} + +EOD; + + if ($fd = @fopen("{$FILE}","w")) { + fwrite($fd, $prefsstr); + fclose($fd); + } else { + return $input_errors[] = "Unable to write preferences to file: {$FILE}"; + } + } + + $statusmsg = "DSPAM preferences have been written to: {$FILE}."; + } + + $PREFS =& GetPrefs($username); + + $DATA["SEDATION_{$PREFS['statisticalSedation']}"] = 'checked="checked"'; + $DATA["S_{$PREFS['trainingMode']}"] = 'checked="checked"'; + $DATA["S_ACTION_" . strtoupper($PREFS['spamAction'])] = 'checked="checked"'; + $DATA["S_LOC_" . strtoupper($PREFS['signatureLocation'])] = 'checked="checked"'; + $DATA["SPAM_SUBJECT"] = $PREFS['spamSubject']; + if ($PREFS['optIn'] == "on") { + $DATA['C_OPTIN'] = 'checked="checked"'; + } + if ($PREFS['optOut'] == "on") { + $DATA['C_OPTOUT'] = 'checked="checked"'; + } + if ($PREFS['enableBNR'] == "on") { + $DATA['C_BNR'] = 'checked="checked"'; + } + if ($PREFS['showFactors'] == "on") { + $DATA['C_FACTORS'] = 'checked="checked"'; + } + if ($PREFS['enableWhitelist'] == "on") { + $DATA['C_WHITELIST'] = 'checked="checked"'; + } +} + +function sortByRating($a, $b){ + if ($a['rating'] == $b['rating']) { + return 0; + } + + return ($a['rating'] < $b['rating']) ? -1 : 1; +} + +/* ========================================================================== */ +/* = Q U A R A N T I N E F U N C T I O N S = */ +/* ========================================================================== */ + +function &ProcessQuarantine($signatures = array(), + $action = "None", + $sortBy = "Rating", + $currentPage = 1, + $qPerPage = 0){ + switch($action){ + case "None": + $input_errors =& DisplayQuarantine($sortBy, $currentPage, $qPerPage); + break; + case "manyNotSpam": + $input_errors =& QuarantineManyNotSpam($signatures, $sortBy, $currentPage, $qPerPage); + break; + case "deleteAll": + QuarantineDeleteSpam($action, $signatures, $sortBy, $currentPage, $qPerPage); + break; + default: + QuarantineDeleteSpam(); + } // switch + + CheckQuarantine(); + + return $input_errors; +} + +function &ProcessFalsePositive($sigID = "", + $sortBy = "Rating", + $currentPage = 1, + $qPerPage = 0) { + global $MAILBOX, $CONFIG, $TMPFILE, $CURRENT_USER; + $buffer = array(); + $head = array(); + $singatures = array(); + $found = 0; + $error = false; + + if ($sigID == "") { + return $input_errors[] = "No Message ID Specified."; + } + + /* 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; + } + + 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 <code>ProcessFalsePositive</code>."; + } + } + } + + /* 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 '<span class="errmsg">An error occured while parsing the message (no message).</span>'; + } + if ($sigID == "") { + return '<span class="errmsg">An error occured while parsing the message (no signature).</span>'; + } + + 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 = <<<EOD + <tr> + <td align="left" valign="top" class="listtopic" colspan="3">Message Infos</td> + </tr> + <tr> + <td valign="baseline" class="vncell" colspan="1">Date:</td> + <td class="vtable" colspan="2">%MSGDATE%</td> + </tr> + <tr> + <td valign="baseline" class="vncell" colspan="1">From:</td> + <td class="vtable" colspan="2">%MSGFROM%</td> + </tr> + <tr> + <td valign="baseline" class="vncell" colspan="1">Subject:</td> + <td class="vtable" colspan="2">%MSGSUB%</td> + </tr> + <tr> + <td valign="baseline" class="vncell" colspan="1">To:</td> + <td class="vtable" colspan="2">%MSGTO%</td> + </tr> + <tr> + <td class="list" height="12" colspan="3"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic">Message Part</td> + <td align="left" valign="top" class="listtopic">Part Type</td> + <td align="left" valign="top" class="listtopic">Part Encoding</td> + </tr> + <tr> + +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 .= "<td align=\"left\" valign=\"top\" class=\"vncell\"{$fontStyle}>" . + "<a href=\"/dspam-viewmsg.php?ctype=1&showpart={$st}&signatureID={$sigID}&command=viewMessage\">{$st}</a>" . + "</td>\n"; + } else { + $htmlstr .= "<td align=\"left\" valign=\"top\" class=\"vncell\"{$fontStyle}>" . + "<a href=\"/dspam-viewmsg.php?showpart={$st}&signatureID={$sigID}&command=viewMessage\">{$st}</a>" . + "</td>\n"; + } + + $htmlstr .= <<<EOD + <td align="left" valign="top" class="vtable"{$fontStyle}>{$info["content-type"]}</td> + <td align="left" valign="top" class="vtable"{$fontStyle}>{$info["charset"]}</td> + </tr> + +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 .= <<<EOD + <tr> + <td class="list" height="12" colspan="3"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="3">Section {$showpart}</td> + </tr> + <tr> + <td align="top" valign="left" colspan="3" class="vncell"> +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 .= "<pre style=\"font-size: 1.4em;\">" . $contents . "</pre></td>\n</tr>\n"; + } else { + /* an ASCII (text) email message */ + $htmlstr .= htmlentities($contents) . "</td>\n</tr>\n"; + } + } + + return $htmlstr; + } else { + return '<span class="errmsg">Could not load mailparse extension.</span>'; + } +} + +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); + $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'] = "<None Specified>"; + } + + //$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]); + 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); + } + + /* + + <tr> + <td align="left" valign="top" class="listtopic" width="8%"> </td> + <td align="left" valign="top" class="listtopic" width="5%" onclick="sortmsg('Rating');" style="cursor: pointer;">Rating</td> + <td align="left" valign="top" class="listtopic" width="20%" onclick="sortmsg('Date');" style="cursor: pointer;">Date</td> + <td align="left" valign="top" class="listtopic" width="25%" onclick="sortmsg('From');" style="cursor: pointer;">From</td> + <td align="left" valign="top" class="listtopic" width="42%" onclick="sortmsg('Subject');" style="cursor: pointer;">Subject</td> + </tr> + + */ + + $DATA['SORTBY'] = $sortBy; + $DATA['SORT_SELECTOR'] .= <<<EOD + <tr> + <td align="left" valign="top" class="listtopic" width="10%"> </td> + +EOD; + + if ($sortBy == "Rating") { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"5%\" onclick=\"sortmsg('Rating');\" style=\"cursor: pointer;\">Rating ◊</td>"; + } else { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"5%\" onclick=\"sortmsg('Rating');\" style=\"cursor: pointer;\">Rating</td>"; + } + if ($sortBy == "Date") { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"20%\" onclick=\"sortmsg('Date');\" style=\"cursor: pointer;\">Date ◊</td>"; + } else { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"20%\" onclick=\"sortmsg('Date');\" style=\"cursor: pointer;\">Date</td>"; + } + if ($sortBy == "Subject") { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"40%\" onclick=\"sortmsg('Subject');\" style=\"cursor: pointer;\">Subject ◊</td>"; + } else { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"40%\" onclick=\"sortmsg('Subject');\" style=\"cursor: pointer;\">Subject</td>"; + } + if ($sortBy == "From") { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"25%\" onclick=\"sortmsg('From');\" style=\"cursor: pointer;\">From ◊</td>"; + } else { + $DATA{'SORT_SELECTOR'} .= "<td align=\"left\" valign=\"top\" class=\"listtopic\" width=\"25%\" onclick=\"sortmsg('From');\" style=\"cursor: pointer;\">From</td>"; + } + + $DATA{'SORT_SELECTOR'} .= "\n </tr>"; + + 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}"; + } + + /* + + <tr> + <td align="left" valign="top" class="vncell"> + <input type="checkbox" class="formfld" title="check" alt="check" name="chkmsg" id="" /> + </td> + <td align="left" valign="top" class="vncell"> + <span style="color: darkblue; font-weight: bold;">50%</span> + </td> + <td align="left" valign="top" class="vncell">Apr 1 05:59a</td> + <td align="left" valign="top" class="vncell">Mar 30 11:08a</td> + <td align="left" valign="top" class="vncell"> + <u>Last chance to register for Frankfurt, 4 April BEA...</u> + </td> + </tr> + + <tr> + <td align="left" valign="top" class="{$outclass}" nowrap="true"> + <input type="checkbox" class="formfld" title="check" alt="check" name="{$row['X-DSPAM-Signature']}" id="{$row['X-DSPAM-Signature']}" /> + </td> + <td align="left" valign="top" class="{$outclass} {$markclass}" nowrap="true"> + {$rating} + </td> + <td align="left" valign="top" class="{$outclass}" nowrap="true">{$ptime}</td> + <td align="left" valign="top" class="{$outclass}" nowrap="true">{$row['From']}</td> + <td align="left" valign="top" class="{$outclass}" nowrap="true"> + <a href="{$CONFIG['ME']}?{$url}">{$row['Subject']}</a> + </td> + </tr> + */ + + $DATA['QUARANTINE'] .= <<<EOD + <tr> + <td align="left" valign="top" class="{$outclass}" nowrap="true"> + <input type="checkbox" class="formfld" title="check" alt="check" name="chkmsg-{$row['X-DSPAM-Signature']}" id="{$row['X-DSPAM-Signature']}" /> + </td> + <td align="left" valign="top" class="{$outclass} {$markclass}" nowrap="true"> + {$rating} + </td> + <td align="left" valign="top" class="{$outclass}" nowrap="true">{$ptime}</td> + <td align="left" valign="top" class="{$outclass}" nowrap="true">{$sender}</td> + <td align="left" valign="top" class="{$outclass}" nowrap="true"> + <a href="/dspam-viewmsg.php?{$url}">{$rsubject}</a> + </td> + </tr> + +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 + <tr> + <td align="left" valign="top" class="listtopic"> + <input type="checkbox" class="formfld" title="check all" alt="check all" name="checkall" id="checkall" onClick="checkallmsgs();" /> + <label for="checkall">All</label> + </td> + <td align="right" valign="middle" class="listtopic" colspan="4"> + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="First Page (1)"><a href="/dspam-quarantine.php?page=1&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="First Page (1)">|<</a></span> + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$previousPage}"><a href="/dspam-quarantine.php?page={$previousPage}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="Page {$previousPage}"><</a></span> + +EOD; + + $quarantineFooterEnd = <<<EOD + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Page {$nextPage}"><a href="/dspam-quarantine.php?page={$nextPage}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="Page {$nextPage}">></a></span> + <span class="qnavbtn" onmouseover="this.style.backgroundColor='#A5B9E1;'" onmouseout="this.style.backgroundColor='#507DCD;'" title="Last Page ({$pages})"><a href="/dspam-quarantine.php?page={$pages}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}" title="Last Page ({$pages})">>|</a></span> + </td> + </tr> + +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 .= "<span class=\"qnavbtnhl\">{$i}</span> \n"; + } else { + $quarantineFooter .= "<span class=\"qnavbtn\" onmouseover=\"this.style.backgroundColor='#A5B9E1;'\" onmouseout=\"this.style.backgroundColor='#507DCD;'\" title=\"Page {$i}\"><a href=\"/dspam-quarantine.php?page={$i}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}\" title=\"Page {$i}\">{$i}</a></span> \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<cells.length;i++){ + if(cells[i].tagName == "TD"){ + if (fadeType == 0) + new Effect.Fade(cells[i],opts); + else + new Effect.Appear(cells[i],opts); + } + } + if (fadeType == 0) + new Effect.Fade(row,opts); + else + new Effect.Appear(row,opts); + } + + function toggleDSPAMDomain(enable_over, originator) { + var endis = !(originator.checked || enable_over); + + if (endis) { + fadeTableRow("emailnotitb", 1); + } else { + fadeTableRow("emailnotitb", 0); + } + } + + function toggleDBSettings(idx) { + if (idx) + idx = idx; + else + idx = document.iform.sdriver.selectedIndex; + + switch (idx) { + case 0: + fadeTableRow("DBmysql", 1); + fadeTableRow("DBsqlite", 0); + fadeTableRow("DBbdb", 0); + fadeTableRow("DBpgsql", 0); + fadeTableRow("DBoracle", 0); + fadeTableRow("DBhash", 0); + break; + case 1: + fadeTableRow("DBmysql", 0); + fadeTableRow("DBsqlite", 1); + fadeTableRow("DBbdb", 0); + fadeTableRow("DBpgsql", 0); + fadeTableRow("DBoracle", 0); + fadeTableRow("DBhash", 0); + break; + case 2: + fadeTableRow("DBmysql", 0); + fadeTableRow("DBsqlite", 0); + fadeTableRow("DBbdb", 1); + fadeTableRow("DBpgsql", 0); + fadeTableRow("DBoracle", 0); + fadeTableRow("DBhash", 0); + break; + case 3: + fadeTableRow("DBmysql", 0); + fadeTableRow("DBsqlite", 0); + fadeTableRow("DBbdb", 0); + fadeTableRow("DBpgsql", 1); + fadeTableRow("DBoracle", 0); + fadeTableRow("DBhash", 0); + break; + case 4: + fadeTableRow("DBmysql", 0); + fadeTableRow("DBsqlite", 0); + fadeTableRow("DBbdb", 0); + fadeTableRow("DBpgsql", 0); + fadeTableRow("DBoracle", 1); + fadeTableRow("DBhash", 0); + break; + case 5: + fadeTableRow("DBmysql", 0); + fadeTableRow("DBsqlite", 0); + fadeTableRow("DBbdb", 0); + fadeTableRow("DBpgsql", 0); + fadeTableRow("DBoracle", 0); + fadeTableRow("DBhash", 1); + break; + } + } + + function enable_change(enable_over, originator) { + var endis; + + switch (originator) { + case 0: + endis = !(document.iform.enabledbg.checked || enable_over); + endis ? document.iform.debug.style.backgroundColor = "#D4D0C8" : document.iform.debug.style.backgroundColor = "#FFFFFF"; + document.iform.debug.disabled = endis; + endis ? document.iform.dopt.style.backgroundColor = "#D4D0C8" : document.iform.dopt.style.backgroundColor = "#FFFFFF"; + document.iform.dopt.disabled = endis; + case 1: + endis = !(document.iform.enableldap.checked || enable_over); + document.iform.ldapmode.disabled = endis; + endis ? document.iform.ldaphost.style.backgroundColor = "#D4D0C8" : document.iform.ldaphost.style.backgroundColor = "#FFFFFF"; + document.iform.ldaphost.disabled = endis; + endis ? document.iform.ldapfilter.style.backgroundColor = "#D4D0C8" : document.iform.ldapfilter.style.backgroundColor = "#FFFFFF"; + document.iform.ldapfilter.disabled = endis; + endis ? document.iform.ldapbase.style.backgroundColor = "#D4D0C8" : document.iform.ldapbase.style.backgroundColor = "#FFFFFF"; + document.iform.ldapbase.disabled = endis; + case 2: + endis = !(document.iform.enablesbl.checked || enable_over); + endis ? document.iform.sblhost.style.backgroundColor = "#D4D0C8" : document.iform.sblhost.style.backgroundColor = "#FFFFFF"; + document.iform.sblhost.disabled = endis; + case 3: + endis = !(document.iform.enableclam.checked || enable_over); + endis ? document.iform.clamport.style.backgroundColor = "#D4D0C8" : document.iform.clamport.style.backgroundColor = "#FFFFFF"; + document.iform.clamport.disabled = endis; + endis ? document.iform.clamhost.style.backgroundColor = "#D4D0C8" : document.iform.clamhost.style.backgroundColor = "#FFFFFF"; + document.iform.clamhost.disabled = endis; + document.iform.clamresp.disabled = endis; + case 4: + endis = !(document.iform.enabledsclient.checked || enable_over); + endis ? document.iform.dsclhost.style.backgroundColor = "#D4D0C8" : document.iform.dsclhost.style.backgroundColor = "#FFFFFF"; + document.iform.dsclhost.disabled = endis; + endis ? document.iform.dsclport.style.backgroundColor = "#D4D0C8" : document.iform.dsclport.style.backgroundColor = "#FFFFFF"; + document.iform.dsclport.disabled = endis; + endis ? document.iform.dsclident.style.backgroundColor = "#D4D0C8" : document.iform.dsclident.style.backgroundColor = "#FFFFFF"; + document.iform.dsclident.disabled = endis; + case 5: + endis = !(document.iform.tcpipdel.checked || enable_over); + endis ? document.iform.dhost.style.backgroundColor = "#D4D0C8" : document.iform.dhost.style.backgroundColor = "#FFFFFF"; + document.iform.dhost.disabled = endis; + endis ? document.iform.dport.style.backgroundColor = "#D4D0C8" : document.iform.dport.style.backgroundColor = "#FFFFFF"; + document.iform.dport.disabled = endis; + endis ? document.iform.dident.style.backgroundColor = "#D4D0C8" : document.iform.dident.style.backgroundColor = "#FFFFFF"; + document.iform.dident.disabled = endis; + document.iform.delproto.disabled = endis; + case 6: + endis = !(document.iform.enablenoti.checked || enable_over); + document.iform.whichdomain.disabled = endis; + endis ? document.iform.dspamdomain.style.backgroundColor = "#D4D0C8" : document.iform.dspamdomain.style.backgroundColor = "#FFFFFF"; + document.iform.dspamdomain.disabled = endis; + endis ? document.iform.dspamcontact.style.backgroundColor = "#D4D0C8" : document.iform.dspamcontact.style.backgroundColor = "#FFFFFF"; + document.iform.dspamcontact.disabled = endis; + } + } + '; + + break; + case 6: + $scriptstr = ' + + function checkDisabledState(form) { + for (i = 0; i < form.elements.length; i++) { + if (form.elements[i].disabled && form.elements[i].type == "text") + form.elements[i].style.backgroundColor = "#D4D0C8"; + else if (form.elements[i].type == "text") + form.elements[i].style.backgroundColor = "#FFFFFF"; + } + } + '; + + break; + } + + return $scriptstr; +} + +?> diff --git a/config/dspam/pkg/dspam-pkgfunc.inc b/config/dspam/pkg/dspam-pkgfunc.inc new file mode 100644 index 00000000..31a7fa06 --- /dev/null +++ b/config/dspam/pkg/dspam-pkgfunc.inc @@ -0,0 +1,548 @@ +<?php +/* $Id$ */ +/* Copyright (C) 2006 Daniel S. Haischt */ +require_once("functions.inc"); +require_once("dspam.inc"); + +function sync_package_dspam() { + global $config, $g; + conf_mount_rw(); + config_lock(); + $fd = fopen("/etc/dspam.conf","w"); + + $dspamcfg = <<<EOD +## dspam.conf -- DSPAM configuration file +## Generated by pfSense +Home /var/db/dspam +## Database Settings +StorageDriver /usr/local/lib/libmysql_drv.so +MySQLServer /tmp/mysql.sock +MySQLPort +MySQLUser dspam +MySQLPass dspam +MySQLDb dspam +MySQLCompress true +MySQLSupressQuote off +MySQLConnectionCache 10 +MySQLUIDInSignature on +## Delivery Settings +TrustedDeliveryAgent "/usr/bin/mail" +DeliveryHost 192.168.1.6 +DeliveryPort 24 +DeliveryIdent localhost +DeliveryProto smtp +OnFail error +## DSPAM Privileges +Trust root +Trust mail +Trust mailnull +Trust smmsp +Trust daemon +## DSPAM Engine Settings +TrainingMode teft +TestConditionalTraining on +Feature chained +Feature whitelist +Algorithm graham burton +PValue graham +ImprobabilityDrive on +Preference "spamAction=quarantine" +Preference "signatureLocation=message" +Preference "showFactors=on" +AllowOverride trainingMode +AllowOverride spamAction spamSubject +AllowOverride statisticalSedation +AllowOverride enableBNR +AllowOverride enableWhitelist +AllowOverride signatureLocation +AllowOverride showFactors +AllowOverride optIn optOut +AllowOverride whitelistThreshold +## Miscellaneous Settings +FailoverAttempts 1 +IgnoreHeader X-Spam-Scanned +IgnoreHeader X-Spam-Status +IgnoreHeader X-Virus-Scanner-Result +RBLInoculate on +Notifications on +## Maintainance Settings +PurgeSignatures 14 +PurgeNeutral 90 +PurgeUnused 90 +PurgeHapaxes 30 +PurgeHits1S 15 +PurgeHits1I 15 +## System Settings +LocalMX 127.0.0.1 +SystemLog on +UserLog on +Opt out +ParseToHeaders on +ChangeModeOnParse on +ChangeUserOnParse on +Broken returnCodes +Broken case +Broken lineStripping +MaxMessageSize 307200 +ProcessorBias on +## ClamAV Engine Settings +ClamAVPort 3310 +ClamAVHost 127.0.0.1 +ClamAVResponse accept +## DSPAM Daemon Settings (Server) +ServerPort 24 +ServerQueueSize 32 +ServerPID /var/run/dspam/dspam.pid +ServerMode standard +ServerParameters "--deliver=innocent -d %u" +ServerIdent "abysseleven.abyssworld.de" +ServerDomainSocketPath "/var/run/dspam/dspam.sock" +## EOF + +EOD; + + /* flush the default config to the file */ + fwrite($fd, $dspamcfg); + fclose($fd); + + $fd = fopen("/usr/local/bin/dspam_spamfeed","w"); + + $spamfeed = <<<EOD +#!/bin/sh +# +# automatically generated by pfSense + +cat \${2} | dspam --mode=teft --source=corpus --class=spam --feature=chained,noise --user \${1} + +EOD; + + fwrite($fd, $spamfeed); + fclose($fd); + mwexec("chmod a+x /usr/local/bin/dspam_spamfeed"); + + $fd = fopen("/usr/local/bin/dspam_innocentfeed","w"); + + $innocentfeed = <<<EOD +#!/bin/sh +# +# automatically generated by pfSense + +cat \${2} | dspam --mode=teft --source=corpus --class=innocent --feature=chained,noise --user \${1} + +EOD; + + fwrite($fd, $innocentfeed); + fclose($fd); + mwexec("chmod a+x /usr/local/bin/dspam_innocentfeed"); + + $start = <<<EOD +test_dspam_user=`cat /etc/passwd | grep dspam` +test_dspam_db=`mysql information_schema -e "select schema_name from schemata" | grep dspam` +test_dspam_db_user=`mysql mysql -e "select User from user" | grep dspam` + +if [ -z "\${test_dspam_user}" ]; then + pw useradd dspam -u 107 -g mail -d /var/db/dspam -s /bin/csh -c 'DSPAM Daemon User' +fi + +if [ ! -d "/var/run/dspam" ]; then + mkdir /var/run/dspam && chown dspam:mail /var/run/dspam +fi + +if [ -z "\${test_dspam_db}" ]; then + mysql -D mysql -e "create database dspam" + if [ -z "\${test_dspam_db_user}" ]; then + mysql -D mysql -e "GRANT ALL PRIVILEGES ON dspam.* TO dspam@localhost IDENTIFIED BY 'dspam'" + fi + mysql -udspam -pdspam dspam < /usr/local/share/examples/dspam/mysql/mysql_objects-space.sql && \ + mysql -udspam -pdspam dspam < /usr/local/share/examples/dspam/mysql/virtual_users.sql +fi + +/sbin/mount_fdescfs fdescfs /dev/fd +/usr/local/bin/dspam --daemon & + +EOD; + + $stop = "/usr/bin/killall dspam\n" . + "sleep 2"; + write_rcfile(array( + "file" => "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 = <<<EOD +## dspam.conf -- DSPAM configuration file +## Generated by pfSense +Home /var/db/dspam +## Database Settings + +EOD; + + if ($dspamcfg['storage-driver'] == "mysql") { + $dspamconf .= "StorageDriver\t\t/usr/local/lib/libmysql_drv.so\n"; + $dspamconf .= <<<EOD +MySQLServer {$dspamcfg['dbsettings'][0]['mysql-server']} +MySQLPort {$dspamcfg['dbsettings'][0]['mysql-port']} +MySQLUser {$dspamcfg['dbsettings'][0]['mysql-user']} +MySQLPass {$dspamcfg['dbsettings'][0]['mysql-password']} +MySQLDb {$dspamcfg['dbsettings'][0]['mysql-database']} + +EOD; + isset($dspamcfg['dbsettings'][0]['mysql-compress']) ? $dspamconf .= "MySQLCompress\t\ttrue\n" : $dspamconf .= "MySQLCompress\tfalse\n"; + isset($dspamcfg['dbsettings'][0]['mysql-squote']) ? $dspamconf .= "MySQLSupressQuote\ton\n" : $dspamconf .= "MySQLSupressQuote\toff\n"; + isset($dspamcfg['dbsettings'][0]['mysql-ccache']) ? $dspamconf .= "MySQLConnectionCache\t{$dspamcfg['dbsettings'][0]['mysql-ccache']}\n" : $dspamconf .= "MySQLConnectionCache\t10\n"; + isset($dspamcfg['dbsettings'][0]['mysql-uid']) ? $dspamconf .= "MySQLUIDInSignature\ton\n" : $dspamconf .= "MySQLUIDInSignature\toff\n"; + } else if ($dspamcfg['storage-driver'] == "sqlite") { + $dspamconf .= "StorageDriver\t\t/usr/local/lib/libsqlite3_drv.so\n"; + if (isset($dspamcfg['dbsettings'][0]['sqlite-pragma'])) $dspamconf .= "SQLitePragma\t\t{$dspamcfg['dbsettings'][0]['sqlite-pragma']}\n"; + } else if ($dspamcfg['storage-driver'] == "pgsql") { + $dspamconf .= "StorageDriver\t\t/usr/local/lib/libpgsql_drv.so\n"; + $dspamconf .= <<<EOD +PgSQLServer {$dspamcfg['dbsettings'][0]['pgsql-server']} +PgSQLPort {$dspamcfg['dbsettings'][0]['pgsql-port']} +PgSQLUser {$dspamcfg['dbsettings'][0]['pgsql-user']} +PgSQLPass {$dspamcfg['dbsettings'][0]['pgsql-password']} +PgSQLDb {$dspamcfg['dbsettings'][0]['pgsql-database']} + +EOD; + isset($dspamcfg['dbsettings'][0]['pgsql-ccache']) ? $dspamconf .= "PgSQLConnectionCache\t{$dspamcfg['dbsettings'][0]['pgsql-ccache']}\n" : $dspamconf .= "PgSQLConnectionCache\t3\n"; + isset($dspamcfg['dbsettings'][0]['pgsql-uid']) ? $dspamconf .= "PgSQLUIDInSignature\ton\n" : $dspamconf .= "PgSQLUIDInSignature\toff\n"; + } else if ($dspamcfg['storage-driver'] == "oracle") { + $dspamconf .= "StorageDriver\t/usr/local/lib/libora_drv.so\n"; + $dspamconf .= <<<EOD +OraServer {$dspamcfg['dbsettings'][0]['ora-server']} +OraUser {$dspamcfg['dbsettings'][0]['ora-user']} +OraPass {$dspamcfg['dbsettings'][0]['ora-password']} +OraSchema {$dspamcfg['dbsettings'][0]['ora-schema']} + +EOD; + } else if ($dspamcfg['storage-driver'] == "hash") { + $dspamconf .= "StorageDriver\t\t/usr/local/lib/libhash_drv.so\n"; + $dspamconf .= <<<EOD +HashRecMax {$dspamcfg['dbsettings'][0]['hash-rec-max']} +HashMaxExtents {$dspamcfg['dbsettings'][0]['hash-max-ext']} +HashExtentSize {$dspamcfg['dbsettings'][0]['hash-ext-size']} +HashMaxSeek {$dspamcfg['dbsettings'][0]['hash-max-seek']} +HashConnectionCache {$dspamcfg['dbsettings'][0]['hash-co-cache']} + +EOD; + isset($dspamcfg['dbsettings'][0]['hash-auto-ex']) ? $dspamconf .= "HashAutoExtend\t\ton\n" : $dspamconf .= "HashAutoExtend\toff\n"; + if (isset($dspamcfg['dbsettings'][0]['hash-co-user'])) $dspamconf .= "HashConcurrentUser\t{$dspamcfg['dbsettings'][0]['hash-co-user']}\n"; + } + + $dspamconf .= "## Delivery Settings\n"; + + if ($dspamcfg['tdelivery-agent'] == "procmail") { + $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/bin/procmail\"\n"; + } else if ($dspamcfg['tdelivery-agent'] == "mail") { + $dspamconf .= "TrustedDeliveryAgent\t\"/usr/bin/mail\"\n"; + } else if ($dspamcfg['tdelivery-agent'] == "mail.local") { + $dspamconf .= "TrustedDeliveryAgent\t\"/usr/libexec/mail.local\"\n"; + } else if ($dspamcfg['tdelivery-agent'] == "deliver") { + $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/cyrus/bin/deliver\"\n"; + } else if ($dspamcfg['tdelivery-agent'] == "maildrop") { + $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/bin/maildrop\"\n"; + } else if ($dspamcfg['tdelivery-agent'] == "exim") { + $dspamconf .= "TrustedDeliveryAgent\t\"/usr/local/sbin/exim -oMr spam-scanned\"\n"; + } + + if (isset($dspamcfg['tcpip-delivery'])) { + $dspamconf .= <<<EOD +DeliveryHost {$dspamcfg['tcpip-delivery-host']} +DeliveryPort {$dspamcfg['tcpip-delivery-port']} +DeliveryIdent {$dspamcfg['tcpip-delivery-ident']} +DeliveryProto {$dspamcfg['tcpip-delivery-proto']} + +EOD; + } + + /* TODO: If required add the following, currently + missing options: + + - QuarantineAgent + - EnablePlusedDetail + - QuarantineMailbox + */ + + $dspamconf .= "OnFail\t\t\t{$dspamcfg['delivery-onfail']}\n"; + $dspamconf .= "## DSPAM Privileges\n"; + + $t_users = &$dspamcfg['tuser']; + + foreach ($t_users as $user) { + $dspamconf .= "Trust\t\t\t{$user['name']}\n"; + } + + if (isset($dspamcfg['debug-enable'])) { + $dspamconf .= "## DSPAM Debugging Options\n"; + $dspamconf .= "Debug\t\t\t{$dspamcfg['debug-whom']}\n"; + $dspamconf .= "DebugOpt\t\t{$dspamcfg['debug-options']}\n"; + } + + $dspamconf .= "## DSPAM Engine Settings\n"; + $dspamconf .= "TrainingMode\t\t{$dspamcfg['training-mode']}\n"; + isset($dspamcfg['test-cond-training']) ? $dspamconf .= "TestConditionalTraining\ton\n" : $dspamconf .= "TestConditionalTraining\toff\n"; + + $t_features = &$dspamcfg['feature']; + + foreach ($t_features as $feature) { + $dspamconf .= "Feature\t\t\t{$feature['name']}\n"; + } + + $t_algos = &$dspamcfg['algorithm']; + + if (count($t_algos) > 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 .= <<<EOD +## LDAP Settings +LDAPMode {$dspamcfg['ldap-mode']} +LDAPHost {$dspamcfg['ldap-host']} +LDAPFilter {$dspamcfg['ldap-filter']} +LDAPBase {$dspamcfg['ldap-base']} + +EOD; + } + + $dspamconf .= "## Miscellaneous Settings\n"; + if (isset($dspamcfg['failover-attempts'])) $dspamconf .= "FailoverAttempts\t{$dspamcfg['failover-attempts']}\n"; + + $t_headers = &$dspamcfg['header']; + + if (is_array($t_headers)) { + foreach ($t_headers as $header) { + $dspamconf .= "IgnoreHeader\t\t{$header['name']}\n"; + } + } + + if (isset($dspamcfg['sbl-enable'])) { + $dspamconf .= "Lookup\t\t\t\"{$dspamcfg['sbl-host']}\"\n"; + } + + isset($dspamcfg['rbl-inoculate']) ? $dspamconf .= "RBLInoculate\t\ton\n" : $dspamconf .= "RBLInoculate\toff\n"; + isset($dspamcfg['notification-email']) ? $dspamconf .= "Notifications\t\ton\n" : $dspamconf .= "Notifications\toff\n"; + + $dspamconf .= <<<EOD +## Maintainance Settings +PurgeSignatures {$dspamcfg['purge-signatures']} +PurgeNeutral {$dspamcfg['purge-neutral']} +PurgeUnused {$dspamcfg['purge-unused']} +PurgeHapaxes {$dspamcfg['purge-hapaxes']} +PurgeHits1S {$dspamcfg['purge-hits-1s']} +PurgeHits1I {$dspamcfg['purge-hits-1s']} + +EOD; + + $dspamconf .= "## System Settings\n"; + $dspamconf .= "LocalMX\t\t\t{$dspamcfg['local-mx']}\n"; + isset($dspamcfg['system-log']) ? $dspamconf .= "SystemLog\t\ton\n" : $dspamconf .= "SystemLog\toff\n"; + isset($dspamcfg['user-log']) ? $dspamconf .= "UserLog\t\t\ton\n" : $dspamconf .= "UserLog\toff\n"; + $dspamconf .= "Opt\t\t\t{$dspamcfg['filter-opt']}\n"; + isset($dspamcfg['parse-to-headers']) ? $dspamconf .= "ParseToHeaders\t\ton\n" : $dspamconf .= "ParseToHeaders\toff\n"; + isset($dspamcfg['change-mode-on-parse']) ? $dspamconf .= "ChangeModeOnParse\ton\n" : $dspamconf .= "ChangeModeOnParse\toff\n"; + isset($dspamcfg['change-user-on-parse']) ? $dspamconf .= "ChangeUserOnParse\ton\n" : $dspamconf .= "ChangeUserOnParse\toff\n"; + + if (isset($dspamcfg['broken-mta-settings'])) { + $t_bmtas = &$dspamcfg['bmta']; + + foreach ($t_bmtas as $bmta) { + $dspamconf .= "Broken\t\t\t{$bmta['name']}\n"; + } + } + + $dspamconf .= "MaxMessageSize\t\t{$dspamcfg['max-message-size']}\n"; + isset($dspamcfg['processor-bias']) ? $dspamconf .= "ProcessorBias\t\ton\n" : $dspamconf .= "ProcessorBias\toff\n"; + + if (isset($dspamcfg['clamav-enable'])) { + $dspamconf .= <<<EOD +## ClamAV Engine Settings +ClamAVPort {$dspamcfg['clamav-port']} +ClamAVHost {$dspamcfg['clamav-host']} +ClamAVResponse {$dspamcfg['clamav-response']} + +EOD; + } + + $dspamconf .= <<<EOD +## DSPAM Daemon Settings (Server) +ServerPort {$dspamcfg['dspam-server-port']} +ServerQueueSize {$dspamcfg['dspam-server-queue-size']} +ServerPID {$dspamcfg['dspam-server-pid']} +ServerMode {$dspamcfg['dspam-server-mode']} + +EOD; + + if ($dspamcfg['dspam-server-mode'] == "dspam") { + $t_spwds = &$dspamcfg['server-pwd']; + $i = 1; + + if (is_array($t_spwds)) { + foreach ($t_spwds as $spwd) { + $dspamconf .= "ServerPass.Relay{$i}\t\"{$spwd['value']}\"\n"; + $i++; + } + } + } else if ($dspamcfg['dspam-server-mode'] == "standard") { + $dspamconf .= <<<EOD +ServerParameters "{$dspamcfg['dspam-server-params']}" +ServerIdent "{$dspamcfg['dspam-server-id']}" + +EOD; + } + + if (isset($dspamcfg['dspam-server-socket'])) { + $dspamconf .= "ServerDomainSocketPath\t\"{$dspamcfg['dspam-server-socket']}\"\n"; + } + + if (isset($dspamcfg['dspam-client-enable']) && $dspamcfg['dspam-client-enable'] <> "") { + $dspamconf .= <<<EOD +## DSPAM Daemon Settings (Client) +ClientHost {$dspamcfg['dspam-client-host']} +ClientIdent {$dspamcfg['dspam-client-id']} + +EOD; + + if (isset($dspamcfg['dspam-client-port']) && $dspamcfg['dspam-client-port'] <> "") { + $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/dspam/pkg/dspam-utilfunc.inc b/config/dspam/pkg/dspam-utilfunc.inc new file mode 100644 index 00000000..903790b8 --- /dev/null +++ b/config/dspam/pkg/dspam-utilfunc.inc @@ -0,0 +1,458 @@ +<?php +/* $Id$ */ +/* Copyright (C) 2006 Daniel S. Haischt */ +require_once("functions.inc"); +require_once("dspam.inc"); + +function &GetPrefs($user) { + global $CONFIG, $USER; + $prefs = array(); + $FILE = "{$USER}.prefs"; + + if ($CONFIG['PREFERENCES_EXTENSION'] == 1) { + $handle = popen ("{$CONFIG['DSPAM_BIN']}/dspam_admin agg pref " . quotemeta($user)); + + while (!feof($handle)) { + $buffer = chop(fgets($handle, 4096)); + list($key, $value) = split("=", $buffer); + $prefs[$key] = $value; + } + + pclose($handle); + + } + + if (count(array_keys($prefs)) == 0 || $CONFIG['PREFERENCES_EXTENSION'] != 1) { + + /* This step is only required if the user + * wants to use the legacy DSPAm CGI app. + */ + if (! file_exists("{$CONFIG['DSPAM_WWW']}/default.prefs")) { + /* try to copy the sample file */ + if (file_exists("{$CONFIG['DSPAM_WWW']}/default.prefs.sample")) { + copy("{$CONFIG['DSPAM_WWW']}/default.prefs.sample", + "{$CONFIG['DSPAM_WWW']}/default.prefs"); + } + } + $handle = fopen ("{$CONFIG['DSPAM_WWW']}/default.prefs", "r"); + + while (!feof($handle)) { + $buffer = chop(fgets($handle, 4096)); + list($key, $value) = split("=", $buffer); + $prefs[$key] = $value; + } + + fclose($handle); + + if(file_exists($FILE)) { + $handle = fopen ($FILE, "r"); + + while (!feof($handle)) { + $buffer = chop(fgets($handle, 4096)); + list($key, $value) = split("=", $buffer); + $prefs[$key] = $value; + } + } + } + return $prefs; +} + +function CheckQuarantine() { + global $MAILBOX, $DATA; + $f = 0; + + if (file_exists($MAILBOX)) { + $handle = fopen($MAILBOX, "r"); + + while (!feof($handle)) { + $buffer = fgets($handle, 4096); + if (preg_match('/^From /', $buffer) <= 0) {continue;} + $f++; + } + + fclose ($handle); + } + + if ($f == 0) { + $f = "Empty"; + } + + $DATA['TOTAL_QUARANTINED_MESSAGES'] = $f; +} + +function http_parse_query( $array = NULL, $convention = '%s' ) { + if( count( $array ) == 0 ) { + return ''; + } else { + if( function_exists( 'http_build_query' ) ){ + $query = http_build_query( $array ); + } else { + $query = ''; + + foreach( $array as $key => $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/dspam/pkg/dspam.inc b/config/dspam/pkg/dspam.inc new file mode 100644 index 00000000..9a821e6a --- /dev/null +++ b/config/dspam/pkg/dspam.inc @@ -0,0 +1,360 @@ +<?php +/* $Id$ */ +/* Copyright (C) 2006 Daniel S. Haischt */ + +/* include all configuration functions */ +require_once ("functions.inc"); +require_once ("dspam-config.inc"); +require_once ("dspam-guifunc.inc"); +require_once ("dspam-pkgfunc.inc"); +require_once ("dspam-utilfunc.inc"); + +/* General TODO(s): + * + * - Use quotemeta where applicable + * - Issue a change message after a successful GET/POST + * - Issue an error message if something went wrong during a GET/POST + * - Revise user management (CURENT_USER, SESSION_USER etc.) + */ + +$DATA = array(); + +/* + * Determine which extensions are available + */ +if ($CONFIG['AUTODETECT'] == 1 || $CONFIG['AUTODETECT'] == "") { + $CONFIG['PREFERENCES_EXTENSION'] = 0; + $CONFIG['LARGE_SCALE'] = 0; + $CONFIG['DOMAIN_SCALE'] = 0; + + $buffer = ""; + $handle = popen ("/usr/local/bin/dspam --version", "r"); + + while (!feof($handle)) { + $buffer .= fgets($handle, 4096); + } + + pclose($handle); + + if (strpos($buffer, '--enable-preferences-extension') !== false) { + $CONFIG['PREFERENCES_EXTENSION'] = 1; + } + if (strpos($buffer, '--enable-large-scale') !== false) { + $CONFIG['LARGE_SCALE'] = 1; + } + if (strpos($buffer, '--enable-domain-scale') !== false) { + $CONFIG['DOMAIN_SCALE'] = 1; + } +} + +/* + * Determine admin status + */ + +$CONFIG['ADMIN'] = isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER']); + +/* + * Determine which user should be used to display DSPAm related data + */ +$CURRENT_USER = $HTTP_SERVER_VARS['AUTH_USER']; + +if (empty($CONFIG['ADMIN']) && + strpos($_SERVER['SCRIPT_NAME'], "wizard.php") !== false) { + + $group = $config['system']['user'][$userindex[$HTTP_SERVER_VARS['AUTH_USER']]]['groupname']; + $home = "/" . getGroupHomePage($group); + if ($home == "/") { $home = "/index.php"; } + + if (! headers_sent()) { + pfSenseHeader($home); + exit; + } else { + $htmlstr = <<< EOD +<html> + <head> + <title>Unauthorized Access</title> + <meta http-equiv="refresh" content="2; URL={$home}"> + </head> + <body> + <h3>Unauthorized Access - You will be redirected shortly!</h3> + </body> +</html> +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 <code>dspam.inc</code>."; +} + +?>
\ No newline at end of file diff --git a/config/dspam/pkg/dspam.xml b/config/dspam/pkg/dspam.xml new file mode 100644 index 00000000..59740ae1 --- /dev/null +++ b/config/dspam/pkg/dspam.xml @@ -0,0 +1,342 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<packagegui> + <copyright><![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + 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. + */ +/* ========================================================================== */ + ]]></copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>dspam</name> + <version>1.0</version> + <title>Services: DSPAM: Main</title> + <include_file>/usr/local/pkg/dspam.inc</include_file> + <!-- Menu is where this packages menu will appear --> + <menu> + <name>dspam</name> + <section>Services</section> + <configfile>dspam.xml</configfile> + <url>/dspam-perf.php</url> + </menu> + <menu> + <name>DSPAM Legacy WebGUI</name> + <tooltiptext>Original Perl-based GUI</tooltiptext> + <section>Services</section> + <url>/vhosts/dspam/dspam.cgi</url> + </menu> + <service> + <name>dspam</name> + <rcfile>/usr/local/etc/rc.d/dspam.sh</rcfile> + </service> + <tabs> + <tab> + <text>Overview</text> + <url>/dspam.php</url> + <active/> + </tab> + <tab> + <text>Performance</text> + <url>/dspam-perf.php</url> + </tab> + <tab> + <text>Preferences</text> + <url>/dspam-prefs.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pkg.php?xml=dspam_alerts.xml</url> + </tab> + <tab> + <text>Quarantine</text> + <url>/dspam-quarantine.php</url> + </tab> + <tab> + <text>Analysis</text> + <url>/dspam-analysis.php</url> + </tab> + <tab> + <text>History</text> + <url>/dspam-history.php</url> + </tab> + </tabs> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['dspam']['config']</configpath> + <!-- PHP files --> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-perf.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin-graph.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin-prefs.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-admin-stats.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam_settings.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-settings.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-settings-algo.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-settings-bmta.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-settings-feat.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-header.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-overr.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-settings-prefs.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-spwd.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-tuser.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-train.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam-viewmsg.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/verdana.ttf</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-prefs.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-quarantine.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-analysis.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-analysis-graph.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-hfragment.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/dspam-history.php</item> + </additional_files_needed> + <!-- package files --> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.abyssworld.de/packages/config/dspam_alerts.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-config.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-guifunc.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-pkgfunc.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/dspam-utilfunc.inc</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/000.mysql.sh</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/010.clamav-clamd.sh</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/020.clamav-freshclam.sh</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/030.p3scan.sh</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/clamd.conf</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/default.prefs.sample</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/freshclam.conf</item> + </additional_files_needed> + <!-- misc files --> + <additional_files_needed> + <prefix>/usr/local/www/wizards/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam_wizard.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/wizards/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-lda-proxy.png</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/wizards/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-pop-proxy.png</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/wizards/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/wizards/dspam-smtp-relay.png</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/pkg/verdana.ttf</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/themes/metallic/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/dspam/www/themes/metallic/dspam.css</item> + </additional_files_needed> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_php_resync_config_command> + sync_package_dspam(); + </custom_php_resync_config_command> + <custom_php_install_command> + custom_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + custom_php_deinstall_command(); + </custom_php_deinstall_command> +</packagegui> diff --git a/config/dspam/pkg/dspam_alerts.xml b/config/dspam/pkg/dspam_alerts.xml new file mode 100644 index 00000000..ea59cfd2 --- /dev/null +++ b/config/dspam/pkg/dspam_alerts.xml @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<!-- + Tags which can be used to exec arbitrary PHP code: + + <custom_php_global_functions /> + <custom_php_command_before_form /> + <custom_delete_php_command /> if $_POST && act == del + <custom_add_php_command /> if $_POST && act == add + <custom_php_resync_config_command /> + <custom_php_validation_command /> + <custom_add_php_command_late /> + <start_command /> shell exec + <restart_command /> shell exec + <custom_php_after_form_command /> +--> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + 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. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>dspamalerts</name> + <version>1.0</version> + <title>Services: DSPAM: Alerts</title> + <include_file>/usr/local/pkg/dspam.inc</include_file> + <!-- Menu is where this packages menu will appear --> + <tabs> + <tab> + <text>Performance</text> + <url>/dspam-perf.php</url> + </tab> + <tab> + <text>Preferences</text> + <url>/dspam-prefs.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pkg.php?xml=dspam_alerts.xml</url> + <active /> + </tab> + <tab> + <text>Quarantine</text> + <url>/dspam-quarantine.php</url> + </tab> + <tab> + <text>Analysis</text> + <url>/dspam-analysis.php</url> + </tab> + <tab> + <text>History</text> + <url>/dspam-history.php</url> + </tab> + <tab> + <text>Train Filter</text> + <url>/dspam-train.php</url> + </tab> + <tab> + <text>Admin Suite</text> + <url>/dspam-admin.php</url> + </tab> + </tabs> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['dspam']['config']['alerts']</configpath> + <adddeleteeditpagefields> + <columnitem> + <fielddescr>Alert Name</fielddescr> + <fieldname>alertname</fieldname> + </columnitem> + <columnitem> + <fielddescr>Description</fielddescr> + <fieldname>description</fieldname> + </columnitem> + </adddeleteeditpagefields> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <fields> + <field> + <fielddescr>Alert Name</fielddescr> + <fieldname>alertname</fieldname> + <description>Name of an alert that should be raised</description> + <type>input</type> + <size>30</size> + <required /> + </field> + <field> + <fielddescr>Description</fielddescr> + <fieldname>description</fieldname> + <description>You may enter a description here for your reference (not parsed).</description> + <type>input</type> + <size>30</size> + </field> + </fields> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_delete_php_command> + dspam_configure(); + </custom_delete_php_command> + <custom_php_resync_config_command> + dspam_configure(); + </custom_php_resync_config_command> +</packagegui>
\ No newline at end of file diff --git a/config/dspam/pkg/freshclam.conf b/config/dspam/pkg/freshclam.conf new file mode 100644 index 00000000..173d97bf --- /dev/null +++ b/config/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/dspam/pkg/p3scan-pf-emer.xml b/config/dspam/pkg/p3scan-pf-emer.xml new file mode 100644 index 00000000..7475e23c --- /dev/null +++ b/config/dspam/pkg/p3scan-pf-emer.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + 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. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <!-- change this if configpath works --> + <name>p3scanpfemer</name> + <version>1.0</version> + <title>Services: POP3 Proxy: Emergency Contact</title> + <include_file>/usr/local/pkg/p3scan.inc</include_file> + <tabs> + <tab> + <text>Daemon Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf.xml&id=0</url> + </tab> + <tab> + <text>Message Processing</text> + <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&id=0</url> + </tab> + <tab> + <text>Emergency Contact</text> + <url>/pkg.php?xml=p3scan-pf-emer.xml</url> + <active /> + </tab> + <tab> + <text>Virus Scanner Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&id=0</url> + </tab> + <tab> + <text>SPAM Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&id=0</url> + </tab> + </tabs> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['p3scanpf']['config']['contacts']</configpath> + <!-- + adddeleteeditpagefields items will appear on the first page where you can + add / delete or edit items. An example of this would be the nat page where + you add new nat redirects + --> + <adddeleteeditpagefields> + <columnitem> + <fielddescr>Email Address</fielddescr> + <fieldname>emailaddress</fieldname> + </columnitem> + <columnitem> + <fielddescr>Description</fielddescr> + <fieldname>description</fieldname> + </columnitem> + </adddeleteeditpagefields> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <fields> + <field> + <fielddescr>Email Address</fielddescr> + <fieldname>emailaddress</fieldname> + <description> + 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. + </description> + <type>input</type> + </field> + <field> + <fielddescr>Description</fielddescr> + <fieldname>description</fieldname> + <description>Description.</description> + <type>input</type> + </field> + </fields> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_delete_php_command> + sync_package_p3scan(); + </custom_delete_php_command> + <custom_php_resync_config_command> + sync_package_p3scan(); + </custom_php_resync_config_command> +</packagegui> diff --git a/config/dspam/pkg/p3scan-pf-msg.xml b/config/dspam/pkg/p3scan-pf-msg.xml new file mode 100644 index 00000000..b2144fe6 --- /dev/null +++ b/config/dspam/pkg/p3scan-pf-msg.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + 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. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <!-- change this if configpath works --> + <name>p3scanpfmsg</name> + <version>1.0</version> + <title>Services: POP3 Proxy: Message Processing</title> + <note> + 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! + </note> + <aftersaveredirect>pkg_edit.php?xml=p3scan-pf-msg.xml&id=0</aftersaveredirect> + <include_file>/usr/local/pkg/p3scan.inc</include_file> + <tabs> + <tab> + <text>Daemon Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf.xml&id=0</url> + </tab> + <tab> + <text>Message Processing</text> + <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&id=0</url> + <active /> + </tab> + <tab> + <text>Emergency Contact</text> + <url>/pkg.php?xml=p3scan-pf-emer.xml</url> + </tab> + <tab> + <text>Virus Scanner Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&id=0</url> + </tab> + <tab> + <text>SPAM Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&id=0</url> + </tab> + </tabs> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['p3scanpf']['config']['messaging']</configpath> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <fields> + <field> + <fielddescr>Just Delete</fielddescr> + <fieldname>justdelete</fieldname> + <description> + Instead of keeping an infected message in the Virus Directory, delete it + after reporting it to the user. + </description> + <type>checkbox</type> + <donotdisable>true</donotdisable> + </field> + <field> + <fielddescr>Bytes Free</fielddescr> + <fieldname>bytesfree</fieldname> + <description>The number of KB's there must be free before processing any mail.</description> + <type>input</type> + <required /> + <default_value>10000</default_value> + </field> + <field> + <fielddescr>Broken Email Clients</fielddescr> + <fieldname>brokenec</fieldname> + <description> + Some email clients may require special processing. + </description> + <type>checkbox</type> + <donotdisable>true</donotdisable> + </field> + <field> + <fielddescr>ISP Spam</fielddescr> + <fieldname>ispspam</fieldname> + <description> + 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. + </description> + <type>input</type> + <default_value>-- Spam --</default_value> + </field> + <field> + <fielddescr>Subject</fielddescr> + <fieldname>subject</fieldname> + <description> + This option can be used to change the default subject line when + reporting a virus infected message. + </description> + <type>input</type> + <size>60</size> + <required /> + <default_value>Subject: "[Virus] found in a mail to you:" <virus name></default_value> + </field> + <field> + <fielddescr>Notify</fielddescr> + <fieldname>notify</fieldname> + <description> + 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. + </description> + <type>input</type> + <size>60</size> + <required /> + <default_value>Per instruction, the message has been deleted.</default_value> + </field> + <field> + <fielddescr>SMTP Reject</fielddescr> + <fieldname>smtpreject</fieldname> + <description> + 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". + </description> + <type>input</type> + <size>60</size> + <required /> + <default_value>Virus detected! P3scan rejected message!</default_value> + </field> + <field> + <fielddescr>Check SMTP size</fielddescr> + <fieldname>checksize</fieldname> + <description> + 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. + </description> + <type>input</type> + <default_value>1024</default_value> + </field> + <field> + <fielddescr>Footer</fielddescr> + <fieldname>footer</fieldname> + <description> + 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. + </description> + <type>input</type> + <size>40</size> + <default_value>/usr/local/bin/clamdscan -V</default_value> + </field> + </fields> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_php_resync_config_command> + sync_package_p3scan(); + </custom_php_resync_config_command> +</packagegui> diff --git a/config/dspam/pkg/p3scan-pf-spam.xml b/config/dspam/pkg/p3scan-pf-spam.xml new file mode 100644 index 00000000..eae78a0f --- /dev/null +++ b/config/dspam/pkg/p3scan-pf-spam.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + 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. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <!-- change this if configpath works --> + <name>p3scanpfspam</name> + <version>1.0</version> + <title>Services: POP3 Proxy: SPAM Settings</title> + <note> + 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! + </note> + <aftersaveredirect>pkg_edit.php?xml=p3scan-pf-spam.xml&id=0</aftersaveredirect> + <include_file>/usr/local/pkg/p3scan.inc</include_file> + <tabs> + <tab> + <text>Daemon Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf.xml&id=0</url> + </tab> + <tab> + <text>Message Processing</text> + <url>pkg_edit.php?xml=p3scan-pf-msg.xml&id=0</url> + </tab> + <tab> + <text>Emergency Contact</text> + <url>/pkg.php?xml=p3scan-pf-emer.xml</url> + </tab> + <tab> + <text>Virus Scanner Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&id=0</url> + </tab> + <tab> + <text>SPAM Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&id=0</url> + <active /> + </tab> + </tabs> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['p3scanpf']['config']['spam']</configpath> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <fields> + <field> + <fielddescr>Enable Spam Checking</fielddescr> + <fieldname>checkspam</fieldname> + <description> + If set, will scan for Spam before scanning for a virus. + </description> + <type>checkbox</type> + <donotdisable>true</donotdisable> + <enablefields>spamcheck</enablefields> + </field> + <field> + <fielddescr>SPAM Executable Command</fielddescr> + <fieldname>spamcheck</fieldname> + <description>The command (plus arguments) that should be invoked to check for SPAM messages.</description> + <type>input</type> + <size>70</size> + <default_value> + /usr/local/bin/dspam --user dspamuser --mode=teft --stdout --deliver=innocent,spam --feature=ch,no,wh + </default_value> + </field> + </fields> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_php_resync_config_command> + sync_package_p3scan(); + </custom_php_resync_config_command> +</packagegui> diff --git a/config/dspam/pkg/p3scan-pf-vir.xml b/config/dspam/pkg/p3scan-pf-vir.xml new file mode 100644 index 00000000..ed68b8cf --- /dev/null +++ b/config/dspam/pkg/p3scan-pf-vir.xml @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + 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. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <!-- change this if configpath works --> + <name>p3scanpfvir</name> + <version>1.0</version> + <title>Services: POP3 Proxy: Virus Scanner Settings</title> + <note> + 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! + </note> + <aftersaveredirect>pkg_edit.php?xml=p3scan-pf-vir.xml&id=0</aftersaveredirect> + <include_file>/usr/local/pkg/p3scan.inc</include_file> + <tabs> + <tab> + <text>Daemon Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf.xml&id=0</url> + </tab> + <tab> + <text>Message Processing</text> + <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&id=0</url> + </tab> + <tab> + <text>Emergency Contact</text> + <url>/pkg.php?xml=p3scan-pf-emer.xml</url> + </tab> + <tab> + <text>Virus Scanner Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&id=0</url> + <active /> + </tab> + <tab> + <text>SPAM Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&id=0</url> + </tab> + </tabs> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['p3scanpf']['config']['virus']</configpath> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <fields> + <field> + <fielddescr>Scanner Type</fielddescr> + <fieldname>scannertype</fieldname> + <description>Select here which type of scanner you want to use.</description> + <type>select</type> + <size>1</size> + <default_value>clamd</default_value> + <options> + <option><name>Kaspersky Anti-Virus for Linux</name><value>avpd</value></option> + <option><name>Kaspersky Anti-Virus for Linux (New)</name><value>avpd_new</value></option> + <option><name>Shell Script</name><value>bash</value></option> + <option><name>Default Scanner Type</name><value>basic</value></option> + <option><name>Clam Anti-Virus</name><value>clamd</value></option> + <option><name>Trophie Daemon</name><value>trophie</value></option> + </options> + </field> + <field> + <fielddescr>Virusscanner</fielddescr> + <fieldname>scanner</fieldname> + <description>Depends on scannertype.</description> + <type>input</type> + <required /> + <default_value>127.0.0.1:3310</default_value> + </field> + <field> + <fielddescr>Scanner Returncode</fielddescr> + <fieldname>viruscode</fieldname> + <description> + Specify the returncode(s) which the scanner returns when + the mail is infected. + </description> + <type>input</type> + <default_value>1</default_value> + </field> + <field> + <fielddescr>Good Scanner return codes</fielddescr> + <fieldname>goodcode</fieldname> + <description> + 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. + </description> + <type>input</type> + </field> + <field> + <fielddescr>Regular Expression for Virusname</fielddescr> + <fieldname>virusregexp</fieldname> + <description> + Specify here a regular expression which describes where the name of + the virus can be found. + </description> + <type>input</type> + <default_value>.*: (.*) FOUND</default_value> + </field> + <field> + <fielddescr>deMIME Setting</fielddescr> + <fieldname>demime</fieldname> + <description> + 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. + </description> + <type>checkbox</type> + <donotdisable>true</donotdisable> + </field> + </fields> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_php_resync_config_command> + sync_package_p3scan(); + </custom_php_resync_config_command> +</packagegui> diff --git a/config/dspam/pkg/p3scan-pf.xml b/config/dspam/pkg/p3scan-pf.xml new file mode 100644 index 00000000..f78c3912 --- /dev/null +++ b/config/dspam/pkg/p3scan-pf.xml @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "../../schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="../../xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + authng.xml + part of pfSense (http://www.pfSense.com) + Copyright (C) 2007 Daniel S. Haischt <me@daniel.stefan.haischt.name> + All rights reserved. + + Based on m0n0wall (http://m0n0.ch/wall) + Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>. + 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. + */ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>p3scanpf</name> + <version>1.0</version> + <title>Services: POP3 Proxy: Main</title> + <note> + 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! + </note> + <aftersaveredirect>pkg_edit.php?xml=p3scan-pf.xml&id=0</aftersaveredirect> + <include_file>/usr/local/pkg/p3scan.inc</include_file> + <!-- Menu is where this packages menu will appear --> + <menu> + <name>p3scan</name> + <tooltiptext>A transparent POP3-Proxy with virus-scanning capabilities</tooltiptext> + <section>Services</section> + <configfile>p3scan.xml</configfile> + </menu> + <service> + <name>p3scan-pf</name> + <rcfile>/usr/local/etc/rc.d/030.p3scan.sh</rcfile> + </service> + <tabs> + <tab> + <text>Daemon Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf.xml&id=0</url> + <active /> + </tab> + <tab> + <text>Message Processing</text> + <url>/pkg_edit.php?xml=p3scan-pf-msg.xml&id=0</url> + </tab> + <tab> + <text>Emergency Contact</text> + <url>/pkg.php?xml=p3scan-pf-emer.xml</url> + </tab> + <tab> + <text>Virus Scanner Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-vir.xml&id=0</url> + </tab> + <tab> + <text>SPAM Settings</text> + <url>/pkg_edit.php?xml=p3scan-pf-spam.xml&id=0</url> + </tab> + </tabs> + <!-- + configpath gets expanded out automatically and config items + will be stored in that location + --> + <configpath>['installedpackages']['p3scanpf']['config']</configpath> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/p3scan-pf-msg.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/p3scan-pf-emer.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/p3scan-pf-vir.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/p3scan-pf-spam.xml</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/www/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/p3scan_rules.php</item> + </additional_files_needed> + <additional_files_needed> + <prefix>/usr/local/pkg/</prefix> + <chmod>0755</chmod> + <item>http://www.pfsense.com/packages/config/p3scan.inc</item> + </additional_files_needed> + <!-- + fields gets invoked when the user adds or edits a item. The following items + will be parsed and rendered for the user as a gui with input, and selectboxes. + --> + <fields> + <field> + <fielddescr>Max Child's</fielddescr> + <fieldname>maxchilds</fieldname> + <description>The maximum number of connections we will handle at once.</description> + <type>input</type> + <default_value>10</default_value> + </field> + <field> + <fielddescr>IP Address</fielddescr> + <fieldname>ipaddr</fieldname> + <description>The <acronym title="Internet Protocol">IP</acronym> Address we listen on.</description> + <type>input</type> + <required /> + <default_value>0.0.0.0</default_value> + </field> + <field> + <fielddescr>Port</fielddescr> + <fieldname>port</fieldname> + <description>The <acronym title="Transmission Control Protocol">TCP</acronym> port on we should listen.</description> + <type>input</type> + <required /> + <default_value>8110</default_value> + </field> + <field> + <fielddescr>SSL Port</fielddescr> + <fieldname>sslport</fieldname> + <description>The TCP <acronym title="Secure Sockets Layer">SSL</acronym> port on we should listen.</description> + <type>input</type> + <required /> + <default_value>995</default_value> + </field> + <field> + <fielddescr>Target IP</fielddescr> + <fieldname>targetip</fieldname> + <description>Target IP is the IP to connect (0.0.0.0 enables transparent mode).</description> + <type>input</type> + <required /> + <default_value>0.0.0.0</default_value> + </field> + <field> + <fielddescr>Target Port</fielddescr> + <fieldname>targetport</fieldname> + <description>Target Port is the port to connect.</description> + <type>input</type> + <required /> + <default_value>8110</default_value> + </field> + <field> + <fielddescr>Email Port</fielddescr> + <fieldname>emailport</fieldname> + <description>The port we should listen on to scan outgoing email messages.</description> + <type>input</type> + <required /> + <default_value>25</default_value> + </field> + <field> + <fielddescr>Daemon User</fielddescr> + <fieldname>daemonuser</fieldname> + <description>The username the daemon should run as.</description> + <type>input</type> + <required /> + <default_value>root</default_value> + </field> + </fields> + <!-- + Arbitrary PHP Code, that gets executed if a certain event gets triggered. + --> + <custom_delete_php_command> + sync_package_p3scan(); + </custom_delete_php_command> + <custom_php_resync_config_command> + sync_package_p3scan(); + </custom_php_resync_config_command> + <custom_php_install_command> + custom_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + custom_php_deinstall_command(); + </custom_php_deinstall_command> +</packagegui> diff --git a/config/dspam/pkg/p3scan.inc b/config/dspam/pkg/p3scan.inc new file mode 100644 index 00000000..7d675050 --- /dev/null +++ b/config/dspam/pkg/p3scan.inc @@ -0,0 +1,277 @@ +<?php +/* $Id$ */ +/* Copyright (C) 2006 Daniel S. Haischt */ + +/* include all configuration functions */ +require_once("functions.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 = 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:\" <virus name>\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 = <<<EOD +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 & + +EOD; + + $stop = "/usr/bin/killall p3scan\n" . + "sleep 2"; + + write_rcfile(array( + "file" => "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 +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Content-Type: text/plain; + charset="iso-8859-1" + +Hello %USERNAME%. +This message body was generated automatically from P3Scan, which runs on +%HOSTNAME%.%DOMAINNAME% for scanning all incoming email. + +It replaces the body of a message sent to you that contained a VIRUS! + +Instead of the infected email this message has been sent to you. + +You may look at the message header of this message for the complete +email header information of the infected message. + +Virus name: + %VIRUSNAME% +(Supposed) Sender of the email: + %MAILFROM% +Sent To: + %MAILTO% +On Date: + %MAILDATE% +Subject: + %SUBJECT% +Connection data: + %PROTOCOL% from %CLIENTIP%:%CLIENTPORT% to %SERVERIP%:%SERVERPORT% +Message File: + %P3SCANID% +Virus Definition Info: + %VDINFO% +-- +%PROGNAME% %VERSION% +by Jack S. Lai <laitcg@cox.net> + +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/dspam/pkg/verdana.ttf b/config/dspam/pkg/verdana.ttf Binary files differnew file mode 100644 index 00000000..754a9b7b --- /dev/null +++ b/config/dspam/pkg/verdana.ttf diff --git a/config/dspam/www/dspam-admin-graph.php b/config/dspam/www/dspam-admin-graph.php new file mode 100644 index 00000000..508824e2 --- /dev/null +++ b/config/dspam/www/dspam-admin-graph.php @@ -0,0 +1,201 @@ +<?php +/* $Id$ */ +/* + dspam-admin-graph.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +/* required because of system_groupmanager.php */ +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("System Status"), + gettext("Graph")); + +require_once 'Image/Graph.php'; +require_once 'Image/Canvas.php'; +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (! $_GET || + strlen($_SERVER['QUERY_STRING']) == 0 || + ! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + return; +} + +$FORM =& ReadParse($_SERVER['QUERY_STRING']); + +list($spam, $nonspam, $sm, $fp, $inoc, $wh, $period) = split('_', $FORM['data']); +$spam = split(',', $spam); +$nonspam = split(',', $nonspam); +$sm = split(',', $sm); +$fp = split(',', $fp); +$inoc = split(',', $inoc); +$wh = split(',', $wh); +$period = split(',', $period); + +// create a PNG canvas and enable antialiasing (canvas implementation) +$Canvas =& Image_Canvas::factory('png', array('width' => 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/dspam/www/dspam-admin-prefs.php b/config/dspam/www/dspam-admin-prefs.php new file mode 100644 index 00000000..324d961f --- /dev/null +++ b/config/dspam/www/dspam-admin-prefs.php @@ -0,0 +1,249 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Admin Preferences")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + + $pfSenseHead->addScript($jscriptstr); + echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-admin-prefs.php" method="post" name="iform" id="iform"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + This page lets you configure how the filter will handle your messages. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("System Status", false, "/dspam-admin.php?user={$CURRENT_USER}"); + $tab_array[] = array("User Statistics", false, "/dspam-admin-stats.php?user={$CURRENT_USER}"); + $tab_array[] = array("Administration", true, "/dspam-admin-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Settings", false, "/dspam-settings.php?user={$CURRENT_USER}"); + $tab_array[] = array("Control Center", false, "/dspam.php?user={$CURRENT_USER}"); + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Username</td> + <td width="78%" class="vtable"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>Training</strong> – Configure how the filter learns as it processes messages + </td> + </tr> + <tr> + <td align="left" valign="top" class="vncell" width="40%"> + <p>DSPAM should train:</p> + <input <?= $DATA["S_TEFT"]; ?> 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" /> + <label for="rad_train_one"> On every new message scanned by the filter (TEFT)</label> + <br /> + <input <?= $DATA["S_TOE"]; ?> 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" /> + <label for="rad_train_two"> Only when the filter makes a mistake (TOE)</label> + <br /> + <input <?= $DATA["S_TUM"]; ?> 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" /> + <label for="rad_train_three"> Only with new data or if the filter makes a mistake (TUM)</label> + </td> + <td align="left" valign="top" class="vncell" width="60%"> + <p>When I train DSPAM, I prefer:</p> + <input value="message" <?= $DATA["S_LOC_MESSAGE"]; ?> 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" /> + <label for="rad_train_action_one"> To <u>forward</u> my spams (signature appears in message body)</label> + <br /> + <input <?= $DATA["S_LOC_HEADERS"]; ?> 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" /> + <label value="headers" for="rad_train_action_two"> To <u>bounce</u> my spams (signature appears in message headers)</label> + </td> + </tr> + <tr> + <td align="left" valign="middle" class="vncell" colspan="2"> + <p> + Filter sensitivity <strong>during</strong> the training period: + </p> + <p align="center"> + <nobr> + <span> + Catch SPAM (More in Quarantine) + <input value="0" type="radio" class="formfld" title="-5" alt="-5" name="rad_filter_sens" <?= $DATA["SEDATION_0"]; ?> /> + <input value="1" type="radio" class="formfld" title="-4" alt="-4" name="rad_filter_sens" <?= $DATA["SEDATION_1"]; ?> /> + <input value="2" type="radio" class="formfld" title="-3" alt="-3" name="rad_filter_sens" <?= $DATA["SEDATION_2"]; ?> /> + <input value="3" type="radio" class="formfld" title="-2" alt="-2" name="rad_filter_sens" <?= $DATA["SEDATION_3"]; ?> /> + <input value="4" type="radio" class="formfld" title="-1" alt="-1" name="rad_filter_sens" <?= $DATA["SEDATION_4"]; ?> /> + <strong style="font-size: larger;">»</strong> + <input value="5" type="radio" class="formfld" title="0" alt="0" name="rad_filter_sens" <?= $DATA["SEDATION_5"]; ?> /> + <strong style="font-size: larger;">«</strong> + <input value="6" type="radio" class="formfld" title="1" alt="1" name="rad_filter_sens" <?= $DATA["SEDATION_6"]; ?> /> + <input value="7" type="radio" class="formfld" title="2" alt="2" name="rad_filter_sens" <?= $DATA["SEDATION_7"]; ?> /> + <input value="8" type="radio" class="formfld" title="3" alt="3" name="rad_filter_sens" <?= $DATA["SEDATION_8"]; ?> /> + <input value="9" type="radio" class="formfld" title="4" alt="4" name="rad_filter_sens" <?= $DATA["SEDATION_9"]; ?> /> + <input value="10" type="radio" class="formfld" title="5" alt="5" name="rad_filter_sens" <?= $DATA["SEDATION_10"]; ?> /> + Assume Good (Fewer in Quarantine) + </span> + </nobr> + </p> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>Message Handling</strong> – Configure how SPAM is handled + </td> + </tr> + <tr> + <td align="left" valign="top" class="vncell" colspan="2"> + <p>When a SPAM message is identified:</p> + <p> + <input value="quarantine" <?= $DATA["S_ACTION_QUARANTINE"]; ?> type="radio" class="formfld" title="Quarantine the message" alt="Quarantine the message" name="rad_ident_action" id="rad_ident_action_one" /> + <label for="rad_ident_action_one"> Quarantine the message</label> + <br /> + <input value="tag" <?= $DATA["S_ACTION_TAG"]; ?> 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" /> + <label for="rad_ident_action_two">Tag the Subject header with </label> + <input size="35" type="text" class="formfld mail" title="message tag" alt="message tag" value="<?= $DATA["SPAM_SUBJECT"]; ?>" name="msgtag" /> + <br /> + <input value="deliver" <?= $DATA["S_ACTION_DELIVER"]; ?> 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" /> + <label for="rad_ident_action_three"> Deliver the message normally with a X-DSPAM-Result header</label> + </p> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>Features</strong> – Tuning SPAM filtering + </td> + </tr> + <tr> + <td align="left" valign="top" class="vncell" colspan="2"> + <p> + <input <?= $DATA["C_BNR"]; ?> 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" /> + <label for="chk_feature_nr"> Enable noise reduction, which usually improves filtering accuracy</label> + <br /> + <input <?= $DATA["C_WHITELIST"]; ?> 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" /> + <label for="chk_feature_aw"> Enable automatic whitelisting to record frequent correspondence</label> + <br /> + <input <?= $DATA["C_FACTORS"]; ?> 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" /> + <label for="chk_feature_at"> Add the factoring tokens in each email into the message's full headers</label> + <!-- + <input 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" /> + <label for="chk_feature_at"> Add the factoring tokens in each email into the message's full headers</label> + <br /> + <input type="checkbox" class="formbtn" title="opt in of DSPAM filtering" alt="opt in of DSPAM filtering" name="chk_feature_optin" id="chk_feature_optin" /> + <label for="chk_feature_optin"> opt in of DSPAM filtering</label> + <br /> + <input type="checkbox" class="formbtn" title="opt out of DSPAM filtering" alt="opt out of DSPAM filtering" name="chk_feature_optout" id="chk_feature_optout" /> + <label for="chk_feature_optout"> opt out of DSPAM filtering</label> + --> + </p> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td class="list"> </td> + <td class="list"> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" /> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> +<? +} else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php +} // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-admin-stats.php b/config/dspam/www/dspam-admin-stats.php new file mode 100644 index 00000000..82b91831 --- /dev/null +++ b/config/dspam/www/dspam-admin-stats.php @@ -0,0 +1,123 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("User Statistics")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-admin-stats.php" method="post" name="iform" id="iform"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + The following table shows the number of messages processed for each user + along with their current preference settings. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("System Status", false, "/dspam-admin.php?user={$CURRENT_USER}"); + $tab_array[] = array("User Statistics", true, "/dspam-admin-stats.php?user={$CURRENT_USER}"); + $tab_array[] = array("Administration", false, "/dspam-admin-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Settings", false, "/dspam-settings.php?user={$CURRENT_USER}"); + $tab_array[] = array("Control Center", false, "/dspam.php?user={$CURRENT_USER}"); + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="14">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Username</td> + <td width="78%" class="vtable" colspan="13"> + <strong><?= $CURRENT_USER ?></strong> + </td> + </tr> + <tr> + <td colspan="14" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic">Name</td> + <td align="left" valign="top" class="listtopic">Q.Size</td> + <td align="left" valign="top" class="listtopic">TP</td> + <td align="left" valign="top" class="listtopic">TN</td> + <td align="left" valign="top" class="listtopic">FP</td> + <td align="left" valign="top" class="listtopic">FN</td> + <td align="left" valign="top" class="listtopic">SC</td> + <td align="left" valign="top" class="listtopic">IC</td> + <td align="left" valign="top" class="listtopic">Mode</td> + <td align="left" valign="top" class="listtopic">On Spam</td> + <td align="left" valign="top" class="listtopic">BNR</td> + <td align="left" valign="top" class="listtopic">Whitelist</td> + <td align="left" valign="top" class="listtopic">Sed</td> + <td align="left" valign="top" class="listtopic">Sig Loc</td> + </tr> + <?= $DATA['TABLE']; ?> + </table> + </div> + </td> + </tr> +</table> +</form> +<? +} else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php +} // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-admin.php b/config/dspam/www/dspam-admin.php new file mode 100644 index 00000000..45b33b55 --- /dev/null +++ b/config/dspam/www/dspam-admin.php @@ -0,0 +1,207 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("System Status"), + gettext("Overview")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-admin.php" method="post" name="iform" id="iform"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + The following graphs and tables summarize the processing done by the filter. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("System Status", true, "/dspam-admin.php?user={$CURRENT_USER}"); + $tab_array[] = array("User Statistics", false, "/dspam-admin-stats.php?user={$CURRENT_USER}"); + $tab_array[] = array("Administration", false, "/dspam-admin-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Settings", false, "/dspam-settings.php?user={$CURRENT_USER}"); + $tab_array[] = array("Control Center", false, "/dspam.php?user={$CURRENT_USER}"); + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="10%" valign="baseline" class="vncell">Username</td> + <td width="90%" class="vtable"> + <strong><?= $CURRENT_USER ?></strong> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" align="left" valign="top" class="listtopic"> + <strong>Overview</strong> + </td> + </tr> + <tr> + <td colspan="2" align="center" valign="top" class="vncell"> + <table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr">Messages</td> + <td align="left" valign="top" class="listhdrr">Today</td> + <td align="left" valign="top" class="listhdrr">This Hour</td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="listhdrr">Status</td> + <td align="left" valign="top" class="listhdrr">Current Value</td> + </tr> + <tr> + <td align="left" valign="top" class="listr">Spam</td> + <td align="left" valign="top" class="listr"><?= $DATA['SPAM_TODAY']; ?></td> + <td align="left" valign="top" class="listr"><?= $DATA['SPAM_THIS_HOUR']; ?></td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="listr">Average message processing time</td> + <td align="left" valign="top" class="listr"><?= $DATA['AVG_PROCESSING_TIME']; ?> sec.</td> + </tr> + <tr> + <td align="left" valign="top" class="listr">Good</td> + <td align="left" valign="top" class="listr"><?= $DATA['NONSPAM_TODAY']; ?></td> + <td align="left" valign="top" class="listr"><?= $DATA['NONSPAM_THIS_HOUR']; ?></td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="listr">Average throughput</td> + <td align="left" valign="top" class="listr"><?= $DATA['AVG_MSG_PER_SECOND']; ?> messages/sec.</td> + </tr> + <tr> + <td align="left" valign="top" class="listr">Spam Misses</td> + <td align="left" valign="top" class="listr"><?= $DATA['SM_TODAY']; ?></td> + <td align="left" valign="top" class="listr"><?= $DATA['SM_THIS_HOUR']; ?></td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="listr">DSPAM instances</td> + <td align="left" valign="top" class="listr"><?= $DATA['DSPAM_PROCESSES']; ?> process(es)</td> + </tr> + <tr> + <td align="left" valign="top" class="listr">False Positives</td> + <td align="left" valign="top" class="listr"><?= $DATA['FP_TODAY']; ?></td> + <td align="left" valign="top" class="listr"><?= $DATA['FP_THIS_HOUR']; ?></td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="listr">System uptime</td> + <td align="left" valign="top" class="listr"><?= $DATA['UPTIME']; ?></td> + </tr> + <tr> + <td align="left" valign="top" class="listr">Inoculations</td> + <td align="left" valign="top" class="listr"><?= $DATA['INOC_TODAY']; ?></td> + <td align="left" valign="top" class="listr"><?= $DATA['INOC_THIS_HOUR']; ?></td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="listr">Mail queue length</td> + <td align="left" valign="top" class="listr"><?= $DATA['MAIL_QUEUE']; ?> messages</td> + </tr> + <tr> + <td align="left" valign="top" class="listbgns"><strong>Total</strong></td> + <td align="left" valign="top" class="listbgns"><strong><?= $DATA['TOTAL_TODAY']; ?></strong></td> + <td align="left" valign="top" class="listbgns"><strong><?= $DATA['TOTAL_THIS_HOUR']; ?></strong></td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="list"> </td> + <td align="left" valign="top" class="list"> </td> + </tr> + </table> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" align="left" valign="top" class="listtopic"> + <strong>24 Hour Activity</strong> – 125 SPAM, 601 Good, 2 Spam Misses, 0 False Positives, 2 Inoculations + </td> + </tr> + <tr> + <td colspan="2" align="center" valign="top" class="vncell"> + <?php if(isset($_GET['test'])): ?> + <img src="/dspam-admin-graph.php?data=1,2,5,6,2,6,3,1,3,9,5,2,4,8,9,6,9,2,6,8,3,3,5,2_4,22,12,9,11,10,10,8,2,9,9,27,18,26,20,20,11,14,27,69,51,108,86,43_0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0_0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0_0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0_2,8,3,9,7,4,3,2,2,,4,7,6,3,4,6,2,7,4,17,5,3,10,1_10:00pm,11:00pm,12:00am,1:00am,2:00am,3:00am,4:00am,5:00am,6:00am,7:00am,8:00am,9:00am,10:00am,11:00am,12:00pm,1:00pm,2:00pm,3:00pm,4:00pm,5:00pm,6:00pm,7:00pm,8:00pm,9:00pm&x_label=Hour+of+the+day&offset=35" alt="24 Hour Activity" border="0" /> + <?php else: ?> + <img src="/dspam-admin-graph.php?data=<?= $DATA['DATA_DAILY']; ?>&x_label=<?= urlencode("Hour of the day"); ?>&offset=20" alt="24 Hour Activity" border="0" /> + <?php endif; ?> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" align="left" valign="top" class="listtopic"> + <strong>Daily Activity</strong> – 2457 SPAM, 10772 Good, 35 Spam Misses, 0 False Positives, 33 Inoculations + </td> + </tr> + <tr> + <td colspan="2" align="center" valign="top" class="vncell"> + <?php if(isset($_GET['test'])): ?> + <img src="/dspam-admin-graph.php?data=105,98,54,104,85,94,93,103,115,122,109,94,77,103,116,105,112,103,97,83,87,99,97,126,107_368,339,326,395,367,166,176,325,376,382,458,305,149,134,335,396,388,368,403,220,142,534,312,595,600_0,2,0,2,1,3,0,1,4,1,0,0,0,1,2,1,2,1,2,3,4,1,1,2,0_0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0_1,1,2,1,4,1,0,3,1,0,2,0,2,1,2,1,1,5,0,1,0,0,0,2,4_129,142,76,184,139,55,51,94,107,139,168,130,70,63,123,140,118,96,108,88,46,110,133,143,109_5/29/2006,5/30/2006,5/31/2006,6/1/2006,6/2/2006,6/3/2006,6/4/2006,6/5/2006,6/6/2006,6/7/2006,6/8/2006,6/9/2006,6/10/2006,6/11/2006,6/12/2006,6/13/2006,6/14/2006,6/15/2006,6/16/2006,6/17/2006,6/18/2006,6/19/2006,6/20/2006,6/21/2006,6/22/2006&graph=period&x_label=Date&offset=45" border="0" /> + <?php else: ?> + <img src="/dspam-admin-graph.php?data=<?= $DATA['DATA_WEEKLY']; ?>&graph=period&x_label=Date&offset=45" border="0" /> + <?php endif; ?> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> +<? +} else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php +} // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-analysis-graph.php b/config/dspam/www/dspam-analysis-graph.php new file mode 100644 index 00000000..67262564 --- /dev/null +++ b/config/dspam/www/dspam-analysis-graph.php @@ -0,0 +1,137 @@ +<?php +/* $Id$ */ +/* + dspam-analysis-graph.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +/* required because of system_groupmanager.php */ +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Analysis"), + gettext("Graph")); + +require_once 'Image/Graph.php'; +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (! $_GET || + strlen($_SERVER['QUERY_STRING']) == 0) { + return; +} + +$FORM =& ReadParse($_SERVER['QUERY_STRING']); + +list($spam, $nonspam, $period) = split('_', $FORM['data']); +$spam_day = split(',', $spam); +$nonspam_day = split(',', $nonspam); +$period = split(',', $period); + +// create the graph +$Graph =& Image_Graph::factory('graph', array(725, 300)); + +// add a TrueType font +$Font =& $Graph->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/dspam/www/dspam-analysis.php b/config/dspam/www/dspam-analysis.php new file mode 100644 index 00000000..f80bd54b --- /dev/null +++ b/config/dspam/www/dspam-analysis.php @@ -0,0 +1,147 @@ +<?php +/* $Id$ */ +/* + dspam-analysis.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Analysis"), + gettext("Overview")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +/* if this is an AJAX caller then handle via JSON */ +if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-analysis.php" method="post" name="iform" id="iform"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + Graphs showing the number of messages that have been processed are shown below. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", false, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", true, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", false, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="10%" valign="baseline" class="vncell">Username</td> + <td width="90%" class="vtable"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>24 Hour Activity</strong> – <?= $DATA['TS_DAILY']; ?> SPAM, <?= $DATA['TI_DAILY']; ?> Good + </td> + </tr> + <tr> + <td align="center" valign="top" class="vncell" colspan="2"> + <?php if(isset($_GET['test'])): ?> + <img src="/dspam-analysis-graph.php?data=0,0,1,0,1_1,4,0,1,0_4p,6p,7a,11a,2p&x_label=Hour+of+the+day" alt="24 Hour Activity" border="0" /> + <?php else: ?> + <img src="/dspam-analysis-graph.php?data=<?= $DATA['DATA_DAILY']; ?>&x_label=<?= urlencode("Hour of the day"); ?>" alt="24 Hour Activity" border="0" /> + <?php endif; ?> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>14 Day Activity</strong> – <?= $DATA['TS_WEEKLY']; ?> SPAM, <?= $DATA['TI_WEEKLY']; ?> Good + </td> + </tr> + <tr> + <td align="center" valign="top" class="vncell" colspan="2"> + <?php if(isset($_GET['test'])): ?> + <img src="/dspam-analysis-graph.php?data=1,2,0,2,1,2,2,1,4,0,0,2,0,2_5,2,3,5,12,20,7,9,9,8,7,12,6,1_6/9,6/10,6/11,6/12,6/13,6/14,6/15,6/16,6/17,6/18,6/19,6/20,6/21,6/22&graph=period&x_label=Date" alt="24 Hour Activity" border="0" /> + <?php else: ?> + <img src="/dspam-analysis-graph.php?data=<?= $DATA['DATA_WEEKLY']; ?>&graph=period&x_label=Date" alt="24 Hour Activity" border="0" /> + <?php endif; ?> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-hfragment.php b/config/dspam/www/dspam-hfragment.php new file mode 100644 index 00000000..36152a00 --- /dev/null +++ b/config/dspam/www/dspam-hfragment.php @@ -0,0 +1,90 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("History"), + gettext("Fragement")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +/* if this is an AJAX caller then handle via JSON */ +if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?{$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", false, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", true, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php?user={$CURRENT_USER}"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="list" width="10%"> + <br /> + <font color=white><big><?= $DATA['SUBJECT']; ?></big><br /> + <?= $DATA['FROM']; ?><br /> + <small><?= $DATA['TIME']; ?> (<?= $DATA['INFO']; ?>)</small></font><br /> + <br /> + </td> + </tr> + <tr> + <td class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="middle" class="list"> + <pre> + <?= $DATA['MESSSAGE']; ?> + </pre> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-history.php b/config/dspam/www/dspam-history.php new file mode 100644 index 00000000..cb5e4f2c --- /dev/null +++ b/config/dspam/www/dspam-history.php @@ -0,0 +1,172 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("History"), + gettext("Overview")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +/* if this is an AJAX caller then handle via JSON */ +if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= getJScriptFunction(4); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + +$pfSenseHead->addScript($jscriptstr); +$pfSenseHead->addLink("<link rel=\"stylesheet\" type=\"text/css\" href=\"/themes/" . $g['theme'] . "/dspam.css\" media=\"all\" />\n"); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-history.php" method="post" name="iform" id="iform"> +<input type="hidden" name="command" value="retrainChecked" /> +<input type="hidden" name="hpage" value="<?= $DATA['HPAGE']; ?>" /> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + 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. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", false, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", true, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="6">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell" colspan="2">Username</td> + <td width="78%" class="vtable" colspan="4"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="6" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="middle" class="qnavtdl" colspan="4"> + <input type="submit" class="formbtn" title="Retrain Checked" value="Retrain Checked" name="retrain_checked" id="retrain_checked_top" /> + <label for="retrain_checked_top"> because those messages have<strong>n't</strong> been correctly classified.</label> + </td> + <td align="right" valign="middle" class="qnavtdr" colspan="2"> + <label for="hperpage-top">Records per page: </label> + <select class="formselect" id="hperpage-top" name="hperpage" onchange="changeQPerPage(this);"> + <option value="25"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 25) echo ' selected="selected"'; ?>>25</option> + <option value="50"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 50) echo ' selected="selected"'; ?>>50</option> + <option value="75"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 75) echo ' selected="selected"'; ?>>75</option> + <option value="100"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 100) echo ' selected="selected"'; ?>>100</option> + <option value="125"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 125) echo ' selected="selected"'; ?>>125</option> + <option value="150"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 150) echo ' selected="selected"'; ?>>150</option> + </select> + </td> + </tr> + <tr> + <td class="list" height="12" colspan="6"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" width="10%">Type</td> + <td align="left" valign="top" class="listtopic" width="10%">Action</td> + <td align="left" valign="top" class="listtopic" width="10%">Day/Time</td> + <td align="left" valign="top" class="listtopic" width="25%">From</td> + <td align="left" valign="top" class="listtopic" width="25%">Subject</td> + <td align="left" valign="top" class="listtopic" width="20%">Additional Info</td> + </tr> + <?= $DATA['HISTORY']; ?> + <?= $DATA['HISTORY_FOOTER']; ?> + <tr> + <td colspan="6" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="middle" class="qnavtdl" colspan="4"> + <input type="submit" class="formbtn" title="Retrain Checked" value="Retrain Checked" name="retrain_checked" id="retrain_checked_bottom" /> + <label for="retrain_checked_bottom"> because those messages have<strong>n't</strong> correctly been classified.</label> + </td> + <td align="right" valign="middle" class="qnavtdr" colspan="2"> + <label for="hperpage-bottom">Records per page: </label> + <select class="formselect" id="hperpage-bottom" name="hperpage" onchange="changeQPerPage(this);"> + <option value="25"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 25) echo ' selected="selected"'; ?>>25</option> + <option value="50"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 50) echo ' selected="selected"'; ?>>50</option> + <option value="75"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 75) echo ' selected="selected"'; ?>>75</option> + <option value="100"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 100) echo ' selected="selected"'; ?>>100</option> + <option value="125"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 125) echo ' selected="selected"'; ?>>125</option> + <option value="150"<?php if ($CONFIG['HISTORY_PER_PAGE'] == 150) echo ' selected="selected"'; ?>>150</option> + </select> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-perf.php b/config/dspam/www/dspam-perf.php new file mode 100644 index 00000000..8b69319f --- /dev/null +++ b/config/dspam/www/dspam-perf.php @@ -0,0 +1,222 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Performance")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +/* if this is an AJAX caller then handle via JSON */ +if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + +$pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-perf.php" method="post" name="iform" id="iform"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + If you receive a message in your e-mail application that was not caught by + the filter, please forward it to <strong><?= $DATA['SPAM_ALIAS']; ?></strong> + so that it can be analyzed and learned as <acronym title="">SPAM</acronym>. + This will improve the filter's accuracy in the future. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", true, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", false, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", false, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Username</td> + <td width="78%" class="vtable"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>Performance Statistics</strong> – <?= date("l dS of F Y h:i:s A"); ?> + </td> + </tr> + <tr> + <td align="left" valign="top" colspan="2" class="vncell"> + <table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <!- beginn left info pane --> + <td align="left" valign="top"> + <table border="0" cellpadding="0" cellspacing="0" summary="left info pane"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Metric</td> + <td align="left" valign="top" class="listhdrr">Calculated as</td> + <td align="left" valign="top" class="list"></td> + </tr> + <tr> + <td align="left" valign="top" class="listr"> + <nobr>Overall accuracy (since last reset)</nobr> + </td> + <td align="left" valign="top" class="listr"> + <strong><?= $DATA['OVERALL_ACCURACY']; ?>%</strong> + </td> + <td align="left" valign="top" class="listr">(SPAM messages caught + Good messages delivered) / Total number of messages</td> + <td align="left" valign="top" class="none"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listr"> + <nobr>Spam identification (since last reset)</nobr> + </td> + <td align="left" valign="top" class="listr"> + <strong><?= $DATA['SPAM_ACCURACY']; ?>%</strong> + </td> + <td align="left" valign="top" class="listr">(Spam catch rate only)</td> + <td align="left" valign="top" class="none"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listr"> + <nobr>Spam ratio (of total processed)</nobr> + </td> + <td align="left" valign="top" class="listr"> + <strong><?= $DATA['SPAM_RATIO']; ?>%</strong> + </td> + <td align="left" valign="top" class="listr">Total SPAM messages (both caught & missed) / Total number of messages</td> + <td align="left" valign="top" class="none"> </td> + </tr> + </table> + </td> + <!-- spacer td --> + <td align="left" valign="top" class="none"> </td> + <!-- begin right info pane --> + <td align="left" valign="top"> + <table border="0" cellpadding="0" cellspacing="0" summary="right info pane"> + <tr id="frheader"> + <td class="list"> </td> + <td class="listhdrr">SPAM messages</td> + <td class="listhdrr">Good messages</td> + </tr> + <tr> + <td align="left" valign="top" class="listhdrr">Since last reset</td> + <td align="left" valign="top" class="listr"> + <nobr><?= $DATA['TOTAL_SPAM_MISSED']; ?> missed</nobr><br /> + <nobr><?= $DATA['TOTAL_SPAM_CAUGHT']; ?> caught</nobr><br /> + <nobr><?= $DATA['SPAM_ACCURACY']; ?>% caught</nobr><br /> + </td> + <td align="left" valign="top" class="listr"> + <nobr><?= $DATA['TOTAL_NONSPAM_MISSED']; ?> missed</nobr><br /> + <nobr><?= $DATA['TOTAL_NONSPAM_CAUGHT']; ?> delivered</nobr><br /> + <nobr><?= $DATA['NONSPAM_ERROR_RATE']; ?>% missed</nobr><br /> + </td> + </tr> + <tr> + <td align="left" valign="top" class="listhdrr">Total processed by filter</td> + <td align="left" valign="top" class="listr"> + <nobr><?= $DATA['TOTAL_SPAM_LEARNED']; ?> missed</nobr><br /> + <nobr><?= $DATA['TOTAL_SPAM_SCANNED']; ?> caught</nobr><br /> + </td> + <td align="left" valign="top" class="listr"> + <nobr><?= $DATA['TOTAL_NONSPAM_LEARNED']; ?> missed</nobr><br /> + <nobr><?= $DATA['TOTAL_NONSPAM_SCANNED']; ?> delivered</nobr><br /> + </td> + </tr> + <tr> + <td align="left" valign="top" class="listhdrr">From corpus</td> + <td align="left" valign="top" class="listr"> + <nobr><?= $DATA['TOTAL_SPAM_CORPUSFED']; ?> feed</nobr><br /> + </td> + <td align="left" valign="top" class="listr"> + <nobr><?= $DATA['TOTAL_NONSPAM_CORPUSFED']; ?> feed</nobr><br /> + </td> + </tr> + </table> + </td> + </table> + </td> + </tr> + <tr> + <td align="left" valign="top" colspan="2"> + <p> + <a href="/dspam-perf.php?user=<?= $CURRENT_USER ?>&command=resetStats">Reset</a> | <a href="/dspam-perf.php?user=<?= $CURRENT_USER ?>&command=tweak">Tweak -1</a> + </p> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-prefs.php b/config/dspam/www/dspam-prefs.php new file mode 100644 index 00000000..4e6b0f90 --- /dev/null +++ b/config/dspam/www/dspam-prefs.php @@ -0,0 +1,234 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Preferences")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +/* if this is an AJAX caller then handle via JSON */ +if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + +$pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-prefs.php" method="post" name="iform" id="iform"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + This page lets you configure how the filter will handle your messages. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", true, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", false, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", false, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Username</td> + <td width="78%" class="vtable"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER; ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>Training</strong> – Configure how the filter learns as it processes messages + </td> + </tr> + <tr> + <td align="left" valign="top" class="vncell" width="40%"> + <p>DSPAM should train:</p> + <input <?= $DATA["S_TEFT"]; ?> 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" /> + <label for="rad_train_one"> On every new message scanned by the filter (TEFT)</label> + <br /> + <input <?= $DATA["S_TOE"]; ?> 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" /> + <label for="rad_train_two"> Only when the filter makes a mistake (TOE)</label> + <br /> + <input <?= $DATA["S_TUM"]; ?> 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" /> + <label for="rad_train_three"> Only with new data or if the filter makes a mistake (TUM)</label> + </td> + <td align="left" valign="top" class="vncell" width="60%"> + <p>When I train DSPAM, I prefer:</p> + <input value="message" <?= $DATA["S_LOC_MESSAGE"]; ?> 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" /> + <label for="rad_train_action_one"> To <u>forward</u> my spams (signature appears in message body)</label> + <br /> + <input <?= $DATA["S_LOC_HEADERS"]; ?> 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" /> + <label value="headers" for="rad_train_action_two"> To <u>bounce</u> my spams (signature appears in message headers)</label> + </td> + </tr> + <tr> + <td align="left" valign="middle" class="vncell" colspan="2"> + <p> + Filter sensitivity <strong>during</strong> the training period: + </p> + <p align="center"> + <nobr> + <span> + Catch SPAM (More in Quarantine) + <input value="0" type="radio" class="formfld" title="-5" alt="-5" name="rad_filter_sens" <?= $DATA["SEDATION_0"]; ?> /> + <input value="1" type="radio" class="formfld" title="-4" alt="-4" name="rad_filter_sens" <?= $DATA["SEDATION_1"]; ?> /> + <input value="2" type="radio" class="formfld" title="-3" alt="-3" name="rad_filter_sens" <?= $DATA["SEDATION_2"]; ?> /> + <input value="3" type="radio" class="formfld" title="-2" alt="-2" name="rad_filter_sens" <?= $DATA["SEDATION_3"]; ?> /> + <input value="4" type="radio" class="formfld" title="-1" alt="-1" name="rad_filter_sens" <?= $DATA["SEDATION_4"]; ?> /> + <strong style="font-size: larger;">»</strong> + <input value="5" type="radio" class="formfld" title="0" alt="0" name="rad_filter_sens" <?= $DATA["SEDATION_5"]; ?> /> + <strong style="font-size: larger;">«</strong> + <input value="6" type="radio" class="formfld" title="1" alt="1" name="rad_filter_sens" <?= $DATA["SEDATION_6"]; ?> /> + <input value="7" type="radio" class="formfld" title="2" alt="2" name="rad_filter_sens" <?= $DATA["SEDATION_7"]; ?> /> + <input value="8" type="radio" class="formfld" title="3" alt="3" name="rad_filter_sens" <?= $DATA["SEDATION_8"]; ?> /> + <input value="9" type="radio" class="formfld" title="4" alt="4" name="rad_filter_sens" <?= $DATA["SEDATION_9"]; ?> /> + <input value="10" type="radio" class="formfld" title="5" alt="5" name="rad_filter_sens" <?= $DATA["SEDATION_10"]; ?> /> + Assume Good (Fewer in Quarantine) + </span> + </nobr> + </p> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>Message Handling</strong> – Configure how SPAM is handled + </td> + </tr> + <tr> + <td align="left" valign="top" class="vncell" colspan="2"> + <p>When a SPAM message is identified:</p> + <p> + <input value="quarantine" <?= $DATA["S_ACTION_QUARANTINE"]; ?> type="radio" class="formfld" title="Quarantine the message" alt="Quarantine the message" name="rad_ident_action" id="rad_ident_action_one" /> + <label for="rad_ident_action_one"> Quarantine the message</label> + <br /> + <input value="tag" <?= $DATA["S_ACTION_TAG"]; ?> 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" /> + <label for="rad_ident_action_two">Tag the Subject header with </label> + <input size="35" type="text" class="formfld mail" title="message tag" alt="message tag" value="<?= $DATA["SPAM_SUBJECT"]; ?>" name="msgtag" /> + <br /> + <input value="deliver" <?= $DATA["S_ACTION_DELIVER"]; ?> 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" /> + <label for="rad_ident_action_three"> Deliver the message normally with a X-DSPAM-Result header</label> + </p> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="top" class="listtopic" colspan="2"> + <strong>Features</strong> – Tuning SPAM filtering + </td> + </tr> + <tr> + <td align="left" valign="top" class="vncell" colspan="2"> + <p> + <input <?= $DATA["C_BNR"]; ?> 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" /> + <label for="chk_feature_nr"> Enable noise reduction, which usually improves filtering accuracy</label> + <br /> + <input <?= $DATA["C_WHITELIST"]; ?> 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" /> + <label for="chk_feature_aw"> Enable automatic whitelisting to record frequent correspondence</label> + <br /> + <input <?= $DATA["C_FACTORS"]; ?> 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" /> + <label for="chk_feature_at"> Add the factoring tokens in each email into the message's full headers</label> + <!-- + <input 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" /> + <label for="chk_feature_at"> Add the factoring tokens in each email into the message's full headers</label> + <br /> + <input type="checkbox" class="formbtn" title="opt in of DSPAM filtering" alt="opt in of DSPAM filtering" name="chk_feature_optin" id="chk_feature_optin" /> + <label for="chk_feature_optin"> opt in of DSPAM filtering</label> + <br /> + <input type="checkbox" class="formbtn" title="opt out of DSPAM filtering" alt="opt out of DSPAM filtering" name="chk_feature_optout" id="chk_feature_optout" /> + <label for="chk_feature_optout"> opt out of DSPAM filtering</label> + --> + </p> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td class="list"> </td> + <td class="list"> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" /> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-quarantine.php b/config/dspam/www/dspam-quarantine.php new file mode 100644 index 00000000..bc205a50 --- /dev/null +++ b/config/dspam/www/dspam-quarantine.php @@ -0,0 +1,178 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Quarantine"), + gettext("Overview")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +/* if this is an AJAX caller then handle via JSON */ +if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= getJScriptFunction(1); + $jscriptstr .= getJScriptFunction(2); + $jscriptstr .= getJScriptFunction(3); + $jscriptstr .= getJScriptFunction(4); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + +$pfSenseHead->addScript($jscriptstr); +$pfSenseHead->addLink("<link rel=\"stylesheet\" type=\"text/css\" href=\"/themes/" . $g['theme'] . "/dspam.css\" media=\"all\" />\n"); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-quarantine.php" method="post" name="iform" id="iform"> +<input type="hidden" name="command" value="processQuarantine" /> +<input type="hidden" name="processAction" value="None" /> +<input type="hidden" name="qpage" value="<?= $DATA['QPAGE']; ?>" /> +<input type="hidden" name="sortby" value="<?= $DATA['SORTBY']; ?>" > +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + 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 <strong>Deliver Checked</strong> to deliver messages you want + to read, or use <strong>Delete All</strong> to empty the quarantine. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", true, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", false, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="5">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="10%" valign="baseline" class="vncell" colspan="2">Username</td> + <td width="90%" class="vtable" colspan="3"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="5" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="middle" colspan="4" class="qnavtdl"> + <nobr> + <input type="button" class="formbtn" title="Deliver Checked" value="Deliver Checked" name="delichk" id="delichk" onclick="processmsg(0);" /> + <input type="button" class="formbtn" title="Delete Checked" value="Delete Checked" name="delchk" id="delchk" onclick="processmsg(1);" /> + <input type="button" class="formbtn" title="Delete All" value="Delete All" name="delall" id="delall" onclick="processmsg(2);" /> + </nobr> + </td> + <td align="right" valign="middle" class="qnavtdr"> + <label for="qperpage-top">Records per page: </label> + <select class="formselect" id="qperpage-top" name="qperpage" onchange="changeQPerPage(this);"> + <option value="25"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 25) echo ' selected="selected"'; ?>>25</option> + <option value="50"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 50) echo ' selected="selected"'; ?>>50</option> + <option value="75"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 75) echo ' selected="selected"'; ?>>75</option> + <option value="100"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 100) echo ' selected="selected"'; ?>>100</option> + <option value="125"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 125) echo ' selected="selected"'; ?>>125</option> + <option value="150"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 150) echo ' selected="selected"'; ?>>150</option> + </select> + </td> + </tr> + <tr> + <td colspan="5" class="list" height="12"> </td> + </tr> + <?= $DATA['SORT_SELECTOR']; ?> + <?= $DATA['QUARANTINE']; ?> + <?= $DATA['QUARANTINE_FOOTER']; ?> + <tr> + <td colspan="5" class="list" height="12"> </td> + </tr> + <tr> + <td align="left" valign="middle" colspan="4" class="qnavtdl"> + <nobr> + <input type="button" class="formbtn" title="Deliver Checked" value="Deliver Checked" name="delichk" id="delichk" onclick="processmsg(0);" /> + <input type="button" class="formbtn" title="Delete Checked" value="Delete Checked" name="delchk" id="delchk" onclick="processmsg(1);" /> + <input type="button" class="formbtn" title="Delete All" value="Delete All" name="delall" id="delall" onclick="processmsg(2);" /> + </nobr> + </td> + <td align="right" valign="middle" class="qnavtdr"> + <label for="qperpage-bottom">Records per page: </label> + <select class="formselect" id="qperpage-bottom" name="qperpage" onchange="changeQPerPage(this);"> + <option value="25"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 25) echo ' selected="selected"'; ?>>25</option> + <option value="50"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 50) echo ' selected="selected"'; ?>>50</option> + <option value="75"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 75) echo ' selected="selected"'; ?>>75</option> + <option value="100"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 100) echo ' selected="selected"'; ?>>100</option> + <option value="125"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 125) echo ' selected="selected"'; ?>>125</option> + <option value="150"<?php if ($CONFIG['QUARANTINE_PER_PAGE'] == 150) echo ' selected="selected"'; ?>>150</option> + </select> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-settings-algo.php b/config/dspam/www/dspam-settings-algo.php new file mode 100644 index 00000000..58ffb247 --- /dev/null +++ b/config/dspam/www/dspam-settings-algo.php @@ -0,0 +1,204 @@ +<?php +/* $Id$ */ +/* + dspam-settings-algo.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit Algorithm")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <algorithm> + <name>foo</name> + <descr>foo desc</descr> + </algorithm> + <algorithm> + <name>bar</name> + <descr>bar desc</descr> + </algorithm> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-algo.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("DSPAM Algorithm Name");?></td> + <td width="78%" class="vtable"> + <!-- <input name="aname" type="text" class="formfld" id="aname" size="30" value="<?=htmlspecialchars($pconfig['name']);?>"> --> + <select name="aname" id="aname" class="formselect"> + <option value="naive" <?php if($pconfig['name'] == "naive") echo('selected=\"selected\"');?>>naive</option> + <option value="graham" <?php if($pconfig['name'] == "graham") echo('selected=\"selected\"');?>>graham</option> + <option value="burton" <?php if($pconfig['name'] == "burton") echo('selected=\"selected\"');?>>burton</option> + <option value="robinson" <?php if($pconfig['name'] == "robinson") echo('selected=\"selected\"');?>>robinson</option> + <option value="chi-square" <?php if($pconfig['name'] == "chi-square") echo('selected=\"selected\"');?>>chi-square</option> + </select> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_algos[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> + </form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings-bmta.php b/config/dspam/www/dspam-settings-bmta.php new file mode 100644 index 00000000..c670085d --- /dev/null +++ b/config/dspam/www/dspam-settings-bmta.php @@ -0,0 +1,202 @@ +<?php +/* $Id$ */ +/* + dspam-settings-feat.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit Broken MTA Settings")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <bmta> + <name>foo</name> + <descr>foo desc</descr> + </bmta> + <bmta> + <name>bar</name> + <descr>bar desc</descr> + </bmta> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-bmta.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("DSPAM Feature Name");?></td> + <td width="78%" class="vtable"> + <!-- <input name="oname" type="text" class="formfld" id="oname" size="30" value="<?=htmlspecialchars($pconfig['name']);?>"> --> + <select name="oname" id="oname" class="formselect"> + <option value="returnCodes" <?php if($pconfig['name'] == "returnCodes") echo('selected=\"selected\"');?>>returnCodes</option> + <option value="case" <?php if($pconfig['name'] == "case") echo('selected=\"selected\"');?>>case</option> + <option value="lineStripping" <?php if($pconfig['name'] == "lineStripping") echo('selected=\"selected\"');?>>lineStripping</option> + </select> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_bmtas[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings-feat.php b/config/dspam/www/dspam-settings-feat.php new file mode 100644 index 00000000..7805fa43 --- /dev/null +++ b/config/dspam/www/dspam-settings-feat.php @@ -0,0 +1,203 @@ +<?php +/* $Id$ */ +/* + dspam-settings-feat.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit DSPAM Feature")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <feature> + <name>foo</name> + <descr>foo desc</descr> + </feature> + <feature> + <name>bar</name> + <descr>bar desc</descr> + </feature> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-feat.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("DSPAM Feature Name");?></td> + <td width="78%" class="vtable"> + <!-- <input name="fname" type="text" class="formfld" id="fname" size="30" value="<?=htmlspecialchars($pconfig['name']);?>"> --> + <select name="fname" id="fname" class="formselect"> + <option value="sbph" <?php if($pconfig['name'] == "sbph") echo('selected=\"selected\"');?>>sbph</option> + <option value="noise" <?php if($pconfig['name'] == "noise") echo('selected=\"selected\"');?>>noise</option> + <option value="chained" <?php if($pconfig['name'] == "chained") echo('selected=\"selected\"');?>>chained</option> + <option value="whitelist" <?php if($pconfig['name'] == "whitelist") echo('selected=\"selected\"');?>>whitelist</option> + </select> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_features[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings-header.php b/config/dspam/www/dspam-settings-header.php new file mode 100644 index 00000000..d0a5dd9c --- /dev/null +++ b/config/dspam/www/dspam-settings-header.php @@ -0,0 +1,197 @@ +<?php +/* $Id$ */ +/* + dspam-settings-tuser.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit Mail Header")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <header> + <name>foo</name> + <descr>foo desc</descr> + </header> + <header> + <name>bar</name> + <descr>foo desc</descr> + </header> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-header.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Header Name");?></td> + <td width="78%" class="vtable"> + <input name="hname" type="text" class="formfld unknown" id="hname" size="30" value="<?=htmlspecialchars($pconfig['name']);?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_headers[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings-overr.php b/config/dspam/www/dspam-settings-overr.php new file mode 100644 index 00000000..d938b313 --- /dev/null +++ b/config/dspam/www/dspam-settings-overr.php @@ -0,0 +1,197 @@ +<?php +/* $Id$ */ +/* + dspam-settings-overr.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit Override Value")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <override> + <value>foo</value> + <descr>foo desc</descr> + </override> + <override> + <value>bar</value> + <descr>bar desc</descr> + </override> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-overr.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("DSPAM Override Value");?></td> + <td width="78%" class="vtable"> + <input name="ovalue" type="text" class="formfld unknown" id="ovalue" size="30" value="<?=htmlspecialchars($pconfig['value']);?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_overr[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings-prefs.php b/config/dspam/www/dspam-settings-prefs.php new file mode 100644 index 00000000..c30cb7bd --- /dev/null +++ b/config/dspam/www/dspam-settings-prefs.php @@ -0,0 +1,197 @@ +<?php +/* $Id$ */ +/* + dspam-settings-prefs.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit DSPAM Preferences")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <preference> + <name>foo</name> + <descr>foo desc</descr> + </preference> + <preference> + <name>bar</name> + <descr>bar desc</descr> + </preference> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-prefs.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("DSPAM Algorithm Name");?></td> + <td width="78%" class="vtable"> + <input name="pvalue" type="text" class="formfld unknown" id="pvalue" size="30" value="<?=htmlspecialchars($pconfig['value']);?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_prefs[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings-spwd.php b/config/dspam/www/dspam-settings-spwd.php new file mode 100644 index 00000000..7912b0f6 --- /dev/null +++ b/config/dspam/www/dspam-settings-spwd.php @@ -0,0 +1,197 @@ +<?php +/* $Id$ */ +/* + dspam-settings-overr.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit Server Password")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <server-pwd> + <value>foo</value> + <descr>foo desc</descr> + </server-pwd> + <server-pwd> + <value>bar</value> + <descr>bar desc</descr> + </server-pwd> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-spwd.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Server Password Value");?></td> + <td width="78%" class="vtable"> + <input name="pwdvalue" type="text" class="formfld unknown" id="pwdvalue" size="30" value="<?=htmlspecialchars($pconfig['value']);?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_spwds[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings-tuser.php b/config/dspam/www/dspam-settings-tuser.php new file mode 100644 index 00000000..57e9ec71 --- /dev/null +++ b/config/dspam/www/dspam-settings-tuser.php @@ -0,0 +1,195 @@ +<?php +/* $Id$ */ +/* + dspam-settings-tuser.php + + Copyright (C) 2006 Daniel S. Haischt. + 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. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Edit UNIX user")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + +/* + The following code presumes, that the following XML structure exists or + if it does not exist, it will be created. + + <tuser> + <name>foo</name> + </tuser> + <tuser> + <name>bar</name> + </tuser> +*/ + +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(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="dspam-settings-tuser.php" method="post" name="iform" id="iform"> + <div name="inputerrors" id="inputerrors"></div> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("UNIX username");?></td> + <td width="78%" class="vtable"> + <input name="uuname" type="text" class="formfld unknown" id="uuname" size="30" value="<?=htmlspecialchars($pconfig['name']);?>"> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> + <td width="78%" class="vtable"> + <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> + <br> <span class="vexpl"><?=gettext("You may enter a description here + for your reference (not parsed).");?></span></td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <input id="submit" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>"> <input id="cancelbutton" class="formbtn" type="button" value="<?=gettext("Cancel");?>" onclick="history.back()"> + <?php if (isset($id) && $t_users[$id]): ?> + <input name="id" type="hidden" value="<?=$id;?>"> + <?php endif; ?> + <?php if (isset($sectionid)): ?> + <input name="sectionid" type="hidden" value="<?=$sectionid;?>"> + <?php endif; ?> + </td> + </tr> + </table> +</form> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/dspam/www/dspam-settings.php b/config/dspam/www/dspam-settings.php new file mode 100644 index 00000000..05662a6e --- /dev/null +++ b/config/dspam/www/dspam-settings.php @@ -0,0 +1,2955 @@ +<?php +/* $Id$ */ +/* + dspam-settings.php + Copyright (C) 2006 Daniel S. Haischt + 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. +*/ + $pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Advanced Settings"), + gettext("Overview")); + + require("guiconfig.inc"); + include("/usr/local/pkg/dspam.inc"); + + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + + $pconfig['sectionid'] = $_GET['sectionid']; + + $pconfig['sdriver'] = $config['installedpackages']['dspam']['config'][0]['storage-driver']; + /* ============================================================================================= */ + /* == MySQL == */ + /* ============================================================================================= */ + $pconfig['msqlserver'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-server']; + $pconfig['msqlport'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-port']; + $pconfig['msqluser'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-user']; + $pconfig['msqlpwd'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-password']; + $pconfig['msqldb'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-database']; + $pconfig['msqlcomp'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-compress']; + $pconfig['msqlsuqt'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-squote']; + $pconfig['msqlccache'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-ccache']; + $pconfig['msqluid'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-uid']; + /* ============================================================================================= */ + /* == SQLite == */ + /* ============================================================================================= */ + $pconfig['slitepr'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['sqlite-pragma']; + /* ============================================================================================= */ + /* == PostgreSQL == */ + /* ============================================================================================= */ + $pconfig['pgserver'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-server']; + $pconfig['pgport'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-port']; + $pconfig['pguser'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-user']; + $pconfig['pgpwd'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-password']; + $pconfig['pgdb'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-database']; + $pconfig['pgccache'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-ccache']; + $pconfig['pguid'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-uid']; + /* ============================================================================================= */ + /* == Oracle == */ + /* ============================================================================================= */ + $pconfig['oraserver'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-server']; + $pconfig['orauser'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-user']; + $pconfig['orapwd'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-password']; + $pconfig['orasch'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-schema']; + /* ============================================================================================= */ + /* == Hash == */ + /* ============================================================================================= */ + $pconfig['hsrmax'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-rec-max']; + $pconfig['hsatex'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-auto-ex']; + $pconfig['hsmxex'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-ext']; + $pconfig['hsexsz'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-ext-size']; + $pconfig['hsmxse'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-seek']; + $pconfig['hsccus'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-user']; + $pconfig['hscoca'] = $config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-cache']; + /* ============================================================================================= */ + /* == Delivery Settings == */ + /* ============================================================================================= */ + $pconfig['dagent'] = $config['installedpackages']['dspam']['config'][0]['tdelivery-agent']; + $pconfig['dsthinc'] = $config['installedpackages']['dspam']['config'][0]['thin-client']; + $pconfig['tcpipdel'] = $config['installedpackages']['dspam']['config'][0]['tcpip-delivery']; + $pconfig['dhost'] = $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-host']; + $pconfig['dport'] = $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-port']; + $pconfig['dident'] = $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-ident']; + $pconfig['delproto'] = $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-proto']; + $pconfig['onfail'] = $config['installedpackages']['dspam']['config'][0]['delivery-onfail']; + /* ============================================================================================= */ + /* == DSPAM Debugging Options == */ + /* ============================================================================================= */ + $pconfig['enabledbg'] = $config['installedpackages']['dspam']['config'][0]['debug-enable']; + $pconfig['debug'] = $config['installedpackages']['dspam']['config'][0]['debug-whom']; + $pconfig['dopt'] = $config['installedpackages']['dspam']['config'][0]['debug-options']; + /* ============================================================================================= */ + /* == DSPAM Engine Settings == */ + /* ============================================================================================= */ + $pconfig['tmode'] = $config['installedpackages']['dspam']['config'][0]['training-mode']; + $pconfig['testct'] = $config['installedpackages']['dspam']['config'][0]['test-cond-training']; + $pconfig['pvalue'] = $config['installedpackages']['dspam']['config'][0]['pvalue']; + $pconfig['ipdrive'] = $config['installedpackages']['dspam']['config'][0]['improbability-drive']; + /* ============================================================================================= */ + /* == LDAP Settings == */ + /* ============================================================================================= */ + $pconfig['enableldap'] = $config['installedpackages']['dspam']['config'][0]['ldap-enable']; + $pconfig['ldapmode'] = $config['installedpackages']['dspam']['config'][0]['ldap-mode']; + $pconfig['ldaphost'] = $config['installedpackages']['dspam']['config'][0]['ldap-host']; + $pconfig['ldapfilter'] = $config['installedpackages']['dspam']['config'][0]['ldap-filter']; + $pconfig['ldapbase'] = $config['installedpackages']['dspam']['config'][0]['ldap-base']; + /* ============================================================================================= */ + /* == Miscellaneous Settings == */ + /* ============================================================================================= */ + $pconfig['foatt'] = $config['installedpackages']['dspam']['config'][0]['failover-attempts']; + $pconfig['enablesbl'] = $config['installedpackages']['dspam']['config'][0]['sbl-enable']; + $pconfig['sblhost'] = $config['installedpackages']['dspam']['config'][0]['sbl-host']; + $pconfig['enablerbl'] = $config['installedpackages']['dspam']['config'][0]['rbl-inoculate']; + $pconfig['enablenoti'] = $config['installedpackages']['dspam']['config'][0]['notification-email']; + $pconfig['dspamdomain'] = $config['installedpackages']['dspam']['config'][0]['dspam-domain']; + $pconfig['dspamcontact'] = $config['installedpackages']['dspam']['config'][0]['dspam-contact']; + /* ============================================================================================= */ + /* == Maintainance Settings == */ + /* ============================================================================================= */ + $pconfig['psig'] = $config['installedpackages']['dspam']['config'][0]['purge-signatures']; + $pconfig['pneut'] = $config['installedpackages']['dspam']['config'][0]['purge-neutral']; + $pconfig['punu'] = $config['installedpackages']['dspam']['config'][0]['purge-unused']; + $pconfig['phapa'] = $config['installedpackages']['dspam']['config'][0]['purge-hapaxes']; + $pconfig['pones'] = $config['installedpackages']['dspam']['config'][0]['purge-hits-1s']; + $pconfig['ponei'] = $config['installedpackages']['dspam']['config'][0]['purge-hits-1i']; + /* ============================================================================================= */ + /* == System Settings == */ + /* ============================================================================================= */ + $pconfig['locmx'] = $config['installedpackages']['dspam']['config'][0]['local-mx']; + $pconfig['enablesysl'] = $config['installedpackages']['dspam']['config'][0]['system-log']; + $pconfig['enableusel'] = $config['installedpackages']['dspam']['config'][0]['user-log']; + $pconfig['optinout'] = $config['installedpackages']['dspam']['config'][0]['filter-opt']; + $pconfig['enableptoh'] = $config['installedpackages']['dspam']['config'][0]['parse-to-headers']; + $pconfig['enablecmop'] = $config['installedpackages']['dspam']['config'][0]['change-mode-on-parse']; + $pconfig['enablecuop'] = $config['installedpackages']['dspam']['config'][0]['change-user-on-parse']; + $pconfig['enablebmta'] = $config['installedpackages']['dspam']['config'][0]['broken-mta-settings']; + $pconfig['maxmsgs'] = $config['installedpackages']['dspam']['config'][0]['max-message-size']; + $pconfig['procbias'] = $config['installedpackages']['dspam']['config'][0]['processor-bias']; + /* ============================================================================================= */ + /* == ClamAV Engine Settings == */ + /* ============================================================================================= */ + $pconfig['enableclam'] = $config['installedpackages']['dspam']['config'][0]['clamav-enable']; + $pconfig['clamport'] = $config['installedpackages']['dspam']['config'][0]['clamav-port']; + $pconfig['clamhost'] = $config['installedpackages']['dspam']['config'][0]['clamav-host']; + $pconfig['clamresp'] = $config['installedpackages']['dspam']['config'][0]['clamav-response']; + /* ============================================================================================= */ + /* == DSPAM Daemon Settings (Server) == */ + /* ============================================================================================= */ + $pconfig['dsport'] = $config['installedpackages']['dspam']['config'][0]['dspam-server-port']; + $pconfig['dsqsize'] = $config['installedpackages']['dspam']['config'][0]['dspam-server-queue-size']; + $pconfig['dspid'] = $config['installedpackages']['dspam']['config'][0]['dspam-server-pid']; + $pconfig['dssmode'] = $config['installedpackages']['dspam']['config'][0]['dspam-server-mode']; + $pconfig['serverparam'] = $config['installedpackages']['dspam']['config'][0]['dspam-server-params']; + $pconfig['serverid'] = $config['installedpackages']['dspam']['config'][0]['dspam-server-id']; + $pconfig['serversock'] = $config['installedpackages']['dspam']['config'][0]['dspam-server-socket']; + /* ============================================================================================= */ + /* == DSPAM Daemon Settings (Client) == */ + /* ============================================================================================= */ + $pconfig['enabledsclient'] = $config['installedpackages']['dspam']['config'][0]['dspam-client-enable']; + $pconfig['dsclhost'] = $config['installedpackages']['dspam']['config'][0]['dspam-client-host']; + $pconfig['dsclport'] = $config['installedpackages']['dspam']['config'][0]['dspam-client-port']; + $pconfig['dsclident'] = $config['installedpackages']['dspam']['config'][0]['dspam-client-id']; + + if (!is_array($config['installedpackages']['dspam']['config'][0]['tuser'])) { + $config['installedpackages']['dspam']['config'][0]['tuser'] = array(); + } + if (!is_array($config['installedpackages']['dspam']['config'][0]['algorithm'])) { + $config['installedpackages']['dspam']['config'][0]['algorithm'] = array(); + } + if (!is_array($config['installedpackages']['dspam']['config'][0]['feature'])) { + $config['installedpackages']['dspam']['config'][0]['feature'] = array(); + } + if (!is_array($config['installedpackages']['dspam']['config'][0]['preference'])) { + $config['installedpackages']['dspam']['config'][0]['preference'] = array(); + } + if (!is_array($config['installedpackages']['dspam']['config'][0]['override'])) { + $config['installedpackages']['dspam']['config'][0]['override'] = array(); + } + if (!is_array($config['installedpackages']['dspam']['config'][0]['header'])) { + $config['installedpackages']['dspam']['config'][0]['header'] = array(); + } + if (!is_array($config['installedpackages']['dspam']['config'][0]['bmta'])) { + $config['installedpackages']['dspam']['config'][0]['bmta'] = array(); + } + + $t_users = &$config['installedpackages']['dspam']['config'][0]['tuser']; + $t_features = &$config['installedpackages']['dspam']['config'][0]['feature']; + $t_algos = &$config['installedpackages']['dspam']['config'][0]['algorithm']; + $t_prefs = &$config['installedpackages']['dspam']['config'][0]['preference']; + $t_overr = &$config['installedpackages']['dspam']['config'][0]['override']; + $t_headers = &$config['installedpackages']['dspam']['config'][0]['header']; + $t_bmtas = &$config['installedpackages']['dspam']['config'][0]['bmta']; + $t_spwds = &$config['installedpackages']['dspam']['config'][0]['server-pwd']; + +if ($_POST) { + + /* hash */ + $error_bucket = array(); + /* simple error list */ + unset($input_errors); + $pconfig = $_POST; + + /* input validation */ + if($_POST['sdriver'] == "mysql") { + if (! $_POST['msqlserver'] <> "") { + $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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(5); + if (empty($_POST)) + $jscriptstr .= getJScriptFunction(6); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + + $pfSenseHead->addScript($jscriptstr); + echo $pfSenseHead->getHTML();?> + +<body link="#000000" vlink="#000000" alink="#000000" <?php if (empty($_POST)) { echo "onLoad='checkDisabledState(document.iform);'"; } ?>> + <?php include("fbegin.inc"); ?> + <form action="dspam-settings.php" method="post" name="iform" id="iform"> + <input type="hidden" name="sectionid" id="sectionid" value="<?=$pconfig['sectionid'];?>" /> + <?php if ($input_errors) print_input_errors($input_errors); ?> + <?php if ($savemsg) print_info_box($savemsg); ?> + <p> + <span class="vexpl"> + <span class="red"> + <strong>Note: </strong> + </span> + the options on this page are intended for use by advanced users only. + Any setting found on this page is directly going into <code>dspam.conf</code>. + Make sure you do not mess with settings, you do not understand. + </span> + </p> + <p> + <span class="vexpl">If you submit this page, the DSPAM daemon process will be restarted.</span> + </p> + <br /> + <table width="99%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <?php + $tab_array = array(); + $tab_array[] = array("System Status", false, "/dspam-admin.php"); + $tab_array[] = array("User Statistics", false, "/dspam-admin-stats.php"); + $tab_array[] = array("Administration", false, "/dspam-admin-prefs.php"); + $tab_array[] = array("Settings", true, "/dspam-settings.php"); + $tab_array[] = array("Control Center", false, "/dspam-perf.php"); + display_top_tabs($tab_array); + ?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table id="maintable" name="maintable" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <p><strong>Settings</strong></p> + <ul style="font-size:0.95em; font-family:Verdana,Arial,sans-serif"> + <li><a href="#db" class="redlnk">Database Settings<?php if ($pconfig['sectionid'] == "db") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <li><a href="#del" class="redlnk">Delivery Settings<?php if ($pconfig['sectionid'] == "del") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <li><a href="#priv" class="redlnk">DSPAM Privileges<?php if ($pconfig['sectionid'] == "priv") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <li><a href="#dbg" class="redlnk">DSPAM Debugging Options<?php if ($pconfig['sectionid'] == "dbg") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <li><a href="#eng" class="redlnk">DSPAM Engine Settings<?php if ($pconfig['sectionid'] == "eng") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <?php if (checkForLDAPSupport()): ?> + <li><a href="#ldap" class="redlnk">LDAP Settings<?php if ($pconfig['sectionid'] == "ldap") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <?php endif; ?> + <li><a href="#misc" class="redlnk">Miscellaneous Settings<?php if ($pconfig['sectionid'] == "misc") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <li><a href="#main" class="redlnk">Maintainance Settings<?php if ($pconfig['sectionid'] == "main") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <li><a href="#sys" class="redlnk">System Settings<?php if ($pconfig['sectionid'] == "sys") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <?php if (checkForClamAVSupport()): ?> + <li><a href="#clam" class="redlnk">ClamAV Engine Settings<?php if ($pconfig['sectionid'] == "clam") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <?php endif; ?> + <li><a href="#srv" class="redlnk">DSPAM Daemon Settings (Server)<?php if ($pconfig['sectionid'] == "srv") echo '<span class="red"> »last modified«</span>'; ?></a></li> + <li><a href="#cli" class="redlnk">DSPAM Daemon Settings (Client)<?php if ($pconfig['sectionid'] == "cli") echo '<span class="red"> »last modified«</span>'; ?></a></li> + </ul> + <br /> + </td> + </tr> + <tr> + <td> + <table id="sortabletable0" name="sortabletable0" width="100%" border="0" cellpadding="10" cellspacing="0"> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="db" style="visibility: hidden;"> </a>Database Settings</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Storage Driver</td> + <td width="78%" class="vtable"> + <select name="sdriver" onChange="toggleDBSettings();" class="formselect"> + <?php if (checkForMySQLSupport()): ?> + <option value="mysql" <?php if($pconfig['sdriver'] == "mysql") echo('selected="selected"');?>>mysql</option> + <?php endif; ?> + <?php if (checkForSQLiteSupport()): ?> + <option value="sqlite" <?php if($pconfig['sdriver'] == "sqlite") echo('selected="selected"');?>>sqlite</option> + <?php endif; ?> + <option value="bdb" <?php if($pconfig['sdriver'] == "bdb") echo('selected="selected"');?>>bdb</option> + <?php if (checkForPgSQLSupport()): ?> + <option value="pgsql" <?php if($pconfig['sdriver'] == "pgsql") echo('selected="selected"');?>>pgsql</option> + <?php endif; ?> + <option value="oracle" <?php if($pconfig['sdriver'] == "oracle") echo('selected="selected"');?>>oracle</option> + <option value="hash" <?php if($pconfig['sdriver'] == "hash") echo('selected="selected"');?>>hash</option> + </select> + <strong>Specifies the storage driver backend (library) to use.</strong> + <p> + <span class="vexpl"> + 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. + </span> + </p> + </td> + </tr> + <?php if ($pconfig['sdriver'] == "mysql" && checkForMySQLSupport()): ?> + <tbody id="DBmysql" style="display: table-row-group;"> + <?php else: ?> + <tbody id="DBmysql" style="display: none;"> + <?php endif; ?> + <tr> + <td width="22%" valign="top" class="vncell">MySQL Server</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("msqlserver", "formfld host"); ?> name="msqlserver" id="msqlserver" value="<?=htmlspecialchars($pconfig['msqlserver']);?>" /> + <strong> + Either a reference to a Unix domain socket or a reference to a specific host. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL Port</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("msqlport", "formfld unknown"); ?> name="msqlport" id="msqlport" value="<?=htmlspecialchars($pconfig['msqlport']);?>" /> + <strong> + Use this variable if you are going to a MySQL server instance using TCP/IP instead of a socket connection. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL User</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("msqluser", "formfld user"); ?> name="msqluser" id="msqluser" value="<?=htmlspecialchars($pconfig['msqluser']);?>" <?php if ($_POST && $input_error_fields && in_array("msqluser", $input_error_fields)) echo 'style="background-color: red;" onFocus="this.style.backgroundColor = \'white\';" onBlur="this.style.backgroundColor = \'red\';"'; ?>/> + <strong> + Username, that will be used to connect to a MySQL server instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL Password</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("msqlpwd", "formfld pwd"); ?> name="msqlpwd" id="msqlpwd" value="<?=htmlspecialchars($pconfig['msqlpwd']);?>" <?php if ($_POST && $input_error_fields && in_array("msqlpwd", $input_error_fields)) echo 'style="background-color: red;" onFocus="this.style.backgroundColor = \'white\';" onBlur="this.style.backgroundColor = \'red\';"'; ?>/> + <strong> + Password, that will be used to connect to a MySQL server instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL Database</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("msqldb", "formfld unknown"); ?> name="msqldb" id="msqldb" value="<?=htmlspecialchars($pconfig['msqldb']);?>" <?php if ($_POST && $input_error_fields && in_array("msqldb", $input_error_fields)) echo 'style="background-color: red;" onFocus="this.style.backgroundColor = \'white\';" onBlur="this.style.backgroundColor = \'red\';"'; ?>/> + <strong> + Database name, that contains DSPAM data. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL Compress</td> + <td width="78%" class="vtable"> + <input type="checkbox" class="formfld" name="msqlcomp" id="msqlcomp" value="yes" <?php if (isset($pconfig['msqlcomp'])) echo 'checked="checked"'; ?> /> + <strong> + Indicates whether communication data between DSPAM and MySQL should be compressed. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL Supress Quote</td> + <td width="78%" class="vtable"> + <input type="checkbox" class="formfld" name="msqlsuqt" id="msqlsuqt" value="yes" <?php if (isset($pconfig['msqlsuqt'])) echo 'checked="checked"'; ?> /> + <strong> + Use this if you have the 4.1 quote bug (see doc/mysql.txt). + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + If you're running DSPAM in client/server (daemon) mode, uncomment the + setting below to override the default connection cache size (the number + of connections the server pools between all clients). The connection cache + represents the maximum number of database connections *available* and should + be set based on the maximum number of concurrent connections you're likely + to have. Each connection may be used by only one thread at a time, so all + other threads _will block_ until another connection becomes available. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL Connection Cache</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("msqlccache", "formfld unknown"); ?> name="msqlccache" id="msqlccache" value="<?=htmlspecialchars($pconfig['msqlccache']);?>" <?php if ($_POST && $input_error_fields && in_array("msqlccache", $input_error_fields)) echo 'style="background-color: red;" onFocus="this.style.backgroundColor = \'white\';" onBlur="this.style.backgroundColor = \'red\';"'; ?>/> + <strong> + Conection cache default set to 10. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + MySQL supports the insertion of the user id into the DSPAM + signature. This allows you to create one single spam or fp alias + (pointing to some arbitrary user), and the uid in the signature will + switch to the correct user. Result: you need only one spam alias + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">MySQL UID In Signature</td> + <td width="78%" class="vtable"> + <input type="checkbox" class="formfld" name="msqluid" id="msqluid" value="yes" <?php if (isset($pconfig['msqluid'])) echo 'checked="checked"'; ?> /> + <strong> + Insert user id into the DSPAM signature. + </strong> + </td> + </tr> + </tbody> + <?php if ($pconfig['sdriver'] == "sqlite" && checkForSQLiteSupport()): ?> + <tbody id="DBsqlite" style="display: table-row-group;"> + <?php else: ?> + <tbody id="DBsqlite" style="display: none;"> + <?php endif; ?> + <tr> + <td width="22%" valign="top" class="vncell">SQLite Pragma</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("slitepr", "formfld unknown"); ?> name="slitepr" id="slitepr" value="<?=htmlspecialchars($pconfig['slitepr']);?>" /> + <strong> + A particular SQLite pragma command to be used. + </strong> + <p> + <span class="vexpl"> + See: <a href="http://sqlite.org/pragma.html" target="_blank">http://sqlite.org/pragma.html</a> + </span> + </p> + </td> + </tr> + </tbody> + <?php if ($pconfig['sdriver'] == "bdb"): ?> + <tbody id="DBbdb" style="display: table-row-group;"> + <?php else: ?> + <tbody id="DBbdb" style="display: none;"> + <?php endif; ?> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <strong> + Nothing to be configured here ! + </strong> + </td> + </tr> + </tbody> + <?php if ($pconfig['sdriver'] == "pgsql" && checkForPgSQLSupport()): ?> + <tbody id="DBpgsql" style="display: table-row-group;"> + <?php else: ?> + <tbody id="DBpgsql" style="display: none;"> + <?php endif; ?> + <tr> + <td width="22%" valign="top" class="vncell">PostgreSQL Server</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pgserver", "formfld host"); ?> name="pgserver" id="pgserver" value="<?=htmlspecialchars($pconfig['pgserver']);?>" /> + <strong> + A reference to a specific host that is running a PostgreSQL instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">PostgreSQL Port</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pgport", "formfld unknown"); ?> name="pgport" id="pgport" value="<?=htmlspecialchars($pconfig['pgport']);?>" /> + <strong> + A number that represents the port a specific PostgreSQL instance is listening to. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">PostgreSQL User</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pguser", "formfld user"); ?> name="pguser" id="pguser" value="<?=htmlspecialchars($pconfig['pguser']);?>" /> + <strong> + Username, that will be used to connect to a PostgreSQL server instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">PostgreSQL Password</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pgpwd", "formfld pwd"); ?> name="pgpwd" id="pgpwd" value="<?=htmlspecialchars($pconfig['pgpwd']);?>"/> + <strong> + Password, that will be used to connect to a PostgreSQL server instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">PostgreSQL Database</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pgdb", "formfld unknown"); ?> name="pgdb" id="pgdb" value="<?=htmlspecialchars($pconfig['pgdb']);?>" /> + <strong> + Database name, that contains DSPAM data. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + If you're running DSPAM in client/server (daemon) mode, uncomment the + setting below to override the default connection cache size (the number + of connections the server pools between all clients). The connection cache + represents the maximum number of database connections *available* and should + be set based on the maximum number of concurrent connections you're likely + to have. Each connection may be used by only one thread at a time, so all + other threads _will block_ until another connection becomes available. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">PostgreSQL Connection Cache</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pgccache", "formfld unknown"); ?> name="pgccache" id="pgccache" value="<?=htmlspecialchars($pconfig['pgccache']);?>" /> + <strong> + Conection cache default set to 3. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + PostgreSQL supports the insertion of the user id into the DSPAM + signature. This allows you to create one single spam or fp alias + (pointing to some arbitrary user), and the uid in the signature will + switch to the correct user. Result: you need only one spam alias + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">PostgreSQL UID In Signature</td> + <td width="78%" class="vtable"> + <input type="checkbox" class="formfld" name="pguid" id="pguid" value="yes" <?php if (isset($pconfig['pguid'])) echo 'checked="checked"'; ?> /> + <strong> + Insert user id into the DSPAM signature. + </strong> + </td> + </tr> + </tbody> + <?php if ($pconfig['sdriver'] == "oracle"): ?> + <tbody id="DBoracle" style="display: table-row-group;"> + <?php else: ?> + <tbody id="DBoracle" style="display: none;"> + <?php endif; ?> + <tr> + <td width="22%" valign="top" class="vncell">Attention !</td> + <td width="78%" class="vtable"> + <strong style="color: red;"> + This feature is currently unsupported ! + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Oracle Server</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("oraserver", "formfld host"); ?> name="oraserver" id="oraserver" value="<?=htmlspecialchars($pconfig['oraserver']);?>" /> + <strong> + A reference to a specific host that is running an Oracle database instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Oracle User</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("orauser", "formfld user"); ?> name="orauser" id="orauser" value="<?=htmlspecialchars($pconfig['orauser']);?>" /> + <strong> + Username, that will be used to connect to a Oracle database server instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Oracle Password</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("orapwd", "formfld pwd"); ?> name="orapwd" id="orapwd" value="<?=htmlspecialchars($pconfig['orapwd']);?>" /> + <strong> + Password, that will be used to connect to a Oracle database server instance. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Oracle Schema</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("orasch", "formfld unknown"); ?> name="orasch" id="orasch" value="<?=htmlspecialchars($pconfig['orasch']);?>" /> + <strong> + Schema name, that contains DSPAM data. + </strong> + </td> + </tr> + </tbody> + <?php if ($pconfig['sdriver'] == "hash"): ?> + <tbody id="DBhash" style="display: table-row-group;"> + <?php else: ?> + <tbody id="DBhash" style="display: none;"> + <?php endif; ?> + <tr> + <td width="22%" valign="top" class="vncell">Hash Rec Max</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("hsrmax", "formfld unknown"); ?> name="hsrmax" id="hsrmax" value="<?=htmlspecialchars($pconfig['hsrmax']);?>" /> + <strong> + Default number of records to create in the initial segment when building hash files. + </strong> + <p> + <span class="vexpl"> + 100,000 yields files 1.6MB in size, but can fill up fast, so be sure to increase this + (to a million or more) if you're not using autoextend. + </span> + </p> + <p> + <span class="vexpl"> + Primes List: + <pre> +53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, +393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, +100663319, 201326611, 402653189, 805306457, 1610612741, 3221225473, +4294967291 + </pre> + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Hash Auto Extend</td> + <td width="78%" class="vtable"> + <input type="checkbox" class="formfld" name="hsatex" id="hsatex" value="yes" <?php if (isset($pconfig['hsatex'])) echo 'checked="checked"'; ?> /> + <strong> + Autoextend hash databases when they fill up. This allows them to continue + to train by adding extents (extensions) to the file. + </strong> + <p> + <span class="vexpl"> + Note: There will be a small delay during the growth process, + as everything needs to be closed and remapped. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Hash Max Extents</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("hsmxex", "formfld unknown"); ?> name="hsmxex" id="hsmxex" value="<?=htmlspecialchars($pconfig['hsmxex']);?>" /> + <strong> + The maximum number of extents that may be created in a single hash file. + </strong> + <p> + <span class="vexpl"> + Note: Set this to zero for unlimited. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Hash Extent Size</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("hsexsz", "formfld unknown"); ?> name="hsexsz" id="hsexsz" value="<?=htmlspecialchars($pconfig['hsexsz']);?>" /> + <strong> + The record size for newly created extents. + </strong> + <p> + <span class="vexpl"> + Note: Creating this too small could result in many extents + being created. Creating this too large could result in + excessive disk space usage. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Hash Max Seek</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("hsmxse", "formfld unknown"); ?> name="hsmxse" id="hsmxse" value="<?=htmlspecialchars($pconfig['hsmxse']);?>" /> + <strong> + The maximum number of records to seek to insert a new record + before failing or adding a new extent. + </strong> + <p> + <span class="vexpl"> + Note: Setting this too high will exhaustively scan each segment + and kill performance. Typically, a low value is acceptable as + even older extents will continue to fill over time. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Hash Concurrent User</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("hsccus", "formfld unknown"); ?> name="hsccus" id="hsccus" value="<?=htmlspecialchars($pconfig['hsccus']);?>" /> + <strong> + 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. + </strong> + <p> + <span class="vexpl"> + Note: Leave this field blank, if you do not want to use this option. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Hash Connection Cache</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("hscoca", "formfld unknown"); ?> name="hscoca" id="hscoca" value="<?=htmlspecialchars($pconfig['hscoca']);?>" /> + <strong> + If running in daemon mode, this is the max # of concurrent + connections that will be supported. + </strong> + <p> + <span class="vexpl"> + Note: If you are using HashConcurrentUser, this option is ignored, + as all connections are read write locked instead of mutex locked. + </span> + </p> + </td> + </tr> + </tbody> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'db';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="del" style="visibility: hidden;"> </a>Delivery Settings</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Trusted Delivery Agent</td> + <td width="78%" class="vtable"> + <select name="dagent" class="formselect"> + <option value="procmail" <?php if($pconfig['dagent'] == "procmail") echo('selected="selected"');?>>procmail</option> + <option value="mail" <?php if($pconfig['dagent'] == "mail") echo('selected="selected"');?>>mail</option> + <option value="mail.local" <?php if($pconfig['dagent'] == "mail.local") echo('selected="selected"');?>>mail.local</option> + <option value="deliver" <?php if($pconfig['dagent'] == "deliver") echo('selected="selected"');?>>deliver</option> + <option value="maildrop" <?php if($pconfig['dagent'] == "maildrop") echo('selected="selected"');?>>maildrop</option> + <option value="exim" <?php if($pconfig['dagent'] == "exim") echo('selected="selected"');?>>exim</option> + </select> + <strong>Specifies the local delivery agent DSPAM should call when delivering mail as a trusted user.</strong> + <p> + <span class="vexpl"> + 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. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">DSPAM Thin Client</td> + <td width="78%" class="vtable"> + <input type="checkbox" name="dsthinc" id="dsthinc" value="yes" <?php if (isset($pconfig['dsthinc'])) echo 'checked="checked"'; ?> /> + <strong>Use <code>dspamc</code> instead of the <code>dspam</code> binary.</strong> + <p> + <span class="vexpl"> + Note: This requires to enable the dspam daemon as well (section: <i>DSPAM Daemon Settings (Server)</i>). + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">TCP/IP Based Delivery</td> + <td width="78%" class="vtable"> + <input type="checkbox" name="tcpipdel" id="tcpipdel" value="yes" <?php if (isset($pconfig['tcpipdel'])) echo 'checked="checked"'; ?> onClick="enable_change(false, 5);" /> + <strong>Use TCP/IP based delivery.</strong> + <p> + <span class="vexpl"> + Note: This option needs to be ticked if you are going to deliver via LMTP or SMTP. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Deliver Host</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("dhost", "formfld host"); ?> name="dhost" id="dhost" value="<?=htmlspecialchars($pconfig['dhost']);?>" <?php if (! isset($pconfig['tcpipdel'])) echo 'disabled="disabled"'; ?> /> + <strong>Alternatively, you may wish to use SMTP or LMTP delivery to deliver your message to the mail server.</strong> + <p> + <span class="vexpl"> + Note: You will need to configure with <code>--enable-daemon</code> 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. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Deliver Port</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("dport", "formfld unknown"); ?> name="dport" id="dport" value="<?=htmlspecialchars($pconfig['dport']);?>" <?php if (! isset($pconfig['tcpipdel'])) echo 'disabled="disabled"'; ?> /> + <strong>Port number of a particular host.</strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Deliver Ident</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("dident", "formfld unknown"); ?> name="dident" id="dident" value="<?=htmlspecialchars($pconfig['dident']);?>" <?php if (! isset($pconfig['tcpipdel'])) echo 'disabled="disabled"'; ?> /> + <strong>A particular identification string</strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">TCP/IP Delivery Protocol</td> + <td width="78%" class="vtable"> + <select name="delproto" class="formselect" <?php if (! isset($pconfig['tcpipdel'])) echo 'disabled="disabled"'; ?>> + <option value="smtp" <?php if($pconfig['delproto'] == "smtp") echo('selected="selected"');?>>smtp</option> + <option value="lmtp" <?php if($pconfig['delproto'] == "lmtp") echo('selected="selected"');?>>lmtp</option> + </select> + <strong>A particular protocol typ. Either <acronym title="Simple Mail Transfer Protocol">SMTP</acronym> + or <acronym title="Local Mail Transfer Protocol">LMTP</acronym>.</strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">On Fail</td> + <td width="78%" class="vtable"> + <select name="onfail" class="formselect"> + <option value="error" <?php if($pconfig['onfail'] == "error") echo('selected="selected"');?>>error</option> + <option value="unlearn" <?php if($pconfig['onfail'] == "unlearn") echo('selected="selected"');?>>unlearn</option> + </select> + <strong>What to do if local delivery or quarantine should fail.</strong> + <p> + <span class="vexpl"> + 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. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'del';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="priv" style="visibility: hidden;"> </a>DSPAM Privileges</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Trusted Users</td> + <td width="78%" class="vtable"> + <strong>Unix users which are allowed to perform certain actions.</strong> + <p> + <span class="vexpl"> + 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. + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("UNIX username");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_users)): ?> + <?php $i = 0; foreach ($t_users as $user): ?> + <?php if($user['name'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-tuser.php?id=<?=$i;?>§ionid=priv';"> + <?=htmlspecialchars($user['name']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-tuser.php?id=<?=$i;?>§ionid=priv';"> + <font color="#FFFFFF"><?=htmlspecialchars($user['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-tuser.php?id=<?=$i;?>§ionid=priv"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=tuser&id=<?=$i;?>§ionid=priv" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-tuser.php?sectionid=priv"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'priv';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td valign="top" class="listtopic"><a name="dbg" style="visibility: hidden;"> </a>DSPAM Debugging Options</td> + <td align="right" valign="top" class="listtopic"> + <input type="checkbox" name="enabledbg" id="enabledbg" value="yes" <?php if (isset($pconfig['enabledbg'])) echo 'checked="checked"'; ?> onClick="enable_change(false, 0);" /> + <strong>Enable</strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Debug</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("debug", "formfld unknown"); ?> name="debug" id="debug" value="<?=htmlspecialchars($pconfig['debug']);?>" <?php if (! isset($pconfig['enabledbg'])) echo 'disabled="disabled"'; ?> /> + <strong>Enables debugging for some or all users.</strong> + <p> + <span class="vexpl"> + 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. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Debug Options</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("dopt", "formfld unknown"); ?> name="dopt" id="dopt" value="<?=htmlspecialchars($pconfig['dopt']);?>" <?php if (! isset($pconfig['enabledbg'])) echo 'disabled="disabled"'; ?> /> + <strong>One or more of: process, classify, spam, fp, inoculation, corpus</strong> + <p> + <span class="vexpl"> + <pre> +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) + </pre> + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'dbg';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="eng" style="visibility: hidden;"> </a>DSPAM Engine Settings</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Training Mode</td> + <td width="78%" class="vtable"> + <select name="tmode" class="formselect"> + <option value="toe" <?php if($pconfig['tmode'] == "toe") echo('selected="selected"');?>>toe</option> + <option value="tum" <?php if($pconfig['tmode'] == "tum") echo('selected="selected"');?>>tum</option> + <option value="teft" <?php if($pconfig['tmode'] == "teft") echo('selected="selected"');?>>teft</option> + <option value="notrain" <?php if($pconfig['tmode'] == "notrain") echo('selected="selected"');?>>notrain</option> + </select> + <strong> + The default training mode to use for all operations, when one has not been + specified on the commandline or in the user's preferences. + </strong> + <p> + <span class="vexpl"> + Acceptable values are: toe, tum, teft, notrain + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Test Conditional Training</td> + <td width="78%" class="vtable"> + <input name="testct" type="checkbox" id="testct" value="yes" <?php if (isset($pconfig['testct'])) echo 'checked="checked"'; ?> /> + <strong> + By default, dspam will retrain certain errors + until the condition is no longer met. + </strong> + <p> + <span class="vexpl"> + Note: This usually accelerates learning. Some people argue that this can increase + the risk of errors, however. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Features</td> + <td width="78%" class="vtable"> + <strong> + 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. + </strong> + <p> + <span class="vexpl"> + Note: For standard "CRM114" Markovian weighting, use sbph + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("DSPAM Feature");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_features)): ?> + <?php $i = 0; foreach ($t_features as $feature): ?> + <?php if($feature['name'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-feat.php?id=<?=$i;?>§ionid=eng';"> + <?=htmlspecialchars($feature['name']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-feat.php?id=<?=$i;?>§ionid=eng';"> + <font color="#FFFFFF"><?=htmlspecialchars($feature['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-feat.php?id=<?=$i;?>§ionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=feat&id=<?=$i;?>§ionid=eng" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-feat.php?sectionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Algorithms</td> + <td width="78%" class="vtable"> + <strong> + Specify the statistical algorithms to use, overriding any + defaults configured in the build. + </strong> + <p> + <span class="vexpl"> + The options are: + <pre> +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 + </pre> + </span> + </p> + <p> + <span class="vexpl"> + 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. + </p> + <p> + <span class="vexpl"> + NOTE: For standard "CRM114" Markovian weighting, use ‘naive’, or consider + using ‘burton’ for slightly better accuracy. + </span> + </p> + <p> + <span class="vexpl"> + Don't mess with this unless you know what you're doing + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("DSPAM Algorithm");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_algos)): ?> + <?php $i = 0; foreach ($t_algos as $algo): ?> + <?php if($algo['name'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-algo.php?id=<?=$i;?>§ionid=eng';"> + <?=htmlspecialchars($algo['name']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-algo.php?id=<?=$i;?>§ionid=eng';"> + <font color="#FFFFFF"><?=htmlspecialchars($algo['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-algo.php?id=<?=$i;?>§ionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=algo&id=<?=$i;?>§ionid=eng" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-algo.php?sectionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">PValue</td> + <td width="78%" class="vtable"> + <select name="pvalue" class="formselect"> + <option value="graham" <?php if($pconfig['pvalue'] == "toe") echo('selected="selected"');?>>graham</option> + <option value="robinson" <?php if($pconfig['pvalue'] == "toe") echo('selected="selected"');?>>robinson</option> + <option value="markov" <?php if($pconfig['pvalue'] == "toe") echo('selected="selected"');?>>markov</option> + </select> + <strong> + Specify the technique used for calculating PValues, overriding any defaults + configured in the build. + </strong> + <p> + <span class="vexpl"> + These options are: + <pre> +graham Graham's Technique ("A Plan for Spam") +robinson Robinson's Technique +markov Markovian Weighted Technique + </pre> + </span> + </p> + <p> + <span class="vexpl"> + Unlike algorithms, you may only have one of these defined. Use of the + chi-square algorithm automatically changes this to robinson. + </span> + </p> + <p> + <span class="vexpl"> + Don't mess with this unless you know what you're doing. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Improbability Drive</td> + <td width="78%" class="vtable"> + <input name="ipdrive" type="checkbox" id="ipdrive" value="yes" <?php if (isset($pconfig['ipdrive'])) echo 'checked="checked"'; ?> /> + <strong> + Calculate odds-ratios for ham/spam, and add to X-DSPAM-Improbability headers + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Preferences</td> + <td width="78%" class="vtable"> + <strong> + Specify any preferences to set by default, unless otherwise + overridden by the user (see next section) or a default.prefs file. + </strong> + <p> + <span class="vexpl"> + Note: If user or default.prefs are found, the user's + preferences will override any defaults. + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("DSPAM Preference Value");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_prefs)): ?> + <?php $i = 0; foreach ($t_prefs as $pref): ?> + <?php if($pref['value'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-prefs.php?id=<?=$i;?>§ionid=eng';"> + <?=htmlspecialchars($pref['value']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-prefs.php?id=<?=$i;?>§ionid=eng';"> + <font color="#FFFFFF"><?=htmlspecialchars($pref['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-prefs.php?id=<?=$i;?>§ionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=pref&id=<?=$i;?>§ionid=eng" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-prefs.php?sectionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Overrides</td> + <td width="78%" class="vtable"> + <strong> + Specifies the user preferences which may override + configuration and commandline defaults. + </strong> + <p> + <span class="vexpl"> + Note: Any other preferences supplied by an untrusted user will be ignored. + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("DSPAM Override Value");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_overr)): ?> + <?php $i = 0; foreach ($t_overr as $over): ?> + <?php if($over['value'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-overr.php?id=<?=$i;?>§ionid=eng';"> + <?=htmlspecialchars($over['value']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-overr.php?id=<?=$i;?>§ionid=eng';"> + <font color="#FFFFFF"><?=htmlspecialchars($over['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-overr.php?id=<?=$i;?>§ionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=overr&id=<?=$i;?>§ionid=eng" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-overr.php?sectionid=eng"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'eng';" /> + </td> + </tr> + <?php if (checkForLDAPSupport()): ?> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td valign="top" class="listtopic"><a name="ldap" style="visibility: hidden;"> </a>LDAP Settings</td> + <td align="right" valign="top" class="listtopic"> + <input name="enableldap" type="checkbox" id="enableldap" value="yes" <?php if (isset($pconfig['enableldap'])) echo 'checked="checked"'; ?> onClick="enable_change(false, 1);" /> + <strong>Enable</strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">LDAP Mode</td> + <td width="78%" class="vtable"> + <select name="ldapmode" class="formselect" <?php if (! isset($pconfig['enableldap'])) echo 'disabled="disabled"'; ?>> + <option value="verify" selected="selected">verify</option> + </select> + <strong> + Perform various LDAP functions depending on LDAPMode variable. + </strong> + <p> + <span class="vexpl"> + 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. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">LDAP Host</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("hldaphost", "formfld host"); ?> name="ldaphost" id="ldaphost" value="<?=htmlspecialchars($pconfig['ldaphost']);?>" <?php if (! isset($pconfig['enableldap'])) echo 'disabled="disabled"'; ?> /> + <strong> + Hostname of the LDAP directory server. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">LDAP Filter</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("ldapfilter", "formfld unknown"); ?> name="ldapfilter" id="ldapfilter" value="<?=htmlspecialchars($pconfig['ldapfilter']);?>" <?php if (! isset($pconfig['enableldap'])) echo 'disabled="disabled"'; ?> /> + <strong> + A specific query filter, that should be used while querying the LDAP server. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">LDAP Base</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("ldapbase", "formfld unknown"); ?> name="ldapbase" id="ldapbase" value="<?=htmlspecialchars($pconfig['ldapbase']);?>" <?php if (! isset($pconfig['enableldap'])) echo 'disabled="disabled"'; ?> /> + <strong> + A particular distinguish name from where to start LDAP queries. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'ldap';" /> + </td> + </tr> + <?php endif; ?> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="misc" style="visibility: hidden;"> </a>Miscellaneous Settings</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Failover Attempts</td> + <td width="78%" class="vtable"> + <input type="text" size="30"<?= checkForErrorClass("foatt", "formfld unknown"); ?> name="foatt" id="foatt" value="<?=htmlspecialchars($pconfig['foatt']);?>" /> + <strong> + A particular number of attempts. + </strong> + <p> + <span class="vexpl"> + 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). + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Ignore Headers</td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + 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. + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("Header Name");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_headers)): ?> + <?php $i = 0; foreach ($t_headers as $header): ?> + <?php if($header['name'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-header.php?id=<?=$i;?>§ionid=misc';"> + <?=htmlspecialchars($header['name']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-header.php?id=<?=$i;?>§ionid=misc';"> + <font color="#FFFFFF"><?=htmlspecialchars($header['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-header.php?id=<?=$i;?>§ionid=misc"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=header&id=<?=$i;?>§ionid=misc" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-header.php?sectionid=misc"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">SBL Lookup</td> + <td width="78%" class="vtable"> + <p> + <input type="checkbox" name="enablesbl" id="enablesbl" value="yes" <?php if (isset($pconfig['enablesbl'])) echo 'checked="checked"'; ?> onClick="enable_change(false, 2);" /> + <strong> + Enable checks against a particular <acronym title="Streamlined Blackhole List">SBL</acronym> host. + </strong> + </p> + <p> + <input type="text" size="30" c<?= checkForErrorClass("sblhost", "formfld host"); ?> name="sblhost" id="sblhost" value="<?=htmlspecialchars($pconfig['sblhost']);?>" <?php if (! isset($pconfig['enablesbl'])) echo 'disabled="disabled"'; ?> /> + <strong> + A particular SBL hostname. + </strong> + </p> + <p> + <span class="vexpl"> + Perform lookups on streamlined blackhole list servers (see + <a href="http://www.nuclearelephant.com/projects/sbl/" target="_blank">http://www.nuclearelephant.com/projects/sbl/</a>). + 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. + </span> + </p> + <p> + <span class="vexpl"> + 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. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">RBL Inoculate</td> + <td width="78%" class="vtable"> + <input name="enablerbl" type="checkbox" id="enablerbl" value="yes" <?php if (isset($pconfig['enablerbl'])) echo 'checked="checked"'; ?> /> + <strong> + Enable <acronym title="Realtime Blackhole List">RBL</acronym> inoculation support. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Enable Notification</td> + <td width="78%" class="vtable"> + <input name="enablenoti" type="checkbox" id="enablenoti" value="yes" <?php if (isset($pconfig['enablenoti'])) echo 'checked="checked"'; ?> onClick="enable_change(false, 2);" /> + <strong> + Enable the sending of notification emails to users (first message, quarantine full, etc.) + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">DSPAM Support Contact</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("dspamcontact", "formfld mail"); ?> name="dspamcontact" id="dspamcontact" value="<?=htmlspecialchars($pconfig['dspamcontact']);?>" <?php if (empty($pconfig['enablenoti'])) echo 'disabled="disabled"'; ?> /> + <strong> + The username of the person who provides DSPAM support for this DSPAM installation + </strong> + (This is the left most part of an email address before the @ sign). + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Email Domain Name</td> + <td width="78%" class="vtable"> + <input name="whichdomain" type="checkbox" id="whichdomain" value="yes" <?php if (empty($pconfig['dspamdomain'])) echo 'checked="checked"'; if (empty($pconfig['enablenoti'])) echo 'disabled="disabled"'; ?> onClick="toggleDSPAMDomain(false, this);" /> + <strong> + Use global domain settings while trying to send an email message. + </strong> + </td> + </tr> + <?php if (isset($pconfig['dspamdomain'])): ?> + <tbody id="emailnotitb" style="display: table-row-group;"> + <?php else: ?> + <tbody id="emailnotitb" style="display: none;"> + <?php endif; ?> + <tr> + <td width="22%" valign="top" class="vncell">DSPAM Domain Name</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("dspamdomain", "formfld url"); ?> name="dspamdomain" id="dspamdomain" value="<?=htmlspecialchars($pconfig['dspamdomain']);?>" /> + <strong> + Use this domain name while trying to send an email message. + </strong> + </td> + </tr> + </tbody> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'misc';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="main" style="visibility: hidden;"> </a>Maintainance Settings</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + Set dspam_clean purge default options, if not + otherwise specified on the commandline. You may set some of + the below values to <code>off</code>, for instance if you are + using a SQL-based database backend for DSPAM. Please consult your + DSPAM manual for any details. + </span> + </p> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Purge Signatures</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("psig", "formfld unknown"); ?> name="psig" id="psig" value="<?=htmlspecialchars($pconfig['psig']);?>" /> + <strong> + Purge stale signatures + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Purge Neutral</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pneut", "formfld unknown"); ?> name="pneut" id="pneut" value="<?=htmlspecialchars($pconfig['pneut']);?>" /> + <strong> + Purge tokens with neutralish probabilities + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Purge Unused</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("punu", "formfld unknown"); ?> name="punu" id="punu" value="<?=htmlspecialchars($pconfig['punu']);?>" /> + <strong> + Purge unused tokens + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Purge Hapaxes</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("phapa", "formfld unknown"); ?> name="phapa" id="phapa" value="<?=htmlspecialchars($pconfig['phapa']);?>" /> + <strong> + Purge tokens with less than 5 hits (hapaxes) + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Purge Hits 1S</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("pones", "formfld unknown"); ?> name="pones" id="pones" value="<?=htmlspecialchars($pconfig['pones']);?>" /> + <strong> + Purge tokens with only 1 spam hit + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Purge Hits 1I</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("ponei", "formfld unknown"); ?> name="ponei" id="ponei" value="<?=htmlspecialchars($pconfig['ponei']);?>" /> + <strong> + Purge tokens with only 1 innocent hit + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'main';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="sys" style="visibility: hidden;"> </a>System Settings</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Local MX</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("locmx", "formfld host"); ?> name="locmx" id="locmx" value="<?=htmlspecialchars($pconfig['locmx']);?>" /> + <strong> + 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. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <span class="vexpl"> + Disabling logging for users will make usage graphs unavailable to + them. Disabling system logging will make admin graphs unavailable. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Enable System Log</td> + <td width="78%" class="vtable"> + <input name="enablesysl" type="checkbox" id="enablesysl" value="yes" <?php if (isset($pconfig['enablesysl'])) echo 'checked="checked"'; ?> /> + <strong> + Enable system logging. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Enable User Log</td> + <td width="78%" class="vtable"> + <input name="enableusel" type="checkbox" id="enableusel" value="yes" <?php if (isset($pconfig['enableusel'])) echo 'checked="checked"'; ?> /> + <strong> + Enable user logging. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Opt Settings</td> + <td width="78%" class="vtable"> + <select name="optinout" class="formselect"> + <option value="out" <?php if($pconfig['optinout'] == "out") echo('selected="selected"');?>>out</option> + <option value="in" <?php if($pconfig['optinout'] == "in") echo('selected="selected"');?>>in</option> + </select> + <p> + <span class="vexpl"> + 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 + <code>/var/dspam/opt-in/user.dspam</code> (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 <code>.nodspam</code> file is dropped in + <code>/var/dspam/opt-out/user.nodspam</code> + <span class="vexpl"> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <span class="vexpl"> + 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.. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Parse To Headers</td> + <td width="78%" class="vtable"> + <input name="enableptoh" type="checkbox" id="enableptoh" value="yes" <?php if (isset($pconfig['enableptoh'])) echo 'checked="checked"'; ?> /> + <strong> + Parse the <i>To:</i> headers of an incoming message. + </strong> + <p> + <span class="vexpl"> + This must be set to ‘on’ to use either of the following features. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Change Mode On Parse</td> + <td width="78%" class="vtable"> + <input name="enablecmop" type="checkbox" id="enablecmop" value="yes" <?php if (isset($pconfig['enablecmop'])) echo 'checked="checked"'; ?> /> + <strong> + Automatically change the class (to spam or innocent). + </strong> + <p> + <span class="vexpl"> + 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. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Change User On Parse</td> + <td width="78%" class="vtable"> + <input name="enablecuop" type="checkbox" id="enablecuop" value="yes" <?php if (isset($pconfig['enablecuop'])) echo 'checked="checked"'; ?> /> + <strong> + Automatically change the username to match that specified in the <i>To:</i> header. + </strong> + <p> + <span class="vexpl"> + For example, <code>spam-bob@domain.tld</code> 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}-. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Broken MTA Settings</td> + <td width="78%" class="vtable"> + <input name="enablebmta" type="checkbox" id="enablebmta" value="yes" <?php if (isset($pconfig['enablebmta'])) echo 'checked="checked"'; ?> /> + <strong> + Enable broken MTA settings. + </strong> + <p> + <span class="vexpl"> + 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 + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("Broken MTA Option");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_bmtas)): ?> + <?php $i = 0; foreach ($t_bmtas as $bmta): ?> + <?php if($bmta['name'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-bmta.php?id=<?=$i;?>§ionid=sys';"> + <?=htmlspecialchars($bmta['name']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-bmta.php?id=<?=$i;?>§ionid=sys';"> + <font color="#FFFFFF"><?=htmlspecialchars($bmta['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-bmta.php?id=<?=$i;?>§ionid=sys"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=bmta&id=<?=$i;?>§ionid=sys" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-bmta.php?sectionid=sys"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Max Message Size</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("maxmsgs", "formfld unknown"); ?> name="maxmsgs" id="maxmsgs" value="<?=htmlspecialchars($pconfig['maxmsgs']);?>" /> + <strong> + You may specify a maximum message size for DSPAM to process. + </strong> + <p> + <span class="vexpl"> + If the message is larger than the maximum size, it will be delivered + without processing. Value is in bytes. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Processor Bias</td> + <td width="78%" class="vtable"> + <input type="checkbox" name="procbias" id="procbias" value="yes" <?php if (isset($pconfig['procbias'])) echo 'checked="checked"'; ?> /> + <strong> + 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). + </strong> + <p> + <span class="vexpl"> + Note: You probably DONT want this if you're using Markovian Weighting, + unless you are paranoid about false positives. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'sys';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <?php if (checkForClamAVSupport()): ?> + <tr> + <td valign="top" class="listtopic"><a name="clam" style="visibility: hidden;"> </a>ClamAV Engine Settings</td> + <td align="right" valign="top" class="listtopic"> + <input name="enableclam" type="checkbox" id="enableclam" value="yes" <?php if (isset($pconfig['enableclam'])) echo 'checked="checked"'; ?> onClick="enable_change(false, 3);" /> + <strong>Enable</strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + If you are running clamd, DSPAM can perform stream-based + virus checking using TCP. Uncomment the values below to enable virus + checking. + </span> + </p> + <p> + <span class="vexpl"> + ClamAVResponse: + <dl> + <dt>reject</dt> + <dd>(reject or drop the message with a permanent failure)</dd> + <dt>accept</dt> + <dd>(accept the message and quietly drop the message)</dd> + <dt>spam</dt> + <dd>(treat as spam and quarantine/tag/whatever)</dd> + </dl> + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">ClamAV Port</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("clamport", "formfld unknown"); ?> name="clamport" id="clamport" value="<?=htmlspecialchars($pconfig['clamport']);?>" <?php if (! isset($pconfig['enableclam'])) echo 'disabled="disabled"'; ?> /> + <strong> + A number that specifies the port the ClamAV daemon is listening to. + </strong> + </p> + <p> + <span class="vexpl"> + If the message is larger than the maximum size, it will be delivered + without processing. Value is in bytes. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">ClamAV Host</td> + <td width="78%" class="vtable"> + <input type="text" size="30" <?= checkForErrorClass("clamhost", "formfld host"); ?> name="clamhost" id="clamhost" value="<?=htmlspecialchars($pconfig['clamhost']);?>" <?php if (! isset($pconfig['enableclam'])) echo 'disabled="disabled"'; ?> /> + <strong> + An IP address that points to the host the ClamAV daemon is running on. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">ClamAV Response</td> + <td width="78%" class="vtable"> + <select name="clamresp" class="formselect" <?php if (! isset($pconfig['enableclam'])) echo 'disabled="disabled"'; ?>> + <option value="reject" <?php if($pconfig['clamresp'] == "reject") echo('selected="selected"');?>>reject</option> + <option value="accept" <?php if($pconfig['clamresp'] == "accept") echo('selected="selected"');?>>accept</option> + <option value="spam" <?php if($pconfig['clamresp'] == "spam") echo('selected="selected"');?>>spam</option> + </select> + <strong> + The action that should take place, if ClamAV reports a positive. + </strong> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'clam';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <?php endif; ?> + <tr> + <td colspan="2" valign="top" class="listtopic"><a name="srv" style="visibility: hidden;"> </a>DSPAM Daemon Settings (Server)</td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <span class="vexpl"> + If you are running DSPAM as a daemonized server using + <code>--daemon</code>, 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 <code>--stdout</code> option in conjunction with a local setup. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Server Port</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("dsport", "formfld unknown"); ?> name="dsport" id="dsport" value="<?=htmlspecialchars($pconfig['dsport']);?>" /> + <strong> + A number that specifies the port the DSPAM daemon is listening to. + </strong> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Server Queue Size</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("dsqsize", "formfld unknown"); ?> name="dsqsize" id="dsqsize" value="<?=htmlspecialchars($pconfig['dsqsize']);?>" /> + <strong> + A number that specifies the server's queue size. + </strong> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Server PID</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("dspid", "formfld file"); ?> name="dspid" id="dspid" value="<?=htmlspecialchars($pconfig['dspid']);?>" /> + <strong> + Keep this is sync with <code>/usr/local/etc/rc.d/dspam.rc</code> script. + </strong> + </p> + <p> + <span class="vexpl"> + Note: Don't change this value unless you know what you are doing. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Server Mode</td> + <td width="78%" class="vtable"> + <p> + <select name="dssmode" class="formselect"> + <option value="dspam" <?php if($pconfig['dssmode'] == "dspam") echo('selected="selected"');?>>dspam</option> + <option value="standard" <?php if($pconfig['dssmode'] == "standard") echo('selected="selected"');?>>standard</option> + <option value="auto" <?php if($pconfig['dssmode'] == "auto") echo('selected="selected"');?>>auto</option> + </select> + <strong> + Specifies the type of LMTP server to start. + </strong> + <p> + <span class="vexpl"> + This can be one of: + <dl> + <dt>dspam</dt> + <dd>DSPAM-proprietary DLMTP server, for communicating with dspamc</dd> + <dt>standard</dt> + <dd>Standard LMTP server, for communicating with Postfix or other MTA</dd> + <dt>auto</dt> + <dd>Speak both DLMTP and LMTP; auto-detect by ServerPass.IDENT</dd> + </dl> + </span> + </p> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" rowspan="2" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + 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). + </span> + </p> + <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="55%" class="listhdrr"><?=gettext("DLMTP Password Value");?></td> + <td width="35%" class="listhdr"><?=gettext("Description");?></td> + <td width="10%" class="list"></td> + </tr> + <?php if(is_array($t_spwds)): ?> + <?php $i = 0; foreach ($t_spwds as $spwd): ?> + <?php if($spwd['value'] <> ""): ?> + + <tr> + <td class="listlr" ondblclick="document.location='dspam-settings-spwd.php?id=<?=$i;?>§ionid=srv';"> + <?=htmlspecialchars($spwd['value']);?> + </td> + <td class="listbg" ondblclick="document.location='dspam-settings-spwd.php?id=<?=$i;?>§ionid=srv';"> + <font color="#FFFFFF"><?=htmlspecialchars($spwd['descr']);?> </font> + </td> + <td valign="middle" nowrap class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-spwd.php?id=<?=$i;?>§ionid=srv"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="dspam-settings.php?act=del&what=spwd&id=<?=$i;?>§ionid=srv" onclick="return confirm('<?=gettext("Do you really want to delete this mapping?");?>')"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + + <?php endif; ?> + <?php $i++; endforeach; ?> + <?php endif; ?> + <tr> + <td class="list" colspan="3"></td> + <td class="list"> + <table border="0" cellspacing="0" cellpadding="1"> + <tr> + <td valign="middle"><a href="dspam-settings-spwd.php?sectionid=srv"><img src="./themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0"></a></td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + 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. + </span> + </p> + <p> + <span class="vexpl"> + Note: If you specify <code>--user</code> in ServerParameters, the RCPT TO will be used + only for delivery, and not set as the active user for processing. + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Server Parameters</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" class="formfld unknown" name="serverparam" id="serverparam" value="<?=htmlspecialchars($pconfig['serverparam']);?>" /> + <strong> + Parameters which will be passed to the LMTP server. + </strong> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Server Ident</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("serverid", "formfld host"); ?> name="serverid" id="serverid" value="<?=htmlspecialchars($pconfig['serverid']);?>" /> + <strong> + An identification string which will be used to be passed to the LMTP server. + </strong> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Server Domain Socket Path</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("serversock", "formfld file"); ?> name="serversock" id="serversock" value="<?=htmlspecialchars($pconfig['serversock']);?>" /> + <strong> + A local Unix domain socket. + </strong> + </p> + <p> + <span class="vexpl"> + 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. + </span> + </p> + <p> + <span class="vexpl"> + Keep this is sync with <code>/usr/local/etc/rd.d/dspam.rc</code> script + </span> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'srv';" /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td valign="top" class="listtopic"><a name="cli" style="visibility: hidden;"> </a>DSPAM Daemon Settings (Client)</td> + <td align="right" valign="top" class="listtopic"> + <input name="enabledsclient" type="checkbox" id="enabledsclient" value="yes" <?php if (isset($pconfig['enabledsclient'])) echo 'checked="checked"'; ?> onClick="enable_change(false, 4);" /> + <strong>Enable</strong> + </td> + </tr> + + <tr> + <td width="22%" valign="top" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <span class="vexpl"> + If you are running DSPAM in client/server mode, uncomment and + set these variables. A ClientHost beginning with a <code>/</code> + will be treated as a domain socket. + </span> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Client Host</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("dsclhost", "formfld host"); ?> name="dsclhost" id="dsclhost" value="<?=htmlspecialchars($pconfig['dsclhost']);?>" <?php if (! isset($pconfig['enabledsclient'])) echo 'disabled="disabled"'; ?> /> + <strong> + A IP address or a Unix domain socket. + </strong> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Client Port</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("dsclhost", "formfld host"); ?> name="dsclport" id="dsclport" value="<?=htmlspecialchars($pconfig['dsclport']);?>" <?php if (! isset($pconfig['enabledsclient'])) echo 'disabled="disabled"'; ?> /> + <strong> + Will be only used if this client uses TCP/IP communication. + </strong> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top" class="vncell">Client Ident</td> + <td width="78%" class="vtable"> + <p> + <input type="text" size="30" <?= checkForErrorClass("dsclident", "formfld unknown"); ?> name="dsclident" id="dsclident" value="<?=htmlspecialchars($pconfig['dsclident']);?>" <?php if (! isset($pconfig['enabledsclient'])) echo 'disabled="disabled"'; ?> /> + <strong> + A string that will be used to identify the client against a server. + </strong> + </p> + </td> + </tr> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <!-- <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)" /> --> + <input id="submitt" name="Submit" type="submit" class="formbtn" value="<?=gettext("Save");?>" onclick="document.iform.sectionid.value = 'cli';" /> + </td> + </tr> + </table> + </td> + </tr> + </table> + </div> + </td> + </tr> + </table> + </form> + <br> + <?= checkForInputErrors(); ?> +<? + } else { +?> +<?php + $input_errors[] = "Access to this particular site was denied. You need DSPAM admin access rights to be able to view it."; + + include("head.inc"); + echo $pfSenseHead->getHTML(); +?> +<?php include("fbegin.inc");?> +<?php if ($input_errors) print_input_errors($input_errors);?> +<?php if ($savemsg) print_info_box($savemsg);?> + <body link="#000000" vlink="#000000" alink="#000000"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td valign="top" class="listtopic">Access denied for: <?=$HTTP_SERVER_VARS['AUTH_USER']?></td> + </tr> + </table> +<?php + } // end of access denied code +?> +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-train.php b/config/dspam/www/dspam-train.php new file mode 100644 index 00000000..bc0bc087 --- /dev/null +++ b/config/dspam/www/dspam-train.php @@ -0,0 +1,284 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Train Filter")); + +/* omit no-cache headers because it confuses IE with file downloads */ +$omit_nocacheheaders = true; +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +function prepare_compressed_mbox_data($type) { + global $CURRENT_USER; + /* prepare directories */ + mwexec("mkdir -m 0755 -p /tmp/dspam-data/{$CURRENT_USER}/mbox"); + mwexec("mkdir -m 0755 -p /tmp/dspam-data/{$CURRENT_USER}/mdir"); + + switch ($type) { + case 0: + move_uploaded_file($_FILES['archfile']['tmp_name'], "/tmp/" . $_FILES['archfile']['name']); + mwexec("/usr/local/bin/unzip /tmp/{$_FILES['archfile']['name']} -d /tmp/dspam-data/{$CURRENT_USER}/mbox"); + unlink("/tmp/{$_FILES['archfile']['name']}"); + mwexec("/usr/local/bin/mb2md -s /tmp/dspam-data/{$CURRENT_USER}/mbox -R -d /tmp/dspam-data/{$CURRENT_USER}/mdir"); + break; + case 1: + move_uploaded_file($_FILES['archfile']['tmp_name'], "/tmp/dspam-data/" . $_SESSION['Username'] . "/mbox/" . $_FILES['archfile']['name']); + mwexec("/usr/bin/gunzip /tmp/dspam-data/{$CURRENT_USER}/mbox/{$_FILES['archfile']['name']}"); + mwexec("/usr/local/bin/mb2md -s /tmp/dspam-data/{$CURRENT_USER}/mbox -R -d /tmp/dspam-data/{$CURRENT_USER}/mdir"); + break; + case 2: + move_uploaded_file($_FILES['archfile']['tmp_name'], "/tmp/dspam-data/" . $_SESSION['Username'] . "/mbox/" . $_FILES['archfile']['name']); + mwexec("/usr/bin/bunzip2 /tmp/dspam-data/{$CURRENT_USER}/mbox/{$_FILES['archfile']['name']}"); + mwexec("/usr/local/bin/mb2md -s /tmp/dspam-data/{$CURRENT_USER}/mbox -R -d /tmp/dspam-data/{$CURRENT_USER}/mdir"); + break; + } +} + +function prepare_compressed_mdir_data($type) { + global $CURRENT_USER; + /* prepare directories */ + mwexec("mkdir -m 0755 -p /tmp/dspam-data/{$CURRENT_USER}/mdir"); + + switch ($type) { + case 0: + move_uploaded_file($_FILES['archfile']['tmp_name'], "/tmp/" . $_FILES['archfile']['name']); + mwexec("/usr/local/bin/unzip /tmp/{$_FILES['archfile']['name']} -d /tmp/dspam-data/{$CURRENT_USER}/mdir"); + unlink("/tmp/{$_FILES['archfile']['name']}"); + break; + case 1: + move_uploaded_file($_FILES['archfile']['tmp_name'], "/tmp/dspam-data/" . $_SESSION['Username'] . "/mdir/" . $_FILES['archfile']['name']); + mwexec("/usr/bin/gunzip /tmp/dspam-data/{$CURRENT_USER}/mdir/{$_FILES['archfile']['name']}"); + break; + case 2: + move_uploaded_file($_FILES['archfile']['tmp_name'], "/tmp/dspam-data/" . $_SESSION['Username'] . "/mdir/" . $_FILES['archfile']['name']); + mwexec("/usr/bin/bunzip2 /tmp/dspam-data/{$CURRENT_USER}/mdir/{$_FILES['archfile']['name']}"); + break; + } +} + +function prepare_compressed_data($type) { + if ($_POST['archformat'] == "mbox") { + prepare_compressed_mbox_data($type); + } else { + prepare_compressed_mdir_data($type); + } +} + +if ($_POST) { + unset($input_errors); + + if(! extension_loaded( 'fileinfo' )) { + /* fileinfo pecl extension unavailable? */ + if(! @dl( 'fileinfo.so' )) { + if ($_POST['cotype'] == "zip") { + prepare_compressed_data(0); + } else if ($_POST['cotype'] == "gzip") { + prepare_compressed_data(1); + } else if ($_POST['cotype'] == "bzip") { + prepare_compressed_data(2); + } else { + $input_errors[] = "unable to determine compression type."; + } + } else { + if (is_uploaded_file($_FILES['archfile']['tmp_name'])) { + $info = finfo_open( FILEINFO_MIME, '/usr/share/misc/magic' ); + $type = finfo_file( $info, $_FILES['archfile']['tmp_name'] ); + + if ($type == "application/x-zip") { + prepare_compressed_data(0); + } else if ($type == "application/x-gzip") { + prepare_compressed_data(1); + } else if ($type == "application/x-bzip2") { + prepare_compressed_data(2); + } else { + $input_errors[] = "unable to determine compression type."; + } + } + } + } + + /* tell DSPAM to train the messages contained within the maildir */ + if ($_POST['msgtype'] == "spam") { + mwexec("find /tmp/dspam-data/{$CURRENT_USER}/mdir -name '*' -exec /usr/local/bin/dspam_spamfeed {$CURRENT_USER} {} \\;"); + } else if ($_POST['msgtype'] == "ham") { + mwexec("find /tmp/dspam-data/{$CURRENT_USER}/mdir -name '*' -exec /usr/local/bin/dspam_innocentfeed {$CURRENT_USER} {} \\;"); + mwexec("rm -rf /tmp/dspam-data"); + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-train.php" method="post" name="iform" id="iform" enctype="multipart/form-data"> +<input type="hidden" name="MAX_FILE_SIZE" value="<?= (diskfreespace('/') - (10 * pow(10, 6))); ?>"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", false, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", false, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", true, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Username</td> + <td width="78%" class="vtable"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" class="listtopic"><?=gettext("Upload Message Archive");?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Archive Type</td> + <td width="78%" class="vtable"> + <?php if($config['installedpackages']['mb2md'] || file_exists('/usr/local/bin/mb2md')): ?> + <input type="radio" name="archformat" id="mbxformat" value="mbox" class="formfld" /> + <a href="http://en.wikipedia.org/wiki/Mbox" target="_blank">Mailbox</a> format (like it is used for example by Mozilla Thunderbird) + <br /> + <?php endif; ?> + <input type="radio" name="archformat" id="mdirformat" value="mdir" class="formfld" checked="checked"/> + <a href="http://en.wikipedia.org/wiki/Maildir" target="_blank">Maildir</a> format (like it was initially introduced by qmail) + <p> + <strong> + <span class="red"><?=gettext("Note");?>:</span> + </strong> + <br /> + <?=gettext("DSPAM is only able to handle Maildir message archives natively. Mailbox message archives need to be converted (the conversion from mbx to maildir will be done on the fly while you are uploading a message archive).");?> + <br /> + </p> + </td> + </tr> + <?php if(! extension_loaded( 'fileinfo' )): ?> + <?php if(! @dl( 'fileinfo.so' )): ?> + <tr> + <td width="22%" valign="baseline" class="vncell">Compression Type</td> + <td width="78%" class="vtable"> + <input type="radio" name="cotype" id="ziptype" value="zip" class="formfld" /> + Archive was compressed using a ZIP algorithm. + <br /> + <input type="radio" name="cotype" id="gziptype" value="gzip" class="formfld" /> + Archive was compressed using a GNU ZIP algorithm. + <br /> + <input type="radio" name="cotype" id="bziptype" value="bzip" class="formfld" checked="checked" /> + Archive was compressed using a bzip2 algorithm + <br /> + </td> + </tr> + <?php endif; ?> + <?php endif; ?> + <tr> + <td width="22%" valign="baseline" class="vncell">Message Type</td> + <td width="78%" class="vtable"> + <input type="radio" name="msgtype" id="spamtype" value="spam" class="formfld" checked="checked" /> + Archive to be uploaded contains Spam messages. + <br /> + <input type="radio" name="msgtype" id="hamtype" value="ham" class="formfld" /> + Archive to be uploaded contains Ham messages. + <br /> + </td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell"> </td> + <td width="78%" class="vtable"> + <p> + <?=gettext("Open a Ham or Spam message archive (please either zip, gzip or bzip your files).");?> + </p> + <p> + <input name="archfile" type="file" class="formfld file" id="archfile" size="40" maxlength="<?= (diskfreespace('/') - (10 * pow(10, 6))); ?>" /> + </p> + <p> + <input name="Submit" type="submit" class="formbtn" id="restore" value="<?=gettext("Upload Message Archive");?>" /> + </p> + <p> + <strong> + <span class="red"><?=gettext("Note");?>:</span> + </strong> + <br /> + <?=gettext("It may take a long time until the filter stops training, if you are going to upload a huge archive. Therefore the the allowed filesize to be uploaded has been set to " . ((diskfreespace('/') - (10 * pow(10, 6))) / pow(10, 6)) . " MByte (available space minus 10 MByte).");?> + <br /> + </p> + </td> + </tr> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam-viewmsg.php b/config/dspam/www/dspam-viewmsg.php new file mode 100644 index 00000000..e56b081f --- /dev/null +++ b/config/dspam/www/dspam-viewmsg.php @@ -0,0 +1,158 @@ +<?php +/* $Id$ */ +/* + dspam-train.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Quarantine"), + gettext("View Message")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +/* if this is an AJAX caller then handle via JSON */ +if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam-quarantine.php" method="post" name="iform" id="iform"> +<input type="hidden" name="command" value="processFalsePositive" /> +<input type="hidden" name="signatureID" value="<?= $DATA['MESSAGE_ID']; ?>" /> +<input type="hidden" name="qpage" value="<?= $DATA['QPAGE']; ?>" /> +<input type="hidden" name="sortby" value="<?= $DATA['SORTBY']; ?>" > +<input type="hidden" name="qperpage" value="<?= $CONFIG['QUARANTINE_PER_PAGE']; ?>" > +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<p> + <span class="vexpl"> + The contents of the message in the quarantine is shown below. + </span> +</p> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $querystr = "?user=?{$CURRENT_USER}&page={$DATA['QPAGE']}&sortby={$DATA['SORTBY']}&qperpage={$CONFIG['QUARANTINE_PER_PAGE']}"; + + $tab_array = array(); + $tab_array[] = array("Info", false, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine (View)", true, "/dspam-quarantine.php{$querystr}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", false, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="3">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="15%" valign="baseline" class="vncell">Username</td> + <td width="85%" class="vtable" colspan="2"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td class="list" height="12" colspan="3"> </td> + </tr> + <tr> + <td align="left" valign="middle" class="qnavtd" colspan="3"> + <input type="submit" class="formbtn" title="Deliver Message" value="Deliver Message" name="delmsg" id="delmsg" /> + <label for="delmsg"> because it is <strong>not</strong> SPAM</label> + </td> + </tr> + <tr> + <td class="list" height="12" colspan="3"> </td> + </tr> + <?php if(! extension_loaded( 'mailparse' ) && $CONFIG['USE_MAILPARSE']): ?> + <?php if(! @dl( 'mailparse.so' )): ?> + <tr> + <td align="left" valign="top" class="listtopic" colspan="3">Mail Message</td> + </tr> + <tr> + <td align="center" valign="top" colspan="3" class="vncell"> + <textarea rows="36" cols="87" readonly="readonly"> + <?= $DATA['MESSAGE']; ?> + </textarea> + </td> + </tr> + <?php else: ?> + <?= getLayoutedMessage($DATA['MESSAGE'], $DATA['MESSAGE_ID'], $DATA['SHOWPART'], $DATA['CONTENT_TYPE']); ?> + <?php endif; ?> + <?php else: ?> + <tr> + <td align="left" valign="top" class="listtopic" colspan="3">Mail Message</td> + </tr> + <tr> + <td align="center" valign="top" colspan="3" class="vncell"> + <textarea rows="36" cols="87" readonly="readonly"> + <?= $DATA['MESSAGE']; ?> + </textarea> + </td> + </tr> + <?php endif; ?> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/dspam.php b/config/dspam/www/dspam.php new file mode 100644 index 00000000..1f2d7df7 --- /dev/null +++ b/config/dspam/www/dspam.php @@ -0,0 +1,264 @@ +<?php +/* $Id$ */ +/* + dspam.php + + Copyright (C) 2006 Daniel S. Haischt. + All rights reserved. +*/ + +$pgtitle = array(gettext("Services"), + gettext("DSPAM"), + gettext("Overview")); + +require("guiconfig.inc"); +include("/usr/local/pkg/dspam.inc"); + +if ($_POST) { + unset($input_errors); + + if (is_uploaded_file($_FILES['nionelic']['tmp_name'])) { + conf_mount_rw(); + config_lock(); + move_uploaded_file($_FILES['nionelic']['tmp_name'], "{$g['conf_path']}/{$_FILES['nionelic']['name']}"); + chmod("{$g['conf_path']}/{$_FILES['nionelic']['name']}", 0400); + config_unlock(); + conf_mount_ro(); + } + if (is_uploaded_file($_FILES['nionelicchk']['tmp_name'])) { + conf_mount_rw(); + config_lock(); + move_uploaded_file($_FILES['nionelicchk']['tmp_name'], "{$g['conf_path']}/{$_FILES['nionelicchk']['name']}"); + chmod("{$g['conf_path']}/{$_FILES['nionelicchk']['name']}", 0400); + config_unlock(); + conf_mount_ro(); + } + + /* if this is an AJAX caller then handle via JSON */ + if(isAjax() && is_array($input_errors)) { + input_errors2Ajax($input_errors); + 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 +<script type="text/javascript"> +<!-- + +EOD; + + $jscriptstr .= getJScriptFunction(0); + $jscriptstr .= <<<EOD +//--> +</script> +EOD; + + $pfSenseHead->addScript($jscriptstr); +echo $pfSenseHead->getHTML(); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<form action="dspam.php" method="post" name="iform" id="iform" enctype="multipart/form-data"> +<input type="hidden" name="MAX_FILE_SIZE" value="<?= (diskfreespace('/') - (10 * pow(10, 6))); ?>"> +<?php if ($input_errors) print_input_errors($input_errors); ?> +<?php if ($savemsg) print_info_box($savemsg); ?> +<table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td> +<?php + $tab_array = array(); + $tab_array[] = array("Info", true, "/dspam.php?user={$CURRENT_USER}"); + $tab_array[] = array("Performance", false, "/dspam-perf.php?user={$CURRENT_USER}"); + $tab_array[] = array("Preferences", false, "/dspam-prefs.php?user={$CURRENT_USER}"); + $tab_array[] = array("Alerts", false, "/pkg.php?xml=dspam_alerts.xml&user={$CURRENT_USER}"); + $tab_array[] = array("Quarantine ({$DATA['TOTAL_QUARANTINED_MESSAGES']})", false, "/dspam-quarantine.php?user={$CURRENT_USER}"); + $tab_array[] = array("Analysis", false, "/dspam-analysis.php?user={$CURRENT_USER}"); + $tab_array[] = array("History", false, "/dspam-history.php?user={$CURRENT_USER}"); + $tab_array[] = array("Train Filter", false, "/dspam-train.php?user={$CURRENT_USER}"); + if (isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { + $tab_array[] = array("Admin Suite", false, "/dspam-admin.php"); + } + display_top_tabs($tab_array); +?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td align="left" valign="top" class="listhdrr" colspan="2">Statistical SPAM Protection for...</td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Username</td> + <td width="78%" class="vtable"> + <?php if(isset($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <input type="text" name="username" id="username" value="<?= $CURRENT_USER ?>" class="formfld user"<?php if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) { echo " readonly=\"readonly\""; } ?> /> + <?php else: ?> + <input type="text" name="username" id="username" value="Please provide a username" class="formfld user" onFocus="this.value='';" /> + <?php endif; ?> + + <?php + if (! isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])) + $action = "onClick=\"changeuser();\""; + else + $action = "onClick=\"document.iform.submit();\""; + ?> + <input type="button" name="change_user" id="change_user" class="formbtn" value="Change" <?= $action ?> /> + </td> + </tr> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" class="listtopic"><?=gettext("DSPAM Software Details");?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">DSPAM Version</td> + <td width="78%" class="vtable"><?= $DATA['DSPAM_VERSION']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">DSPAM Copyright</td> + <td width="78%" class="vtable"><?= $DATA['DSPAM_COPYRIGHT']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">DSPAM Copyright Text</td> + <td width="78%" class="vtable"><?= $DATA['DSPAM_COPYRIGHT_TEXT']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">DSPAM Website</td> + <td width="78%" class="vtable"> + <a href="<?= $DATA['DSPAM_WEBSITE']; ?>" target="_blank"><?= $DATA['DSPAM_WEBSITE']; ?></a> + </td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">DSPAM Configure Args</td> + <td width="78%" class="vtable"> + <code style="font-size: small;"><?= $DATA['DSPAM_CONFIGURE_ARGS']; ?></code> + </td> + </tr> + <?php if($CONFIG['OPENSOURCE'] == false): ?> + <tr> + <td colspan="2" class="list" height="12"> </td> + </tr> + <tr> + <td colspan="2" class="listtopic"><?=gettext("Ni-ONE License Information");?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">License User</td> + <td width="78%" class="vtable"><?= $DATA['OWNER']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Company</td> + <td width="78%" class="vtable"><?= $DATA['COMPANY']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">License Key</td> + <td width="78%" class="vtable"><?= $DATA['LICENSE_KEY']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">License Validity</td> + <td width="78%" class="vtable"> + <?= $DATA['LICENSE_VALIDITY']; ?> + <?php if(strpos($DATA['LICENSE_VALIDITY'], "expired") !== false && isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <a href="http://www.niefert.net/nione.php?customer<?= $DATA['LICENSE_KEY']; ?>" target="_blank">Renew License</a> + <?php endif; ?> + </td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Purchase Date</td> + <td width="78%" class="vtable"><?= $DATA['PURCHASE_DATE']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Expiry Date</td> + <td width="78%" class="vtable"><?= $DATA['EXPIRY_DATE']; ?></td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Ni-ONE Website</td> + <td width="78%" class="vtable"> + <a href="http://www.niefert.net/nione.php" target="_blank">http://www.niefert.net/nione.php</a> + </td> + </tr> + <?php if($DATA['LICENSE_VALIDITY'] == "valide"): ?> + <tr> + <td width="22%" valign="baseline" class="vncell">Support Request</td> + <td width="78%" class="vtable"> + <a href="http://www.niefert.net/nione.php?supportreq=true&customer=<?= $DATA['LICENSE_KEY']; ?>" target="_blank">Issue a support request</a> + </td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">Ni-ONE Customer Forum</td> + <td width="78%" class="vtable"> + <a href="http://www.niefert.net/nione-forum.php?customer=<?= $DATA['LICENSE_KEY']; ?>" target="_blank">Visit Ni-ONE Customer Forum</a> + </td> + </tr> + <?php endif; ?> + <?php if(strpos($DATA['LICENSE_VALIDITY'], "found") !== false && isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <tr> + <td width="22%" valign="baseline" class="vncell">License File (nione.lic)</td> + <td width="78%" class="vtable"> + <input type="file" name="nionelic" id="nionelic" class="formfld file" size="50" maxlength="100" /> + </td> + </tr> + <tr> + <td width="22%" valign="baseline" class="vncell">License Checksum (nione.lic.sha1)</td> + <td width="78%" class="vtable"> + <input type="file" name="nionelicchk" id="nionelicchk" class="formfld file" size="50" maxlength="100" /> + </td> + </tr> + <?php endif; ?> + <?php if($DATA['LICENSE_VALIDITY'] == "valide"): ?> + <tr> + <td width="22%" valign="baseline" class="vncell">License Disclaimer</td> + <td width="78%" class="vtable"> + <p> + 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. + </p> + <p> + The Ni-ONE license provides 1<sup>st</sup> 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 <i>expired</i>, you may consider to purchase a renewal license + option using the <i>renew license</i> button that will be provided by the web + interface in such circumstances. + </p> + </td> + </tr> + <?php endif; ?> + <?php if(strpos($DATA['LICENSE_VALIDITY'], "found") !== false && isDSPAMAdmin($HTTP_SERVER_VARS['AUTH_USER'])): ?> + <tr> + <td width="22%" valign="baseline"> </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" id="restore" value="<?=gettext("Upload License");?>" /> + <p> + <strong> + <span class="red"><?=gettext("Note");?>:</span> + </strong> + <br /> + <?=gettext("You may have to hit the reload button of your browser after uploading your license files to be able to see the license data.");?> + <br /> + </p> + </td> + </tr> + <?php endif; ?> + <?php endif; ?> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/dspam/www/themes/metallic/dspam.css b/config/dspam/www/themes/metallic/dspam.css new file mode 100644 index 00000000..5b39ba32 --- /dev/null +++ b/config/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/dspam/www/wizards/dspam-lda-proxy.png b/config/dspam/www/wizards/dspam-lda-proxy.png Binary files differnew file mode 100644 index 00000000..7a4565ec --- /dev/null +++ b/config/dspam/www/wizards/dspam-lda-proxy.png diff --git a/config/dspam/www/wizards/dspam-pop-proxy.png b/config/dspam/www/wizards/dspam-pop-proxy.png Binary files differnew file mode 100644 index 00000000..fa373385 --- /dev/null +++ b/config/dspam/www/wizards/dspam-pop-proxy.png diff --git a/config/dspam/www/wizards/dspam-smtp-relay.png b/config/dspam/www/wizards/dspam-smtp-relay.png Binary files differnew file mode 100644 index 00000000..07f554c8 --- /dev/null +++ b/config/dspam/www/wizards/dspam-smtp-relay.png diff --git a/config/dspam/www/wizards/dspam_wizard.xml b/config/dspam/www/wizards/dspam_wizard.xml new file mode 100644 index 00000000..4ac96a4c --- /dev/null +++ b/config/dspam/www/wizards/dspam_wizard.xml @@ -0,0 +1,1848 @@ +<?xml version="1.0" encoding="utf-8" ?> +<pfsensewizard> +<!-- + Tags which can be used to exec arbitrary PHP code: + + <stepsubmitbeforesave /> + <stepsubmitphpaction /> + <stepbeforeformdisplay /> + <formvalidate /> + <disableallfieldsbydefault /> + <stepafterformdisplay /> + <javascriptafterformdisplay /> +--> +<copyright> +<![CDATA[ +/* + dspam_wizard.xml + part of pfSense (http://www.pfsense.org/) + + Copyright (C) 2006 Daniel S. Haischt + All rights reserved. +*/ +]]> +</copyright> +<totalsteps>15</totalsteps> +<title>Services: DSPAM: DSPAM Wizard</title> +<step> + <id>1</id> + <includefile>dspam.inc</includefile> + <title>DSPAM Setup Wizard</title> + <disableheader>true</disableheader> + <description>This wizard will guide you through the initial configuration of the DSPAM filter.</description> + <fields> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>2</id> + <includefile>dspam.inc</includefile> + <title>DSPAM Profile Selection</title> + <disableheader>true</disableheader> + <description>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.</description> + <fields> + <field> + <name>dspamprofile</name> + <type>radio</type> + <bindstofield>installedpackages->dspam->config->0->dspam-profile</bindstofield> + <description> + <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> + </description> + <value>lda</value> + <dontdisplayname /> + <typehint><center><img src="/wizards/dspam-lda-proxy.png" alt="DSPAM acts as a LDA proxy" border="0" /></center></typehint> + </field> + <field> + <name>dspamprofile</name> + <type>radio</type> + <bindstofield>installedpackages->dspam->config->0->dspam-profile</bindstofield> + <description> + <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> + </description> + <value>pop</value> + <dontdisplayname /> + <typehint><center><img src="/wizards/dspam-pop-proxy.png" alt="DSPAM will be invoked by a POP3 proxy" border="0" /></center></typehint> + </field> + <field> + <name>dspamprofile</name> + <type>radio</type> + <bindstofield>installedpackages->dspam->config->0->dspam-profile</bindstofield> + <description> + <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> + </description> + <value>smtp</value> + <dontdisplayname /> + <typehint><center><img src="/wizards/dspam-smtp-relay.png" alt="DSPAM acts as a SMTP realy" border="0" /></center></typehint> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> + <stepsubmitphpaction> + <![CDATA[ + if($_POST['dspamprofile'] != "") { + + /* set default trusted users */ + $config['installedpackages']['dspam']['config'][0]['tuser'][0]['name'] = "root"; + $config['installedpackages']['dspam']['config'][0]['tuser'][0]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['tuser'][1]['name'] = "mail"; + $config['installedpackages']['dspam']['config'][0]['tuser'][1]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['tuser'][2]['name'] = "mailnull"; + $config['installedpackages']['dspam']['config'][0]['tuser'][2]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['tuser'][3]['name'] = "smmsp"; + $config['installedpackages']['dspam']['config'][0]['tuser'][3]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['tuser'][4]['name'] = "daemon"; + $config['installedpackages']['dspam']['config'][0]['tuser'][4]['descr'] = "desc"; + /* set default features */ + $config['installedpackages']['dspam']['config'][0]['feature'][0]['name'] = "chained"; + $config['installedpackages']['dspam']['config'][0]['feature'][0]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['feature'][1]['name'] = "whitelist"; + $config['installedpackages']['dspam']['config'][0]['feature'][1]['descr'] = "desc"; + /* set default algorithms */ + $config['installedpackages']['dspam']['config'][0]['algorithm'][0]['name'] = "graham"; + $config['installedpackages']['dspam']['config'][0]['algorithm'][0]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['algorithm'][1]['name'] = "burton"; + $config['installedpackages']['dspam']['config'][0]['algorithm'][1]['descr'] = "desc"; + /* set default prefs */ + $config['installedpackages']['dspam']['config'][0]['preference'][0]['value'] = "\"spamAction=quarantine\""; + $config['installedpackages']['dspam']['config'][0]['preference'][0]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['preference'][1]['value'] = "\"signatureLocation=message\""; + $config['installedpackages']['dspam']['config'][0]['preference'][1]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['preference'][2]['value'] = "\"showFactors=on\""; + $config['installedpackages']['dspam']['config'][0]['preference'][2]['descr'] = "desc"; + /* set default overrides */ + $config['installedpackages']['dspam']['config'][0]['override'][0]['value'] = "trainingMode"; + $config['installedpackages']['dspam']['config'][0]['override'][0]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][1]['value'] = "spamAction spamSubject"; + $config['installedpackages']['dspam']['config'][0]['override'][1]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][2]['value'] = "statisticalSedation"; + $config['installedpackages']['dspam']['config'][0]['override'][2]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][3]['value'] = "enableBNR"; + $config['installedpackages']['dspam']['config'][0]['override'][3]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][4]['value'] = "enableWhitelist"; + $config['installedpackages']['dspam']['config'][0]['override'][4]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][5]['value'] = "signatureLocation"; + $config['installedpackages']['dspam']['config'][0]['override'][5]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][6]['value'] = "showFactors"; + $config['installedpackages']['dspam']['config'][0]['override'][6]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][7]['value'] = "optIn optOut"; + $config['installedpackages']['dspam']['config'][0]['override'][7]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['override'][8]['value'] = "whitelistThreshold"; + $config['installedpackages']['dspam']['config'][0]['override'][8]['descr'] = "desc"; + + if($_POST['dspamprofile'] == "lda" || $_POST['dspamprofile'] == "pop") { + $config['installedpackages']['dspam']['config'][0]['tdelivery-agent'] = "mail"; + /* TCP/IP based deliver is not needed */ + 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'] = "error"; + + /* We will asume that the user is going to use the dspam and not the dspamc + * binary. Hence we are unsetting server/client settings. + */ + unset($config['installedpackages']['dspam']['config'][0]['dspam-server-port']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-server-queue-size']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-server-pid']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-server-mode']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-server-params']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-server-id']); + unset($config['installedpackages']['dspam']['config'][0]['dspam-server-socket']); + /* Client */ + 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']); + } else if($_POST['dspamprofile'] == "smtp") { + /* TCP/IP based deliver is not needed */ + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery'] = "on"; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-host'] = "127.0.0.1"; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-port'] = "25"; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-ident'] = "localhost"; + $config['installedpackages']['dspam']['config'][0]['tcpip-delivery-proto'] = "smtp"; + $config['installedpackages']['dspam']['config'][0]['delivery-onfail'] = "error"; + + /* We will asume that the user is going to use the dspam and not the dspamc + * binary. Hence we are unsetting server/client settings. + */ + $config['installedpackages']['dspam']['config'][0]['dspam-server-port'] = "24"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-queue-size'] = "32"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-pid'] = "/var/run/dspam/dspam.pid"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-mode'] = "standard"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-params'] = "--deliver=innocent -d %u"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-id'] = "localhost"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-socket'] = "/var/run/dspam/dspam.sock"; + /* server passwords */ + $config['installedpackages']['dspam']['config'][0]['server-pwd'][0]['value'] = "secret"; + $config['installedpackages']['dspam']['config'][0]['server-pwd'][0]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['server-pwd'][1]['value'] = "password"; + $config['installedpackages']['dspam']['config'][0]['server-pwd'][1]['descr'] = "desc"; + /* Client */ + $config['installedpackages']['dspam']['config'][0]['dspam-client-enable'] = "on"; + $config['installedpackages']['dspam']['config'][0]['dspam-client-host'] = "/tmp/dspam.sock"; + $config['installedpackages']['dspam']['config'][0]['dspam-client-port'] = "24"; + $config['installedpackages']['dspam']['config'][0]['dspam-client-id'] = "secret@Relay1"; + } + + write_config(); + } + ]]> + </stepsubmitphpaction> +</step> +<step> + <id>3</id> + <includefile>dspam.inc</includefile> + <title>Database Settings</title> + <description> + 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. + </description> + <fields> + <field> + <name>storagedriver</name> + <type>select</type> + <bindstofield>installedpackages->dspam->config->0->storage-driver</bindstofield> + <description>Specifies the storage driver backend (library) to use.</description> + <default_value>mysql</default_value> + <onchange>toggleDBSettings();</onchange> + <size>1</size> + <options> + <option> + <name>mysql</name> + <value>mysql</value> + </option> + <option> + <name>sqlite</name> + <value>sqlite</value> + </option> + <option> + <name>bdb</name> + <value>bdb</value> + </option> + <option> + <name>pgsql</name> + <value>pgsql</value> + </option> + <option> + <name>oracle</name> + <value>oracle</value> + </option> + <option> + <name>hash</name> + <value>hash</value> + </option> + </options> + </field> + <field> + <name>msqlserver</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-server</bindstofield> + <description>Either a reference to a Unix domain socket or a reference to a specific host.</description> + <default_value>/tmp/mysql.sock</default_value> + <validate>^[a-z0-9.|/]+$</validate> + <message>Server name field is invalid</message> + <required /> + </field> + <field> + <name>msqlport</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-port</bindstofield> + <description>Use this variable if you are going to a MySQL server instance using TCP/IP instead of a socket connection.</description> + <default_value>3306</default_value> + <validate>^[0-9]+$</validate> + <message>Port field is invalid</message> + <required /> + </field> + <field> + <name>msqluser</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-user</bindstofield> + <description>Username, that will be used to connect to a MySQL server instance.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>msqlpwd</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-password</bindstofield> + <description>Password, that will be used to connect to a MySQL server instance.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>msqldb</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-database</bindstofield> + <description>Database name, that contains DSPAM data.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>msqlcomp</name> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-compress</bindstofield> + <description>Indicates whether communication data between DSPAM and MySQL should be compressed.</description> + <default_value>on</default_value> + </field> + <field> + <name>msqlsuqt</name> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-squote</bindstofield> + <description>Use this if you have the 4.1 quote bug (see doc/mysql.txt).</description> + </field> + <field> + <name>msqlccache</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-ccache</bindstofield> + <description>Conection cache default set to 10.</description> + <default_value>10</default_value> + <validate>^[0-9]+$</validate> + <message>Connection cache field is invalid</message> + <required /> + </field> + <field> + <name>msqluid</name> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->mysql-uid</bindstofield> + <description>Insert user id into the DSPAM signature.</description> + <default_value>on</default_value> + </field> + <field> + <name>slitepr</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->sqlite-pragma</bindstofield> + <description>A particular SQLite pragma command to be used.</description> + </field> + <field> + <name>pgserver</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->pgsql-server</bindstofield> + <description>A reference to a specific host that is running a PostgreSQL instance.</description> + <default_value>127.0.0.1</default_value> + <validate>^[a-z0-9.|-]+$</validate> + <message>Server name field is invalid</message> + <required /> + </field> + <field> + <name>pgport</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->pgsql-port</bindstofield> + <description>A number that represents the port a specific PostgreSQL instance is listening to.</description> + <default_value>5432</default_value> + <validate>^[0-9]+$</validate> + <message>Port field is invalid</message> + <required /> + </field> + <field> + <name>pguser</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->pgsql-user</bindstofield> + <description>Username, that will be used to connect to a PostgreSQL server instance.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>pgpwd</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->pgsql-password</bindstofield> + <description>Password, that will be used to connect to a PostgreSQL server instance.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>pgdb</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->pgsql-database</bindstofield> + <description>Database name, that contains DSPAM data.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>pgccache</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->pgsql-ccache</bindstofield> + <description>Conection cache default set to 3.</description> + <default_value>3</default_value> + <validate>^[0-9]+$</validate> + <message>Connection cache field is invalid</message> + <required /> + </field> + <field> + <name>pguid</name> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->pgsql-uid</bindstofield> + <description>Insert user id into the DSPAM signature.</description> + <default_value>on</default_value> + </field> + <field> + <name>oraserver</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->ora-server</bindstofield> + <description>A reference to a specific host that is running an Oracle database instance.</description> + <size>50</size> + <default_value>"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SID=PROD)))"</default_value> + <required /> + </field> + <field> + <name>orauser</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->ora-user</bindstofield> + <description>Username, that will be used to connect to a Oracle database server instance.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>orapwd</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->ora-password</bindstofield> + <description>Password, that will be used to connect to a Oracle database server instance.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>orasch</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->ora-schema</bindstofield> + <description>Schema name, that contains DSPAM data.</description> + <default_value>dspam</default_value> + <required /> + </field> + <field> + <name>hsrmax</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->hash-rec-max</bindstofield> + <description>Default number of records to create in the initial segment when building hash files.</description> + <default_value>98317</default_value> + <validate>^[0-9]+$</validate> + <message>Default number of record field is invalid</message> + <required /> + </field> + <field> + <name>hsatex</name> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->hash-auto-ex</bindstofield> + <description>Autoextend hash databases when they fill up. This allows them to continue to train by adding extents (extensions) to the file.</description> + <default_value>on</default_value> + <required /> + </field> + <field> + <name>hsmxex</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->hash-max-ext</bindstofield> + <description>The maximum number of extents that may be created in a single hash file.</description> + <default_value>0</default_value> + <validate>^[0-9]+$</validate> + <message>Default number of record field is invalid</message> + <required /> + </field> + <field> + <name>hsexsz</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->hash-ext-size</bindstofield> + <description>The record size for newly created extents.</description> + <default_value>49157</default_value> + <validate>^[0-9]+$</validate> + <message>Default number of record field is invalid</message> + <required /> + </field> + <field> + <name>hsmxse</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->hash-max-seek</bindstofield> + <description>The maximum number of records to seek to insert a new record before failing or adding a new extent.</description> + <default_value>100</default_value> + <validate>^[0-9]+$</validate> + <message>Default number of record field is invalid</message> + <required /> + </field> + <field> + <name>hsccus</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->hash-co-user</bindstofield> + <description>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.</description> + <default_value>user</default_value> + <required /> + </field> + <field> + <name>hscoca</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dbsettings->0->hash-co-cache</bindstofield> + <description>If running in daemon mode, this is the max # of concurrent connections that will be supported.</description> + <default_value>10</default_value> + <validate>^[0-9]+$</validate> + <message>Default number of record field is invalid</message> + <required /> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> + <stepsubmitphpaction> + <![CDATA[ + if ($_POST['storagedriver'] == "mysql") { + /* ============================================================================================= */ + /* == SQLite == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['sqlite-pragma']); + /* ============================================================================================= */ + /* == PostgreSQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-uid']); + /* ============================================================================================= */ + /* == Oracle == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-schema']); + /* ============================================================================================= */ + /* == Hash == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-rec-max']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-auto-ex']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-ext']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-ext-size']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-seek']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-cache']); + } else if ($_POST['storagedriver'] == "sqlite") { + /* ============================================================================================= */ + /* == MySQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-compress']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-squote']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-uid']); + /* ============================================================================================= */ + /* == PostgreSQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-uid']); + /* ============================================================================================= */ + /* == Oracle == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-schema']); + /* ============================================================================================= */ + /* == Hash == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-rec-max']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-auto-ex']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-ext']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-ext-size']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-seek']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-cache']); + } else if ($_POST['storagedriver'] == "bdb") { + /* NOP */ + } else if ($_POST['storagedriver'] == "pgsql") { + /* ============================================================================================= */ + /* == MySQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-compress']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-squote']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-uid']); + /* ============================================================================================= */ + /* == SQLite == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['sqlite-pragma']); + /* ============================================================================================= */ + /* == Oracle == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-schema']); + /* ============================================================================================= */ + /* == Hash == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-rec-max']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-auto-ex']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-ext']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-ext-size']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-seek']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-cache']); + } else if ($_POST['storagedriver'] == "oracle") { + /* ============================================================================================= */ + /* == MySQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-compress']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-squote']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-uid']); + /* ============================================================================================= */ + /* == SQLite == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['sqlite-pragma']); + /* ============================================================================================= */ + /* == PostgreSQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-uid']); + /* ============================================================================================= */ + /* == Hash == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-rec-max']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-auto-ex']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-ext']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-ext-size']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-max-seek']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['hash-co-cache']); + } else if ($_POST['storagedriver'] == "hash") { + /* ============================================================================================= */ + /* == MySQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-compress']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-squote']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['mysql-uid']); + /* ============================================================================================= */ + /* == SQLite == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['sqlite-pragma']); + /* ============================================================================================= */ + /* == PostgreSQL == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-port']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-database']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-ccache']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['pgsql-uid']); + /* ============================================================================================= */ + /* == Oracle == */ + /* ============================================================================================= */ + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-server']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-user']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-password']); + unset($config['installedpackages']['dspam']['config'][0]['dbsettings'][0]['ora-schema']); + } + ]]> + </stepsubmitphpaction> + <javascriptafterformdisplay> + <![CDATA[ + function toggleDBSettings(idx) { + if (idx) + idx = idx; + else + idx = document.iform.storagedriver.selectedIndex; + + switch (idx) { + case 0: /* mysql */ + /* mysql specifics */ + trNode = document.iform.msqlserver.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqlport.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqluser.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqlpwd.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqldb.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqlcomp.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqlsuqt.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqlccache.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.msqluid.parentNode.parentNode; + trNode.style.display = "table-row"; + /* sqlite specifics */ + trNode = document.iform.slitepr.parentNode.parentNode; + trNode.style.display = "none"; + /* pgsql specifics */ + trNode = document.iform.pgserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgdb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguid.parentNode.parentNode; + trNode.style.display = "none"; + /* oracle specifics */ + trNode = document.iform.oraserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orauser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orapwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orasch.parentNode.parentNode; + trNode.style.display = "none"; + /* hash specifics */ + trNode = document.iform.hsrmax.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsatex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsexsz.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxse.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsccus.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hscoca.parentNode.parentNode; + trNode.style.display = "none"; + break; + case 1: /* sqlite */ + /* mysql specifics */ + trNode = document.iform.msqlserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqldb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlcomp.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlsuqt.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluid.parentNode.parentNode; + trNode.style.display = "none"; + /* sqlite specifics */ + trNode = document.iform.slitepr.parentNode.parentNode; + trNode.style.display = "table-row"; + /* pgsql specifics */ + trNode = document.iform.pgserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgdb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguid.parentNode.parentNode; + trNode.style.display = "none"; + /* oracle specifics */ + trNode = document.iform.oraserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orauser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orapwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orasch.parentNode.parentNode; + trNode.style.display = "none"; + /* hash specifics */ + trNode = document.iform.hsrmax.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsatex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsexsz.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxse.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsccus.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hscoca.parentNode.parentNode; + trNode.style.display = "none"; + break; + case 2: /* bdb */ + /* mysql specifics */ + trNode = document.iform.msqlserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqldb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlcomp.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlsuqt.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluid.parentNode.parentNode; + trNode.style.display = "none"; + /* sqlite specifics */ + trNode = document.iform.slitepr.parentNode.parentNode; + trNode.style.display = "none"; + /* pgsql specifics */ + trNode = document.iform.pgserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgdb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguid.parentNode.parentNode; + trNode.style.display = "none"; + /* oracle specifics */ + trNode = document.iform.oraserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orauser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orapwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orasch.parentNode.parentNode; + trNode.style.display = "none"; + /* hash specifics */ + trNode = document.iform.hsrmax.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsatex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsexsz.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxse.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsccus.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hscoca.parentNode.parentNode; + trNode.style.display = "none"; + break; + case 3: /* pgsql */ + /* mysql specifics */ + trNode = document.iform.msqlserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqldb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlcomp.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlsuqt.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluid.parentNode.parentNode; + trNode.style.display = "none"; + /* sqlite specifics */ + trNode = document.iform.slitepr.parentNode.parentNode; + trNode.style.display = "none"; + /* pgsql specifics */ + trNode = document.iform.pgserver.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.pgport.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.pguser.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.pgpwd.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.pgdb.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.pgccache.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.pguid.parentNode.parentNode; + trNode.style.display = "table-row"; + /* oracle specifics */ + trNode = document.iform.oraserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orauser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orapwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orasch.parentNode.parentNode; + trNode.style.display = "none"; + /* hash specifics */ + trNode = document.iform.hsrmax.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsatex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsexsz.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxse.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsccus.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hscoca.parentNode.parentNode; + trNode.style.display = "none"; + break; + case 4: /* oracle */ + /* mysql specifics */ + trNode = document.iform.msqlserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqldb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlcomp.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlsuqt.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluid.parentNode.parentNode; + trNode.style.display = "none"; + /* sqlite specifics */ + trNode = document.iform.slitepr.parentNode.parentNode; + trNode.style.display = "none"; + /* pgsql specifics */ + trNode = document.iform.pgserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgdb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguid.parentNode.parentNode; + trNode.style.display = "none"; + /* oracle specifics */ + trNode = document.iform.oraserver.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.orauser.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.orapwd.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.orasch.parentNode.parentNode; + trNode.style.display = "table-row"; + /* hash specifics */ + trNode = document.iform.hsrmax.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsatex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxex.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsexsz.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsmxse.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hsccus.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.hscoca.parentNode.parentNode; + trNode.style.display = "none"; + break; + case 5: /* hash */ + /* mysql specifics */ + trNode = document.iform.msqlserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqldb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlcomp.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlsuqt.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqlccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.msqluid.parentNode.parentNode; + trNode.style.display = "none"; + /* sqlite specifics */ + trNode = document.iform.slitepr.parentNode.parentNode; + trNode.style.display = "none"; + /* pgsql specifics */ + trNode = document.iform.pgserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgport.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgpwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgdb.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pgccache.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.pguid.parentNode.parentNode; + trNode.style.display = "none"; + /* oracle specifics */ + trNode = document.iform.oraserver.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orauser.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orapwd.parentNode.parentNode; + trNode.style.display = "none"; + trNode = document.iform.orasch.parentNode.parentNode; + trNode.style.display = "none"; + /* hash specifics */ + trNode = document.iform.hsrmax.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.hsatex.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.hsmxex.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.hsexsz.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.hsmxse.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.hsccus.parentNode.parentNode; + trNode.style.display = "table-row"; + trNode = document.iform.hscoca.parentNode.parentNode; + trNode.style.display = "table-row"; + break; + } + } + + toggleDBSettings(0); + ]]> + </javascriptafterformdisplay> +</step> +<step> + <id>4</id> + <includefile>dspam.inc</includefile> + <title>Delivery Settings</title> + <description> + 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. + </description> + <fields> + <field> + <name>dagent</name> + <description>Specifies the local delivery agent DSPAM should call when delivering mail as a trusted user.</description> + <type>select</type> + <options> + <option> + <name>procmail</name> + <value>procmail</value> + </option> + <option> + <name>mail</name> + <value>mail</value> + </option> + <option> + <name>mail.local</name> + <value>mail.local</value> + </option> + <option> + <name>deliver</name> + <value>deliver</value> + </option> + <option> + <name>maildrop</name> + <value>maildrop</value> + </option> + <option> + <name>exim</name> + <value>exim</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->tdelivery-agent</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>dspamc</name> + <description>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).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->thin-client</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>tcpipdel</name> + <description>Use TCP/IP based delivery. This option needs to be ticked if you are going to deliver via LMTP or SMTP.</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->tcpip-delivery</bindstofield> + <enablefields>dhost,dport,dident,delproto</enablefields> + </field> + <field> + <name>dhost</name> + <type>input</type> + <donotdisable>false</donotdisable> + <bindstofield>installedpackages->dspam->config->0->tcpip-delivery-host</bindstofield> + <description>Alternatively, you may wish to use SMTP or LMTP delivery to deliver your message to the mail server.</description> + <validate>^[a-z0-9.|-]+$</validate> + <message>Host name field is invalid</message> + </field> + <field> + <name>dport</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->tcpip-delivery-port</bindstofield> + <description>Port number of a particular host.</description> + <validate>^[0-9]+$</validate> + <message>Port field is invalid</message> + </field> + <field> + <name>dident</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->tcpip-delivery-ident</bindstofield> + <description>A particular identification string.</description> + </field> + <field> + <name>delproto</name> + <description>A particular protocol typ. Either SMTP or LMTP.</description> + <type>select</type> + <options> + <option> + <name>ltmp</name> + <value>lmtp</value> + </option> + <option> + <name>smtp</name> + <value>smtp</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->tcpip-delivery-proto</bindstofield> + </field> + <field> + <name>onfail</name> + <description>What to do if local delivery or quarantine should fail.</description> + <type>select</type> + <options> + <option> + <name>error</name> + <value>error</value> + </option> + <option> + <name>unlearn</name> + <value>unlearn</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->delivery-onfail</bindstofield> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> + <stepsubmitphpaction> + <![CDATA[ + if($_POST['dspamc'] != "") { + /* DSPAM server settings */ + $config['installedpackages']['dspam']['config'][0]['dspam-server-port'] = "24"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-queue-size'] = "32"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-pid'] = "/var/run/dspam/dspam.pid"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-mode'] = "auto"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-params'] = "--deliver=innocent -d %u"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-id'] = "abysseleven.abyssworld.de"; + $config['installedpackages']['dspam']['config'][0]['dspam-server-socket'] = "/var/run/dspam/dspam.sock"; + + /* server passwords */ + $config['installedpackages']['dspam']['config'][0]['server-pwd'][0]['value'] = "secret"; + $config['installedpackages']['dspam']['config'][0]['server-pwd'][0]['descr'] = "desc"; + $config['installedpackages']['dspam']['config'][0]['server-pwd'][1]['value'] = "password"; + $config['installedpackages']['dspam']['config'][0]['server-pwd'][1]['descr'] = "desc"; + + /* DSPAM client settings */ + $config['installedpackages']['dspam']['config'][0]['dspam-client-enable'] = "on"; + $config['installedpackages']['dspam']['config'][0]['dspam-client-host'] = "/tmp/dspam.sock"; + $config['installedpackages']['dspam']['config'][0]['dspam-client-port'] = "24"; + $config['installedpackages']['dspam']['config'][0]['dspam-client-id'] = "secret@Relay1"; + write_config(); + } + ]]> + </stepsubmitphpaction> +</step> +<step> + <id>5</id> + <includefile>dspam.inc</includefile> + <title> DSPAM Debugging Options</title> + <description> + 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. + </description> + <fields> + <field> + <donotdisable>true</donotdisable> + <name>enabledbg</name> + <description>Enable debugging.</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->debug-enable</bindstofield> + <enablefields>debug,dopt</enablefields> + </field> + <field> + <name>debug</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->debug-whom</bindstofield> + <description>Enables debugging for some or all users.</description> + </field> + <field> + <name>dopt</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->debug-options</bindstofield> + <description>One or more of: process, classify, spam, fp, inoculation, corpus</description> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>6</id> + <includefile>dspam.inc</includefile> + <title>DSPAM Engine Settings</title> + <description> + 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. + </description> + <fields> + <field> + <name>tmode</name> + <description> + 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). + </description> + <type>select</type> + <default_value>teft</default_value> + <options> + <option> + <name>toe</name> + <value>toe</value> + </option> + <option> + <name>tum</name> + <value>tum</value> + </option> + <option> + <name>teft</name> + <value>teft</value> + </option> + <option> + <name>notrain</name> + <value>notrain</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->training-mode</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>testct</name> + <default_value>on</default_value> + <description> + By default, dspam will retrain certain errors until the condition is + no longer met (default: enabled). + </description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->test-cond-training</bindstofield> + </field> + <field> + <name>pvalue</name> + <description> + Specify the technique used for calculating PValues, overriding any + defaults configured in the build (default: graham). + </description> + <type>select</type> + <default_value>teft</default_value> + <options> + <option> + <name>graham</name> + <value>graham</value> + </option> + <option> + <name>robinson</name> + <value>robinso</value> + </option> + <option> + <name>markov</name> + <value>markov</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->pvalue</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>ipdrive</name> + <default_value>on</default_value> + <description> + Calculate odds-ratios for ham/spam, and add to X-DSPAM-Improbability + headers (default: disabled). + </description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->improbability-drive</bindstofield> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>7</id> + <includefile>dspam.inc</includefile> + <title>LDAP Settings</title> + <description> + 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. + </description> + <fields> + <field> + <donotdisable>true</donotdisable> + <name>enableldap</name> + <description>Enable checks against a LDAP directory.</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->ldap-enable</bindstofield> + <enablefields>ldapmode,ldaphost,ldapfilter,ldapbase</enablefields> + </field> + <field> + <name>ldapmode</name> + <description> + Perform various LDAP functions depending on LDAPMode variable. + </description> + <type>select</type> + <default_value>verify</default_value> + <options> + <option> + <name>verify</name> + <value>verify</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->ldap-mode</bindstofield> + </field> + <field> + <name>ldaphost</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->ldap-host</bindstofield> + <description>Hostname of the LDAP directory server.</description> + </field> + <field> + <name>ldapfilter</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->ldap-filter</bindstofield> + <description>A specific query filter, that should be used while querying the LDAP server.</description> + </field> + <field> + <name>ldapbase</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->ldap-base</bindstofield> + <description>A particular distinguish name from where to start LDAP queries.</description> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>8</id> + <includefile>dspam.inc</includefile> + <title>Miscellaneous Settings</title> + <description> + 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. + </description> + <fields> + <field> + <name>foatt</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->failover-attempts</bindstofield> + <description>A particular number of attempts (default: 1).</description> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enablesbl</name> + <description>Enable checks against a particular SBL host (default: disabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->sbl-enable</bindstofield> + <enablefields>sblhost</enablefields> + </field> + <field> + <name>sblhost</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->sbl-host</bindstofield> + <description>A particular SBL hostname (default: none).</description> + <size>30</size> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enablerbl</name> + <description>Enable RBL inoculation support (default: disabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->rbl-inoculate</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enablenoti</name> + <description>Enable the sending of notification emails to users (first message, quarantine full, etc. default: disabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->notification-email</bindstofield> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>9</id> + <includefile>dspam.inc</includefile> + <title>Maintainance Settings</title> + <description> + 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. + </description> + <fields> + <field> + <name>psig</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->purge-signatures</bindstofield> + <description>Purge stale signatures (default: 14).</description> + </field> + <field> + <name>pneut</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->purge-neutral</bindstofield> + <description>Purge tokens with neutralish probabilities (default: 90).</description> + </field> + <field> + <name>punu</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->purge-unused</bindstofield> + <description>Purge unused tokens (default: 90).</description> + </field> + <field> + <name>phapa</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->purge-hapaxes</bindstofield> + <description> Purge tokens with less than 5 hits (hapaxes - default: 30).</description> + </field> + <field> + <name>pones</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->purge-hits-1s</bindstofield> + <description>Purge tokens with only 1 spam hit (default: 15).</description> + </field> + <field> + <name>ponei</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->purge-hits-1i</bindstofield> + <description> Purge tokens with only 1 innocent hit (default: 15).</description> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>10</id> + <includefile>dspam.inc</includefile> + <title>System Settings</title> + <description> + This page contains additional settings related to the DSPAM system such as logging, + message processing behaviour et cetera. + </description> + <fields> + <field> + <name>locmx</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->local-mx</bindstofield> + <description> + 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). + </description> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enablesysl</name> + <description>Enable system logging (default: enabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->system-log</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enableusel</name> + <description>Enable per user logging (default: enabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->user-log</bindstofield> + </field> + <field> + <name>optinout</name> + <description> + Opt: in or out; determines DSPAM's default filtering behavior (default: out). + </description> + <type>select</type> + <default_value>out</default_value> + <options> + <option> + <name>out</name> + <value>out</value> + </option> + <option> + <name>in</name> + <value>in</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->filter-opt</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enableptoh</name> + <description>Parse the To: headers of an incoming message. (default: disabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->parse-to-headers</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enablecmop</name> + <description>Automatically change the class (to spam or innocent - default: disabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->change-mode-on-parse</bindstofield> + </field> + <field> + <donotdisable>true</donotdisable> + <name>enablecuop</name> + <description>Automatically change the username to match that specified in the To: header (default: enabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->change-user-on-parse</bindstofield> + </field> + <field> + <name>maxmsgs</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->max-message-size</bindstofield> + <description> + You may specify a maximum message size in bytes for DSPAM to process. (default: 307200). + </description> + </field> + <field> + <donotdisable>true</donotdisable> + <name>procbias</name> + <description> + 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). + </description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->processor-bias</bindstofield> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>11</id> + <includefile>dspam.inc</includefile> + <title>ClamAV Engine Settings</title> + <description> + 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. + </description> + <fields> + <field> + <donotdisable>true</donotdisable> + <name>enableclam</name> + <description>Enable ClamAV Engine (default: disabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->clamav-enable</bindstofield> + <enablefields>clamport,clamhost,clamresp</enablefields> + </field> + <field> + <name>clamport</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->clamav-port</bindstofield> + <description>A number that specifies the port the ClamAV daemon is listening to (default: none).</description> + </field> + <field> + <name>clamhost</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->clamav-host</bindstofield> + <description>An IP address that points to the host the ClamAV daemon is running on (default: none).</description> + </field> + <field> + <name>clamresp</name> + <description>The action that should take place, if ClamAV reports a positive (default: none).</description> + <type>select</type> + <default_value>accept</default_value> + <options> + <option> + <name>reject</name> + <value>reject</value> + </option> + <option> + <name>accept</name> + <value>accept</value> + </option> + <option> + <name>spam</name> + <value>spam</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->clamav-response</bindstofield> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>12</id> + <includefile>dspam.inc</includefile> + <title>DSPAM Daemon Settings (Server)</title> + <description> + 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. + </description> + <fields> + <field> + <name>dsport</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-server-port</bindstofield> + <description>A number that specifies the port the DSPAM daemon is listening to (default: none).</description> + </field> + <field> + <name>dsqsize</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-server-queue-size</bindstofield> + <description>A number that specifies the server's queue size (default: none).</description> + </field> + <field> + <name>dspid</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-server-pid</bindstofield> + <description> Keep this is sync with <code>/usr/local/etc/rc.d/dspam.rc</code> script (default: none).</description> + <size>40</size> + </field> + <field> + <name>dssmode</name> + <description>Specifies the type of LMTP server to start. (default: none).</description> + <type>select</type> + <default_value>auto</default_value> + <options> + <option> + <name>dspam</name> + <value>dspam</value> + </option> + <option> + <name>standard</name> + <value>standard</value> + </option> + <option> + <name>auto</name> + <value>auto</value> + </option> + </options> + <bindstofield>installedpackages->dspam->config->0->dspam-server-mode</bindstofield> + </field> + <field> + <name>serverparam</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-server-params</bindstofield> + <description>Parameters which will be passed to the LMTP server (default: none).</description> + </field> + <field> + <name>serverid</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-server-id</bindstofield> + <description>An identification string which will be used to be passed to the LMTP server (default: none).</description> + </field> + <field> + <name>serversock</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-server-socket</bindstofield> + <description>A local Unix domain socket (default: none).</description> + <size>40</size> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>13</id> + <includefile>dspam.inc</includefile> + <title>DSPAM Daemon Settings (Client)</title> + <description> + 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. + </description> + <fields> + <field> + <donotdisable>true</donotdisable> + <name>enabledsclient</name> + <description>Run DSPAM in client mode (default: disabled).</description> + <type>checkbox</type> + <bindstofield>installedpackages->dspam->config->0->dspam-client-enable</bindstofield> + <enablefields>dsclhost,dsclport,dsclident</enablefields> + </field> + <field> + <name>dsclhost</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-client-host</bindstofield> + <description>An IP address or a Unix domain socket (default: none).</description> + </field> + <field> + <name>dsclport</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-client-port</bindstofield> + <description>Will be only used if this client uses TCP/IP communication (default: none).</description> + </field> + <field> + <name>dsclident</name> + <type>input</type> + <bindstofield>installedpackages->dspam->config->0->dspam-client-id</bindstofield> + <description>A string that will be used to identify the client against a server. (default: none).</description> + <size>40</size> + </field> + <field> + <name>Next</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>14</id> + <includefile>dspam.inc</includefile> + <title>Reload configuration</title> + <disableheader>true</disableheader> + <description>Click 'Reload' to reload the DSPAM daemon with new changes.</description> + <fields> + <field> + <name>Reload</name> + <type>submit</type> + </field> + </fields> +</step> +<step> + <id>15</id> + <includefile>dspam.inc</includefile> + <title>Reload in progress</title> + <description> + 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. + </description> + <javascriptafterformdisplay> + <![CDATA[ + Effect.Pulsate('wzd_step_title', { duration: 10}); + window.setTimeout('window.location.href = "/dspam-settings.php"', 120000); + ]]> + </javascriptafterformdisplay> + <stepafterformdisplay> + <![CDATA[ + dspam_configure(); + mwexec("/usr/local/etc/rc.d/spamd.sh stop"); + mwexec("/usr/local/etc/rc.d/spamd.sh start"); + ]]> + </stepafterformdisplay> +</step> +</pfsensewizard> |