/trunk/.htaccess |
---|
0,0 → 1,2 |
RewriteEngine off |
/trunk/LICENSE |
---|
0,0 → 1,202 |
Apache License |
Version 2.0, January 2004 |
http://www.apache.org/licenses/ |
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
1. Definitions. |
"License" shall mean the terms and conditions for use, reproduction, |
and distribution as defined by Sections 1 through 9 of this document. |
"Licensor" shall mean the copyright owner or entity authorized by |
the copyright owner that is granting the License. |
"Legal Entity" shall mean the union of the acting entity and all |
other entities that control, are controlled by, or are under common |
control with that entity. For the purposes of this definition, |
"control" means (i) the power, direct or indirect, to cause the |
direction or management of such entity, whether by contract or |
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
outstanding shares, or (iii) beneficial ownership of such entity. |
"You" (or "Your") shall mean an individual or Legal Entity |
exercising permissions granted by this License. |
"Source" form shall mean the preferred form for making modifications, |
including but not limited to software source code, documentation |
source, and configuration files. |
"Object" form shall mean any form resulting from mechanical |
transformation or translation of a Source form, including but |
not limited to compiled object code, generated documentation, |
and conversions to other media types. |
"Work" shall mean the work of authorship, whether in Source or |
Object form, made available under the License, as indicated by a |
copyright notice that is included in or attached to the work |
(an example is provided in the Appendix below). |
"Derivative Works" shall mean any work, whether in Source or Object |
form, that is based on (or derived from) the Work and for which the |
editorial revisions, annotations, elaborations, or other modifications |
represent, as a whole, an original work of authorship. For the purposes |
of this License, Derivative Works shall not include works that remain |
separable from, or merely link (or bind by name) to the interfaces of, |
the Work and Derivative Works thereof. |
"Contribution" shall mean any work of authorship, including |
the original version of the Work and any modifications or additions |
to that Work or Derivative Works thereof, that is intentionally |
submitted to Licensor for inclusion in the Work by the copyright owner |
or by an individual or Legal Entity authorized to submit on behalf of |
the copyright owner. For the purposes of this definition, "submitted" |
means any form of electronic, verbal, or written communication sent |
to the Licensor or its representatives, including but not limited to |
communication on electronic mailing lists, source code control systems, |
and issue tracking systems that are managed by, or on behalf of, the |
Licensor for the purpose of discussing and improving the Work, but |
excluding communication that is conspicuously marked or otherwise |
designated in writing by the copyright owner as "Not a Contribution." |
"Contributor" shall mean Licensor and any individual or Legal Entity |
on behalf of whom a Contribution has been received by Licensor and |
subsequently incorporated within the Work. |
2. Grant of Copyright License. Subject to the terms and conditions of |
this License, each Contributor hereby grants to You a perpetual, |
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
copyright license to reproduce, prepare Derivative Works of, |
publicly display, publicly perform, sublicense, and distribute the |
Work and such Derivative Works in Source or Object form. |
3. Grant of Patent License. Subject to the terms and conditions of |
this License, each Contributor hereby grants to You a perpetual, |
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
(except as stated in this section) patent license to make, have made, |
use, offer to sell, sell, import, and otherwise transfer the Work, |
where such license applies only to those patent claims licensable |
by such Contributor that are necessarily infringed by their |
Contribution(s) alone or by combination of their Contribution(s) |
with the Work to which such Contribution(s) was submitted. If You |
institute patent litigation against any entity (including a |
cross-claim or counterclaim in a lawsuit) alleging that the Work |
or a Contribution incorporated within the Work constitutes direct |
or contributory patent infringement, then any patent licenses |
granted to You under this License for that Work shall terminate |
as of the date such litigation is filed. |
4. Redistribution. You may reproduce and distribute copies of the |
Work or Derivative Works thereof in any medium, with or without |
modifications, and in Source or Object form, provided that You |
meet the following conditions: |
(a) You must give any other recipients of the Work or |
Derivative Works a copy of this License; and |
(b) You must cause any modified files to carry prominent notices |
stating that You changed the files; and |
(c) You must retain, in the Source form of any Derivative Works |
that You distribute, all copyright, patent, trademark, and |
attribution notices from the Source form of the Work, |
excluding those notices that do not pertain to any part of |
the Derivative Works; and |
(d) If the Work includes a "NOTICE" text file as part of its |
distribution, then any Derivative Works that You distribute must |
include a readable copy of the attribution notices contained |
within such NOTICE file, excluding those notices that do not |
pertain to any part of the Derivative Works, in at least one |
of the following places: within a NOTICE text file distributed |
as part of the Derivative Works; within the Source form or |
documentation, if provided along with the Derivative Works; or, |
within a display generated by the Derivative Works, if and |
wherever such third-party notices normally appear. The contents |
of the NOTICE file are for informational purposes only and |
do not modify the License. You may add Your own attribution |
notices within Derivative Works that You distribute, alongside |
or as an addendum to the NOTICE text from the Work, provided |
that such additional attribution notices cannot be construed |
as modifying the License. |
You may add Your own copyright statement to Your modifications and |
may provide additional or different license terms and conditions |
for use, reproduction, or distribution of Your modifications, or |
for any such Derivative Works as a whole, provided Your use, |
reproduction, and distribution of the Work otherwise complies with |
the conditions stated in this License. |
5. Submission of Contributions. Unless You explicitly state otherwise, |
any Contribution intentionally submitted for inclusion in the Work |
by You to the Licensor shall be under the terms and conditions of |
this License, without any additional terms or conditions. |
Notwithstanding the above, nothing herein shall supersede or modify |
the terms of any separate license agreement you may have executed |
with Licensor regarding such Contributions. |
6. Trademarks. This License does not grant permission to use the trade |
names, trademarks, service marks, or product names of the Licensor, |
except as required for reasonable and customary use in describing the |
origin of the Work and reproducing the content of the NOTICE file. |
7. Disclaimer of Warranty. Unless required by applicable law or |
agreed to in writing, Licensor provides the Work (and each |
Contributor provides its Contributions) on an "AS IS" BASIS, |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
implied, including, without limitation, any warranties or conditions |
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
PARTICULAR PURPOSE. You are solely responsible for determining the |
appropriateness of using or redistributing the Work and assume any |
risks associated with Your exercise of permissions under this License. |
8. Limitation of Liability. In no event and under no legal theory, |
whether in tort (including negligence), contract, or otherwise, |
unless required by applicable law (such as deliberate and grossly |
negligent acts) or agreed to in writing, shall any Contributor be |
liable to You for damages, including any direct, indirect, special, |
incidental, or consequential damages of any character arising as a |
result of this License or out of the use or inability to use the |
Work (including but not limited to damages for loss of goodwill, |
work stoppage, computer failure or malfunction, or any and all |
other commercial damages or losses), even if such Contributor |
has been advised of the possibility of such damages. |
9. Accepting Warranty or Additional Liability. While redistributing |
the Work or Derivative Works thereof, You may choose to offer, |
and charge a fee for, acceptance of support, warranty, indemnity, |
or other liability obligations and/or rights consistent with this |
License. However, in accepting such obligations, You may act only |
on Your own behalf and on Your sole responsibility, not on behalf |
of any other Contributor, and only if You agree to indemnify, |
defend, and hold each Contributor harmless for any liability |
incurred by, or claims asserted against, such Contributor by reason |
of your accepting any such warranty or additional liability. |
END OF TERMS AND CONDITIONS |
APPENDIX: How to apply the Apache License to your work. |
To apply the Apache License to your work, attach the following |
boilerplate notice, with the fields enclosed by brackets "[]" |
replaced with your own identifying information. (Don't include |
the brackets!) The text should be enclosed in the appropriate |
comment syntax for the file format. We also recommend that a |
file or class name and description of purpose be included on the |
same "printed page" as the copyright notice for easier |
identification within third-party archives. |
Copyright 2018 Daniel Marschall, ViaThinkSoft |
Licensed under the Apache License, Version 2.0 (the "License"); |
you may not use this file except in compliance with the License. |
You may obtain a copy of the License at |
http://www.apache.org/licenses/LICENSE-2.0 |
Unless required by applicable law or agreed to in writing, software |
distributed under the License is distributed on an "AS IS" BASIS, |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
See the License for the specific language governing permissions and |
limitations under the License. |
/trunk/README.md |
---|
0,0 → 1,23 |
# Visual web counter using PHP and MySQL |
**Project description (German)** |
Features: |
- Keine Registrierung notwendig! Geben Sie einfach einen beliebigen Namen im Feld "id" ein. Wenn dieser frei ist, wird automatisch ein neuer Webcounter für Sie eingerichtet. |
- Reload-Sperre für 60 Minuten (Neu laden bzw. F5-Taste wird den Besucherzähler nicht erhöhen) |
- Unterstützt SSL, sodass es zu keinen Warnungen kommen wird, wenn Sie den Counter auf einer HTTPS-Webseite einbinden |
- Mehrere Designs können parallel verwendet werden (z.B. für verschiedene Unterseiten) |
- Vertraulich und sicher: Keine erzwungenen Rückverlinkungen, keine Cookies, kein JavaScript! |
[Jetzt kostenlosen Besucherzähler nutzen!](https://www.daniel-marschall.de/counter/) |
**Project description (English)** |
Features: |
- No registration needed! Just use any value for "id" that is free. A counter will be automatically created. |
- Reload lock for 60 minutes (Refresh button will not cause the counter to increase). |
- Supports SSL, so there won't be any warnings when you include this counter to your HTTPS website. |
- You can use several themes and modes simultaneously. |
- Private and secure: No forced back-links, no cookies, no JavaScript! |
[Get your web counter now!](https://www.daniel-marschall.de/counter/) |
/trunk/TODO |
---|
0,0 → 1,5 |
Lieber einen Assistent, wo man z.B. die Counter auswählen kann, mit vorschau, und den Hue per Scrollrad etc? |
und wo man sehen kann, ob der counter schon besetzt ist |
kontaktadresse eingeben |
/trunk/config/.htaccess |
---|
0,0 → 1,3 |
deny from all |
/trunk/config/config_dist.inc.php |
---|
0,0 → 1,15 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2017 Daniel Marschall |
* Revision: 2017-05-04 |
*/ |
// EDIT THIS FILE, THEN RENAME IT TO config.inc.php ! |
define('RELOADSPERRE_MINS', 60); |
define('PDO_HOST', 'mysql:host=localhost;dbname=xxx'/*.';charset=utf8'*/); |
define('PDO_USER', 'xxx'); |
define('PDO_PASS', 'xxx'); |
define('OWN_URL', 'https://www.daniel-marschall.de/counter/'); |
/trunk/config |
---|
Property changes: |
Added: svn:ignore |
+config.inc.php |
/trunk/counter.php |
---|
0,0 → 1,97 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2017 Daniel Marschall |
* Revision: 2017-05-14 |
*/ |
error_reporting(E_ALL | E_NOTICE); |
assert_options(ASSERT_ACTIVE, true); |
assert_options(ASSERT_BAIL, true); |
if (!file_exists(__DIR__ . '/config/config.inc.php')) { |
die('Please edit config/config_dist.inc.php and then rename it to config/config.inc.php !'); |
} |
require_once __DIR__ . '/config/config.inc.php'; |
require_once __DIR__ . '/includes/functions.inc.php'; |
require_once __DIR__ . '/includes/VtsCounterTheme.class.php'; |
require_once __DIR__ . '/includes/VtsCounter.class.php'; |
require_once __DIR__ . '/includes/VtsCounterInfo.class.php'; |
if ((!isset($_REQUEST['id'])) || ($_REQUEST['id'] == '')) { |
die('Argument "id" is missing'); |
} |
if ($_REQUEST['id'] == 'demo') { |
$visitors = isset($_REQUEST['demo']) ? $_REQUEST['demo'] : 123456; |
$created = '2017-05-04 00:00:00'; |
} else { |
$pdo = new PDO(PDO_HOST, PDO_USER, PDO_PASS); |
$c = new VtsCounter($pdo); |
$c->clearReloadSperre(RELOADSPERRE_MINS); |
$counter_id = $c->getIDfromIDStr($_REQUEST['id']); |
$c->visitCount($counter_id, fetchip()); |
$info = $c->getCounterInfo($counter_id); |
$visitors = $info->visitors; |
$created = $info->created; |
} |
$querytime = gmdate('Y-m-d\TH:i:s\Z'); // ISO 8601 |
$created = date('Y-m-d\TH:i:s\Z', strtotime($created)); |
/* |
// No caching |
header("HTTP/1.1 200 OK"); |
header("Expires: Thu, 24 Dec 1987 08:30:00 GMT"); |
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); |
header("Cache-Control: no-store, no-cache, must-revalidate"); |
header("Cache-Control: post-check=0, pre-check=0", false); |
header("Pragma: no-cache"); |
*/ |
$etag = md5($visitors . $_SERVER['QUERY_STRING']); |
header("ETag: $etag"); |
if (anyTagMatched($etag)) { |
header("HTTP/1.1 304 Not Modified"); |
die(); |
} else { |
header("HTTP/1.1 200 OK"); |
} |
$format = isset($_REQUEST['format']) ? $_REQUEST['format'] : 'graphic'; |
if ($format == 'graphic') { |
$theme = isset($_REQUEST['theme']) ? preg_replace('/[^a-z0-9_\-]/', '', $_REQUEST['theme']) : null; |
if (is_null($theme)) die('Parameter "theme" is missing'); |
$themeFile = __DIR__ . "/themes/$theme/theme.inc.php"; |
if (!file_exists($themeFile)) die("Theme '$theme' does not exist."); |
$themeObj = null; |
include $themeFile; |
assert(!is_null($themeObj)); |
$hue = isset($_REQUEST['hue']) ? $_REQUEST['hue'] : 0; |
$themeObj->outputCounterImage($visitors, 'png', $hue); |
} else if ($format == 'silent') { |
// nothing |
} else if ($format == 'spacer') { |
header('Content-Type: image/png'); |
readfile(__DIR__ . '/spacer.png'); |
} else if ($format == 'plaintext') { |
header('Content-Type: text/plain'); |
echo $visitors; |
} else if ($format == 'json') { |
header('Content-Type: application/json'); |
$out = array(); |
$out['created'] = $created; |
$out['querytime'] = $querytime; |
$out['visitors'] = $visitors; |
echo json_encode($out); |
} else { |
die('Argument "format" must be either graphic, silent, spacer, plaintext or json'); |
} |
/trunk/includes/.htaccess |
---|
0,0 → 1,3 |
deny from all |
/trunk/includes/VtsCounter.class.php |
---|
0,0 → 1,75 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2019 Daniel Marschall |
* Revision: 2019-02-18 |
*/ |
class VtsCounter { |
private $pdo = null; |
function __construct($pdo) { |
$this->pdo = $pdo; |
} |
public function clearReloadSperre($minutes) { |
if ($minutes < 1) return; |
$statement = $this->pdo->prepare("DELETE FROM counter_reloadsperre WHERE tsLastVisit < (UTC_TIMESTAMP() - INTERVAL $minutes MINUTE)"); |
pdox_execute($statement); |
# Alte Counter / Fake Counter / SQL Injection Tests löschen |
$statement = $this->pdo->prepare("DELETE FROM counter_visitors WHERE tsLastVisit < (UTC_TIMESTAMP() - INTERVAL 1 YEAR)"); |
pdox_execute($statement); |
} |
public function getIDfromIDStr($idstr) { |
$statement = $this->pdo->prepare("SELECT id FROM counter_visitors WHERE idstr = ?"); |
pdox_execute($statement, array($idstr)); |
$numrows = $statement->rowCount(); |
$id = -1; |
if ($numrows == 0) { |
$statement = $this->pdo->prepare("INSERT INTO counter_visitors (idstr, tsCreated) VALUES (?, UTC_TIMESTAMP())"); |
pdox_execute($statement, array($idstr)); |
$id = $this->pdo->lastInsertId(); |
} else { |
assert($numrows == 1); |
$row = $statement->fetch(); |
$id = $row['id']; |
} |
assert($id > 0); |
return $id; |
} |
public function visitCount($counter_id, $ip) { |
$statement = $this->pdo->prepare("SELECT * FROM counter_reloadsperre WHERE fk_counter = ? AND ip = ?"); |
pdox_execute($statement, array($counter_id, $ip)); |
$numrows = $statement->rowCount(); |
if ($numrows == 0) { |
$statement = $this->pdo->prepare("INSERT INTO counter_reloadsperre (fk_counter, ip, tsLastVisit) VALUES (?, ?, UTC_TIMESTAMP())"); |
pdox_execute($statement, array($counter_id, $ip)); |
$statement = $this->pdo->prepare("UPDATE counter_visitors SET counter = counter + 1, tsLastVisit = UTC_TIMESTAMP() WHERE id = ?"); |
pdox_execute($statement, array($counter_id)); |
} else { |
assert($numrows == 1); |
$row = $statement->fetch(); |
$sperre_id = $row['id']; |
$statement = $this->pdo->prepare("UPDATE counter_reloadsperre SET tsLastVisit = UTC_TIMESTAMP() WHERE id = ?"); |
pdox_execute($statement, array($sperre_id)); |
} |
} |
public function getCounterInfo($counter_id) { |
$statement = $this->pdo->prepare("SELECT counter, tsCreated FROM counter_visitors WHERE id = ?"); |
pdox_execute($statement, array($counter_id)); |
$numrows = $statement->rowCount(); |
assert($numrows == 1); |
$row = $statement->fetch(); |
$out = new VtsCounterInfo(); |
$out->visitors = $row['counter']; |
$out->created = $row['tsCreated']; |
return $out; |
} |
} |
/trunk/includes/VtsCounterInfo.class.php |
---|
0,0 → 1,12 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2017 Daniel Marschall |
* Revision: 2017-05-05 |
*/ |
class VtsCounterInfo { |
public $visitors; |
public $created; |
} |
/trunk/includes/VtsCounterTheme.class.php |
---|
0,0 → 1,39 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2022 Daniel Marschall |
* Revision: 2022-01-09 |
*/ |
abstract class VtsCounterTheme { |
public $stellenMin; |
abstract protected function getImg($visitors, $hue=0); |
function outputCounterImage($visitors, $format='png', $hue=0) { |
$visitors = sprintf("% ".$this->stellenMin."d", $visitors); |
$im = $this->getImg($visitors, $hue); |
$format = strtolower($format); |
if ($format == 'png') { |
header('Content-Type: image/png'); |
imagepng($im); |
} else if (($format == 'jpg') || ($format == 'jpeg')) { |
header('Content-Type: image/jpeg'); |
imagejpeg($im); |
} else if ($format == 'gif') { |
header('Content-Type: image/gif'); |
imagegif($im); |
} else if ($format == 'wbmp') { |
header('Content-Type: image/vnd.wap.wbmp'); |
imagewbmp($im); |
} else { |
assert(false); |
} |
@imagedestroy($im); |
} |
} |
/trunk/includes/functions.inc.php |
---|
0,0 → 1,156 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2022 Daniel Marschall |
* Revision: 2022-01-09 |
*/ |
function pdox_execute($statement, $args=array()) { |
if (!$statement->execute($args)) { |
echo "SQL Error <br />"; |
echo $statement->queryString."<br />"; |
echo $statement->errorInfo()[2]; |
die(); |
} |
} |
function fetchip() { |
return md5($_SERVER['REMOTE_ADDR']); // masked IP wegen DSGVO Kacke |
// Das ist alles Quatsch! Dann kann man die IP ja fälschen |
/* |
// Source: http://lists.phpbar.de/pipermail/php/Week-of-Mon-20040322/007749.html |
$client_ip = (isset($_SERVER['HTTP_CLIENT_IP'])) ? $_SERVER['HTTP_CLIENT_IP'] : ''; |
$x_forwarded_for = (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : ''; |
$remote_addr = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : ''; |
if (!empty($client_ip)) { |
$ip_expl = explode('.', $client_ip); |
$referer = explode('.', $remote_addr); |
if($referer[0] != $ip_expl[0]) { |
$ip = array_reverse($ip_expl); |
$return = implode('.', $ip); |
} else { |
$return = $client_ip; |
} |
} else if (!empty($x_forwarded_for)) { |
if (strstr($x_forwarded_for, ',')) { |
$ip_expl = explode(',', $x_forwarded_for); |
$return = end($ip_expl); |
} |
} else { |
$return = $remote_addr; |
} |
unset ($client_ip, $x_forwarded_for, $remote_addr, $ip_expl); |
return $return; |
*/ |
} |
function rgb2hsl($r, $g, $b) { |
$var_R = ($r / 255); |
$var_G = ($g / 255); |
$var_B = ($b / 255); |
$var_Min = min($var_R, $var_G, $var_B); |
$var_Max = max($var_R, $var_G, $var_B); |
$del_Max = $var_Max - $var_Min; |
$v = $var_Max; |
if ($del_Max == 0) { |
$h = 0; |
$s = 0; |
} else { |
$s = $del_Max / $var_Max; |
$del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; |
$del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; |
$del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; |
if ($var_R == $var_Max) $h = $del_B - $del_G; |
else if ($var_G == $var_Max) $h = ( 1 / 3 ) + $del_R - $del_B; |
else if ($var_B == $var_Max) $h = ( 2 / 3 ) + $del_G - $del_R; |
else $h = 0; // should not happen |
if ($h < 0) $h++; |
if ($h > 1) $h--; |
} |
return array($h, $s, $v); |
} |
function hsl2rgb($h, $s, $v) { |
if($s == 0) { |
$r = $g = $B = $v * 255; |
} else { |
$var_H = $h * 6; |
$var_i = floor( $var_H ); |
$var_1 = $v * ( 1 - $s ); |
$var_2 = $v * ( 1 - $s * ( $var_H - $var_i ) ); |
$var_3 = $v * ( 1 - $s * (1 - ( $var_H - $var_i ) ) ); |
if ($var_i == 0) { $var_R = $v ; $var_G = $var_3 ; $var_B = $var_1 ; } |
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $v ; $var_B = $var_1 ; } |
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $v ; $var_B = $var_3 ; } |
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $v ; } |
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $v ; } |
else { $var_R = $v ; $var_G = $var_1 ; $var_B = $var_2 ; } |
$r = $var_R * 255; |
$g = $var_G * 255; |
$B = $var_B * 255; |
} |
return array($r, $g, $B); |
} |
function imagehue(&$image, $angle) { |
if (!is_numeric($angle)) return; |
if($angle % 360 == 0) return; |
$width = imagesx($image); |
$height = imagesy($image); |
$imout = imagecreate($width, $height); |
for($x = 0; $x < $width; $x++) { |
for($y = 0; $y < $height; $y++) { |
$rgb = imagecolorat($image, $x, $y); |
$r = ($rgb >> 16) & 0xFF; |
$g = ($rgb >> 8) & 0xFF; |
$b = $rgb & 0xFF; |
$alpha = ($rgb & 0x7F000000) >> 24; |
list($h, $s, $l) = rgb2hsl($r, $g, $b); |
$h += $angle / 360; |
if($h > 1) $h--; |
list($r, $g, $b) = hsl2rgb($h, $s, $l); |
imagesetpixel($imout, $x, $y, imagecolorallocatealpha($imout, $r, $g, $b, $alpha)); |
} |
} |
imagedestroy($image); |
$image = $imout; |
} |
/** |
* TRUE if any tag matched |
* FALSE if none matched |
* NULL if header is not specified |
* http://stackoverflow.com/questions/2086712/http-if-none-match-and-if-modified-since-and-304-clarification-in-php |
*/ |
function anyTagMatched($myTag) { |
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? |
stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : |
false ; |
if( false !== $if_none_match ) { |
$tags = explode( ", ", $if_none_match ) ; |
foreach( $tags as $tag ) { |
if( $tag == $myTag ) return true ; |
} |
return false ; |
} |
return null ; |
} |
/trunk/index.php |
---|
0,0 → 1,120 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2017 Daniel Marschall |
* Revision: 2017-05-05 |
*/ |
if (!file_exists(__DIR__ . '/config/config.inc.php')) { |
die('Please edit config/config_dist.inc.php and then rename it to config/config.inc.php !'); |
} |
require_once __DIR__ . '/config/config.inc.php'; |
$pdo = new PDO(PDO_HOST, PDO_USER, PDO_PASS); |
$statement = $pdo->prepare("SELECT COUNT(*) AS cnt, SUM(counter) AS total FROM counter_visitors"); |
$statement->execute(); |
$stats = $statement->fetch(); |
?><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
<html> |
<head> |
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
<meta name="author" content="Daniel Marschall"> |
<meta name="keywords" content="Freeware, webcounter, visitors, counter, homepage, tools, HTML, PHP, Website, Internet"> |
<meta name="description" content="Free webcounter for your homepage!"> |
<title>Web counter by Daniel Marschall</title> |
<style type="text/css"> |
body { |
font-family: Verdana; |
background-color: #D6EAF8; |
} |
.tooltip { |
border-bottom: 1px dotted #000; |
text-decoration: none; |
cursor: help; |
} |
</style> |
</head> |
<body> |
<h1>Web counter by Daniel Marschall</h1> |
<h2>Features</h2> |
<ul> |
<li>No registration needed! Just use any value for "id" that is free. A counter will be automatically created.</li> |
<li>Reload lock for <?php echo RELOADSPERRE_MINS; ?> minutes (Refresh button will not cause the counter to increase). The IP of the visitor is hashed to ensure privacy.</li> |
<li>Supports SSL, so there won't be any warnings when you include this counter to your HTTPS website.</li> |
<li>You can use several themes and modes simultaneously.</li> |
<li>Private and secure: No forced back-links, no cookies, no JavaScript!</li> |
<li>Note: Counters which are not visited for more than 1 year automatically get removed from the database.</li> |
</ul> |
<p>Currently hosted web counters: <b><?php echo $stats['cnt']; ?></b><br> |
Visitors total: <b><?php echo $stats['total']; ?></b></p> |
<h2>Available counters and modes</h2> |
<?php |
$dirs = array_filter(glob('themes/*'), 'is_dir'); |
$themes = array(); |
foreach ($dirs as $d) $themes[] = explode('/', $d, 2)[1]; |
foreach ($themes as $theme) { |
echo '<h3>Theme "'.$theme.'"</h3>'; |
echo 'URL: '.OWN_URL.'counter.php?id=<b><span class="tooltip" title="Choose any ID you like. No registration needed!">demo</span></b>&format=<b>graphic</b>&theme=<b>'.$theme.'</b><br><br>'; |
echo 'HTML example:<br><textarea cols="110" rows="4"><a href="'.OWN_URL.'"><img src="'.OWN_URL.'counter.php?id=demo&amp;format=graphic&amp;theme='.$theme.'" alt="Visitors" title="Visitors"></a></textarea><br>'; |
echo '<br><a href="'.OWN_URL.'"><img src="'.OWN_URL.'counter.php?id=demo&format=graphic&theme='.$theme.'" alt="Visitors" title="Visitors"></a>'; |
} |
echo '<h3>Spacer (1x1 invisible image)</h3>'; |
echo 'URL: '.OWN_URL.'counter.php?id=<b><span class="tooltip" title="Choose any ID you like. No registration needed!">demo</span></b>&format=<b>spacer</b><br><br>'; |
echo 'HTML example:<br><textarea cols="110" rows="2"><img src="'.OWN_URL.'counter.php?id=demo&amp;format=spacer" alt=""></textarea><br>'; |
echo '<h3>Silent (no output)</h3>'; |
echo 'URL: '.OWN_URL.'counter.php?id=<b><span class="tooltip" title="Choose any ID you like. No registration needed!">demo</span></b>&format=<b>silent</b><br>'; |
echo '<a href="'.OWN_URL.'counter.php?id=demo&format=silent">Demo</a>'; |
echo '<h3>Text</h3>'; |
echo 'URL: '.OWN_URL.'counter.php?id=<b><span class="tooltip" title="Choose any ID you like. No registration needed!">demo</span></b>&format=<b>plaintext</b><br>'; |
echo '<a href="'.OWN_URL.'counter.php?id=demo&format=plaintext">Demo</a>'; |
echo '<h3>JSON</h3>'; |
echo 'URL: '.OWN_URL.'counter.php?id=<b><span class="tooltip" title="Choose any ID you like. No registration needed!">demo</span></b>&format=<b>json</b><br>'; |
echo '<a href="'.OWN_URL.'counter.php?id=demo&format=json">Demo</a>'; |
?> |
<h2>Different hues</h2> |
<p>You can change the hue of every counter by adding the argument "&hue=" followed by a number between <b>1</b> and <b>359</b> . Just try out a few numbers until you see the color you desire.</p> |
<p><u>Example:</u></p> |
<?php |
$theme = 'digital'; |
$hue = 145; |
echo 'URL: '.OWN_URL.'counter.php?id=<b><span class="tooltip" title="Choose any ID you like. No registration needed!">demo</span></b>&format=<b>graphic</b>&theme=<b>'.$theme.'</b>&hue=<b>'.$hue.'</b><br><br>'; |
echo 'HTML example:<br><textarea cols="110" rows="4"><a href="'.OWN_URL.'"><img src="'.OWN_URL.'counter.php?id=demo&amp;format=graphic&amp;theme='.$theme.'&amp;hue='.$hue.'" alt="Visitors" title="Visitors"></a></textarea><br>'; |
echo '<br><a href="'.OWN_URL.'"><img src="'.OWN_URL.'counter.php?id=demo&format=graphic&theme='.$theme.'&hue='.$hue.'" alt="Visitors" title="Visitors"></a>'; |
?> |
<hr> |
<p> |
<a href="https://validator.w3.org/check?uri=referer"><img src="https://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a> |
<a href="https://jigsaw.w3.org/css-validator/check/referer"><img style="border:0;width:88px;height:31px" src="https://jigsaw.w3.org/css-validator/images/vcss" alt="CSS ist valide!"></a> |
</p> |
</body> |
</html> |
/trunk/mysql_schema/counter_reloadsperre.sql |
---|
0,0 → 1,71 |
-- phpMyAdmin SQL Dump |
-- version 5.1.1 |
-- https://www.phpmyadmin.net/ |
-- |
-- Host: localhost |
-- Erstellungszeit: 09. Jan 2022 um 01:11 |
-- Server-Version: 10.3.31-MariaDB-0+deb10u1-log |
-- PHP-Version: 7.3.31-1~deb10u1 |
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; |
START TRANSACTION; |
SET time_zone = "+00:00"; |
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; |
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; |
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; |
/*!40101 SET NAMES utf8mb4 */; |
-- |
-- Datenbank: `daniel-marschall` |
-- |
-- -------------------------------------------------------- |
-- |
-- Tabellenstruktur für Tabelle `counter_reloadsperre` |
-- |
CREATE TABLE `counter_reloadsperre` ( |
`id` int(11) NOT NULL, |
`fk_counter` int(11) NOT NULL, |
`ip` varchar(50) NOT NULL, |
`tsLastVisit` timestamp NOT NULL DEFAULT current_timestamp() |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
-- |
-- Indizes der exportierten Tabellen |
-- |
-- |
-- Indizes für die Tabelle `counter_reloadsperre` |
-- |
ALTER TABLE `counter_reloadsperre` |
ADD PRIMARY KEY (`id`), |
ADD KEY `fk_counter` (`fk_counter`); |
-- |
-- AUTO_INCREMENT für exportierte Tabellen |
-- |
-- |
-- AUTO_INCREMENT für Tabelle `counter_reloadsperre` |
-- |
ALTER TABLE `counter_reloadsperre` |
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; |
-- |
-- Constraints der exportierten Tabellen |
-- |
-- |
-- Constraints der Tabelle `counter_reloadsperre` |
-- |
ALTER TABLE `counter_reloadsperre` |
ADD CONSTRAINT `counter_reloadsperre_ibfk_1` FOREIGN KEY (`fk_counter`) REFERENCES `counter_visitors` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; |
COMMIT; |
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; |
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; |
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; |
/trunk/mysql_schema/counter_visitors.sql |
---|
0,0 → 1,62 |
-- phpMyAdmin SQL Dump |
-- version 5.1.1 |
-- https://www.phpmyadmin.net/ |
-- |
-- Host: localhost |
-- Erstellungszeit: 09. Jan 2022 um 01:11 |
-- Server-Version: 10.3.31-MariaDB-0+deb10u1-log |
-- PHP-Version: 7.3.31-1~deb10u1 |
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; |
START TRANSACTION; |
SET time_zone = "+00:00"; |
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; |
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; |
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; |
/*!40101 SET NAMES utf8mb4 */; |
-- |
-- Datenbank: `daniel-marschall` |
-- |
-- -------------------------------------------------------- |
-- |
-- Tabellenstruktur für Tabelle `counter_visitors` |
-- |
CREATE TABLE `counter_visitors` ( |
`id` int(11) NOT NULL, |
`idstr` varchar(255) NOT NULL, |
`counter` int(11) NOT NULL DEFAULT 0, |
`tsCreated` timestamp NULL DEFAULT NULL, |
`tsLastVisit` timestamp NULL DEFAULT NULL |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
-- |
-- Indizes der exportierten Tabellen |
-- |
-- |
-- Indizes für die Tabelle `counter_visitors` |
-- |
ALTER TABLE `counter_visitors` |
ADD PRIMARY KEY (`id`), |
ADD UNIQUE KEY `idstr` (`idstr`); |
-- |
-- AUTO_INCREMENT für exportierte Tabellen |
-- |
-- |
-- AUTO_INCREMENT für Tabelle `counter_visitors` |
-- |
ALTER TABLE `counter_visitors` |
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; |
COMMIT; |
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; |
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; |
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; |
/trunk/phpstan.neon.dist |
---|
0,0 → 1,19 |
parameters: |
level: 5 |
fileExtensions: |
- php |
- phps |
paths: |
- . |
excludePaths: |
analyse: |
- includes/recaptcha |
analyseAndScan: |
- .phpstan.tmp |
tmpDir: .phpstan.tmp |
bootstrapFiles: |
- config/config_dist.inc.php |
ignoreErrors: |
#- '#is always (true|false)\.#' |
- '#Call to function assert\(\) with false will always evaluate to false\.#' |
#- '#with no typehint specified\.#' |
/trunk/spacer.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_0.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_1.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_2.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_3.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_4.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_5.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_6.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_7.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_8.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_9.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/digit_x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/digital/theme.inc.php |
---|
0,0 → 1,39 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2017 Daniel Marschall |
* Revision: 2017-05-05 |
*/ |
class VtsCounterThemeImpl extends VtsCounterTheme { |
protected function getImg($visitors, $hue=0) { |
$im = ImageCreate(strlen($visitors)*15 + 2 - 1, 17 + 4); |
$black = imagecolorallocate($im,0,0,0); |
imagefill($im,0,0,$black); |
$offset_x = 2; |
$offset_y = 2; |
for ($i=0; $i<strlen($visitors); $i++) { |
if ($visitors[$i] == ' ') $visitors[$i] = 'x'; |
$digit_im = ImageCreateFromPNG(__DIR__.'/digit_'.$visitors[$i].'.png'); |
$digit_w = imagesx($digit_im); |
$digit_h = imagesy($digit_im); |
imagehue($digit_im, $hue); |
ImageCopy($im, $digit_im, $offset_x, $offset_y, 0, 0, $digit_w, $digit_h); |
ImageDestroy($digit_im); |
$offset_x += $digit_w + 3; |
} |
return $im; |
} |
} |
$themeObj = new VtsCounterThemeImpl(); |
$themeObj->stellenMin = 8; |
/trunk/themes/gold/digit_0.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_1.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_2.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_3.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_4.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_5.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_6.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_7.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_8.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_9.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/digit_x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/gold/theme.inc.php |
---|
0,0 → 1,58 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2017 Daniel Marschall |
* Revision: 2017-05-05 |
*/ |
class VtsCounterThemeImpl extends VtsCounterTheme { |
protected function getImg($visitors, $hue=0) { |
$offset_x = 0; |
$offset_y = 0; |
$digit_middle_pad = 2; |
$digits = array(); |
$img_size_w = $offset_x; |
$img_size_h = 0; |
for ($i=0; $i<strlen($visitors); $i++) { |
if ($visitors[$i] == ' ') $visitors[$i] = 'x'; // don't support "blank" digits |
$digit_im = ImageCreateFromPNG(__DIR__.'/digit_'.$visitors[$i].'.png'); |
$digit_w = imagesx($digit_im); |
$digit_h = imagesy($digit_im); |
$digits[] = array($digit_im, $digit_w, $digit_h); |
$img_size_w += $digit_w + ($i == 0 ? 0 : $digit_middle_pad); |
$img_size_h = max($img_size_h, $digit_h+$offset_y); |
} |
$im = ImageCreate($img_size_w, $img_size_h); |
imagesavealpha($im, true); |
$pos_x = $offset_x; |
for ($i=0; $i<strlen($visitors); $i++) { |
$digit_im = $digits[$i][0]; |
$digit_w = $digits[$i][1]; |
$digit_h = $digits[$i][2]; |
imagehue($digit_im, $hue); |
$pos_y = $offset_y + ($img_size_h - $digit_h); // auf Boden platzieren |
ImageCopy($im, $digit_im, $pos_x, $pos_y, 0, 0, $digit_w, $digit_h); |
$pos_x += $digit_w + $digit_middle_pad; |
ImageDestroy($digit_im); |
} |
return $im; |
} |
} |
$themeObj = new VtsCounterThemeImpl(); |
$themeObj->stellenMin = 1; |
/trunk/themes/sword/bg.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_0.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_1.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_2.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_3.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_4.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_5.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_6.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_7.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_8.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_9.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/digit_x.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/themes/sword/theme.inc.php |
---|
0,0 → 1,38 |
<?php |
/* |
* PHP Counter mit Reloadsperre, Textdatenbank und Graphic-Libary (without Error Images) |
* (C)Copyright 2010 - 2017 Daniel Marschall |
* Revision: 2017-05-05 |
*/ |
class VtsCounterThemeImpl extends VtsCounterTheme { |
protected function getImg($visitors, $hue=0) { |
$im = ImageCreateFromPNG(__DIR__.'/bg.png'); |
imagesavealpha($im, true); |
$offset_x = 60; |
$offset_y = 16; |
for ($i=0; $i<strlen($visitors); $i++) { |
if ($visitors[$i] == ' ') $visitors[$i] = 'x'; // don't support "blank" digits |
$digit_im = ImageCreateFromPNG(__DIR__.'/digit_'.$visitors[$i].'.png'); |
$digit_w = imagesx($digit_im); |
$digit_h = imagesy($digit_im); |
imagehue($digit_im, $hue); |
ImageCopy($im, $digit_im, $offset_x, $offset_y, 0, 0, $digit_w, $digit_h); |
ImageDestroy($digit_im); |
$offset_x += $digit_w + 4; |
} |
return $im; |
} |
} |
$themeObj = new VtsCounterThemeImpl(); |
$themeObj->stellenMin = 6; |
/trunk/. |
---|
Property changes: |
Added: svn:ignore |
+.phpstan.tmp |
+ |