Simple Download Monitor - Version 0.19

Version Description

  • Filenames are now returned quoted, which allows proper download of files with a space in their filenames. Thanks Sameh Farouk for the tip.

  • Possibility to limit the number of downloads per IP address and day. When the number is exceeded, the user gets an error message.

This functionality requires detailed logs to be turned on. Ignored users can always download as many files as they want.

  • Support for a sidebar widget showing top-10 (or top-anything) most downloaded files (either all files or those matching a given mask).

  • The user who has rights to delete statistics can now mark some downloads as hidden. This setting only affects the sidebar widget and is mostly intended to remove obsolete versions of files from the list while keeping the download statistics themselves.

Download this release

Release Info

Developer pepak.net
Plugin Icon 128x128 Simple Download Monitor
Version 0.19
Comparing to
See all releases

Code changes from version 0.18 to 0.19

Files changed (5) hide show
  1. css/sdmon.css +2 -0
  2. lang/cs_CZ.mo +0 -0
  3. lang/cs_CZ.po +146 -62
  4. readme.txt +21 -2
  5. simple-download-monitor.php +201 -21
css/sdmon.css CHANGED
@@ -3,6 +3,8 @@
3
  #sdmon .sdmon-count { text-align: right; }
4
  #sdmon .sdmon-date { width: 24ex; text-align: center; }
5
  #sdmon .sdmon-nonex { width: 5ex; text-align: center; }
 
 
6
  #sdmon .sdmon-ipaddr { }
7
  #sdmon .sdmon-referer { }
8
  #sdmon .sdmon-username { }
3
  #sdmon .sdmon-count { text-align: right; }
4
  #sdmon .sdmon-date { width: 24ex; text-align: center; }
5
  #sdmon .sdmon-nonex { width: 5ex; text-align: center; }
6
+ #sdmon .sdmon-hidden { width: 15ex; }
7
+ #sdmon .sdmon-delete { width: 15ex; }
8
  #sdmon .sdmon-ipaddr { }
9
  #sdmon .sdmon-referer { }
10
  #sdmon .sdmon-username { }
lang/cs_CZ.mo CHANGED
Binary file
lang/cs_CZ.po CHANGED
@@ -1,10 +1,10 @@
1
  msgid ""
2
  msgstr ""
3
- "Project-Id-Version: Simple Download Monitor v0.04\n"
4
  "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2010-11-06 12:13+0100\n"
6
  "PO-Revision-Date: \n"
7
- "Last-Translator: Pepak <pepak@pepak.net>\n"
8
  "Language-Team: Pepak <pepak@pepak.net>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
@@ -16,225 +16,309 @@ msgstr ""
16
  "X-Poedit-Basepath: .\n"
17
  "X-Poedit-SearchPath-0: ..\n"
18
 
19
- #: ../simple-download-monitor.php:418
20
- #: ../simple-download-monitor.php:852
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  msgid "Simple Download Monitor options"
22
  msgstr "Simple Download Monitor - nastavení"
23
 
24
- #: ../simple-download-monitor.php:419
25
  msgid "Access rights"
26
  msgstr "Přístupová práva"
27
 
28
- #: ../simple-download-monitor.php:420
29
  msgid "You can set up user rights required to access various functions of Simple Download Monitor. Rights are assigned through capabilities (see <a href=\"http://codex.wordpress.org/Roles_and_Capabilities#Roles\">Roles and Capabilities</a> in WordPress Codex). Predefined values are <strong>read</strong> (\"any registered user\") for displaying stats, <strong>delete_users</strong> (\"administrator\") for reseting stats and <strong>manage_options</strong> (\"administrator\") for changing options."
30
  msgstr "Zde můžete nastavit uživatelská práva potřebná pro přístup k jednotlivým funkcím Simple Download Monitoru. Práva jsou definována prostřednictvím schopností (capabilities, viz <a href=\"http://codex.wordpress.org/Roles_and_Capabilities#Roles\">Roles and Capabilities</a> ve WordPress Codex). Výchozí hodnoty jsou <strong>read</strong> (\"každý registrovaný uživatel) pro zobrazení statistik, <strong>delete_users</strong> (\"administrátor\") pro mazání statistik a <strong>manage_options</strong> (\"administrátor\") pro změnu nastavení."
31
 
32
- #: ../simple-download-monitor.php:421
33
  msgid "Capability required for viewing download stats:"
34
  msgstr "Schopnost (capability) pro zobrazení statistik:"
35
 
36
- #: ../simple-download-monitor.php:423
37
  msgid "Capability required for reseting download stats:"
38
  msgstr "Schopnost (capability) pro smazání statistik:"
39
 
40
- #: ../simple-download-monitor.php:425
41
  msgid "Capability required for setting SDMON options:"
42
  msgstr "Schopnost (capability) pro nastavení:"
43
 
44
- #: ../simple-download-monitor.php:427
45
  msgid "Allowed directories"
46
  msgstr "Povolené adresáře"
47
 
48
- #: ../simple-download-monitor.php:428
49
  msgid "Only requested files whose full names (relative to document root) start with this regular expression will be processed. It is strongly recommended to place all downloadable files (and ONLY downloadable files) into a designated directory and then placing that directory's name followed by a slash here. It is possible to use the power of PREG to allow multiple directories, but make sure there are ONLY files which you are comfortable with malicious users downloading. Do not EVER allow directories which contain PHP files here! That could lead to disclosure of sensitive data, including username and password used to connect to WordPress database."
50
  msgstr "Zpracovávány budou pouze soubory, jejichž plná jména (relativní vůči kořenovému adresáři webu) začínají tímto regulárním výrazem. Silně doporučuji umístit všechny stažitelné soubory (a JENOM stažitelné soubory) do jednoho určeného adresáře a vepsat sem název tohoto adresáře zakončený lomítkem. Lze také využít všech možností, které dává PREG, pro povolení více adresářů, ale dejte si pozor, ať v nich jsou JEDINĚ soubory, u kterých vám nevadí, když si je stáhne útočník. NIKDY do těchto adresářů neukládejte žádné PHP soubory! To by mohlo vést k zveřejnění citlivých dat, včetně uživatelského jména a hesla pro připojení k databázi."
51
 
52
- #: ../simple-download-monitor.php:429
53
  msgid "Default value is <code>files/</code>, which only allows download from /files directory (the leading <code>/</code> is implicit)."
54
  msgstr "Výchozí hodnota je <code>files/</code>, která dovolí stahovat pouze soubory z adresáře /files (úvodní <code>/</code> je dosazeno automaticky)."
55
 
56
- #: ../simple-download-monitor.php:431
57
  msgid "Allowed extensions"
58
  msgstr "Povolené přípony"
59
 
60
- #: ../simple-download-monitor.php:432
61
  msgid "Only files with extensions matching this regular expressions will be processed. This is another important security value. Make sure you only add extensions which are safe for malicious users to have, e.g. archives and possibly images. Do NOT use any expression that could allow a user to download PHP files, even if you think it safe given the Allowed Directories option above."
62
  msgstr "Zpracovávány budou pouze soubory, jejichž přípony odpovídají tomuto regulárnímu výrazu. Jde o další důležitý bezpečnostní prvek. Dejte si pozor, ať jsou zde uvedeny pouze takové přípony, které nemohou být zneužity útočníky, tzn. komprimované archívy a případně obrázky. NEPOUŽÍVEJTE výrazy, které by mohly uživateli dovolit download PHP souborů, ani kdyby tyto soubory vylučovalo nastavení \"Povolené adresáře\" výše."
63
 
64
- #: ../simple-download-monitor.php:433
65
  msgid "Default value is <code>zip|rar|7z</code> which only allows download of files ending with <code>.zip</code>, <code>.rar</code> and <code>.7z</code> (the leading <code>.</code> is implicit)."
66
  msgstr "Výchozí hodnota je <code>zip|rar|7z</code>, která povolí pouze stahování souborů s příponou <code>.zip</code>, <code>.rar</code> a <code>.7z</code> (úvodní <code>.</code> je dosazena automaticky)."
67
 
68
- #: ../simple-download-monitor.php:435
69
  msgid "Inline files"
70
  msgstr "Soubory pro inline zobrazení"
71
 
72
- #: ../simple-download-monitor.php:436
73
  msgid "Files whose names match this regular expression will be displayed inline (within a HTML page) rather than downloaded."
74
  msgstr "Soubory, které vyhovují tomuto regulárnímu výrazu, budou zobrazeny inline (jako objekt - např. obrázek nebo video - uvnitř HTML stránky) místo aby se stahovaly."
75
 
76
- #: ../simple-download-monitor.php:437
77
  msgid "By default, this value is empty - no files will appear inline, all will be downloaded. You may want to place something like <code>\\.(jpe?g|gif|png|swf)$</code> here to make images and Flash videos appear inline."
78
  msgstr "Výchozí hodnotou je prázdný řetězec - všechny soubory se budou stahovat, žádný nebude zobrazen inline. Vepište sem něco jako <code>\\.(jpe?g|gif|png|swf)$</code> pro zobrazování obrázků a Flashů inline."
79
 
80
- #: ../simple-download-monitor.php:438
81
  msgid "Note: Unlike the options above, nothing is implied in this regular expression. You <em>must</em> use an explicit <code>\\.</code> to denote \"start of extension\", you <em>must</em> use an explicit <code>$</code> to mark \"end of filename\", etc."
82
  msgstr "Pozn.: Narozdíl od nastavení uvedených výše se do tohoto regulárního výrazu nic nedoplňuje. Pokud chcete vyznačit \"začátek přípony\", <em>musíte</em> sem napsat <code>\\.</code>; pokud chcete vyznačit \"konec názvu souboru\", <em>musíte</em> sem napsat <code>$</code>, a podobně."
83
 
84
- #: ../simple-download-monitor.php:439
85
  msgid "Also note that this plugin uses PCRE-compatible regular expressions, NOT the better-known POSIX-compatible regular expressions. As a result, a valid regular expression must be at least three characters long - separator twice, and at least one character for a meaningful r.e."
86
  msgstr "Dále upozorňuji, že plugin používá PCRE-kompatibilní regulární výrazy a ne známější POSIX-kompatibilní. Z tohoto důvodu je vyžadováno, aby regulární výraz byl aspoň tři znaky dlouhý - dva znaky na dva výskyty oddělovače a aspoň jeden znak pro smysluplný r.e."
87
 
88
- #: ../simple-download-monitor.php:441
89
  msgid "Store detailed logs?"
90
  msgstr "Ukládat detailní záznamy?"
91
 
92
- #: ../simple-download-monitor.php:442
93
  msgid "If detailed logs are allowed, various information (including exact time of download, user's IP address, referrer etc.) is stored. This can fill your database quickly if you have only a little space or a lot of popular downloads. Otherwise just the total numbers of downloads are stored, consuming significantly less space."
94
  msgstr "Pokud je tato volba zapnuta, ukládají se detailní informace (jako přesný čas, IP adresa uživatele nebo referer) o každém downloadu. To může rychle zahltit databázi, pokud máte jen málo prostoru nebo populární downloady. Normálně se ukládá jen celkový počet stažení, který zabírá podstatně méně místa."
95
 
96
- #: ../simple-download-monitor.php:443
97
  msgid "Use detailed statistics."
98
  msgstr "Používat detailní statistiky"
99
 
100
- #: ../simple-download-monitor.php:444
101
  msgid "Ignored users"
102
  msgstr "Ignorovaní uživatelé"
103
 
104
- #: ../simple-download-monitor.php:445
105
  msgid "List of users whose downloads are not monitored. Separate multiple users with pipe character <code>|</code>. It is useful to prevent administrator damaging the statistics by testing that downloads work."
106
  msgstr "Seznam uživatelů, jejichž downloady nejsou sledovány. Uživatelská jména oddělujte znakem roury <code>|</code>. Funkce se hodí pro administrátory, kteří chtějí ověřovat funkčnost odkazů, ale nepřejí si, aby se jejich testy zaznamenávaly do statistik."
107
 
108
- #: ../simple-download-monitor.php:447
109
  msgid "Ignore quick re-downloads"
110
  msgstr "Ignorovat rychlé opakované downloady"
111
 
112
- #: ../simple-download-monitor.php:448
113
  msgid "If one IP address requests the same download several times within a given time interval, only the first time will be recorded. If a zero or a negative value is entered, all downloads will get recorded regardless of how quickly they occur after each other."
114
  msgstr "Pokud se jedna IP adresa pokusí stáhnout jeden soubor několikrát po sobě v daném časovém intervalu, zaznamená se do statistik jen první pokus. Pokud je rozpětí stanoveno na nula nebo záporné číslo, budou se zaznamenávat všechny downloady, bez ohledu na to, jak rychle po sobě následují."
115
 
116
- #: ../simple-download-monitor.php:449
117
  msgid "seconds"
118
  msgstr "sekund"
119
 
120
- #: ../simple-download-monitor.php:450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  msgid "Update settings"
122
  msgstr "Uložit nastavení"
123
 
124
- #: ../simple-download-monitor.php:571
125
  msgid "First"
126
  msgstr "První"
127
 
128
- #: ../simple-download-monitor.php:572
129
  msgid "Previous"
130
  msgstr "Předchozí"
131
 
132
- #: ../simple-download-monitor.php:579
133
  msgid "Next"
134
  msgstr "Další"
135
 
136
- #: ../simple-download-monitor.php:580
137
  msgid "Last"
138
  msgstr "Poslední"
139
 
140
- #: ../simple-download-monitor.php:678
141
- #: ../simple-download-monitor.php:755
142
- #: ../simple-download-monitor.php:852
143
  #: ../simple-download-monitor.php:853
 
 
144
  msgid "Simple Download Monitor"
145
  msgstr "Simple Download Monitor"
146
 
147
- #: ../simple-download-monitor.php:679
148
  msgid "Nonexistent downloads"
149
  msgstr "Neexistující soubory"
150
 
151
- #: ../simple-download-monitor.php:679
152
  msgid "All downloads"
153
  msgstr "Všechny downloady"
154
 
155
- #: ../simple-download-monitor.php:680
156
  msgid "Show all downloads"
157
  msgstr "Zobrazit všechny soubory"
158
 
159
- #: ../simple-download-monitor.php:680
160
  msgid "Show nonexistent downloads"
161
  msgstr "Zobrazit neexistující soubory"
162
 
163
- #: ../simple-download-monitor.php:695
164
  msgid "Filename"
165
  msgstr "Název souboru"
166
 
167
- #: ../simple-download-monitor.php:696
168
  msgid "Download count"
169
  msgstr "Počet stažení"
170
 
171
- #: ../simple-download-monitor.php:697
172
  msgid "Last date"
173
  msgstr "Poslední datum"
174
 
175
- #: ../simple-download-monitor.php:720
176
- msgid "Reset this statistic"
177
- msgstr "Vymazat tuto statistiku"
178
 
179
- #: ../simple-download-monitor.php:728
 
 
 
 
 
 
 
 
 
 
 
 
180
  msgid "Reset checked statistics"
181
  msgstr "Vymazat označené statistiky"
182
 
183
- #: ../simple-download-monitor.php:729
184
  msgid "Reset all statistics"
185
  msgstr "Vymazat všechny statistiky"
186
 
187
- #: ../simple-download-monitor.php:729
188
- #: ../simple-download-monitor.php:826
189
  msgid "Yes, I am sure"
190
  msgstr "Ano, chci to udělat"
191
 
192
- #: ../simple-download-monitor.php:756
193
  #, php-format
194
  msgid "Detailed data for <strong>%s</strong>:"
195
  msgstr "Detailní data pro <strong>%s</strong>:"
196
 
197
- #: ../simple-download-monitor.php:757
198
  #, php-format
199
  msgid "Total number of downloads: <strong>%d</strong>."
200
  msgstr "Celkový počet stažení: <strong>%d</strong>."
201
 
202
- #: ../simple-download-monitor.php:774
203
  msgid "Date"
204
  msgstr "Datum"
205
 
206
- #: ../simple-download-monitor.php:775
207
  msgid "Country"
208
  msgstr "Země"
209
 
210
- #: ../simple-download-monitor.php:776
211
  msgid "IP address"
212
  msgstr "IP adresa"
213
 
214
- #: ../simple-download-monitor.php:777
215
  msgid "Referer"
216
  msgstr "Referer"
217
 
218
- #: ../simple-download-monitor.php:778
219
  msgid "Username"
220
  msgstr "Uživatel"
221
 
222
- #: ../simple-download-monitor.php:815
223
  msgid "Delete this statistic"
224
  msgstr "Vymazat tuto statistiku"
225
 
226
- #: ../simple-download-monitor.php:823
227
  msgid "Delete checked statistics"
228
  msgstr "Vymazat označené statistiky"
229
 
230
- #: ../simple-download-monitor.php:826
231
  msgid "Delete all statistics"
232
  msgstr "Vymazat všechny statistiky"
233
 
234
- #: ../simple-download-monitor.php:830
235
  msgid "Return to full list."
236
  msgstr "Návrat do úplného seznamu"
237
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  #~ msgid "Delete"
239
  #~ msgstr "Smazat"
240
  #~ msgid "Delete All"
1
  msgid ""
2
  msgstr ""
3
+ "Project-Id-Version: Simple Download Monitor v0.19\n"
4
  "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2011-05-15 17:44+0100\n"
6
  "PO-Revision-Date: \n"
7
+ "Last-Translator: pepak <http://www.pepak.net>\n"
8
  "Language-Team: Pepak <pepak@pepak.net>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
16
  "X-Poedit-Basepath: .\n"
17
  "X-Poedit-SearchPath-0: ..\n"
18
 
19
+ #: ../simple-download-monitor.php:283
20
+ msgid "Simple Download Monitor error"
21
+ msgstr "Simple Download Monitor: chyba"
22
+
23
+ #: ../simple-download-monitor.php:324
24
+ #, php-format
25
+ msgid "You have exceeded your download quota today. Please try again in %d hours and %d minutes."
26
+ msgstr "Překročil jste svůj dnešní povolený počet downloadů. Zkuste to prosím znovu za %d hodin a %d minut."
27
+
28
+ #: ../simple-download-monitor.php:364
29
+ #, php-format
30
+ msgid "Requested file <strong>%s</strong> not found."
31
+ msgstr "Požadovaný soubor <strong>%s</strong> nebyl nalezen."
32
+
33
+ #: ../simple-download-monitor.php:468
34
+ #: ../simple-download-monitor.php:954
35
  msgid "Simple Download Monitor options"
36
  msgstr "Simple Download Monitor - nastavení"
37
 
38
+ #: ../simple-download-monitor.php:469
39
  msgid "Access rights"
40
  msgstr "Přístupová práva"
41
 
42
+ #: ../simple-download-monitor.php:470
43
  msgid "You can set up user rights required to access various functions of Simple Download Monitor. Rights are assigned through capabilities (see <a href=\"http://codex.wordpress.org/Roles_and_Capabilities#Roles\">Roles and Capabilities</a> in WordPress Codex). Predefined values are <strong>read</strong> (\"any registered user\") for displaying stats, <strong>delete_users</strong> (\"administrator\") for reseting stats and <strong>manage_options</strong> (\"administrator\") for changing options."
44
  msgstr "Zde můžete nastavit uživatelská práva potřebná pro přístup k jednotlivým funkcím Simple Download Monitoru. Práva jsou definována prostřednictvím schopností (capabilities, viz <a href=\"http://codex.wordpress.org/Roles_and_Capabilities#Roles\">Roles and Capabilities</a> ve WordPress Codex). Výchozí hodnoty jsou <strong>read</strong> (\"každý registrovaný uživatel) pro zobrazení statistik, <strong>delete_users</strong> (\"administrátor\") pro mazání statistik a <strong>manage_options</strong> (\"administrátor\") pro změnu nastavení."
45
 
46
+ #: ../simple-download-monitor.php:471
47
  msgid "Capability required for viewing download stats:"
48
  msgstr "Schopnost (capability) pro zobrazení statistik:"
49
 
50
+ #: ../simple-download-monitor.php:473
51
  msgid "Capability required for reseting download stats:"
52
  msgstr "Schopnost (capability) pro smazání statistik:"
53
 
54
+ #: ../simple-download-monitor.php:475
55
  msgid "Capability required for setting SDMON options:"
56
  msgstr "Schopnost (capability) pro nastavení:"
57
 
58
+ #: ../simple-download-monitor.php:477
59
  msgid "Allowed directories"
60
  msgstr "Povolené adresáře"
61
 
62
+ #: ../simple-download-monitor.php:478
63
  msgid "Only requested files whose full names (relative to document root) start with this regular expression will be processed. It is strongly recommended to place all downloadable files (and ONLY downloadable files) into a designated directory and then placing that directory's name followed by a slash here. It is possible to use the power of PREG to allow multiple directories, but make sure there are ONLY files which you are comfortable with malicious users downloading. Do not EVER allow directories which contain PHP files here! That could lead to disclosure of sensitive data, including username and password used to connect to WordPress database."
64
  msgstr "Zpracovávány budou pouze soubory, jejichž plná jména (relativní vůči kořenovému adresáři webu) začínají tímto regulárním výrazem. Silně doporučuji umístit všechny stažitelné soubory (a JENOM stažitelné soubory) do jednoho určeného adresáře a vepsat sem název tohoto adresáře zakončený lomítkem. Lze také využít všech možností, které dává PREG, pro povolení více adresářů, ale dejte si pozor, ať v nich jsou JEDINĚ soubory, u kterých vám nevadí, když si je stáhne útočník. NIKDY do těchto adresářů neukládejte žádné PHP soubory! To by mohlo vést k zveřejnění citlivých dat, včetně uživatelského jména a hesla pro připojení k databázi."
65
 
66
+ #: ../simple-download-monitor.php:479
67
  msgid "Default value is <code>files/</code>, which only allows download from /files directory (the leading <code>/</code> is implicit)."
68
  msgstr "Výchozí hodnota je <code>files/</code>, která dovolí stahovat pouze soubory z adresáře /files (úvodní <code>/</code> je dosazeno automaticky)."
69
 
70
+ #: ../simple-download-monitor.php:481
71
  msgid "Allowed extensions"
72
  msgstr "Povolené přípony"
73
 
74
+ #: ../simple-download-monitor.php:482
75
  msgid "Only files with extensions matching this regular expressions will be processed. This is another important security value. Make sure you only add extensions which are safe for malicious users to have, e.g. archives and possibly images. Do NOT use any expression that could allow a user to download PHP files, even if you think it safe given the Allowed Directories option above."
76
  msgstr "Zpracovávány budou pouze soubory, jejichž přípony odpovídají tomuto regulárnímu výrazu. Jde o další důležitý bezpečnostní prvek. Dejte si pozor, ať jsou zde uvedeny pouze takové přípony, které nemohou být zneužity útočníky, tzn. komprimované archívy a případně obrázky. NEPOUŽÍVEJTE výrazy, které by mohly uživateli dovolit download PHP souborů, ani kdyby tyto soubory vylučovalo nastavení \"Povolené adresáře\" výše."
77
 
78
+ #: ../simple-download-monitor.php:483
79
  msgid "Default value is <code>zip|rar|7z</code> which only allows download of files ending with <code>.zip</code>, <code>.rar</code> and <code>.7z</code> (the leading <code>.</code> is implicit)."
80
  msgstr "Výchozí hodnota je <code>zip|rar|7z</code>, která povolí pouze stahování souborů s příponou <code>.zip</code>, <code>.rar</code> a <code>.7z</code> (úvodní <code>.</code> je dosazena automaticky)."
81
 
82
+ #: ../simple-download-monitor.php:485
83
  msgid "Inline files"
84
  msgstr "Soubory pro inline zobrazení"
85
 
86
+ #: ../simple-download-monitor.php:486
87
  msgid "Files whose names match this regular expression will be displayed inline (within a HTML page) rather than downloaded."
88
  msgstr "Soubory, které vyhovují tomuto regulárnímu výrazu, budou zobrazeny inline (jako objekt - např. obrázek nebo video - uvnitř HTML stránky) místo aby se stahovaly."
89
 
90
+ #: ../simple-download-monitor.php:487
91
  msgid "By default, this value is empty - no files will appear inline, all will be downloaded. You may want to place something like <code>\\.(jpe?g|gif|png|swf)$</code> here to make images and Flash videos appear inline."
92
  msgstr "Výchozí hodnotou je prázdný řetězec - všechny soubory se budou stahovat, žádný nebude zobrazen inline. Vepište sem něco jako <code>\\.(jpe?g|gif|png|swf)$</code> pro zobrazování obrázků a Flashů inline."
93
 
94
+ #: ../simple-download-monitor.php:488
95
  msgid "Note: Unlike the options above, nothing is implied in this regular expression. You <em>must</em> use an explicit <code>\\.</code> to denote \"start of extension\", you <em>must</em> use an explicit <code>$</code> to mark \"end of filename\", etc."
96
  msgstr "Pozn.: Narozdíl od nastavení uvedených výše se do tohoto regulárního výrazu nic nedoplňuje. Pokud chcete vyznačit \"začátek přípony\", <em>musíte</em> sem napsat <code>\\.</code>; pokud chcete vyznačit \"konec názvu souboru\", <em>musíte</em> sem napsat <code>$</code>, a podobně."
97
 
98
+ #: ../simple-download-monitor.php:489
99
  msgid "Also note that this plugin uses PCRE-compatible regular expressions, NOT the better-known POSIX-compatible regular expressions. As a result, a valid regular expression must be at least three characters long - separator twice, and at least one character for a meaningful r.e."
100
  msgstr "Dále upozorňuji, že plugin používá PCRE-kompatibilní regulární výrazy a ne známější POSIX-kompatibilní. Z tohoto důvodu je vyžadováno, aby regulární výraz byl aspoň tři znaky dlouhý - dva znaky na dva výskyty oddělovače a aspoň jeden znak pro smysluplný r.e."
101
 
102
+ #: ../simple-download-monitor.php:491
103
  msgid "Store detailed logs?"
104
  msgstr "Ukládat detailní záznamy?"
105
 
106
+ #: ../simple-download-monitor.php:492
107
  msgid "If detailed logs are allowed, various information (including exact time of download, user's IP address, referrer etc.) is stored. This can fill your database quickly if you have only a little space or a lot of popular downloads. Otherwise just the total numbers of downloads are stored, consuming significantly less space."
108
  msgstr "Pokud je tato volba zapnuta, ukládají se detailní informace (jako přesný čas, IP adresa uživatele nebo referer) o každém downloadu. To může rychle zahltit databázi, pokud máte jen málo prostoru nebo populární downloady. Normálně se ukládá jen celkový počet stažení, který zabírá podstatně méně místa."
109
 
110
+ #: ../simple-download-monitor.php:493
111
  msgid "Use detailed statistics."
112
  msgstr "Používat detailní statistiky"
113
 
114
+ #: ../simple-download-monitor.php:494
115
  msgid "Ignored users"
116
  msgstr "Ignorovaní uživatelé"
117
 
118
+ #: ../simple-download-monitor.php:495
119
  msgid "List of users whose downloads are not monitored. Separate multiple users with pipe character <code>|</code>. It is useful to prevent administrator damaging the statistics by testing that downloads work."
120
  msgstr "Seznam uživatelů, jejichž downloady nejsou sledovány. Uživatelská jména oddělujte znakem roury <code>|</code>. Funkce se hodí pro administrátory, kteří chtějí ověřovat funkčnost odkazů, ale nepřejí si, aby se jejich testy zaznamenávaly do statistik."
121
 
122
+ #: ../simple-download-monitor.php:497
123
  msgid "Ignore quick re-downloads"
124
  msgstr "Ignorovat rychlé opakované downloady"
125
 
126
+ #: ../simple-download-monitor.php:498
127
  msgid "If one IP address requests the same download several times within a given time interval, only the first time will be recorded. If a zero or a negative value is entered, all downloads will get recorded regardless of how quickly they occur after each other."
128
  msgstr "Pokud se jedna IP adresa pokusí stáhnout jeden soubor několikrát po sobě v daném časovém intervalu, zaznamená se do statistik jen první pokus. Pokud je rozpětí stanoveno na nula nebo záporné číslo, budou se zaznamenávat všechny downloady, bez ohledu na to, jak rychle po sobě následují."
129
 
130
+ #: ../simple-download-monitor.php:499
131
  msgid "seconds"
132
  msgstr "sekund"
133
 
134
+ #: ../simple-download-monitor.php:500
135
+ msgid "Limit number of downloads per IP address"
136
+ msgstr "Omezit počet downloadů z jedné IP adresy"
137
+
138
+ #: ../simple-download-monitor.php:501
139
+ msgid "Limit the number of files an IP address can download per day. The default value of zero means 'no limits' - an IP address can download as many files as it likes. Note that various download managers can initiate several downloads for each file, so make sure the limit is high enough not to interfere with the normal usage of your site. Also, please understand that this is NOT a perfect solution: One IP address can be shared by multiple users, and one user can easily use more than one IP address."
140
+ msgstr "Omezit počet souborů, které může jedna IP adresa stáhnout za jeden den. Výchozí hodnota nula značí \"bez omezení\" - IP adresa může stáhnout libovolné množství souborů. Pozor, různé download managery mohou spustit pro jeden soubor několik stahování najednou; ujistěte se, že je limit dost velký na to, aby bránil v běžném používání vašich stránek. Také si prosím uvědomte, že toto NENÍ dokonalé řešení: Jednu IP adresu může sdílet mnoho uživatelů, a naopak jeden uživatel může mít mnoho IP adres."
141
+
142
+ #: ../simple-download-monitor.php:502
143
+ msgid "Users listed in the <strong>Ignored users</strong> section above can always download an unlimited number of files."
144
+ msgstr "Uživatelé uvedení v sekci <strong>Ignorovaní uživatelé</strong> výše mohou stahovat neomezený počet souborů."
145
+
146
+ #: ../simple-download-monitor.php:503
147
+ msgid "Visitors:"
148
+ msgstr "Návštěvníci:"
149
+
150
+ #: ../simple-download-monitor.php:504
151
+ msgid "Registered users:"
152
+ msgstr "Registrovaní uživatelé"
153
+
154
+ #: ../simple-download-monitor.php:505
155
+ msgid "Error message:"
156
+ msgstr "Chybová zpráva:"
157
+
158
+ #: ../simple-download-monitor.php:507
159
+ #, php-format
160
+ msgid "(The first <code>%d</code> will be replaced by number of hours, the second one by number of minutes.)"
161
+ msgstr "(První <code>%d</code> bude nahrazeno počtem hodin, druhé počtem minut.)"
162
+
163
+ #: ../simple-download-monitor.php:509
164
+ #: ../simple-download-monitor.php:825
165
  msgid "Update settings"
166
  msgstr "Uložit nastavení"
167
 
168
+ #: ../simple-download-monitor.php:634
169
  msgid "First"
170
  msgstr "První"
171
 
172
+ #: ../simple-download-monitor.php:635
173
  msgid "Previous"
174
  msgstr "Předchozí"
175
 
176
+ #: ../simple-download-monitor.php:642
177
  msgid "Next"
178
  msgstr "Další"
179
 
180
+ #: ../simple-download-monitor.php:643
181
  msgid "Last"
182
  msgstr "Poslední"
183
 
184
+ #: ../simple-download-monitor.php:763
 
 
185
  #: ../simple-download-monitor.php:853
186
+ #: ../simple-download-monitor.php:954
187
+ #: ../simple-download-monitor.php:955
188
  msgid "Simple Download Monitor"
189
  msgstr "Simple Download Monitor"
190
 
191
+ #: ../simple-download-monitor.php:764
192
  msgid "Nonexistent downloads"
193
  msgstr "Neexistující soubory"
194
 
195
+ #: ../simple-download-monitor.php:764
196
  msgid "All downloads"
197
  msgstr "Všechny downloady"
198
 
199
+ #: ../simple-download-monitor.php:765
200
  msgid "Show all downloads"
201
  msgstr "Zobrazit všechny soubory"
202
 
203
+ #: ../simple-download-monitor.php:765
204
  msgid "Show nonexistent downloads"
205
  msgstr "Zobrazit neexistující soubory"
206
 
207
+ #: ../simple-download-monitor.php:781
208
  msgid "Filename"
209
  msgstr "Název souboru"
210
 
211
+ #: ../simple-download-monitor.php:782
212
  msgid "Download count"
213
  msgstr "Počet stažení"
214
 
215
+ #: ../simple-download-monitor.php:783
216
  msgid "Last date"
217
  msgstr "Poslední datum"
218
 
219
+ #: ../simple-download-monitor.php:784
220
+ msgid "Hide from sidebar"
221
+ msgstr "Skrýt z postranního panelu"
222
 
223
+ #: ../simple-download-monitor.php:785
224
+ msgid "Reset to zero"
225
+ msgstr "Vynulovat"
226
+
227
+ #: ../simple-download-monitor.php:810
228
+ msgid "Hidden"
229
+ msgstr "Skrytý"
230
+
231
+ #: ../simple-download-monitor.php:815
232
+ msgid "Reset"
233
+ msgstr "Vynulovat"
234
+
235
+ #: ../simple-download-monitor.php:826
236
  msgid "Reset checked statistics"
237
  msgstr "Vymazat označené statistiky"
238
 
239
+ #: ../simple-download-monitor.php:827
240
  msgid "Reset all statistics"
241
  msgstr "Vymazat všechny statistiky"
242
 
243
+ #: ../simple-download-monitor.php:827
244
+ #: ../simple-download-monitor.php:924
245
  msgid "Yes, I am sure"
246
  msgstr "Ano, chci to udělat"
247
 
248
+ #: ../simple-download-monitor.php:854
249
  #, php-format
250
  msgid "Detailed data for <strong>%s</strong>:"
251
  msgstr "Detailní data pro <strong>%s</strong>:"
252
 
253
+ #: ../simple-download-monitor.php:855
254
  #, php-format
255
  msgid "Total number of downloads: <strong>%d</strong>."
256
  msgstr "Celkový počet stažení: <strong>%d</strong>."
257
 
258
+ #: ../simple-download-monitor.php:872
259
  msgid "Date"
260
  msgstr "Datum"
261
 
262
+ #: ../simple-download-monitor.php:873
263
  msgid "Country"
264
  msgstr "Země"
265
 
266
+ #: ../simple-download-monitor.php:874
267
  msgid "IP address"
268
  msgstr "IP adresa"
269
 
270
+ #: ../simple-download-monitor.php:875
271
  msgid "Referer"
272
  msgstr "Referer"
273
 
274
+ #: ../simple-download-monitor.php:876
275
  msgid "Username"
276
  msgstr "Uživatel"
277
 
278
+ #: ../simple-download-monitor.php:913
279
  msgid "Delete this statistic"
280
  msgstr "Vymazat tuto statistiku"
281
 
282
+ #: ../simple-download-monitor.php:921
283
  msgid "Delete checked statistics"
284
  msgstr "Vymazat označené statistiky"
285
 
286
+ #: ../simple-download-monitor.php:924
287
  msgid "Delete all statistics"
288
  msgstr "Vymazat všechny statistiky"
289
 
290
+ #: ../simple-download-monitor.php:928
291
  msgid "Return to full list."
292
  msgstr "Návrat do úplného seznamu"
293
 
294
+ #: ../simple-download-monitor.php:969
295
+ msgid "Allows you to display the most popular downloads in the sidebar."
296
+ msgstr "Dovoluje zobrazit v postranním panelu seznam nejoblíbenějších souborů."
297
+
298
+ #: ../simple-download-monitor.php:1014
299
+ msgid "Popular files"
300
+ msgstr "Oblíbené soubory"
301
+
302
+ #: ../simple-download-monitor.php:1020
303
+ msgid "Title:"
304
+ msgstr "Zobrazovaný název:"
305
+
306
+ #: ../simple-download-monitor.php:1024
307
+ msgid "Number of files to show:"
308
+ msgstr "Počet zobrazených souborů:"
309
+
310
+ #: ../simple-download-monitor.php:1027
311
+ msgid "Only show filenames which match this LIKE condition:"
312
+ msgstr "Zobrazovat pouze soubory, které vyhovují této LIKE podmínce:"
313
+
314
+ #: ../simple-download-monitor.php:1029
315
+ msgid "Empty string matches all filenames and is useful for most usage scenarios. You would only use a non-empty value if you wanted to create multiple SDMon widgets, each showing a different list of files: only filenames which match the given string in a LIKE condition of a SQL query will be shown. The most common values would be something like <code>files/documents/%</code> (meaning \"The filename must begin with <code>files/documents/</code>\") or <code>%.mp3</code> (meaning \"The filename must end with <code>.mp3</code>\") - the percentage symbol <code>%</code> means \"anything\", the underscore symbol <code>_</code> means \"Any one character\"."
316
+ msgstr "Prázdný řetězec neomezuje seznam souborů a je vhodný pro nejběžnější typy použití. Neprázdnou hodnotu použijte, pokud chcete zobrazit několik nezávislých widgetů, kde každý bude zobrazovat jiný seznam souborů - pak budou zobrazeny jen ty soubory, jejichž názvy vyhoví podmínce. Typické hodnoty vypadají jako <code>files/dokumenty/%</code> (\"Jméno souboru musí začínat <code>files/dokumenty/</code>\") nebo <code>%.mp3</code> (\"Jméno souboru musí končit <code>.mp3</code>\") - symbol procenta <code>%</code> značí \"cokoliv\", symbol podtržítka <code>_</code> značí \"právě jeden libovolný znak\"."
317
+
318
+ #~ msgid "<h2>Simple Download Monitor error</h2>"
319
+ #~ msgstr "<h2>Simple Download Monitor - chyba</h2>"
320
+ #~ msgid "Reset this statistic"
321
+ #~ msgstr "Vymazat tuto statistiku"
322
  #~ msgid "Delete"
323
  #~ msgstr "Smazat"
324
  #~ msgid "Delete All"
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Plugin Name ===
2
  Contributors: Pepak
3
- Donate link:
4
  Tags: files, counter, count, tracking, download monitor, monitor, downloads, download
5
  Requires at least: 2.8.0
6
  Tested up to: 3.0.3
7
- Stable tag: 0.18
8
 
9
  Count the number of downloads without having to maintain a comprehensive download page.
10
 
@@ -118,6 +118,25 @@ http://www.pepak.net/wordpress/simple-download-monitor-plugin/#comment-4729
118
 
119
  == Changelog ==
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  = 0.18 =
122
 
123
  * When Simple Download Monitor was used in conjunction with W3 Total Cache
1
  === Plugin Name ===
2
  Contributors: Pepak
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=paypal.com@pepak.net&currency_code=USD
4
  Tags: files, counter, count, tracking, download monitor, monitor, downloads, download
5
  Requires at least: 2.8.0
6
  Tested up to: 3.0.3
7
+ Stable tag: 0.19
8
 
9
  Count the number of downloads without having to maintain a comprehensive download page.
10
 
118
 
119
  == Changelog ==
120
 
121
+ = 0.19 =
122
+
123
+ * Filenames are now returned quoted, which allows proper download of files
124
+ with a space in their filenames. Thanks Sameh Farouk for the tip.
125
+
126
+ * Possibility to limit the number of downloads per IP address and day. When
127
+ the number is exceeded, the user gets an error message.
128
+
129
+ This functionality requires detailed logs to be turned on. Ignored users
130
+ can always download as many files as they want.
131
+
132
+ * Support for a sidebar widget showing top-10 (or top-anything) most
133
+ downloaded files (either all files or those matching a given mask).
134
+
135
+ * The user who has rights to delete statistics can now mark some downloads
136
+ as hidden. This setting only affects the sidebar widget and is mostly
137
+ intended to remove obsolete versions of files from the list while keeping
138
+ the download statistics themselves.
139
+
140
  = 0.18 =
141
 
142
  * When Simple Download Monitor was used in conjunction with W3 Total Cache
simple-download-monitor.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: Simple Download Monitor
5
  Plugin URI: http://www.pepak.net/wordpress/simple-download-monitor-plugin
6
  Description: Count the number of downloads without having to maintain a comprehensive download page.
7
- Version: 0.18
8
  Author: Pepak
9
  Author URI: http://www.pepak.net
10
  */
@@ -31,7 +31,7 @@ if (!class_exists('SimpleDownloadMonitor'))
31
  class SimpleDownloadMonitor
32
  {
33
 
34
- const VERSION = '0.18';
35
  const PREFIX = 'sdmon_';
36
  const PREG_DELIMITER = '`';
37
  const GET_PARAM = 'sdmon';
@@ -66,6 +66,7 @@ if (!class_exists('SimpleDownloadMonitor'))
66
  download_count INTEGER NOT NULL,
67
  last_date TIMESTAMP NOT NULL,
68
  file_exists TINYINT,
 
69
  PRIMARY KEY id (id),
70
  KEY download_count (download_count),
71
  KEY last_date (last_date)
@@ -97,9 +98,12 @@ if (!class_exists('SimpleDownloadMonitor'))
97
  add_option(self::PREFIX . 'rights_view', 'read');
98
  add_option(self::PREFIX . 'rights_delete', 'delete_users');
99
  add_option(self::PREFIX . 'rights_options', 'manage_options');
 
 
 
100
  }
101
 
102
- protected function table_downloads()
103
  {
104
  static $table = null;
105
  if ($table == null)
@@ -107,7 +111,7 @@ if (!class_exists('SimpleDownloadMonitor'))
107
  return $table;
108
  }
109
 
110
- protected function table_details()
111
  {
112
  static $table = null;
113
  if ($table == null)
@@ -265,6 +269,25 @@ if (!class_exists('SimpleDownloadMonitor'))
265
  }
266
  //-----------------------------------------------------------------------------------
267
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  public function Download($filename)
269
  {
270
  global $wpdb, $user_login, $user_ID;
@@ -289,6 +312,19 @@ if (!class_exists('SimpleDownloadMonitor'))
289
  $monitor = empty($username) || empty($ignored_users) || (!in_array($username, explode('|', $ignored_users)));
290
  if ($monitor)
291
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  // Store uncorrected request name to database for security/mistake review
293
  $id = $wpdb->get_var($wpdb->prepare("SELECT id FROM ${downloads} WHERE filename=%s", $filename));
294
  if ($id)
@@ -325,7 +361,7 @@ if (!class_exists('SimpleDownloadMonitor'))
325
  // If the file exists and is valid, download it
326
  // Make sure the file is available for download
327
  if (!$exists OR !$valid)
328
- return FALSE;
329
  // Generate proper headers
330
  $mimetype = '';
331
  if (function_exists('finfo_open') AND defined('FILEINFO_MIME_TYPE'))
@@ -341,7 +377,7 @@ if (!class_exists('SimpleDownloadMonitor'))
341
  $inlineregexp = self::PREG_DELIMITER . get_option(self::PREFIX . 'inline') . self::PREG_DELIMITER;
342
  if ($inlineregexp && preg_match($inlineregexp, $relfilename))
343
  $disposition = 'inline';
344
- $disposition = $disposition . '; filename=' . basename($fullfilename);
345
  $this->byteserve($fullfilename, $mimetype, $disposition);
346
  // Successful end
347
  return TRUE;
@@ -383,6 +419,9 @@ if (!class_exists('SimpleDownloadMonitor'))
383
  $rights_view = strval($_POST[self::PREFIX . 'rights_view']);
384
  $rights_delete = strval($_POST[self::PREFIX . 'rights_delete']);
385
  $rights_options = strval($_POST[self::PREFIX . 'rights_options']);
 
 
 
386
  // Remove slashes if necessary
387
  if (get_magic_quotes_gpc())
388
  {
@@ -390,6 +429,7 @@ if (!class_exists('SimpleDownloadMonitor'))
390
  $extensions = stripslashes($extensions);
391
  $inline = stripslashes($inline);
392
  $ignored_users = stripslashes($ignored_users);
 
393
  }
394
  // Escape the delimiter
395
  list($directories, $extensions) = str_replace(self::PREG_DELIMITER, '\\'.self::PREG_DELIMITER, array($directories, $extensions));
@@ -404,6 +444,9 @@ if (!class_exists('SimpleDownloadMonitor'))
404
  update_option(self::PREFIX . 'rights_view', $rights_view);
405
  update_option(self::PREFIX . 'rights_delete', $rights_delete);
406
  update_option(self::PREFIX . 'rights_options', $rights_options);
 
 
 
407
  }
408
  // Load options from the database
409
  $directories = get_option(self::PREFIX . 'directories');
@@ -415,6 +458,9 @@ if (!class_exists('SimpleDownloadMonitor'))
415
  $rights_view = get_option(self::PREFIX . 'rights_view');
416
  $rights_delete = get_option(self::PREFIX . 'rights_delete');
417
  $rights_options = get_option(self::PREFIX . 'rights_options');
 
 
 
418
  // Build the form
419
  ?>
420
  <div class="wrap">
@@ -423,34 +469,43 @@ if (!class_exists('SimpleDownloadMonitor'))
423
  <h3><?php echo __('Access rights', self::GETTEXT_REALM); ?></h3>
424
  <p><?php echo __('You can set up user rights required to access various functions of Simple Download Monitor. Rights are assigned through capabilities (see <a href="http://codex.wordpress.org/Roles_and_Capabilities#Roles">Roles and Capabilities</a> in WordPress Codex). Predefined values are <strong>read</strong> ("any registered user") for displaying stats, <strong>delete_users</strong> ("administrator") for reseting stats and <strong>manage_options</strong> ("administrator") for changing options.', self::GETTEXT_REALM); ?></p>
425
  <p><?php echo __('Capability required for viewing download stats:', self::GETTEXT_REALM); ?></p>
426
- <p><input type="text" name="<?php echo self::PREFIX; ?>rights_view" value="<?php echo attribute_escape($rights_view); ?>" /></p>
427
  <p><?php echo __('Capability required for reseting download stats:', self::GETTEXT_REALM); ?></p>
428
- <p><input type="text" name="<?php echo self::PREFIX; ?>rights_delete" value="<?php echo attribute_escape($rights_delete); ?>" /></p>
429
  <p><?php echo __('Capability required for setting SDMON options:', self::GETTEXT_REALM); ?></p>
430
- <p><input type="text" name="<?php echo self::PREFIX; ?>rights_options" value="<?php echo attribute_escape($rights_options); ?>" /></p>
431
  <h3><?php echo __('Allowed directories', self::GETTEXT_REALM); ?></h3>
432
  <p><?php echo __("Only requested files whose full names (relative to document root) start with this regular expression will be processed. It is strongly recommended to place all downloadable files (and ONLY downloadable files) into a designated directory and then placing that directory's name followed by a slash here. It is possible to use the power of PREG to allow multiple directories, but make sure there are ONLY files which you are comfortable with malicious users downloading. Do not EVER allow directories which contain PHP files here! That could lead to disclosure of sensitive data, including username and password used to connect to WordPress database.", self::GETTEXT_REALM); ?></p>
433
  <p><?php echo __("Default value is <code>files/</code>, which only allows download from /files directory (the leading <code>/</code> is implicit).", self::GETTEXT_REALM); ?></p>
434
- <p><input type="text" name="<?php echo self::PREFIX; ?>directories" value="<?php echo attribute_escape($directories); ?>" /></p>
435
  <h3><?php echo __('Allowed extensions', self::GETTEXT_REALM); ?></h3>
436
  <p><?php echo __('Only files with extensions matching this regular expressions will be processed. This is another important security value. Make sure you only add extensions which are safe for malicious users to have, e.g. archives and possibly images. Do NOT use any expression that could allow a user to download PHP files, even if you think it safe given the Allowed Directories option above.', self::GETTEXT_REALM); ?></p>
437
  <p><?php echo __("Default value is <code>zip|rar|7z</code> which only allows download of files ending with <code>.zip</code>, <code>.rar</code> and <code>.7z</code> (the leading <code>.</code> is implicit).", self::GETTEXT_REALM); ?></p>
438
- <p><input type="text" name="<?php echo self::PREFIX; ?>extensions" value="<?php echo attribute_escape($extensions); ?>" /></p>
439
  <h3><?php echo __('Inline files', self::GETTEXT_REALM); ?></h3>
440
  <p><?php echo __('Files whose names match this regular expression will be displayed inline (within a HTML page) rather than downloaded.', self::GETTEXT_REALM); ?></p>
441
  <p><?php echo __("By default, this value is empty - no files will appear inline, all will be downloaded. You may want to place something like <code>\.(jpe?g|gif|png|swf)$</code> here to make images and Flash videos appear inline.", self::GETTEXT_REALM); ?></p>
442
  <p><?php echo __('Note: Unlike the options above, nothing is implied in this regular expression. You <em>must</em> use an explicit <code>\.</code> to denote "start of extension", you <em>must</em> use an explicit <code>$</code> to mark "end of filename", etc.', self::GETTEXT_REALM); ?></p>
443
  <p><?php echo __('Also note that this plugin uses PCRE-compatible regular expressions, NOT the better-known POSIX-compatible regular expressions. As a result, a valid regular expression must be at least three characters long - separator twice, and at least one character for a meaningful r.e.', self::GETTEXT_REALM); ?></p>
444
- <p><input type="text" name="<?php echo self::PREFIX; ?>inline" value="<?php echo attribute_escape($inline); ?>" /></p>
445
  <h3><?php echo __("Store detailed logs?", self::GETTEXT_REALM); ?></h3>
446
  <p><?php echo __("If detailed logs are allowed, various information (including exact time of download, user's IP address, referrer etc.) is stored. This can fill your database quickly if you have only a little space or a lot of popular downloads. Otherwise just the total numbers of downloads are stored, consuming significantly less space.", self::GETTEXT_REALM); ?></p>
447
  <p><label for="<?php echo self::PREFIX; ?>detailed"><input type="checkbox" name="<?php echo self::PREFIX; ?>detailed" value="1" <?php if ($detailed) echo 'checked="checked" '; ?>/> <?php echo __('Use detailed statistics.', self::GETTEXT_REALM); ?></label></p>
448
  <h3><?php echo __("Ignored users", self::GETTEXT_REALM); ?></h3>
449
  <p><?php echo __("List of users whose downloads are not monitored. Separate multiple users with pipe character <code>|</code>. It is useful to prevent administrator damaging the statistics by testing that downloads work.", self::GETTEXT_REALM); ?></p>
450
- <p><input type="text" name="<?php echo self::PREFIX; ?>ignored_users" value="<?php echo attribute_escape($ignored_users); ?>" /></p>
451
  <h3><?php echo __("Ignore quick re-downloads", self::GETTEXT_REALM); ?></h3>
452
  <p><?php echo __("If one IP address requests the same download several times within a given time interval, only the first time will be recorded. If a zero or a negative value is entered, all downloads will get recorded regardless of how quickly they occur after each other.", self::GETTEXT_REALM); ?></p>
453
- <p><input type="text" name="<?php echo self::PREFIX; ?>group_within" value="<?php echo attribute_escape($group_within); ?>" /> <?php echo __('seconds', self::GETTEXT_REALM); ?></p>
 
 
 
 
 
 
 
 
 
454
  <div class="submit"><input type="submit" name="SimpleDownloadMonitor_Submit" value="<?php echo __("Update settings", self::GETTEXT_REALM) ?>" /></div>
455
  </form>
456
  </div><?php
@@ -466,6 +521,10 @@ if (!class_exists('SimpleDownloadMonitor'))
466
  $options = array('download' => $download, 'from' => $from, 'order' => $order, 'flags' => $flags);
467
  if ($this->IsAdmin())
468
  {
 
 
 
 
469
  if (isset($_POST['SimpleDownloadMonitor_Delete']) && isset($_POST['SimpleDownloadMonitor_DeleteIds']) && is_array($_POST['SimpleDownloadMonitor_DeleteIds']))
470
  {
471
  $this->DeleteDownloads($_POST['SimpleDownloadMonitor_DeleteIds']);
@@ -601,6 +660,28 @@ if (!class_exists('SimpleDownloadMonitor'))
601
  return FALSE;
602
  }
603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604
  protected function DeleteDownloadDetails($ids = array())
605
  {
606
  global $wpdb;
@@ -691,7 +772,8 @@ if (!class_exists('SimpleDownloadMonitor'))
691
  <col class="sdmon-filename" />
692
  <col class="sdmon-count" align="right" width="64" />
693
  <col class="sdmon-date" align="center" />
694
- <col class="sdmon-tools" />
 
695
  </colgroup>
696
  <thead>
697
  <tr>
@@ -699,7 +781,8 @@ if (!class_exists('SimpleDownloadMonitor'))
699
  <th><a href="<?php echo $this->GetUrlForList(array_merge($options, array('order' => self::ORDER_NAME ))); ?>"><?php echo __("Filename", self::GETTEXT_REALM); ?></a></th>
700
  <th><a href="<?php echo $this->GetUrlForList(array_merge($options, array('order' => self::ORDER_COUNT))); ?>"><?php echo __("Download count", self::GETTEXT_REALM); ?></a></th>
701
  <th><a href="<?php echo $this->GetUrlForList(array_merge($options, array('order' => self::ORDER_DATE ))); ?>"><?php echo __("Last date", self::GETTEXT_REALM); ?></a></th>
702
- <th>&nbsp;</th>
 
703
  </tr>
704
  </thead>
705
  <tbody><?php
@@ -707,21 +790,31 @@ if (!class_exists('SimpleDownloadMonitor'))
707
  $where = $this->GetWhere($flags);
708
  $orderby = $this->GetOrderBy($order);
709
  $limit = $this->GetLimit($from);
710
- $sql = "SELECT id, filename, download_count, last_date, file_exists FROM ${table_downloads} ${where} ${orderby} ${limit}";
711
  $totalcount = $wpdb->get_var("SELECT COUNT(*) FROM ${table_downloads} ${where}");
712
  $results = $wpdb->get_results($sql, ARRAY_N);
713
  $rownum = intval($options['from']);
714
  if (is_array($results)) {
715
  foreach ($results as $row) {
716
  $rownum++;
717
- list($download, $filename, $count, $date, $exists) = $row;
718
  ?>
719
  <tr<?php if (!$exists) echo ' class="not-exist"'; ?>>
720
  <td><?php echo $rownum; ?>.</td>
721
  <td><?php if ($detailed): ?><a href="<?php echo $this->GetUrlForList(array('download' => $download)); ?>"><?php endif; echo htmlspecialchars($filename); if ($detailed): ?></a><?php endif; ?></td>
722
  <td><?php echo $count; ?></td>
723
  <td><?php echo mysql2date('Y-m-d H:i:s', $date, TRUE); ?></td>
724
- <td><?php if ($this->IsAdmin()): ?><input type="checkbox" name="SimpleDownloadMonitor_DeleteIds[]" value="<?php echo $download; ?>" /><label for="SimpleDownloadMonitor_DeleteIds[]"> <?php echo __('Reset this statistic', self::GETTEXT_REALM); ?></label><?php else: ?>&nbsp;<?php endif; ?></td>
 
 
 
 
 
 
 
 
 
 
725
  </tr>
726
  </tbody><?php
727
  }
@@ -729,6 +822,7 @@ if (!class_exists('SimpleDownloadMonitor'))
729
  ?>
730
  </table>
731
  <?php if ($this->isAdmin()): ?>
 
732
  <div><input type="submit" name="SimpleDownloadMonitor_Delete" value="<?php echo __('Reset checked statistics', self::GETTEXT_REALM); ?>" /></div>
733
  <div><input type="submit" name="SimpleDownloadMonitor_DeleteAll" value="<?php echo __('Reset all statistics', self::GETTEXT_REALM); ?>" /> - <input type="checkbox" name="SimpleDownloadMonitor_DeleteAllReally" value="yes" /><label for="SimpleDownloadMonitor_DeleteAllReally"> <?php echo __('Yes, I am sure', self::GETTEXT_REALM); ?></label></div>
734
  </form>
@@ -839,13 +933,13 @@ if (!class_exists('SimpleDownloadMonitor'))
839
  {
840
  echo '<link type="text/css" rel="stylesheet" href="' . $this->plugin_url . '/css/sdmon.css" />'."\n";
841
  }
842
-
843
  }
844
  }
845
 
846
  if (!isset($sdmon))
847
  $sdmon = new SimpleDownloadMonitor();
848
-
849
  if (!function_exists('SimpleDownloadMonitor_BuildAdminMenu'))
850
  {
851
  function SimpleDownloadMonitor_BuildAdminMenu()
@@ -863,3 +957,89 @@ if (!function_exists('SimpleDownloadMonitor_BuildAdminMenu'))
863
  }
864
  }
865
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  Plugin Name: Simple Download Monitor
5
  Plugin URI: http://www.pepak.net/wordpress/simple-download-monitor-plugin
6
  Description: Count the number of downloads without having to maintain a comprehensive download page.
7
+ Version: 0.19
8
  Author: Pepak
9
  Author URI: http://www.pepak.net
10
  */
31
  class SimpleDownloadMonitor
32
  {
33
 
34
+ const VERSION = '0.19';
35
  const PREFIX = 'sdmon_';
36
  const PREG_DELIMITER = '`';
37
  const GET_PARAM = 'sdmon';
66
  download_count INTEGER NOT NULL,
67
  last_date TIMESTAMP NOT NULL,
68
  file_exists TINYINT,
69
+ hide_from_sidebar TINYINT,
70
  PRIMARY KEY id (id),
71
  KEY download_count (download_count),
72
  KEY last_date (last_date)
98
  add_option(self::PREFIX . 'rights_view', 'read');
99
  add_option(self::PREFIX . 'rights_delete', 'delete_users');
100
  add_option(self::PREFIX . 'rights_options', 'manage_options');
101
+ add_option(self::PREFIX . 'max_downloads_per_ip_and_day', '0');
102
+ add_option(self::PREFIX . 'max_downloads_per_ip_and_day_registered', '0');
103
+ add_option(self::PREFIX . 'error_download_limit', '');
104
  }
105
 
106
+ public function table_downloads()
107
  {
108
  static $table = null;
109
  if ($table == null)
111
  return $table;
112
  }
113
 
114
+ public function table_details()
115
  {
116
  static $table = null;
117
  if ($table == null)
269
  }
270
  //-----------------------------------------------------------------------------------
271
 
272
+ protected function ErrorMessage($code, $message, $shortmessage)
273
+ {
274
+ $code = intval($code);
275
+ // Clean all buffering components, if any.
276
+ while (ob_list_handlers())
277
+ ob_end_clean();
278
+ header('Cache-control: no-cache');
279
+ if ($code >= 200)
280
+ header(sprintf('%s %d %s', $_SERVER["SERVER_PROTOCOL"], $code, $shortmessage));
281
+ get_header();
282
+ ?><div class="error">
283
+ <h2><?php echo __("Simple Download Monitor error", self::GETTEXT_REALM); ?></h2>
284
+ <p><?php echo $message; ?></p>
285
+ <?php
286
+ get_sidebar();
287
+ get_footer();
288
+ die();
289
+ }
290
+
291
  public function Download($filename)
292
  {
293
  global $wpdb, $user_login, $user_ID;
312
  $monitor = empty($username) || empty($ignored_users) || (!in_array($username, explode('|', $ignored_users)));
313
  if ($monitor)
314
  {
315
+ // Check the number of downloads per IP and day
316
+ $max_downloads = intval(get_option(self::PREFIX . (is_user_logged_in() ? 'max_downloads_per_ip_and_day_registered' : 'max_downloads_per_ip_and_day')));
317
+ if ($max_downloads > 0)
318
+ {
319
+ $row = $wpdb->get_row($wpdb->prepare("SELECT COUNT(*) count, MIN(TIMESTAMPDIFF(MINUTE, NOW(), TIMESTAMPADD(DAY, 1, download_date))) retry FROM ${details} WHERE (download_date > TIMESTAMPADD(DAY, -1, NOW())) AND ip=%s", $ip_addr), ARRAY_N);
320
+ list($download_count, $retry_minutes) = $row;
321
+ if ($download_count >= $max_downloads)
322
+ {
323
+ $msg = get_option(self::PREFIX . 'error_download_limit');
324
+ if ($msg == '') $msg = __("You have exceeded your download quota today. Please try again in %d hours and %d minutes.", self::GETTEXT_REALM);
325
+ $this->ErrorMessage(403, sprintf($msg, $retry_minutes/60, abs($retry_minutes%60)), 'Forbidden');
326
+ }
327
+ }
328
  // Store uncorrected request name to database for security/mistake review
329
  $id = $wpdb->get_var($wpdb->prepare("SELECT id FROM ${downloads} WHERE filename=%s", $filename));
330
  if ($id)
361
  // If the file exists and is valid, download it
362
  // Make sure the file is available for download
363
  if (!$exists OR !$valid)
364
+ $this->ErrorMessage(404, sprintf(__("Requested file <strong>%s</strong> not found."), htmlspecialchars($filename)), 'Not found');
365
  // Generate proper headers
366
  $mimetype = '';
367
  if (function_exists('finfo_open') AND defined('FILEINFO_MIME_TYPE'))
377
  $inlineregexp = self::PREG_DELIMITER . get_option(self::PREFIX . 'inline') . self::PREG_DELIMITER;
378
  if ($inlineregexp && preg_match($inlineregexp, $relfilename))
379
  $disposition = 'inline';
380
+ $disposition = $disposition . '; filename="' . basename($fullfilename) . '"';
381
  $this->byteserve($fullfilename, $mimetype, $disposition);
382
  // Successful end
383
  return TRUE;
419
  $rights_view = strval($_POST[self::PREFIX . 'rights_view']);
420
  $rights_delete = strval($_POST[self::PREFIX . 'rights_delete']);
421
  $rights_options = strval($_POST[self::PREFIX . 'rights_options']);
422
+ $downloads_per_day = intval($_POST[self::PREFIX . 'max_downloads_per_ip_and_day']);
423
+ $downloads_per_day_registered = intval($_POST[self::PREFIX . 'max_downloads_per_ip_and_day_registered']);
424
+ $error_download_limit = strval($_POST[self::PREFIX . 'error_download_limit']);
425
  // Remove slashes if necessary
426
  if (get_magic_quotes_gpc())
427
  {
429
  $extensions = stripslashes($extensions);
430
  $inline = stripslashes($inline);
431
  $ignored_users = stripslashes($ignored_users);
432
+ $error_download_limit = stripslashes($error_download_limit);
433
  }
434
  // Escape the delimiter
435
  list($directories, $extensions) = str_replace(self::PREG_DELIMITER, '\\'.self::PREG_DELIMITER, array($directories, $extensions));
444
  update_option(self::PREFIX . 'rights_view', $rights_view);
445
  update_option(self::PREFIX . 'rights_delete', $rights_delete);
446
  update_option(self::PREFIX . 'rights_options', $rights_options);
447
+ update_option(self::PREFIX . 'max_downloads_per_ip_and_day', $downloads_per_day);
448
+ update_option(self::PREFIX . 'max_downloads_per_ip_and_day_registered', $downloads_per_day_registered);
449
+ update_option(self::PREFIX . 'error_download_limit', $error_download_limit);
450
  }
451
  // Load options from the database
452
  $directories = get_option(self::PREFIX . 'directories');
458
  $rights_view = get_option(self::PREFIX . 'rights_view');
459
  $rights_delete = get_option(self::PREFIX . 'rights_delete');
460
  $rights_options = get_option(self::PREFIX . 'rights_options');
461
+ $downloads_per_day = get_option(self::PREFIX . 'max_downloads_per_ip_and_day');
462
+ $downloads_per_day_registered = get_option(self::PREFIX . 'max_downloads_per_ip_and_day_registered');
463
+ $error_download_limit = get_option(self::PREFIX . 'error_download_limit');
464
  // Build the form
465
  ?>
466
  <div class="wrap">
469
  <h3><?php echo __('Access rights', self::GETTEXT_REALM); ?></h3>
470
  <p><?php echo __('You can set up user rights required to access various functions of Simple Download Monitor. Rights are assigned through capabilities (see <a href="http://codex.wordpress.org/Roles_and_Capabilities#Roles">Roles and Capabilities</a> in WordPress Codex). Predefined values are <strong>read</strong> ("any registered user") for displaying stats, <strong>delete_users</strong> ("administrator") for reseting stats and <strong>manage_options</strong> ("administrator") for changing options.', self::GETTEXT_REALM); ?></p>
471
  <p><?php echo __('Capability required for viewing download stats:', self::GETTEXT_REALM); ?></p>
472
+ <p><input type="text" name="<?php echo self::PREFIX; ?>rights_view" value="<?php echo esc_attr($rights_view); ?>" /></p>
473
  <p><?php echo __('Capability required for reseting download stats:', self::GETTEXT_REALM); ?></p>
474
+ <p><input type="text" name="<?php echo self::PREFIX; ?>rights_delete" value="<?php echo esc_attr($rights_delete); ?>" /></p>
475
  <p><?php echo __('Capability required for setting SDMON options:', self::GETTEXT_REALM); ?></p>
476
+ <p><input type="text" name="<?php echo self::PREFIX; ?>rights_options" value="<?php echo esc_attr($rights_options); ?>" /></p>
477
  <h3><?php echo __('Allowed directories', self::GETTEXT_REALM); ?></h3>
478
  <p><?php echo __("Only requested files whose full names (relative to document root) start with this regular expression will be processed. It is strongly recommended to place all downloadable files (and ONLY downloadable files) into a designated directory and then placing that directory's name followed by a slash here. It is possible to use the power of PREG to allow multiple directories, but make sure there are ONLY files which you are comfortable with malicious users downloading. Do not EVER allow directories which contain PHP files here! That could lead to disclosure of sensitive data, including username and password used to connect to WordPress database.", self::GETTEXT_REALM); ?></p>
479
  <p><?php echo __("Default value is <code>files/</code>, which only allows download from /files directory (the leading <code>/</code> is implicit).", self::GETTEXT_REALM); ?></p>
480
+ <p><input type="text" name="<?php echo self::PREFIX; ?>directories" value="<?php echo esc_attr($directories); ?>" /></p>
481
  <h3><?php echo __('Allowed extensions', self::GETTEXT_REALM); ?></h3>
482
  <p><?php echo __('Only files with extensions matching this regular expressions will be processed. This is another important security value. Make sure you only add extensions which are safe for malicious users to have, e.g. archives and possibly images. Do NOT use any expression that could allow a user to download PHP files, even if you think it safe given the Allowed Directories option above.', self::GETTEXT_REALM); ?></p>
483
  <p><?php echo __("Default value is <code>zip|rar|7z</code> which only allows download of files ending with <code>.zip</code>, <code>.rar</code> and <code>.7z</code> (the leading <code>.</code> is implicit).", self::GETTEXT_REALM); ?></p>
484
+ <p><input type="text" name="<?php echo self::PREFIX; ?>extensions" value="<?php echo esc_attr($extensions); ?>" /></p>
485
  <h3><?php echo __('Inline files', self::GETTEXT_REALM); ?></h3>
486
  <p><?php echo __('Files whose names match this regular expression will be displayed inline (within a HTML page) rather than downloaded.', self::GETTEXT_REALM); ?></p>
487
  <p><?php echo __("By default, this value is empty - no files will appear inline, all will be downloaded. You may want to place something like <code>\.(jpe?g|gif|png|swf)$</code> here to make images and Flash videos appear inline.", self::GETTEXT_REALM); ?></p>
488
  <p><?php echo __('Note: Unlike the options above, nothing is implied in this regular expression. You <em>must</em> use an explicit <code>\.</code> to denote "start of extension", you <em>must</em> use an explicit <code>$</code> to mark "end of filename", etc.', self::GETTEXT_REALM); ?></p>
489
  <p><?php echo __('Also note that this plugin uses PCRE-compatible regular expressions, NOT the better-known POSIX-compatible regular expressions. As a result, a valid regular expression must be at least three characters long - separator twice, and at least one character for a meaningful r.e.', self::GETTEXT_REALM); ?></p>
490
+ <p><input type="text" name="<?php echo self::PREFIX; ?>inline" value="<?php echo esc_attr($inline); ?>" /></p>
491
  <h3><?php echo __("Store detailed logs?", self::GETTEXT_REALM); ?></h3>
492
  <p><?php echo __("If detailed logs are allowed, various information (including exact time of download, user's IP address, referrer etc.) is stored. This can fill your database quickly if you have only a little space or a lot of popular downloads. Otherwise just the total numbers of downloads are stored, consuming significantly less space.", self::GETTEXT_REALM); ?></p>
493
  <p><label for="<?php echo self::PREFIX; ?>detailed"><input type="checkbox" name="<?php echo self::PREFIX; ?>detailed" value="1" <?php if ($detailed) echo 'checked="checked" '; ?>/> <?php echo __('Use detailed statistics.', self::GETTEXT_REALM); ?></label></p>
494
  <h3><?php echo __("Ignored users", self::GETTEXT_REALM); ?></h3>
495
  <p><?php echo __("List of users whose downloads are not monitored. Separate multiple users with pipe character <code>|</code>. It is useful to prevent administrator damaging the statistics by testing that downloads work.", self::GETTEXT_REALM); ?></p>
496
+ <p><input type="text" name="<?php echo self::PREFIX; ?>ignored_users" value="<?php echo esc_attr($ignored_users); ?>" /></p>
497
  <h3><?php echo __("Ignore quick re-downloads", self::GETTEXT_REALM); ?></h3>
498
  <p><?php echo __("If one IP address requests the same download several times within a given time interval, only the first time will be recorded. If a zero or a negative value is entered, all downloads will get recorded regardless of how quickly they occur after each other.", self::GETTEXT_REALM); ?></p>
499
+ <p><input type="text" name="<?php echo self::PREFIX; ?>group_within" value="<?php echo esc_attr($group_within); ?>" /> <?php echo __('seconds', self::GETTEXT_REALM); ?></p>
500
+ <h3><?php echo __("Limit number of downloads per IP address", self::GETTEXT_REALM); ?></h3>
501
+ <p><?php echo __("Limit the number of files an IP address can download per day. The default value of zero means 'no limits' - an IP address can download as many files as it likes. Note that various download managers can initiate several downloads for each file, so make sure the limit is high enough not to interfere with the normal usage of your site. Also, please understand that this is NOT a perfect solution: One IP address can be shared by multiple users, and one user can easily use more than one IP address.", self::GETTEXT_REALM); ?></p>
502
+ <p><?php echo __("Users listed in the <strong>Ignored users</strong> section above can always download an unlimited number of files.", self::GETTEXT_REALM); ?></p>
503
+ <p><?php echo __("Visitors:", self::GETTEXT_REALM); ?> <input type="text" name="<?php echo self::PREFIX; ?>max_downloads_per_ip_and_day" value="<?php echo esc_attr($downloads_per_day); ?>" /></p>
504
+ <p><?php echo __("Registered users:", self::GETTEXT_REALM); ?> <input type="text" name="<?php echo self::PREFIX; ?>max_downloads_per_ip_and_day_registered" value="<?php echo esc_attr($downloads_per_day_registered); ?>" /></p>
505
+ <p><?php echo __("Error message:", self::GETTEXT_REALM); ?></p>
506
+ <p><textarea name="<?php echo self::PREFIX; ?>error_download_limit" rows="4" cols="64"><?php echo htmlspecialchars($error_download_limit); ?></textarea></p>
507
+ <p><?php echo __("(The first <code>%d</code> will be replaced by number of hours, the second one by number of minutes.)", self::GETTEXT_REALM); ?>
508
+ <p>&nbsp;</p>
509
  <div class="submit"><input type="submit" name="SimpleDownloadMonitor_Submit" value="<?php echo __("Update settings", self::GETTEXT_REALM) ?>" /></div>
510
  </form>
511
  </div><?php
521
  $options = array('download' => $download, 'from' => $from, 'order' => $order, 'flags' => $flags);
522
  if ($this->IsAdmin())
523
  {
524
+ if (isset($_POST['SimpleDownloadMonitor_Update']) && isset($_POST['SimpleDownloadMonitor_HideIds']) && is_array($_POST['SimpleDownloadMonitor_HideIds']) && isset($_POST['SimpleDownloadMonitor_ShowIds']) && is_array($_POST['SimpleDownloadMonitor_ShowIds']))
525
+ {
526
+ $this->HideDownloads($_POST['SimpleDownloadMonitor_ShowIds'], $_POST['SimpleDownloadMonitor_HideIds']);
527
+ }
528
  if (isset($_POST['SimpleDownloadMonitor_Delete']) && isset($_POST['SimpleDownloadMonitor_DeleteIds']) && is_array($_POST['SimpleDownloadMonitor_DeleteIds']))
529
  {
530
  $this->DeleteDownloads($_POST['SimpleDownloadMonitor_DeleteIds']);
660
  return FALSE;
661
  }
662
 
663
+ protected function HideDownloads($show_ids, $hide_ids = array())
664
+ {
665
+ global $wpdb;
666
+ $show_ids = implode(',', array_map('intval', $show_ids));
667
+ $hide_ids = implode(',', array_map('intval', $hide_ids));
668
+ $downloads = $this->table_downloads();
669
+ if ($show_ids)
670
+ {
671
+ $sql = "UPDATE ${downloads} SET hide_from_sidebar=0, last_date=last_date WHERE id IN (${show_ids})";
672
+ // The last_date is used to prevent automatic update to current_timestamp
673
+ $wpdb->query($sql);
674
+ }
675
+ if ($hide_ids)
676
+ {
677
+ $sql = "UPDATE ${downloads} SET hide_from_sidebar=1, last_date=last_date WHERE id IN (${hide_ids})";
678
+ // The last_date is used to prevent automatic update to current_timestamp
679
+ $wpdb->query($sql);
680
+ }
681
+ //wp_redirect($_SERVER['REQUEST_URI']);
682
+ //die();
683
+ }
684
+
685
  protected function DeleteDownloadDetails($ids = array())
686
  {
687
  global $wpdb;
772
  <col class="sdmon-filename" />
773
  <col class="sdmon-count" align="right" width="64" />
774
  <col class="sdmon-date" align="center" />
775
+ <col class="sdmon-hidden" />
776
+ <col class="sdmon-delete" />
777
  </colgroup>
778
  <thead>
779
  <tr>
781
  <th><a href="<?php echo $this->GetUrlForList(array_merge($options, array('order' => self::ORDER_NAME ))); ?>"><?php echo __("Filename", self::GETTEXT_REALM); ?></a></th>
782
  <th><a href="<?php echo $this->GetUrlForList(array_merge($options, array('order' => self::ORDER_COUNT))); ?>"><?php echo __("Download count", self::GETTEXT_REALM); ?></a></th>
783
  <th><a href="<?php echo $this->GetUrlForList(array_merge($options, array('order' => self::ORDER_DATE ))); ?>"><?php echo __("Last date", self::GETTEXT_REALM); ?></a></th>
784
+ <th><?php echo __('Hide from sidebar', self::GETTEXT_REALM); ?></th>
785
+ <th><?php echo __('Reset to zero', self::GETTEXT_REALM); ?></th>
786
  </tr>
787
  </thead>
788
  <tbody><?php
790
  $where = $this->GetWhere($flags);
791
  $orderby = $this->GetOrderBy($order);
792
  $limit = $this->GetLimit($from);
793
+ $sql = "SELECT id, filename, download_count, last_date, file_exists, hide_from_sidebar FROM ${table_downloads} ${where} ${orderby} ${limit}";
794
  $totalcount = $wpdb->get_var("SELECT COUNT(*) FROM ${table_downloads} ${where}");
795
  $results = $wpdb->get_results($sql, ARRAY_N);
796
  $rownum = intval($options['from']);
797
  if (is_array($results)) {
798
  foreach ($results as $row) {
799
  $rownum++;
800
+ list($download, $filename, $count, $date, $exists, $hidden) = $row;
801
  ?>
802
  <tr<?php if (!$exists) echo ' class="not-exist"'; ?>>
803
  <td><?php echo $rownum; ?>.</td>
804
  <td><?php if ($detailed): ?><a href="<?php echo $this->GetUrlForList(array('download' => $download)); ?>"><?php endif; echo htmlspecialchars($filename); if ($detailed): ?></a><?php endif; ?></td>
805
  <td><?php echo $count; ?></td>
806
  <td><?php echo mysql2date('Y-m-d H:i:s', $date, TRUE); ?></td>
807
+ <td><?php if ($this->IsAdmin()): ?>
808
+ <input type="checkbox" name="SimpleDownloadMonitor_HideIds[]" value="<?php echo $download; ?>" <?php if ($hidden) echo ' checked="checked"'; ?> />
809
+ <input type="hidden" name="SimpleDownloadMonitor_ShowIds[]" value="<?php echo $download; ?>" />
810
+ <label for="SimpleDownloadMonitor_HideIds[]" /> <?php echo __('Hidden', self::GETTEXT_REALM); ?></label>
811
+ <?php else: ?>&nbsp;<?php endif; ?>
812
+ </td>
813
+ <td><?php if ($this->IsAdmin()): ?>
814
+ <input type="checkbox" name="SimpleDownloadMonitor_DeleteIds[]" value="<?php echo $download; ?>" />
815
+ <label for="SimpleDownloadMonitor_DeleteIds[]"> <?php echo __('Reset', self::GETTEXT_REALM); ?></label>
816
+ <?php else: ?>&nbsp;<?php endif; ?>
817
+ </td>
818
  </tr>
819
  </tbody><?php
820
  }
822
  ?>
823
  </table>
824
  <?php if ($this->isAdmin()): ?>
825
+ <div><input type="submit" name="SimpleDownloadMonitor_Update" value="<?php echo __('Update settings', self::GETTEXT_REALM); ?>" /></div>
826
  <div><input type="submit" name="SimpleDownloadMonitor_Delete" value="<?php echo __('Reset checked statistics', self::GETTEXT_REALM); ?>" /></div>
827
  <div><input type="submit" name="SimpleDownloadMonitor_DeleteAll" value="<?php echo __('Reset all statistics', self::GETTEXT_REALM); ?>" /> - <input type="checkbox" name="SimpleDownloadMonitor_DeleteAllReally" value="yes" /><label for="SimpleDownloadMonitor_DeleteAllReally"> <?php echo __('Yes, I am sure', self::GETTEXT_REALM); ?></label></div>
828
  </form>
933
  {
934
  echo '<link type="text/css" rel="stylesheet" href="' . $this->plugin_url . '/css/sdmon.css" />'."\n";
935
  }
936
+
937
  }
938
  }
939
 
940
  if (!isset($sdmon))
941
  $sdmon = new SimpleDownloadMonitor();
942
+
943
  if (!function_exists('SimpleDownloadMonitor_BuildAdminMenu'))
944
  {
945
  function SimpleDownloadMonitor_BuildAdminMenu()
957
  }
958
  }
959
  }
960
+
961
+ if (!class_exists('SimpleDownloadMonitor_Widget'))
962
+ {
963
+ class SimpleDownloadMonitor_Widget extends WP_Widget
964
+ {
965
+ function SimpleDownloadMonitor_Widget()
966
+ {
967
+ $widget_options = array(
968
+ 'classname' => 'sdmon',
969
+ 'description' => __('Allows you to display the most popular downloads in the sidebar.', SimpleDownloadMonitor::GETTEXT_REALM)
970
+ );
971
+ $control_options = array(
972
+ //'width' => 250,
973
+ //'height' => 0,
974
+ 'id_base' => 'sdmon-widget'
975
+ );
976
+ $this->WP_Widget('sdmon-widget', 'Simple Download Monitor', $widget_options, $control_options);
977
+ }
978
+
979
+ function widget($arguments, $instance)
980
+ {
981
+ global $wpdb;
982
+ $title = apply_filters('widget_title', $instance['title']);
983
+ $count = intval(isset($instance['count']) ? intval($instance['count']) : 0);
984
+ if ($count <= 0) $count = 10;
985
+ $like = isset($instance['like']) ? $instance['like'] : '';
986
+ echo $arguments['before_widget'];
987
+ if ($title) echo $arguments['before_title'] . $title . $arguments['after_title'];
988
+ $downloads = SimpleDownloadMonitor::table_downloads();
989
+ $liketest = $like ? ' AND filename LIKE "%s"' : '';
990
+ $sql = "SELECT id, filename, download_count FROM ${downloads} WHERE file_exists<>0 AND COALESCE(hide_from_sidebar,0)=0 ${liketest} ORDER BY download_count DESC LIMIT ${count}";
991
+ $results = $wpdb->get_results($wpdb->prepare($sql, $like), ARRAY_N);
992
+ echo "<ul>\n";
993
+ foreach ($results as $row)
994
+ {
995
+ list($id, $filename, $downloadcount) = $row;
996
+ ?><li><a href="/<?php echo esc_attr($filename); ?>"><?php echo htmlspecialchars(basename($filename)); ?></a> <strong><?php echo $downloadcount; ?></strong></li><?php
997
+ }
998
+ echo "</ul>\n";
999
+ echo $arguments['after_widget'];
1000
+ }
1001
+
1002
+ function update($new_instance, $old_instance)
1003
+ {
1004
+ $instance = $old_instance;
1005
+ $instance['title'] = strip_tags($new_instance['title']);
1006
+ $instance['count'] = intval($new_instance['count']);
1007
+ $instance['like'] = $new_instance['like'];
1008
+ return $instance;
1009
+ }
1010
+
1011
+ function form($instance)
1012
+ {
1013
+ $defaults = array(
1014
+ 'title' => __('Popular files', SimpleDownloadMonitor::GETTEXT_REALM),
1015
+ 'count' => '10',
1016
+ 'like' => ''
1017
+ );
1018
+ $instance = wp_parse_args((array) $instance, $defaults);
1019
+ ?><p>
1020
+ <label for="<?php echo $this->get_field_id('title'); ?>"><?php echo __('Title:', SimpleDownloadMonitor::GETTEXT_REALM); ?></label>
1021
+ <input id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php echo esc_attr($instance['title']); ?>" type="text" style="width: 100%;" />
1022
+ </p>
1023
+ <p>
1024
+ <label for="<?php echo $this->get_field_id('count'); ?>"><?php echo __('Number of files to show:', SimpleDownloadMonitor::GETTEXT_REALM); ?></label>
1025
+ <input id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>" value="<?php echo esc_attr($instance['count']); ?>" type="text" />
1026
+ </p><p>
1027
+ <label for="<?php echo $this->get_field_id('like'); ?>"><?php echo __('Only show filenames which match this LIKE condition:', SimpleDownloadMonitor::GETTEXT_REALM); ?></label>
1028
+ <input id="<?php echo $this->get_field_id('like'); ?>" name="<?php echo $this->get_field_name('like'); ?>" value="<?php echo esc_attr($instance['like']); ?>" type="text" style="width: 100%;" />
1029
+ <br /><?php echo __("Empty string matches all filenames and is useful for most usage scenarios. You would only use a non-empty value if you wanted to create multiple SDMon widgets, each showing a different list of files: only filenames which match the given string in a LIKE condition of a SQL query will be shown. The most common values would be something like <code>files/documents/%</code> (meaning \"The filename must begin with <code>files/documents/</code>\") or <code>%.mp3</code> (meaning \"The filename must end with <code>.mp3</code>\") - the percentage symbol <code>%</code> means \"anything\", the underscore symbol <code>_</code> means \"Any one character\".", SimpleDownloadMonitor::GETTEXT_REALM); ?>
1030
+ </p><?php
1031
+ }
1032
+
1033
+ }
1034
+ }
1035
+
1036
+ if (!function_exists('SimpleDownloadMonitorWidget_Init'))
1037
+ {
1038
+ function SimpleDownloadMonitorWidget_Init()
1039
+ {
1040
+ register_widget('SimpleDownloadMonitor_Widget');
1041
+ }
1042
+
1043
+ }
1044
+
1045
+ add_action('widgets_init', 'SimpleDownloadMonitorWidget_Init');