Compare commits

...

1637 commits

Author SHA1 Message Date
Heiko August
e1515c1b84 Fix: replace the obsolete column name "filename" with the new name "pathname" 2025-04-03 22:00:57 +02:00
Heiko August
e99a16c489 Change: add the new version number to the files index.php and config/VERSION 2025-03-23 18:51:59 +01:00
Heiko August
5c81c0d144 Change: add the changes since 20241215.1 to the changelog 2025-03-23 18:51:59 +01:00
Heiko August
2b6abc25d4 Change: add the files to replace to the upgrade script 2025-03-23 18:51:59 +01:00
Heiko August
c86fa13cd3 Change: correct date and time formats for Arabic language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Bahrain
2025-03-17 23:38:17 +01:00
Heiko August
eb9d9a00a0 Change: correct date and time formats for Simplified Chinese language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Asia#Greater_China
2025-03-17 23:38:17 +01:00
Heiko August
26222f0efc Change: correct date and time formats for Traditional Chinese language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Asia#Greater_China
2025-03-17 23:38:17 +01:00
Heiko August
11744f257e Change: correct date and time formats for Croatian language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Croatia
2025-03-17 23:38:17 +01:00
Heiko August
fbdc08d133 Change: enclosing the date and time format schemes in Danish language with single quotes
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Denmark
2025-03-17 23:38:17 +01:00
Heiko August
5e2f007ed5 Change: add correct date and tme formats to French language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_France
2025-03-17 23:38:17 +01:00
Heiko August
fafdf876f8 Change: enclose German language date and time schemes in single quotes 2025-03-17 23:38:17 +01:00
Heiko August
e2499bb981 Change: add the correct date and time format for Italian language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Italy
2025-03-17 23:38:17 +01:00
Heiko August
b5d9b7cc15 Change: enclose date and time formatting schemes and correct short date for Norwegian language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Norway
2025-03-17 23:38:17 +01:00
Heiko August
bd0d5d3cda Change: correct date and time format for Russian language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Russia
2025-03-17 23:38:17 +01:00
Heiko August
96bac06cf6 Change: enclose date and time formatting schemes for Spanish language
Check also https://en.wikipedia.org/wiki/Date_and_time_notation_in_Spain
2025-03-17 23:38:17 +01:00
Heiko August
ccfcfc4232 Change: add the correct date and time format to Swedish language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Sweden
2025-03-17 23:38:17 +01:00
Heiko August
5159c8b8e0 Change: Tamil tome format is unknown to me, add am/pm to 12h-time format 2025-03-17 23:38:17 +01:00
Heiko August
3010ed8c42 Change: add the correct date and time format to the Turkish language
According to https://en.wikipedia.org/wiki/Date_and_time_notation_in_Turkey
2025-03-17 23:38:17 +01:00
Heiko August
59967e28e0 Fix: add am/pm to the date format definition for English language 2025-03-17 23:38:17 +01:00
Michael Lösler
b64c634090
Blank (#802)
- no-break space added to the checkbox elements data_privacy_agreement and terms_of_use_agree  so that the boxes match show_signature and email_notification
2025-03-12 20:27:03 +01:00
Heiko August
a333233418 Change: add a furter level of indentation 2025-03-12 18:29:01 +01:00
Heiko August
065435d1dd Change: replace class .small with .normalform, this increases the font size a bit 2025-03-12 18:29:01 +01:00
Heiko August
82b57f2f40 Change: move the link to the password-forgotten form to the buttonbar of the login form 2025-03-12 18:29:01 +01:00
Heiko August
9f798aae51 Change: add a link to the login to the registration form 2025-03-12 18:29:01 +01:00
Heiko August
db08605c3e Change: add class .buttonbar to the divs containing the form button(s) and link(s) 2025-03-12 18:29:01 +01:00
Heiko August
0b51685ac2 Change: move the explanations for logging in and registering into the card to its top 2025-03-12 18:29:01 +01:00
Heiko August
a8a313170b Change: add #card around the forms to make them appear similar 2025-03-12 18:29:01 +01:00
Heiko August
9c04c5f971 Fix: add the attributes autofocus and required to the e-mail input field 2025-03-12 16:55:24 +01:00
Heiko August
d6525285a2 Fix: change the type of the input field from "text" to "email" 2025-03-12 16:55:24 +01:00
Heiko August
feec4b7160 Fix: correct a spelling mistake that distorts the meaning (reaktiviert versus deaktiviert) 2025-03-12 16:31:29 +01:00
Heiko August
87eadebd85 Fix: use the correct column name for searching for the images database entry 2025-03-11 20:00:09 +01:00
Heiko August
e8c48891ad Fix: mark an image as not managed also if there is no entry in the uploads table …
… not only if there are entries but not for the current image.
2025-03-11 20:00:09 +01:00
Heiko August
6541b2bf5b Change: make mlf2_entries.pid, .tid, .category and .views unsigned in the installation and upgrade script 2025-03-10 21:53:46 +01:00
Heiko August
b98c007113 Change: add the changes to unsigned integer columns to the upgrade block for version 20241215.1 2025-03-10 21:53:46 +01:00
Heiko August
3442d08140 Change: add a foreign key that points to mlf2_userdata.user_id when altering the table mlf2_uploads 2025-03-10 21:53:46 +01:00
Heiko August
5f35c9d8b5 Change: add a foreign key that points to mlf2_userdata.user_id when creating the table mlf2_uploads
If a user gets deleted, the matching value in the column "uploader" automatically will be changed to NULL.
2025-03-10 21:53:46 +01:00
Heiko August
a30c0df76c Change: determine the table name prefix for all upgrade cases at once 2025-03-10 21:53:46 +01:00
Heiko August
dbfc617615 Change: add line to set the table prefix into constraint names
Those are necessary in example for foreign keys. We prefix Constraint names with "smbl_" followed by the table prefix to make them unique in the database.
2025-03-10 21:53:46 +01:00
Heiko August
bcf3781022 Change: add a bottom/end margin to the image list 2025-03-10 21:53:46 +01:00
Heiko August
a2d0ee16a9 Fix: always display the filter form, not only with displayed images 2025-03-10 21:53:46 +01:00
Heiko August
a942b95763 Fix: use the altered column name pathname instead the obsolete filename 2025-03-10 21:53:46 +01:00
Heiko August
4b9692666e Change: mark MLF version 20241215.1 to be an upgrade target 2025-03-10 21:53:46 +01:00
Heiko August
7dd2b3af0a Change: add the files to update when upgrading from version 20241215.1 2025-03-10 21:53:46 +01:00
Heiko August
783658994b Fix: remove the alter statement
It only repeats the charset conversion from the CREATE statement in the same upgrade step
2025-03-10 21:53:46 +01:00
Heiko August
1b30324722 Change: adapt the changes in the uploads table to the installation and the other upgrade steps 2025-03-10 21:53:46 +01:00
Heiko August
5c1366668f Fix: it makes no sense to allow NULL values if the column gets a unique index afterwards 2025-03-10 21:53:46 +01:00
Heiko August
d6ca049f5e Change: alter the uploads table when updating MLF 20241215.1
- delete duplicate file name entries (keep first entry)
- enlarge the column filename and rename it to pathname
- add unique index pathname to column pathname, if it not exists
2025-03-10 21:53:46 +01:00
Heiko August
1b295cf13b Change: new structure for updating MLF version 20241215.1 2025-03-10 21:53:46 +01:00
Heiko August
1b47cb6af4 Change: add the new styles also to style.css 2025-03-10 21:53:46 +01:00
Heiko August
b9de68d59c Change: add the filter to the management form if present and use it in the redirect afterwards 2025-03-10 21:53:46 +01:00
Heiko August
8e1f1a13b6 Change: offer the filter value to smarty and use it in the paginations 2025-03-10 21:53:46 +01:00
Heiko August
75560da8e6 Change: move the filter form method from POST to GET 2025-03-10 21:53:46 +01:00
Heiko August
b671e25f0c Change: server side of the filter mechanism for managing uploaded images 2025-03-10 21:53:46 +01:00
Heiko August
4f0d3c2fd0 Change: UI for filtering of uploads according to whether they already have a database entry or not 2025-03-10 21:53:46 +01:00
Heiko August
cb903ec37f Cleanup: another code style thingamabop 2025-03-10 21:53:46 +01:00
Heiko August
a3149deb8d Fix: if we find no user-ID set the ID as Null but do it as string while in PHP
The query including the word NULL is a string in PHP and NULL will only become a boolean when executing the query on the database server.
2025-03-10 21:53:46 +01:00
Heiko August
b4f623ae44 Cleanup: code style thingamabop 2025-03-10 21:53:46 +01:00
Heiko August
cc72db8d29 Change: redirect to the uploads list at the end of the recording 2025-03-10 21:53:46 +01:00
Heiko August
d786396836 Change: delete the database entry for the image before deleting it from the file system 2025-03-10 21:53:46 +01:00
Heiko August
e2108444aa Cleanup: remove obsolete array variable $unlisted 2025-03-10 21:53:46 +01:00
Heiko August
ecc1e640e9 Change: resize mlf2_uploads.filename from 64 to 128 bytes, add a unique key to the column 2025-03-10 21:53:46 +01:00
Heiko August
4eee73dfc3 Change: put the values blocks into the query to generate database entries and run the query 2025-03-10 21:53:46 +01:00
Heiko August
5e3b26bcb1 Change: reintroduce $rec_row and generate the values block of one image for the query 2025-03-10 21:53:46 +01:00
Heiko August
2e9f149c82 Change: move the code for generating database entries for images in front of the block for listing the uploaded images 2025-03-10 21:53:46 +01:00
Heiko August
247c414eb5 Change: move the code for deleting uploaded images in front of the block for displaying the uploaded images 2025-03-10 21:53:46 +01:00
Heiko August
9dc11cfa84 Change: remove testing code of the development stage 2025-03-10 21:53:46 +01:00
Heiko August
805ca07d46 Change: add the block for generating upload entries in database and determine the uploader if registered 2025-03-10 21:53:46 +01:00
Heiko August
22cf1f6c7c Change: add a button to call the function to add database entries for unmanaged uploaded images 2025-03-10 21:53:46 +01:00
Heiko August
e71f90ddd4 Change: add icons to show if there is a database entry for an uploaded image 2025-03-10 21:53:46 +01:00
Heiko August
574e09bc62 Change: formatting thingamabob for unified displaying of the variable initialisation 2025-03-10 21:53:46 +01:00
Heiko August
94b492c968 Change: join the initialisation of the variables into one section 2025-03-10 21:53:46 +01:00
Heiko August
b40bac6ada Change: add the status to the array elements of an entry in $image 2025-03-10 21:53:46 +01:00
Heiko August
f957b60365 Change: make mlf2_useronline.user_id unsigned in the installation and upgrade scripts 2025-03-10 20:51:38 +01:00
Heiko August
15b89b3ece Change: make mlf2_tags.id unsigned in the installation and upgrade scripts 2025-03-10 20:51:38 +01:00
Heiko August
e6df1416a4 Change: make mlf2_smilies.id unsigned in the installation and upgrade scripts 2025-03-10 20:51:38 +01:00
Heiko August
5230c55f9c Change: make mlf2_pages.id unsigned in the installation and upgrade scripts 2025-03-10 20:51:38 +01:00
Heiko August
a62336c381 Change: make mlf2_categories.id unsigned in the installation and upgrade scripts 2025-03-10 20:51:38 +01:00
Heiko August
26d0db86dc Change: make mlf2_bookmarks.id, .user_id and .posting_id unsigned in the installation and upgrade scripts 2025-03-10 20:51:38 +01:00
Heiko August
a8e22e937c Change: make mlf2_entries.id, .edited_by and .user_id unsigned in the installation and upgrade scripts 2025-03-10 20:51:38 +01:00
Heiko August
e305782f72 Change: make mlf2_userdata.user_id unsigned in the installation and upgrade scripts
Attention: When upgrading from 2.4.x it must be done before creating the new tables.
2025-03-10 20:51:38 +01:00
Michael Lösler
05bedc1c25
Permission (#795)
- Depending on the user type, the view of the thread list is restricted, #794
- https://mylittleforum.net/forum/index.php?id=18870
2025-03-05 21:58:41 +01:00
Michael Lösler
d17f2542b9 Update main.min.js
This is just a new compressed version of the main.js (using https://www.toptal.com/developers/javascript-minifier).
2025-02-17 20:31:35 +01:00
Heiko August
1b6f4f7892 Change: remove the function setFocusToContentForm and its call in main.min.js 2025-02-17 20:31:35 +01:00
Heiko August
56a1be1287 Change: remove the JS-function setFocusToContentForm
There is the HTML-attribute autofocus nowadays.
2025-02-17 20:31:35 +01:00
Michael Lösler
00a2a07198
Remove function setDefaultInputValue (#792)
- function `setDefaultInputValue` removed as proposed in #791
2025-02-15 14:56:38 +01:00
Heiko August
875577a7e3 Fix: add missing strings to the Arabic translation
Those was untranslated because of the non existing arabic translation at the time of adding them to the other languages.
2025-01-13 22:09:04 +01:00
Heiko August
d158bf8fca Fix: the value of the checkbox has to be the path/filename, not the counter 2025-01-13 21:50:12 +01:00
Heiko August
51ffcb6410 Fix: move the counter only when an image was found 2025-01-13 21:39:18 +01:00
Heiko August
625b2d0cf8 Change: replace the submit-input with a button 2025-01-13 21:39:18 +01:00
Heiko August
f45d811f02 Change: repurpose the managing checkbox, adapt the variable name, add a counter to the image array 2025-01-13 21:39:18 +01:00
Heiko August
a4d33000ce Change: the management container should be a list, not a paragraph 2025-01-13 21:39:18 +01:00
Heiko August
97d81f95ce Change: first attempt to display a list unrecorded uploads 2025-01-13 21:39:18 +01:00
Heiko August
4cd51a114c Change: add strings for the UI to check for uploads, missing in the uploads 2025-01-13 21:39:18 +01:00
Heiko August
e38de7753c Change: reformat the category options list to be more clearly arranged 2025-01-09 21:37:19 +01:00
Heiko August
b2b508d08c Fix: display the content of user.homepage and user.email as alternative text
A section thread_entry does not exist in the language files.
2025-01-09 21:37:19 +01:00
Heiko August
f35a60fed5 Fix: provide date and time of a posting in a time element in the posting preview 2025-01-09 21:37:19 +01:00
Heiko August
5626becae7 Fix: syntax error in the HTML-code in div.wrapper of the preview 2025-01-09 21:37:19 +01:00
Michael Lösler
9916a2729c
Access v2.0 (#785)
- depending on the forum settings, access to the user area is restricted
- https://mylittleforum.net/forum/index.php?id=18808
- (more) corrected version of #783
2024-12-30 20:22:35 +01:00
Michael Lösler
24f8b677cf
Revert "Access (#783)" (#784)
This reverts commit 9452c2fe0f.
2024-12-30 20:10:13 +01:00
Michael Lösler
9452c2fe0f
Access (#783)
- depending on the forum settings, access to the user area is restricted
- if-condition removed, which is fulfilled in every case (by surrounding global if-condition)
- https://mylittleforum.net/forum/index.php?id=18808
2024-12-30 11:51:06 +01:00
Heiko August
762f3acad3 Change: remove selectors with empty blocks which are not present in style.min.css 2024-12-29 18:04:12 +01:00
Heiko August
7221027151 Change: add missing spaces between properties and their values 2024-12-29 18:04:12 +01:00
Heiko August
e85d0147d6 Change: reformat style.css, one selector per line 2024-12-29 18:04:12 +01:00
Heiko August
8a23bea227 Change: reformat style.css, one property per line 2024-12-29 18:04:12 +01:00
Heiko August
a247742b84 Change: repeat the changes of style.min.css in style.css 2024-12-28 13:33:55 +01:00
Michael Lösler
a7877adace Toggle icon removed
- tiny toggle icon for the sidebar removed in table view
2024-12-28 13:33:55 +01:00
Michael Lösler
4c9cd99a95 JavaScript-Minification
- minificated/compressed version added (https://www.toptal.com/developers/javascript-minifier)
2024-12-28 13:33:55 +01:00
Heiko August
01e834eaed Change: small adjustments for the positions of the icon and the link text 2024-12-28 13:33:55 +01:00
Heiko August
f290498d47 Change: new icons for the sidebar toggle for narrow and wide viewports 2024-12-28 13:33:55 +01:00
Heiko August
1253769da2 Change: unitless line height, padding "0" and font weight "bold" for h2 in the sidebar 2024-12-28 13:33:55 +01:00
Heiko August
77927ea6e9 Change: replace the loop over the link collection with code for the one specific link 2024-12-28 13:33:55 +01:00
Heiko August
a2ce83f8f4 Change: remove variable icon for the removed toggle icon 2024-12-28 13:33:55 +01:00
Heiko August
f29d015dd1 Change: replace keyword var with const 2024-12-28 13:33:55 +01:00
Heiko August
75a97d9499 Change: remove the tiny toggle icon for the sidebar 2024-12-28 13:33:55 +01:00
Heiko August
7e9371323c Fix: configure the MySQL error reporting 2024-12-22 14:24:54 +01:00
Heiko August
a5704d99b9 Fix: use the exception object to display MySQL error information 2024-12-22 14:24:54 +01:00
Heiko August
ec0ea66e2c Change: add the changelogfor version 20241215.1 2024-12-15 23:01:28 +01:00
Heiko August
4e07a27020 Change: add the new version number to the files index.php and config/VERSION 2024-12-15 23:01:28 +01:00
Heiko August
7f21bc79ff Fix: correct the name of the language key for the reenabling-forum message 2024-12-15 23:01:28 +01:00
Heiko August
47e146061c Change: add the version 20240827.1 to the list of upgradable versions 2024-12-15 23:01:28 +01:00
Heiko August
8263af3bf2 Change: add date handling with NULL values to the upgrade blocks for 20240729.1 and 20240827.1
There was errors in some cases. This steps excludes the last error possibilities
2024-12-15 23:01:28 +01:00
Heiko August
b8640b3615 Change<. adapt the entries for files ti upgrade to the blocks for the previous versions 2024-12-15 23:01:28 +01:00
Heiko August
794a8470a3 Change: add the block for upgrading from version 20240827.1 2024-12-15 23:01:28 +01:00
Heiko August
3151626297 Fix: comparison of posting time and registration time was the wrong way round (> versus <) 2024-12-13 17:55:46 +01:00
Heiko August
54cfd3ae3e Change: provide only a Unix timestamp and let MySQL do the datetime magic
This makes it unnecessary to add an additional test for $posting_time being a proper formatted datetime value.
2024-12-13 17:55:46 +01:00
Heiko August
94eb3d8db8 Change: add a second clause in where to take into account the date of the posting in the check for a user name collision 2024-12-13 17:55:46 +01:00
Heiko August
c238f822bb Change: generate $posting_time with the current time for a new and initial saving time of a posting for an edited posting 2024-12-13 17:55:46 +01:00
Heiko August
0d988fb66c Fix: remove the type attribute from the script element, text/javascript is already the default value 2024-12-10 21:25:37 +01:00
Heiko August
570d6b7650 Cleanup: remove the empty line between style and script elements in the avatar template 2024-12-10 21:25:37 +01:00
Heiko August
3fb9541b87 Fix: remove the unnecessary comment markers from the style element 2024-12-10 21:25:37 +01:00
Heiko August
7b369f1708 Changr: add the close window button also to the upload form …
… and make it invisible when submitting the image to upload.
2024-12-10 21:01:55 +01:00
Heiko August
7ed5491bfb Change: add JS and CSS code to make the spinning "throbber" gif visible 2024-12-10 21:01:55 +01:00
Heiko August
5fd65373fc Change: make the rules for the image upload template and the avatar template equal 2024-12-10 21:01:55 +01:00
Heiko August
3bcc4ab511 Change: remove CSS-rules for .delete and its children, element was removed 2024-12-10 21:01:55 +01:00
Heiko August
06b9ab308e Change: set margin-block for p.instruction and p.small 2024-12-10 21:01:55 +01:00
Heiko August
af4f3d7848 Change: set the font size for p.instruction to 0.82em 2024-12-10 21:01:55 +01:00
Heiko August
d2903cb71e Cleanup: remove the empty {literal} at the end of the JS-script block 2024-12-10 21:01:55 +01:00
Heiko August
b218f96bce Change: styling of system message headings (h2) 2024-12-10 21:01:55 +01:00
Heiko August
3968216730 Change: rewrite the JS-code to close the popup window with a button 2024-12-10 21:01:55 +01:00
Heiko August
d1f3f21089 Change: rename setPictureToProfil to setPictureToProfile and reformat the code 2024-12-10 21:01:55 +01:00
Heiko August
3affd55e55 Change: formatting of lists, especially the one item list to display the avatar image 2024-12-10 21:01:55 +01:00
Heiko August
00fe9979dc Change: formatting of the main form elements 2024-12-10 21:01:55 +01:00
Heiko August
a0da7ed990 Change: replace the partially JS generated steering elements for viewing a present avatar with form buttons 2024-12-10 21:01:55 +01:00
Heiko August
4df17d0a30 Change: add styling of the elements header and main 2024-12-10 21:01:55 +01:00
Heiko August
38d1f24ffb Change: reformatting of image displaying and the downsizing message 2024-12-10 21:01:55 +01:00
Heiko August
49588649cf Change: add element main to the default view of an existing or just uploaded avatar 2024-12-10 21:01:55 +01:00
Heiko August
785c95d98d Change: add class .instruction for the paragraph, naming the requirements 2024-12-10 21:01:55 +01:00
Heiko August
e2b33f6b1c Change: reformatting of the upload success section 2024-12-10 21:01:55 +01:00
Heiko August
315b7f1a2a Change: reformatting of the upload error section 2024-12-10 21:01:55 +01:00
Heiko August
b0e1f4acb7 Change: put the heading for showing or deleting the uploaded avatar image into element header 2024-12-10 21:01:55 +01:00
Heiko August
80f3317dbc Change: put the heading (h1) for the upload form into a header element 2024-12-10 21:01:55 +01:00
Heiko August
0686c7280d Change: reformatting the upload avatar form to use the same structure as the upload image form 2024-12-10 21:01:55 +01:00
Heiko August
2903f0309a Change: reformatting the HTML-source of the message block in case of disabled feature 2024-12-10 21:01:55 +01:00
Heiko August
50f376f72d Change: apply the properties for a:hover also to a:focus 2024-12-10 21:01:55 +01:00
Heiko August
45e1d8a427 Change: use the same values for link properties as in the upload image template 2024-12-10 21:01:55 +01:00
Heiko August
9bb8e12316 Change: unify the properties of a:link and a:visited into a, use shorthand for text colour 2024-12-10 21:01:55 +01:00
Heiko August
ad9e67f5d7 Change: remove obsolete line height definition from .small 2024-12-10 21:01:55 +01:00
Heiko August
f48068a975 Change: adjust the font size to the same value as in the image upload form 2024-12-10 21:01:55 +01:00
Heiko August
cfd56463a6 Change: adjust the text color for message boxes 2024-12-10 21:01:55 +01:00
Heiko August
6dad642fa7 Change: restructure the CSS properties for message boxes 2024-12-10 21:01:55 +01:00
Heiko August
cec62006a3 Change: apply the same rules for h1 as in the template for image upload 2024-12-10 21:01:55 +01:00
Heiko August
24817297dc Change: apply the box model border-box to all elements of the document 2024-12-10 21:01:55 +01:00
Heiko August
80c4bb0d2e Change: remove redundant rules, those are already defined for body 2024-12-10 21:01:55 +01:00
Heiko August
73d2033acf Change use shorthands, relative units and same values like for the upload image template 2024-12-10 21:01:55 +01:00
Heiko August
be43c2f1d5 Change: reformatting of the CSS properties without any functional change 2024-12-10 21:01:55 +01:00
Heiko August
d211dde44b Change: remove the CDATA-comments 2024-12-10 21:01:55 +01:00
Heiko August
6c09ebf7c8 Change: reorder the positions of the Smarty-tags {literal} and {/literal} 2024-12-10 21:01:55 +01:00
Heiko August
c705139cae Change: formatting of #imgtab list items as flexboxes 2024-12-08 22:49:46 +01:00
Heiko August
4b749ffd09 Change: give the list #imgtab a minimal and maximal width and center it 2024-12-08 22:49:46 +01:00
Heiko August
bfc48ae4bb Change: use unobstrusive JS to fade in the spinning 'throbber' image 2024-12-08 22:49:46 +01:00
Heiko August
f328c30466 Change: reformatting of the return on invalid state orders 2024-12-08 22:49:46 +01:00
Heiko August
535d06b6f5 Cleanup: remove comment markers from the style block, that's an completely outdated techique 2024-12-08 22:49:46 +01:00
Heiko August
32e7b2482b Change: formatting of the insert image description elements 2024-12-08 22:49:46 +01:00
Heiko August
c9ee28e9a7 Change: add text-decoration to a:active for better visibility
and a bit of experimenting with the sub features of text-decoration.
2024-12-08 22:49:46 +01:00
Heiko August
c205022b7b Change: use the shorthand notation for link text colours 2024-12-08 22:49:46 +01:00
Heiko August
e6468df376 Change: summarise the rules for a:link and a:visited into a 2024-12-08 22:49:46 +01:00
Heiko August
8a239c6795 Change: apply CSS-rules for a:hover also to a:focus 2024-12-08 22:49:46 +01:00
Heiko August
515e1d3c66 Change: reformatting of the CSS rules for links (elements a) 2024-12-08 22:49:46 +01:00
Heiko August
fbc0ece19e Change: replace elements div#header with header elements 2024-12-08 22:49:46 +01:00
Heiko August
4d47314177 Change: replace elements div#wrapper with main elements 2024-12-08 22:49:46 +01:00
Heiko August
e3ef91d4f2 Change: display all visible elements centered in the form #del-upload-form 2024-12-08 22:49:46 +01:00
Heiko August
59ae06121f Change: adjust the position of the cross in .deletelink to match better the new font size definition 2024-12-08 22:49:46 +01:00
Heiko August
b3993b723f Change: use the same font size for .insert-desc and .deletelink as for .small 2024-12-08 22:49:46 +01:00
Heiko August
090214af03 Change: use a slightly smaller font size for .small 2024-12-08 22:49:46 +01:00
Heiko August
2a97654a34 Change: formulate the selector less specific to applying not only to divs 2024-12-08 22:49:46 +01:00
Heiko August
86cb084a76 Change: show buttons without background and border when inside #imgtab and containing an image 2024-12-08 22:49:46 +01:00
Heiko August
13759ed784 change: show the cursor as hand when hovering a button 2024-12-08 22:49:46 +01:00
Heiko August
1bc42f6c9d Change: run the function insertCode when finding clicked buttons in ul#imgtab 2024-12-08 22:49:46 +01:00
Heiko August
7dd0876009 Change: rewrite JS-function insertCode for general use with buttons around the images 2024-12-08 22:49:46 +01:00
Heiko August
c426105c52 Change: remove the type attribute because "text/javascript" already is the default value 2024-12-08 22:49:46 +01:00
Heiko August
4bacdf1dc3 Change: remove the code enclosing CDATA comment
It's not necessary in HTML(5).
2024-12-08 22:49:46 +01:00
Heiko August
74489dda22 Change: remove the JS inline code to insert the just now uploaded image 2024-12-08 22:49:46 +01:00
Heiko August
f59caf585a Change: add the link to the uploaded image gallery also to the upload success view 2024-12-08 22:49:46 +01:00
Heiko August
97a75fb03e Change: reformatting of the downsizing notice 2024-12-08 22:49:46 +01:00
Heiko August
3afcf7e368 Change: replace the non-JS insert image instruction with the JS one 2024-12-08 22:49:46 +01:00
Heiko August
7f4543f0dc Change: add insert image instruction also to the image browsing view 2024-12-08 22:49:46 +01:00
Heiko August
5c1b529076 Change: rewrite the insert image instruction for an uploaded image without inline JS 2024-12-08 22:49:46 +01:00
Heiko August
4391964824 Change: put the images into button if they should be clickable, remove JS-code 2024-12-08 22:49:46 +01:00
Heiko August
3146ca0452 Change: rename the ids of the upload and the delete image forms for distinction 2024-12-08 22:49:46 +01:00
Heiko August
ed4373f95a Change: reformatting of the image upload from 2024-12-08 22:49:46 +01:00
Heiko August
6ffd766094 Change: reformatting of the HTML-source of the information about no present uploaded images 2024-12-08 22:49:46 +01:00
Heiko August
5b93a3ca3c Change: reformatting of the HTML-source of the deleting confirmation form 2024-12-08 22:49:46 +01:00
Heiko August
2c460eb5b0 Cleanup: remove unnecessary CSS-rules 2024-12-08 22:49:46 +01:00
Heiko August
c1fc1b4a71 Change: reformatting of the properties of elements with class .deletelink 2024-12-08 22:49:46 +01:00
Heiko August
3aa680981c Fix: add missing font family monospace 2024-12-08 22:49:46 +01:00
Heiko August
eefcbed5eb Change: reformatting of the properties for the element code 2024-12-08 22:49:46 +01:00
Heiko August
85f5a58d3c Change: make the cursor a pointer only in the upload galery but not …
… in the views of newly uploaded images and for image deleting confirmation.
2024-12-08 22:49:46 +01:00
Heiko August
0210f1cec0 Change: move the centering of images from img to #imgtab img 2024-12-08 22:49:46 +01:00
Heiko August
9e4c2d9e00 Change: formatting of the upload form similar to the rest of the MLF-forms 2024-12-08 22:49:46 +01:00
Heiko August
4f0bae3be4 Change: replace pixel-based value for font size with an em-based value 2024-12-08 22:49:46 +01:00
Heiko August
3cabe244b9 Change: remove redundant line-height, is already defined for body 2024-12-08 22:49:46 +01:00
Heiko August
3053a8f8c6 Change: reformatting of the properties of elements with class .small 2024-12-08 22:49:46 +01:00
Heiko August
2699f7b9e8 Change: remove the now obsolete class .browse
The CSS-rules was applied to img and #imgtab img instead
2024-12-08 22:49:46 +01:00
Heiko August
b5f47f1cf1 Change: reuse the code for the image galery with a shrinked image size 2024-12-08 22:49:46 +01:00
Heiko August
aa322fcb12 Change: rework the galery of uploaded images
- replace the table with a list
- add CSS-rules to set the size of the images without JavaScript
- remove the now obsolete JS-function getMaxWidth
2024-12-08 22:49:46 +01:00
Heiko August
9d4a57f6dd Change: fix the page header in all possible views 2024-12-08 22:49:46 +01:00
Heiko August
c01ed5a4f7 Change: reformatting of the already existing div#header 2024-12-08 22:49:46 +01:00
Heiko August
5d8a9ac52f Change: add div#header where it has been missing, put h1 into div#header 2024-12-08 22:49:46 +01:00
Heiko August
b8f03a249d Change: reformatting of div#wrapper, adding it, where it's missing 2024-12-08 22:49:46 +01:00
Heiko August
cb89119ef4 Change: restructuring of error and success messages
Put the messages into dedicated divs with a heading (h2) and their optional additional text into the matching elements.
2024-12-08 22:49:46 +01:00
Heiko August
7a0c228d4f Change: reduce the font size for h1 2024-12-08 22:49:46 +01:00
Heiko August
168e50ad69 Change: set box-sizing: border-box for all elements 2024-12-08 22:49:46 +01:00
Heiko August
5f8e739bc8 Change: join identical properties and values for .ok and .caution into one block 2024-12-08 22:49:46 +01:00
Heiko August
c4aa95a138 Change: green text colour for .ok, darker red for .caution 2024-12-08 22:49:46 +01:00
Heiko August
1848a10237 Change. remove the separate formatting for #wrapper
… use the default page settings for all direct childs of body instead
2024-12-08 22:49:46 +01:00
Heiko August
bf013f7f18 Change: reformatting of the properties for .caution and .ok 2024-12-08 22:49:46 +01:00
Heiko August
1dd05148d1 Change: remove definitions for element p because everything necessary is set elsewhere 2024-12-08 22:49:46 +01:00
Heiko August
c6dab07b51 Change: remove font-family because of redundance, set size in unit em instead of px 2024-12-08 22:49:46 +01:00
Heiko August
8c1ae75f23 Change: reformatting of the CSS properties for the elements h1 2024-12-08 22:49:46 +01:00
Heiko August
8b4dfa83db Change: replace the float contruction for the childs of #header with a flexbox 2024-12-08 22:49:46 +01:00
Heiko August
455f08a257 Change: remove font size definition because they only repeats the properties of body 2024-12-08 22:49:46 +01:00
Heiko August
6c71b95e0f Change: reformatting of the CSS-properties of the element #header 2024-12-08 22:49:46 +01:00
Heiko August
834bc48589 Change: redefinition of the font size for the document 2024-12-08 22:49:46 +01:00
Heiko August
7883477ab6 Change: reformatting of the CSS-properties for element body 2024-12-08 22:49:46 +01:00
Michael Lösler
a30281839a
User id (#771)
- check whether the user id is present in the session array to avoid incomplete queries
- add mysqli_real_escape_string for security reasons
- details: https://mylittleforum.net/forum/index.php?id=18760
2024-12-01 11:07:49 +01:00
Heiko August
3c5992e26d
Make WebP images appear in the uploaded-images browsing view (#769)
* Fix: add webp and svg to file types and collect all file types in one regex

* Change: allow file ending .jpeg also in the uploads listing of the admin area
2024-11-27 22:41:11 +01:00
Michael Lösler
7c578c3c7a
File filter (#768)
- WEBP file extension added, cf. #766
2024-11-27 21:45:15 +01:00
Michael Lösler
cfde25b39e
ISO-timestamps (#767)
According to #758, #761 timestamps should be formatted by HTML time elements, but entry date and edit date are still not formatted correctly. Time element is added to thread-view and linear thread-view as well as table-view.
2024-11-27 21:34:16 +01:00
Michael Lösler
3b54474b2a
Code cleaning (#765)
- redundant code parts reduced
2024-11-26 23:03:09 +01:00
Michael Lösler
1fd5a0aec4
Scope of statement (#764)
- Change scope of ‘$pid_result_sql’ statement to be available in conditions
2024-11-26 17:44:07 +01:00
Michael Lösler
ef576dba70
eid vs. id in SQL stmt (#763)
- SQL statement corrected as reported and analysed by https://mylittleforum.net/forum/index.php?id=18724 , i.e. `eid` vs. `id`
- To avoid side effects with entry.inc.php, where `$spam_sql_and` is also used, the column `eid` is renamed in the stmt by `id`
2024-11-26 10:25:11 +01:00
Michael Lösler
a812ecca3e
Date (#762)
- WHERE clause `= '0000-00-00 00:00:00'` replaced by `<= STR_TO_DATE('1900-01-01','%Y-%d-%m')`
2024-11-25 21:39:47 +01:00
Michael Lösler
f0063b73ea
ISO-timestamps (#761)
According to #758, timestamps should be formatted by HTML time elements, but entry date and edit date are still not formatted correctly
2024-11-24 13:33:23 +01:00
Heiko August
49401587cc Change: some formatting foo in the avatar template 2024-11-19 22:46:01 +01:00
Heiko August
736f0ad4a0 Change: add the meta element viewport which makes the document responsive in a mobile device (avatar.tpl) 2024-11-19 22:46:01 +01:00
Heiko August
5bc23c35bf Change: set the documents charset according to the rules of HTML 5 (avatar.tpl) 2024-11-19 22:46:01 +01:00
Heiko August
f14371ac36 Change: move the HTML from XHTML 1.0 strict to HTML 5 (avatar.tpl) 2024-11-19 22:46:01 +01:00
Heiko August
cfc8076b23 Change: some formatting foo in the upload template 2024-11-19 22:46:01 +01:00
Heiko August
eb73b75194 Change: add the meta element viewport which makes the document responsive in a mobile device 2024-11-19 22:46:01 +01:00
Heiko August
0015525048 Change: set the documents charset according to the rules of HTML 5 2024-11-19 22:46:01 +01:00
Heiko August
18298d3131 Change: move the HTML from XHTML 1.0 strict to HTML 5
This commit affects naming the doctype and the remving of the XML namespace and the naming of the document language according to the rules of HTML 5
2024-11-19 22:46:01 +01:00
Heiko August
fa89d768f2 Fix: add the time element and the ISO-formatted timestamp to the flag ham page 2024-11-19 22:09:00 +01:00
Heiko August
6d9ab8d3f5 Fix: add the ISO-formatted timestamp to the time element in the report spam page 2024-11-19 22:09:00 +01:00
Heiko August
9eb86358ae Fix: add the rules of the previous two commits to style.css 2024-11-19 21:31:08 +01:00
Heiko August
eafa51b6e3 Fix: add forgotten CSS-rule for links in a buttonbar 2024-11-19 21:31:08 +01:00
Heiko August
5160e13e8f Fix: add forgotten styling rule for labels of class "main" 2024-11-19 21:31:08 +01:00
Heiko August
003f3150a3 Change: general reformatting of the posting form template 2024-11-17 23:37:05 +01:00
Heiko August
43b2e87f1c Change: remove tabindex, because it caused weird tab order 2024-11-17 23:37:05 +01:00
Heiko August
c9bef69929 Change: code indentation in the search form template 2024-11-17 23:37:05 +01:00
Heiko August
e6116134c7 Change: labels for the search term field and the category selection 2024-11-17 23:37:05 +01:00
Heiko August
70c857c379 Change: put the search selection on top of the submit button 2024-11-17 23:37:05 +01:00
Heiko August
e73b8b0d46 Change: reformatting a few form templates 2024-11-17 23:37:05 +01:00
Heiko August
d1457f2105 Change: attribute required for contact form fields 2024-11-17 23:37:05 +01:00
Heiko August
06a7c1dec5 Change: add attribute required to the author name and subject fields 2024-11-17 23:37:05 +01:00
Heiko August
187e1f6f24 Change: add attribute required to the input fields in the login form 2024-11-17 23:37:05 +01:00
Heiko August
f7c370a653 Change: reformat several forms 2024-11-17 23:37:05 +01:00
Heiko August
22f17d797c Change: set input type to email for the senders e-mail address 2024-11-17 23:37:05 +01:00
Heiko August
a1c375a7f7 Change: replace input type submit/reset with buttons in several forms 2024-11-17 23:37:05 +01:00
Heiko August
c19e421ac7 Change: set type number for inputs, reformatting 2024-11-17 23:37:05 +01:00
Heiko August
d5811d5b76 Change: replace input type submit with button 2024-11-17 23:37:05 +01:00
Heiko August
5adcb0002b Change: reformat templates for flagging postings as spam or ham 2024-11-17 23:37:05 +01:00
Heiko August
56b8ccb8d1 Change: remove inactive, commented code 2024-11-17 23:37:05 +01:00
Heiko August
45a6512fc7 Change: matching input types for homepage url and birthday date 2024-11-17 23:37:05 +01:00
Heiko August
e3eebaf41e Cleanup: further corrections of HTML-code indentation 2024-11-17 23:37:05 +01:00
Heiko August
ca60c3c740 Change: replace input of type submit with a button 2024-11-17 23:37:05 +01:00
Heiko August
dabc7f84e4 Cleanup: remove the attribute tabindex because the values are reflecting only the natural order of the inputs 2024-11-17 23:37:05 +01:00
Heiko August
927859a476 Change: add proper types in the input fields, new attributes autofocus, required 2024-11-17 23:37:05 +01:00
Heiko August
2d5f33812d Cleanup: reformat email edit form 2024-11-17 23:37:05 +01:00
Heiko August
37c5d14438 Change: replace input submit with a button 2024-11-17 23:37:05 +01:00
Heiko August
2927fc931d Change: new attribute required for the password field
Replace the enclosing paragraph with div
2024-11-17 23:37:05 +01:00
Heiko August
9a74cb8a35 Change: set type "email" for the input fields, New atttributes: autofocus, required
Replace the enclosing paragraphs with divs
2024-11-17 23:37:05 +01:00
Heiko August
cfcfe75fcf Cleanup: code nesting, forgotten div 2024-11-17 23:37:05 +01:00
Heiko August
d4787abb71 Change: replace the strong element with a label for the new password field
New attribute: required
2024-11-17 23:37:05 +01:00
Heiko August
b82979798d Change: replace the strong element with a label for the old password field
New attributes: autofocus, required
2024-11-17 23:37:05 +01:00
Heiko August
dca2018056 Change: remove form elements enclosing div 2024-11-17 23:37:05 +01:00
Heiko August
42774f9183 Change: button to submit the password edit form 2024-11-17 23:37:05 +01:00
Heiko August
ced3fec8e5 Change: reformat the remove account form 2024-11-17 23:37:05 +01:00
Heiko August
aa2003c748 Change: replace the paragraph with a div and reformat the code 2024-11-17 23:37:05 +01:00
Heiko August
868a3a16b6 Change: remove the form enclosing div 2024-11-17 23:37:05 +01:00
Heiko August
4898b22769 Cleanup: partially reformatting of the template 2024-11-17 23:37:05 +01:00
Heiko August
40bf39a2dd Change: add attributes autofocus and required in the password input of the remove account form 2024-11-17 23:37:05 +01:00
Heiko August
60158bdb26 Change: replace inputs of types submit with buttons in the remove account form 2024-11-17 23:37:05 +01:00
Heiko August
81ed9ddc73 Fix: use background-position for inḿage in .a.internal, add missing rules to style.css 2024-10-28 22:38:22 +01:00
Heiko August
2033f905ba Change: unifiy common rules, use only background-position for images in rtl-languages 2024-10-28 22:38:22 +01:00
Heiko August
dbc01b85fa Change: apply the changes of the latest commit in style.min.css to style.css 2024-10-28 22:38:22 +01:00
Heiko August
4261dd0e42 Change: unify all common and often repeated rules for the thread tree subject link under .subject 2024-10-28 22:38:22 +01:00
Michael Lösler
3c93022020
user name (#752)
- add missing style definition defined in #749
2024-10-25 20:35:24 +02:00
Michael Lösler
3c61d31bc5
Existing username (#751)
- exclude the check for existing usernames when the admin/mod edits the post
- https://github.com/My-Little-Forum/mylittleforum/issues/750
2024-10-25 20:28:52 +02:00
Heiko August
7000bf6329 Change: replace the element <strong> for the user or author name with a <span> 2024-10-22 10:20:37 +02:00
Michael Lösler
d075a0a518
el.getAttribute("id") vs. el.id (#748)
If an element `el` does not have an `id`, `el.id` returns an (empty) string but `el.getAttribute("id")` returns `null` (at least in Opera), cf. #741
A condition has been added to catch errors (when using image or code without any attribute).
2024-10-07 21:23:26 +02:00
Michael Lösler
5cf8e52fa3 JavaScript-Minifikation
- compressed version of the main javascript
2024-09-29 13:02:35 +00:00
Heiko August
1f7ef6353d Revert "Change: adapt the changes in main.js to main.min.js"
This reverts commit 02a6a5c6be.
2024-09-29 13:02:35 +00:00
Heiko August
ea1542dc6f Change: adapt the changes in main.js to main.min.js 2024-09-29 13:02:35 +00:00
Heiko August
f093edcdb2 Cleanup: correct a few formatting issues (trailing tabs) 2024-09-29 13:02:35 +00:00
Heiko August
f5b42822fa Change: access no-text-icon with querySelector 2024-09-29 13:02:35 +00:00
Heiko August
3069b8baeb Change: add class .subject to subject links in thread trees, adapt access in JS 2024-09-29 13:02:35 +00:00
Heiko August
02c46a2f23 Change: add element time for the posting time and provide the machine readable timestamp 2024-09-29 13:02:35 +00:00
Heiko August
13a9d645a7 Change: move the icon for empty postings from after the subject to the metadata section 2024-09-29 13:02:35 +00:00
Heiko August
155846563c Change: split the author name and the tail with the metadata in the source code 2024-09-29 13:02:35 +00:00
Heiko August
a7e8562fd1 Fix: remove the separator behind the subject, was replaced with a CSS rule before 2024-09-29 13:02:35 +00:00
Heiko August
e47eb5d406 Change: split the codeline into two parts, one for subject and one for the metadata 2024-09-29 13:02:35 +00:00
Heiko August
88fa688743 Change: split the thread tree item line between swubject and metadata including the authors name 2024-09-29 13:02:35 +00:00
Heiko August
322609d1ae Fix: add the changed definition of sidebar width in wider viewports to style.css 2024-09-29 13:02:35 +00:00
Heiko August
e3948b34c6 Fix: restrict the content width to the width of element main 2024-09-29 13:02:35 +00:00
Heiko August
1ac8f1eef6 Change: add new attribute "writingsuggestions" with value "false"
This prevents AI based suggestions (exposure to the web based AI-service) for the password, if the password is shown as plaintext.
2024-09-15 12:35:35 +02:00
Michael Lösler
4fd0696bb6
JS Compression (#743)
c- mpressed main.js using https://www.toptal.com/developers/javascript-minifier
2024-09-15 12:12:48 +02:00
Michael Lösler
8b419931cb
CSS (#742)
- ltr <--> rtl corrected
- remove class `.checkbox`
2024-09-15 12:00:10 +02:00
Heiko August
f64d8d7c93 Change: remove class .checkbox to move the checkbox to the start of the line 2024-09-15 11:54:53 +02:00
Heiko August
2fcbe466a1 Change: move the help texts from behind the input into the label 2024-09-15 11:54:53 +02:00
Heiko August
7d0a88e6f0 Change: formatting of the bb-code and smilies formatting help 2024-09-15 11:54:53 +02:00
Heiko August
e488fb4a57 Change: add the strings for the instruction heading and the skip link to the template and the language files 2024-09-15 11:54:53 +02:00
Heiko August
2305068128 Cleanup: remove trailing spaces/tabs (again) 2024-09-15 11:54:53 +02:00
Heiko August
72daabbd12 Change: set margin to 0 because (at least) in Firefox a textarea has a small margin 2024-09-15 11:54:53 +02:00
Heiko August
dc858a2788 Change: restrict the bottom margin to all fieldsets except the last one 2024-09-15 11:54:53 +02:00
Heiko August
e61a92d3d8 Change: restrict the width of the posting form to 60em 2024-09-15 11:54:53 +02:00
Heiko August
2211d7d8eb Cleanup: remove the definitions for #more-smilies and its children elements
This ID was replaced with #additional-smilies a longer time ago.
2024-09-15 11:54:53 +02:00
Heiko August
5e763375c2 Change: remove the class .more-smilies from the button definition
The class is not needed anymore. It was used to format the button twice the width than the smiley buttons of class .default.
2024-09-15 11:54:53 +02:00
Heiko August
73f4f53996 Change: a bit of reformatting and correctiion of a phrasing error 2024-09-15 11:54:53 +02:00
Heiko August
c70532d177 Change: redefine the width and height of the posting textarea and remove the definitions for float 2024-09-15 11:54:53 +02:00
Heiko August
6b16cc2bc2 Change: define the maximal width of div#entry-input and text based input fields in #postingform 2024-09-15 11:54:53 +02:00
Heiko August
e57b0cf05f Change: unify the rules for images in buttons in #smiley-bar and #additional-smilies 2024-09-15 11:54:53 +02:00
Heiko August
dc6de3a392 Change: adapt the rules of #additional-smilies to the new HTML-structure of a list with buttons 2024-09-15 11:54:53 +02:00
Heiko August
c679782a73 Change: remove formatting of buttons in #smiley-bar
Was replaced by formatting of buttons in #format-bar.
2024-09-15 11:54:53 +02:00
Heiko August
779919c595 Fix: remove the float-based formatting for #format-bar amd #smiley-bar 2024-09-15 11:54:53 +02:00
Heiko August
5e21e13251 Change: add joint rules for bb-code buttons and smiley buttons 2024-09-15 11:54:53 +02:00
Heiko August
da86e8e9ab Change: replace formatting for #bbcode-bar with the more general formatting of #format-bar
This includes also general formatting of #smiley-bar.
2024-09-15 11:54:53 +02:00
Heiko August
87a3172f9e Change: make input.checkbox writing direction aware 2024-09-15 11:54:53 +02:00
Heiko August
a5e22b346f Change: add necessary margins to button#insert-quote and make it writing direction aware 2024-09-15 11:54:53 +02:00
Heiko August
3079ea9084 Change: add a bottom margin to label.textarea 2024-09-15 11:54:53 +02:00
Heiko August
55f70de068 Change: target all direct childs of fieldsets instead all div in #postingform 2024-09-15 11:54:53 +02:00
Heiko August
5785a0ba1f Change: format sticky selection, remove bullets, margin and padding 2024-09-15 11:54:53 +02:00
Heiko August
469af94fe6 Fix: remove the last added class "input", this label should not use display:block; 2024-09-15 11:54:53 +02:00
Heiko August
fd0328a92f Change: create the bb-code-buttons with the new HTML-structure of the instructions
The instruction items are now capsuled in an additional div. The JS-code has to respect this change.
2024-09-15 11:54:53 +02:00
Heiko August
049c131264 Change: create the buttons of smilies with the new HTML-structure of the instructions
The instruction items are now capsuled in an additional div. The JS-code has to respect this change.
2024-09-15 11:54:53 +02:00
Heiko August
a1af9b5215 Change: read the value for insertion of an additional smiley from the button value 2024-09-15 11:54:53 +02:00
Heiko August
da6be2bb72 Change: replace links with a list with buttons in the list of additional smilies 2024-09-15 11:54:53 +02:00
Heiko August
704b2f3937 Cleanup: remove trailing spaces/tabs, add spaces for better readability 2024-09-15 11:54:53 +02:00
Heiko August
33408247f2 Change: hide the complete div#formatting-help instead the both instruction blocks 2024-09-15 11:54:53 +02:00
Heiko August
2ea363ce1c Change: reorder the elements in fieldset#message
This is part of the preparation to place the button bars above the textarea.
2024-09-15 11:54:53 +02:00
Heiko August
696de3ed9d Change: determine the length once instead of with each loop pass 2024-09-15 11:54:53 +02:00
Heiko August
93edd1d979 Change: replace search for label in tag collection with a query selector 2024-09-15 11:54:53 +02:00
Heiko August
94eca06a09 Change: put the labels of the posting form above the inputs 2024-09-15 11:54:53 +02:00
Heiko August
8ea8d28afd Change: replace p with div in entry form, there are no paragraphs (p) 2024-09-15 11:54:53 +02:00
Heiko August
5613f33a9d Change: add the input description as suffix to the label
A description how to input something makes no sense *behind* the input field.
2024-09-15 11:54:53 +02:00
Heiko August
273eb53e7a Change: use the proper input types instead type text 2024-09-15 11:54:53 +02:00
Heiko August
449569e77b Change: replace input type=button with buttons 2024-09-15 11:54:53 +02:00
Heiko August
d9b657df6a Fix: add arabic and italian language files to the list of files to upload 2024-08-27 15:09:45 +00:00
Heiko August
34c3e5d95c Fix: provide the new version number for displaying in the template 2024-08-27 15:09:45 +00:00
Heiko August
e565b9fd3c Change; add the new version number to the files index.php and config/VERSION 2024-08-27 15:09:45 +00:00
Heiko August
e62d30f6bd Change: add the list of changes and fixes to the changelog 2024-08-27 15:09:45 +00:00
Heiko August
16bd83a564 Change: add version 20240729.1 to the list of upgradable versions 2024-08-27 15:09:45 +00:00
Heiko August
d0515bc711 Change: add the files to upload to the former upgrade blocks 2024-08-27 15:09:45 +00:00
Heiko August
06cd50b032 Change: add the block for an upgrade from version 20240729.1 to the upgrade file 2024-08-27 15:09:45 +00:00
Heiko August
3d9fb80ccb Change: format the date and time in arabic language
… corresponding to the rules of PHP's DateTimeInterface
2024-08-27 14:08:28 +00:00
Heiko August
d40c64a072 Change: translate "sidebar" to "Barra laterale" in italian language file 2024-08-27 13:30:24 +00:00
Heiko August
8eb2048f63 Fix: move from h3.sidebar to h2.sidebar and remove the ID from the selector
This makes it possible to remove the margin in case of the folded sidebar/infobar without selecting the h2 with naming the ID.
2024-08-27 13:14:45 +00:00
Heiko August
16a0c4cba1 Change: remove the definitions for the removed ID #bottombar and its children elements 2024-08-27 13:14:45 +00:00
Heiko August
185d0daa7f Change: ensure to switch the grid only in the threaded overview with class .threaded 2024-08-27 13:14:45 +00:00
Heiko August
98c6e69c18 Fix: the definition for the admin main page grid needs grid-template-areas
Removed it accidently, what caused the grid not to switch to the side-by-side view in wider viewports.
2024-08-27 13:14:45 +00:00
Heiko August
40003159af Fix: the main heading for the sidebar/infobar is a h2 not a h3 2024-08-27 13:14:45 +00:00
Heiko August
dd1cd3c304 Change: replace the ID #bottombar with #sidebar
The differentiation between the infobars in the threaded and table-based overview pages is done with the classes .threaded and .table in the element #main-grid.
2024-08-27 13:14:45 +00:00
Heiko August
13022be5f7 Change: add ID #threadlist to the table of the thread list overview
This binds the table to the grid area "threadlist".
2024-08-27 13:14:45 +00:00
Heiko August
da414df161 Change: add class .threaded to the grif of the threaded overview template
This makes it possible to distinguish it from the table overview.
2024-08-27 13:14:45 +00:00
Heiko August
be26761955 Change: add the main grid also to the table overview template 2024-08-27 13:14:45 +00:00
Heiko August
1addbb43ac Fix: add spans to the modmenu link texts because the new rules makes this necessary 2024-08-27 13:14:45 +00:00
Heiko August
7208279d2b Fix: remove the reversal of the order of the boxes in the admin menu in wider viewports 2024-08-27 13:14:45 +00:00
Heiko August
fcd6a383cb Fix: remove a bunch of trailing spaces 2024-08-27 13:14:45 +00:00
Heiko August
f9655fd45d Change: collection of a few logical margin, padding and border definitions 2024-08-27 13:14:45 +00:00
Heiko August
bbdf14d96e Fix: add not yet commited optimisations for background icon images 2024-08-27 13:14:45 +00:00
Heiko August
9c1dbdf4e5 Change: supplement floats and clears with their logical counterparts
This includes a few text-aligns
2024-08-27 13:14:45 +00:00
Heiko August
0691ae36f6 Change: reformat the modoptions-block to support both writing directions 2024-08-27 13:14:45 +00:00
Heiko August
02525cf6f9 Change: adjust line-heigt and padding for h3-headings in the sidebar 2024-08-27 13:14:45 +00:00
Heiko August
40cfe4a6b6 Change: reposition of the sidebartoggle icon 2024-08-27 13:14:45 +00:00
Heiko August
86761ef9eb Change: optimise line-height and padding of links in #latest-postings 2024-08-27 13:14:45 +00:00
Heiko August
57fc230bc5 Change: optimise the background-image positioning in #subnavmenu, change only what's necessary 2024-08-27 13:14:45 +00:00
Heiko August
9b3c75e741 Fix: code style thingamabob, use tab instead spaces for indentation 2024-08-27 13:14:45 +00:00
Heiko August
1b83a1d7dc Change: adjust the inline-padding for links in .adminmenu
Use the same value as for the content of the admin info boxes beside.
2024-08-27 13:14:45 +00:00
Heiko August
4a0c09cab4 Change: narrow the sidebar to 8.5em if one used the sidebars hide-link 2024-08-27 13:14:45 +00:00
Heiko August
ca580bfe65 Fix: adjust font-weight and inline padding of the sidebars main heading again 2024-08-27 13:14:45 +00:00
Heiko August
85f17622f3 Change: make the main heading of the sidebar visible again 2024-08-27 13:14:45 +00:00
Heiko August
5c7f255c86 Change: adjust the bottom-margin of the blocks in the sidebar
Has now 0.75em to match the boxes on the admin main page.
2024-08-27 13:14:45 +00:00
Heiko August
660572fc25 Change: adjust the min-width for the first width-based media query 2024-08-27 13:14:45 +00:00
Heiko August
6c53ba3461 Change: add a grid container to the main thread list in threaded view
The dǵrid is only necessary if the sidebar is visible. So don't add it if it's not visible.
2024-08-27 13:14:45 +00:00
Heiko August
65089a8dea Fix: remove the unit "em" from the line height definition for main
This makes it matching 150% for every defined font size.
2024-08-27 13:14:45 +00:00
Heiko August
7db8934046 Change: format the upload management list as flexbox 2024-08-27 13:14:45 +00:00
Heiko August
0bf486fab5 Change: add a few colour and padding adjustments to the administration links 2024-08-27 13:14:45 +00:00
Heiko August
81bee0f6d0 Change: reformat the items in .adminmenu for better visibility 2024-08-27 13:14:45 +00:00
Heiko August
c72909f108 Change: reformat the content of admin info blocks, make the font-size larger 2024-08-27 13:14:45 +00:00
Heiko August
b131fef734 Change: adjust margin and bottom for ul.adminmenu as direct child of main 2024-08-27 13:14:45 +00:00
Heiko August
431c125c7c Change: add the delete icon to the delete-selected-items button 2024-08-27 13:14:45 +00:00
Heiko August
9dc7e88487 Change: remove addow image from the HTML and replace it with writing direction aware CSS-background 2024-08-27 13:14:45 +00:00
Heiko August
1a7b26ae05 Change: remove superfluous div#admin-usernav-bottom and its CSS-rules 2024-08-27 13:14:45 +00:00
Heiko August
ce1a82fab4 Fix: swap the elements of the grid in the admin main page in wider viewports 2024-08-27 13:14:45 +00:00
Heiko August
3c953f3355 Change: links in .adminmenu are flexboxes now 2024-08-27 13:14:45 +00:00
Heiko August
67bf7ecc9b Change: move the line-height definition for elements to main (#content)
This makes it simpler to change the line height for specific elements without the need of !important.
2024-08-27 13:14:45 +00:00
Heiko August
36fa46a25c Change: add a mirrored version of the move-posting-icon 2024-08-27 13:14:45 +00:00
Heiko August
f229c8140c Change: replace the right margin for the link images with inline-start margin for the text span 2024-08-27 13:14:45 +00:00
Heiko August
f52b59cdba Change: replace the 20px for the bottom margin with 0.75em
This corresponds to the 0.75em-gap of the admin main page grid.
2024-08-27 13:14:45 +00:00
Heiko August
0ae0c2290d Change: add a grid to the admin main page 2024-08-27 13:14:45 +00:00
Heiko August
0b177ccfc9 Change: regormat the notices (success, caution, spam) 2024-08-27 13:14:45 +00:00
Heiko August
bc2815aeb3 Change: a few corrections, found by chance 2024-08-27 13:14:45 +00:00
Heiko August
65867aacca Change: make the pagination bars writing direction aware 2024-08-27 13:14:45 +00:00
Heiko August
90361ae67a Change: make blockquotes writing direction aware 2024-08-27 13:14:45 +00:00
Heiko August
fa82d218e0 Change: reformat the posting header in the threaded view 2024-08-27 13:14:45 +00:00
Heiko August
d2778fdb9f general rules for threadview indentation and new-posting-marking 2024-08-27 13:14:45 +00:00
Heiko August
2559ba302c Change: formatting of the icons of the posting footer links react now correcly to writing direction 2024-08-27 13:14:45 +00:00
Heiko August
0e170d286e Change: rebuild the posting footer with grid-template-areas
This makes servicing far more understandable.
2024-08-27 13:14:45 +00:00
Heiko August
164f393aef Fix: the misaligned icon jumped a bit when focussing or hovering over the links of class .stronglink 2024-08-27 13:14:45 +00:00
Heiko August
6dd1ba763d Change: provide margin of the indentation and dotted indentation line for rtl-languages 2024-08-27 13:14:45 +00:00
Heiko August
ba661b88f9 Change: make the indentation of the list items in the thread tree rtl-languages aware 2024-08-27 13:14:45 +00:00
Heiko August
0f660efae9 Change: positioning of icons in .currentthreads for rtl-languages 2024-08-27 13:14:45 +00:00
Heiko August
180781a3fc Change: positioning of posting and thread icons in the thread tree for rtl-languages 2024-08-27 13:14:45 +00:00
Heiko August
75c6e433f8 Change: make folded threads and the toggle icon rtl-language-aware 2024-08-27 13:14:45 +00:00
Heiko August
0a7d4cfcc1 Change: adjustments in the search results list for rtl-language support, rtl-optimised icons 2024-08-27 13:14:45 +00:00
Heiko August
2210050365 Change: replace left and right with inset-inline-start and -end for the Ajax-preview box 2024-08-27 13:14:45 +00:00
Heiko August
7b752a0f28 Change: redistribute the grid items in wider viewports and realign the elements of the linklist 2024-08-27 13:14:45 +00:00
Heiko August
1586130893 Change: rename the IDs of footer childs and apply the grid areas to the elements 2024-08-27 13:14:45 +00:00
Heiko August
6de2263173 Change: define the grid columns, rows and area names, stack all childs in a vertical order 2024-08-27 13:14:45 +00:00
Heiko August
04299e4e37 Change: use border-box as CSS box model
With border-box the width of a box includes not only its content but also the padding and border. This is far more intuitive than measuring the width of the content only.
2024-08-27 13:14:45 +00:00
Heiko August
52dd204a0a Change: display the RSS-icon in the RSS-links in front of the link text in both writing directions 2024-08-27 13:14:45 +00:00
Heiko August
af957cb189 Change: put the up-arrow in the link to #top in front of the link text in both writing directions 2024-08-27 13:14:45 +00:00
Heiko August
54c93b0825 Change: format the #footermenu similar to the #usermenu 2024-08-27 13:14:45 +00:00
Heiko August
4bf6c0eabe Change: set margin and padding to 0 for the list #footermenu 2024-08-27 13:14:45 +00:00
Heiko August
a70baec4c5 Change: the direct childs of #footer share the rules for margin and padding 2024-08-27 13:14:45 +00:00
Heiko August
afe9ff93b2 Change: add more padding and grid-gaps to the footer 2024-08-27 13:14:45 +00:00
Heiko August
da77b8fa0f Change: the footer is now a grid 2024-08-27 13:14:45 +00:00
Heiko August
08f5fb97a2 Change: replace padding value 20px with 1rem
Use 1em instead 1rem for older browsers, which does not support the unit rem.
2024-08-27 13:14:45 +00:00
Heiko August
bac761111a Fix: publish forgotten codeblock for bullets in ltr languages 2024-08-27 13:14:45 +00:00
Heiko August
a1e6cba1e3 Change: exclude the first list item from leading margin 2024-08-27 13:14:45 +00:00
Heiko August
9e98003664 Fix: use margin-inline-end to set the gap to the next link
With margin-block-end the gap was created below the link, not on it's side.
2024-08-27 13:14:45 +00:00
Heiko August
4ce3c32caa Change: place the direct childs of #subnav in the flexbox
The placement depends on the width of the viewport.
2024-08-27 13:14:45 +00:00
Heiko August
2f9665136f Change: #subnav is now a flexbox 2024-08-27 13:14:45 +00:00
Heiko August
b52add3a3e Change: move the content of #usermenu to flex-start by default and to flex-end in wide viewports 2024-08-27 13:14:45 +00:00
Heiko August
31369e74a1 Fix: correct the min-width value of the media-query in the file style.css
Change it from 45em to 48em, according to the value in style.min.css.
2024-08-27 13:14:45 +00:00
Heiko August
f9e329dee1 Change: remove the extra padding for element #nav in wide viewports (>=48em) 2024-08-27 13:14:45 +00:00
Heiko August
83f1dd116b Change: adjust the font size of the page title and enlagre it in wider viewports 2024-08-27 13:14:45 +00:00
Heiko August
d59a3c155a Change: define the header to be a flexbox generally
Narrow screens display the flexbox content boxes vertically, viewports with a width of at least 36em horizontally.
2024-08-27 13:14:45 +00:00
Heiko August
7f82886d09 Fix: correct a copy'n'paste error in the selector 2024-08-27 13:14:45 +00:00
Heiko August
a5799db39b Change: display the bullet of the breadcrumb navigation in front of the text in both writing directions 2024-08-27 13:14:45 +00:00
Heiko August
d452156cd8 Change: display the icons in front of the link text in both writing directions 2024-08-27 13:14:45 +00:00
Heiko August
d911685f07 Change: remove horizontal padding from element #logo
This is a followup to the move of the padding to the ruleset for direct childs of body.
2024-08-27 13:14:45 +00:00
Heiko August
8490a1700e Change: move the horizontal padding from the different main page elements to one general rule
The only exception is the element main, where this rule is overwritten.
2024-08-27 13:14:45 +00:00
Heiko August
11bac1bf22 Change: put the arrow to the right side of the linktext in rtl languages 2024-08-27 13:14:45 +00:00
Heiko August
0c554b53ef Change: move the arrows for rtl languages to the right side of the image 2024-08-27 13:14:45 +00:00
Heiko August
de65775de0 Change: adding red arrows pointing to the left for use in rtl languages where necessary 2024-08-27 13:14:45 +00:00
Heiko August
dffc801e34 Change: overwrite alignment for #nav for the user menu 2024-08-27 13:14:45 +00:00
Heiko August
a524bf2280 Change: replace text-align value "right" with "end" in the block for the user menu and the search 2024-08-27 13:14:45 +00:00
Heiko August
6aa4224c58 Change: set text-align with "start" for support of both horizontal writing directions
The value "start" replaces "left" in ltr and "right" in rtl languages.
2024-08-27 13:14:45 +00:00
Heiko August
a33401fef1 Change: add a yellow background colour to the box with selector .notice.caution 2024-08-27 13:14:45 +00:00
Heiko August
bb33c508fe Change: adjust the gap between the icon and the starting point of the text for .notice 2024-08-27 13:14:45 +00:00
Heiko August
ee38b24a47 Fix: the self defined function should have the same return values as the original function 2024-08-21 19:15:38 +00:00
Heiko August
8b2eec6897 Fix: collect the table names in $db_settings
I was assuming them to exist when writing the affected query even the entries in $db_settings in reality wasn't present. Now the script collects the existing entries only for use in the query.
2024-08-21 19:15:38 +00:00
Heiko August
779d44cb35 Change: introduce function str_ends_with to PHP versions prior to version 8.0
This is for the specific use case of check $db_settings elements for table names.
2024-08-21 19:15:38 +00:00
Michael Lösler
eb85d2b66f
SQL stm (#736)
- Quotes in SQL stms fixed
- Exception message added because the current error message looks like "0, " and is not helpful
2024-08-15 17:27:40 +02:00
Heiko August
7b38751024 Fix: add last_reply to the select to be able to order the result by that column 2024-08-07 13:53:53 +00:00
Heiko August
6edc80b0ed Fix: in german language the time format is 0-24 with no am/pm 2024-08-07 13:51:09 +00:00
Heiko August
7f7b6b71d5 Change: mark the Bad Behavior plugin as removed because the project is abandoned 2024-08-04 11:58:44 +00:00
Heiko August
764de49b2f Fix: alter all URLs to the old repository to link to the new one 2024-08-04 11:58:44 +00:00
Heiko August
8842bb8bae Change: clarify the instructions to remove files
This affects upgrades from the stable versions of the 2.5-branch because some or all files might be removed previously.
2024-08-04 11:58:44 +00:00
Heiko August
bd660e669a Change: rename language name "arabian" to "arabic" 2024-08-04 11:58:44 +00:00
Heiko August
df3399c1a8 Fix: add definition of primary key for mlf2_banlists in the installation script 2024-07-31 14:49:41 +00:00
Heiko August
4f2142ace3 Fix: deduplicate banlists before saving the lists in the database 2024-07-29 20:55:24 +00:00
Heiko August
59b05f74fe Change: add a block to recreate the banlist table with column "name" as PK 2024-07-29 20:18:07 +00:00
Heiko August
cf37feec94 Change: add the new version number and the date of the release to index.php 2024-07-28 20:22:29 +00:00
Heiko August
b941ebdab3 Change: add the new version number to config/VERSION 2024-07-28 20:22:29 +00:00
Heiko August
79ae99278c Change: add the features, changes and fixes to the changelog 2024-07-28 20:22:29 +00:00
Heiko August
d60a5ebbc8 Change: a few formatting issues and an text enhancement 2024-07-28 20:22:29 +00:00
Heiko August
0b002ef0e0 Change: add new available language Arabian to the list 2024-07-28 20:22:29 +00:00
Heiko August
6127884fb0 Fix: correct spelling error 2024-07-28 20:22:29 +00:00
Heiko August
18e0be2348 Change: add information about formatting capabilities 2024-07-28 20:22:29 +00:00
Heiko August
ff3348076d Change: add the interim testing version 20240308.1 to the list of updateable versions 2024-07-28 20:22:29 +00:00
Heiko August
5e86e642c1 Change: set dates and timestamps with zero values to NULL in the entries table
Affected are the values '0000-00-00' and '0000-00-00 00:00:00'.
2024-07-28 20:22:29 +00:00
Heiko August
f6f19934cd Change: set dates and timestamps with zero values to NULL in the userdata table
Affected are the values '0000-00-00' and '0000-00-00 00:00:00'.
2024-07-28 20:22:29 +00:00
Heiko August
a98630e9c6 Fix: define a few date(time) columns as NULL-able in the entries table
This affects only very old installations, made with a version older than version 2.3.5.
2024-07-28 20:22:29 +00:00
Heiko August
e2e1fba7ae Fix: define a few date(time) columns as NULL-able in the userdata table
This affects only very old installations, made with a version older than version 2.3.5.
2024-07-28 20:22:29 +00:00
Heiko August
7dfed8930e Fix: remove trailing tabs at the end of the line 2024-07-28 20:19:15 +00:00
Heiko August
5ebdeeaa60 Fix: columns, that are used in ORDER BY must be selected before
This is at least the case on my DB-server. It might be an issue of the server configuration an may be handled not so strict on other servers.
2024-07-28 20:19:15 +00:00
Heiko August
45cffb033e Fix: add forgotten section names when using language strings 2024-07-28 20:18:30 +00:00
Heiko August
8e30344e5e Change: mark the radio button of the (pre)-selected language entry as checked 2024-07-28 20:18:30 +00:00
Heiko August
f20ac777dd Change: remove the commented and unused code for inserting the password on page reload 2024-07-28 20:18:30 +00:00
Heiko August
c1177a2254 Change: use the already existing info about the writing direction in the HTML-template 2024-07-28 20:18:30 +00:00
Heiko August
e45d04dc18 Fix: add the key error_update_settings to all language files
This key was utilised in the installation script but was not available in the language files.
2024-07-28 20:18:30 +00:00
Heiko August
3aa741204a Fix: correct a small formatting issue 2024-07-28 20:18:30 +00:00
Heiko August
97854ff6bb Change: add the section names when using language strings 2024-07-28 20:18:30 +00:00
Heiko August
c1137cd61b Change: read the language file with the function my_parse_ini_file 2024-07-28 20:18:30 +00:00
Heiko August
2d3f50019a Change: add the function my_parse_ini_file to improve language string reading
Function is based on a user note in the PHP manual page for parse_ini_string.
https://www.php.net/manual/de/function.parse-ini-string.php#111845
2024-07-28 20:18:30 +00:00
Heiko August
b26f8a3ddc Fix: move the entry to remove the flash processing code from $update[items] to $update[delete] 2024-07-21 13:55:30 +00:00
Heiko August
4fb4a24711 Change: add the files to upgrade to the blocks of upgrades from earlier versions 2024-07-21 13:55:30 +00:00
Heiko August
80c1554dc3 Change: add the block of database changes for an upgrade from 20240308.1 2024-07-21 13:55:30 +00:00
Heiko August
9cdeed3bb2 Fix: remove LIKE from the query, was a remnant of a former change 2024-07-21 13:55:30 +00:00
Heiko August
521bb48036 Change: formatting thingamabob 2024-07-18 19:21:23 +00:00
Heiko August
7d7d9bb47e Change: add selected translations and solve a few formatting issues (turkish) 2024-07-18 19:21:23 +00:00
Heiko August
4825d22d7f Change: add markings for missing translations and solve formatting issues (tamil) 2024-07-18 19:21:23 +00:00
Heiko August
0a2033a4ec Change: add selected translations (swedish) 2024-07-18 19:21:23 +00:00
Heiko August
13506a6637 Fix: corrected a typo and a missing masking of a single quote in a string (swedish) 2024-07-18 19:21:23 +00:00
Heiko August
39c19096e2 Fix: solve a few formatting issues and mark one strings for translation (spanish) 2024-07-18 19:21:23 +00:00
Heiko August
b3c5ffa86a Change: add missing strings and selected translations (russian) 2024-07-18 19:21:23 +00:00
Heiko August
c38c754cf4 Fix: solve a few further formatting issues (english)
Insert blank lines between the greeting and the beginning of the email text.
2024-07-18 19:21:23 +00:00
Heiko August
9185cf2276 Change: add missing strings and selected translations (norwegian) 2024-07-18 19:21:23 +00:00
Heiko August
73be6ae907 Change: add translations to the e-mails section (italian) 2024-07-18 19:21:23 +00:00
Heiko August
065aa431ba Change: add the translation for the information on the automatic generation of the e-mail (italian) 2024-07-18 19:21:23 +00:00
Heiko August
31d17a2ae5 Change: remi+
ove the TODO marking bacause the word Avatar is also in italian language Avatar
2024-07-18 19:21:23 +00:00
Heiko August
54931a3a26 Fix: solve a formatting issue (italian) 2024-07-18 19:21:23 +00:00
Heiko August
90e56ac349 Fix: correct invalid HTML comment marking 2024-07-18 19:21:23 +00:00
Heiko August
d7a7c3c45c Fix: solve a few further formatting issues (english) 2024-07-18 19:21:23 +00:00
Heiko August
301e663097 Fix: correct a further typo 2024-07-18 19:21:23 +00:00
Heiko August
d0e070d838 Fix: correct a few occurences of a typo 2024-07-18 19:21:23 +00:00
Heiko August
06b14c1e09 Fix: solve a few formatting issues (english) 2024-07-18 19:21:23 +00:00
Heiko August
c797f19d30 Fix: solve a formatting issue (german) 2024-07-18 19:21:23 +00:00
Heiko August
9b687c81b1 Change: translation of the new string update_reenabling_notice 2024-07-18 19:21:23 +00:00
Heiko August
06bb7020f9 Fix: solve a few formatting issues (french) 2024-07-18 19:21:23 +00:00
Heiko August
a2f528bad9 Change: remove outdated and add missing strings (croatian) 2024-07-18 19:21:23 +00:00
Heiko August
d360b39298 Change: remove outdated and add missing strings (traditional chinese) 2024-07-18 19:21:23 +00:00
Heiko August
1e8ea6d428 Change: remove outdated and add missing strings (simplified chinese) 2024-07-18 19:21:23 +00:00
Heiko August
0a00364beb Change: add new language file for arabian language (beta status)
The language file was provided by the project forum visitor Abdus_salam
see therefore: https://mylittleforum.net/forum/index.php?id=16619
2024-07-18 19:21:23 +00:00
Heiko August
7f0eb9650a Change: add language names in native and english language for later use 2024-07-18 19:21:23 +00:00
Heiko August
9aaafbd71b Fix: unify the content of head-sections and correct a few formatting issues 2024-07-18 19:21:23 +00:00
Heiko August
3c48f05982 Fix: add forgotten closing tag for paragraph in the spam-prevention settings form
This splits the grouped list of options for B8 filter from the threshold input.
2024-07-12 00:06:59 +02:00
Heiko August
3328cca421 Fix: provide the missing strings for the Bayesian filter settings 2024-07-12 00:06:59 +02:00
Heiko August
6664187766 Fix: remove unnecessary spaces and semicolons in style.min.css 2024-06-29 12:35:47 +02:00
Heiko August
7fe251e951 Fix: correct typo in comment 2024-06-29 12:35:47 +02:00
Michael Lösler
571a5e2b5e
Clean code (#718)
- code redundancy reduced
2024-05-30 08:39:04 +02:00
Heiko August
94c1eaab11 Fix: raise the minimum requirements for the database server 2024-05-29 19:50:47 +00:00
Heiko August
89faaa54c2 Fix: redefine column user_name after converting the table to utf8mb4
Defining of column user_email is not necessary because the definition matches with the conversion of the table.
2024-05-29 19:50:47 +00:00
Heiko August
7910a45d52 Fix: state explicit, that the content of the column user_email has to be not NULL 2024-05-29 19:50:47 +00:00
Heiko August
4eba711ad1 Fix: esure, that only the indexes user_type and user_name get deleted 2024-05-29 19:50:47 +00:00
Heiko August
7293af046a Fix: in an upgrade from version 2.4.99.1 the index key_user_name was added for the non existing column key_user_name 2024-05-29 19:50:47 +00:00
Heiko August
aee5e2a9dd Fix: add missing index key_user_type and delete outdated index user_type, when present 2024-05-29 19:50:47 +00:00
Heiko August
4dd9a4b4dd Fix: corrected table name, was a further copy'n'paste error
This caused no error because the named column (spam) in the wrong table (mlf2_userdata) does not exist. So the query did simply nothing. The only effect was that the index was still missing after execution.
2024-05-29 19:50:47 +00:00
Heiko August
6723fca78a Fix: remove superfluous comma, it's a copy'n'paste syntax error 2024-05-29 19:50:47 +00:00
Michael Lösler
76f407d1db
Include user name (#717)
- user name of _registered_ users added to query
- #716
2024-05-29 19:39:30 +02:00
joeiacoponi1
153abc3c4c
SQL & php Spam performance changes for 20240308.1 (#713)
undefined
2024-04-24 15:34:04 +02:00
Florian Caspar
4c77637d32 Update README.md
Explicit information for overwriting VERSION.
2024-04-09 14:39:21 +02:00
Heiko August
c303949847 Fix: add strings for the upload management area in the chinese language files
Seems to be forgotten or accidently removed by interfering work on the language files
2024-04-02 22:52:38 +02:00
Heiko August
b135914737 Change: add a second regex for checking for valid hex colour codes 2024-03-31 15:10:07 +02:00
Heiko August
470893a15c Cleanup: remove outdated and commented code 2024-03-31 15:10:07 +02:00
Heiko August
af1aef0ec1 Change: refactoring of the HTML-output-part of the function raise_error 2024-03-31 15:10:07 +02:00
Heiko August
645165adab Change: reformattion of the function get_themes 2024-03-31 15:10:07 +02:00
Heiko August
6e53618816 Change: reformattion of the function get_languages 2024-03-31 15:10:07 +02:00
Heiko August
bc94ca4c66 Change: reformattion of the function get_timezones 2024-03-31 15:10:07 +02:00
Heiko August
9f63a7c568 Change: reformatting of the function get_not_accepted_words 2024-03-31 15:10:07 +02:00
Heiko August
dc562998b3 Change: reformatting of the function is_ip_banned 2024-03-31 15:10:07 +02:00
Heiko August
249c81914b Change: reformatting of the function move_item 2024-03-31 15:10:07 +02:00
Heiko August
e8553ee7bf Change: fix a few formatting issues in the function is_valid_birthday 2024-03-31 15:10:07 +02:00
Heiko August
dbc2a73fb9 Change: reformatting of the function is_user_agent_banned 2024-03-31 15:10:07 +02:00
Heiko August
f7a0ebdf2a Change: solve a few small code style issues 2024-03-31 15:10:07 +02:00
Heiko August
9b745142ac Change: reformatting of the function my_mb_encode_mimeheader 2024-03-31 15:10:07 +02:00
Heiko August
228e802c78 Change: reformatting of the function mail_header_filter 2024-03-31 15:10:07 +02:00
Heiko August
1ab386dffd Change: reformatting of the function encode_mail_name 2024-03-31 15:10:07 +02:00
Heiko August
92af6b0360 Change: reformatting of the function my_strpos 2024-03-31 15:10:07 +02:00
Heiko August
de94e8bacb Change: reformatting of the function my_substr 2024-03-31 15:10:07 +02:00
Heiko August
f0630ddc4c Change: reformatting of the function my_strtolower 2024-03-31 15:10:07 +02:00
Heiko August
f7e8726d8b Change: reformatting of the function my_strlen 2024-03-31 15:10:07 +02:00
Heiko August
6080ed7d35 Change: reformatting of the function add_http_if_no_protocol 2024-03-31 15:10:07 +02:00
Heiko August
683aa02a23 Change: reformatting of the function is_pw_correct 2024-03-31 15:10:07 +02:00
Heiko August
33e169dcdc Change: reformatting of the function generate_pw_hash 2024-03-31 15:10:07 +02:00
Heiko August
ae9d6873a6 Change: reformatting of the function random_string 2024-03-31 15:10:07 +02:00
Heiko August
1b9f8a66b7 Change: reformatting of the function check_filename 2024-03-31 15:10:07 +02:00
Heiko August
5de0bda145 Change: refactoring of the function get_edit_authorization 2024-03-31 15:10:07 +02:00
Heiko August
31fcda37fa Change: small code style issue in the function format_time 2024-03-31 15:10:07 +02:00
Heiko August
8ac9dbf608 Change: small refactoring of the function tag_cloud 2024-03-31 15:10:07 +02:00
Heiko August
854c205ffc Change: reformatting of the function resize_image 2024-03-31 15:10:07 +02:00
Heiko August
c62c9cbc89 Change: reformatting of the function emailNotification2ModsAndAdmins 2024-03-31 15:10:07 +02:00
Heiko August
68a20d61ea Change: reformatting of the function child_ids_recursive 2024-03-31 15:10:07 +02:00
Heiko August
5d30abf1c8 Change: refactoring of the function smilies 2024-03-31 15:10:07 +02:00
Heiko August
afe23fedbf Change: reformatting of the function user_online 2024-03-31 15:10:07 +02:00
Heiko August
89bfcd01f7 Change: refactoring of the function get_child_ids
Merge the two consecutive queries.
2024-03-31 15:10:07 +02:00
Heiko August
c552bca3f9 Change: reformatting of the function shorten_url 2024-03-31 15:10:07 +02:00
Heiko August
d02eedbe25 Change: refactoring of the function shorten_link 2024-03-31 15:10:07 +02:00
Heiko August
19ff764fe8 Change: reformatting of the function quote_reply 2024-03-31 15:10:07 +02:00
Heiko August
e938a69938 Change: reformatting of the function quote 2024-03-31 15:10:07 +02:00
Heiko August
fca5bdd70f Change: reformatting of the function do_bbcode_code_email 2024-03-31 15:10:07 +02:00
Heiko August
7e4ef773ec Change: reformatting of the function do_bbcode_code 2024-03-31 15:10:07 +02:00
Heiko August
af1d79486c Change: reformatting of the function do_bbcode_size_email 2024-03-31 15:10:07 +02:00
Heiko August
98b5e4c48d Change: reformatting of the function do_bbcode_color_email 2024-03-31 15:10:07 +02:00
Heiko August
0fd36e6e40 Change: reformatting of the function do_bbcode_tex_email 2024-03-31 15:10:07 +02:00
Heiko August
ec5affd42e Change: reformatting of the function do_bbcode_img_email 2024-03-31 15:10:07 +02:00
Heiko August
29893a180d Change: reformatting of the function db_bbcode_msg_email 2024-03-31 15:10:07 +02:00
Heiko August
dbe9fa30b7 Change: reformatting of the function do_bbcode_email 2024-03-31 15:10:07 +02:00
Heiko August
95b0dfe717 Change: reformatting of the function do_bbcode_size 2024-03-31 15:10:07 +02:00
Heiko August
d820ff413e Change: refactoring of do_bbcode_color, split variables for valid colours into one for codes and one for names 2024-03-31 15:10:07 +02:00
Heiko August
7190b58a37 Change: replace function call of parse_monospace with identical parse_inlinecode
… and remove the function parse_monospace
2024-03-31 15:10:07 +02:00
Heiko August
64ed71df6b Change: reformatting of the function do_bbcode_msg 2024-03-31 15:10:07 +02:00
Heiko August
3db69d21ec Change: reformatting of the function do_bbcode_url
… and correction of a typo including its copy'n'paste comrads
2024-03-31 15:10:07 +02:00
Heiko August
68c1b109d0 Change: reformattion of the function contains_invalid_string 2024-03-31 15:10:07 +02:00
Heiko August
467806b037 Change: reformattion of the function is_valid_url 2024-03-31 15:10:07 +02:00
Heiko August
8c0f245909 Change: reformatting of the function parse_inlinecode 2024-03-31 15:10:07 +02:00
Heiko August
dbffc35163 Change: reformatting of the function bbcode_stripcontents 2024-03-31 15:10:07 +02:00
Heiko August
6957cb61d6 Change: a little formatting issue in function convertlinebreaks 2024-03-31 15:10:07 +02:00
Heiko August
12ff5a224d Change: refactoring of the function pagination
Mainly it's a replacement of if-else blocks with ternary operators.
2024-03-31 15:10:07 +02:00
Heiko August
621da24b6f Change: reformattion of the function convertlinebreaks 2024-03-31 15:10:07 +02:00
Heiko August
87f5459c40 Change: reformatting of the function make_link 2024-03-31 15:10:07 +02:00
Heiko August
c3a2ac6e59 Change: reformatting of the function get_thread_items 2024-03-31 15:10:07 +02:00
Heiko August
bc67558276 Change: reformatting of the function filter_category_selection 2024-03-31 15:10:07 +02:00
Heiko August
3b3b153bfc Change: reformatting of the function get_categories 2024-03-31 15:10:07 +02:00
Heiko August
6e6c3a7d31 Change: refactoring of the function get_settings 2024-03-31 15:10:07 +02:00
Heiko August
cb809c9f0d Change: refactoring of the function count_failed_logins 2024-03-31 15:10:07 +02:00
Heiko August
98321a912b Change: refactoring of the function log_out 2024-03-31 15:10:07 +02:00
Michael Lösler
65bb31f330
SameSite attribute in setcookie function (#705)
- SameSite attribute added in setcookie function, cf. #696
2024-03-25 21:16:04 +01:00
Michael Lösler
002b304461
SameSite (#704)
- added SameSite option as discussed by Auge #696
2024-03-25 20:00:40 +01:00
Heiko August
1a43219cf4 Change: add localised date formats for IntlDateFormatter::format
https://www.php.net/manual/de/intldateformatter.format.php
https://framework.zend.com/manual/1.12/en/zend.date.constants.html#zend.date.constants.selfdefinedformats
2024-03-22 22:47:14 +01:00
Heiko August
eb0f3f9bb5 Cleanup: solve a small formatting issue 2024-03-22 22:47:14 +01:00
Heiko August
ab13c0e323 Change: apply the enhancements of the danish translation by Tommy Nilsson
only a few changes need further research,
see the source: https://mylittleforum.net/forum/index.php?id=15763
2024-03-22 22:47:14 +01:00
Heiko August
6c7cacccf6 Change: retire the function compare_versions and use PHPs native version_compare instead 2024-03-21 22:16:18 +01:00
Heiko August
be29fc66b2 Fix: added queries for adding indexes to table mlf2_akismet_rating
Adding the indexes might be forgotten in earlier update scripts. Check for existence of the indexes and add them, if necessary.
2024-03-18 20:22:23 +01:00
Heiko August
44fef3f35d Fix: correct wrong order of queries
Put query for userdata table after comment line for entries table and vice versa
2024-03-18 20:22:23 +01:00
Heiko August
85b38d2d60 Change: taking over the files to upload and remove for the changes after the release of version 20220803.1 to previous starting points 2024-03-18 20:22:23 +01:00
Heiko August
bf9e22d836 Fix: broken and forgotten queries to set a new default source for loading MathJax
This adapts some of the changes in #674, authored by @fcaspar
2024-03-18 20:22:23 +01:00
Heiko August
b979e18971 Change: taking over the changes fro removing bad behavior to the other upgrade blocks 2024-03-18 20:22:23 +01:00
Heiko August
d584a71b14 Change: add the block for changes in an upgrade, starting from version 20220803.1 2024-03-18 20:22:23 +01:00
Heiko August
6eca946cba Fix: enlarge the column mlf2_useronline.ip from 15 to 128 Bytes
The column was not able to store IPv6 addresses before. That lead to HTTP-status 500 messages or to blank pages.
2024-03-18 20:22:23 +01:00
Heiko August
e1ca5d40dd Fix: restrict the column mlf2_logincontrol.ip to 128 bytes
This is enough to store IPv6 addresses and is the same lenght as the corresponding columns in the other tables
2024-03-18 20:22:23 +01:00
Heiko August
608483f0b0 Change: put a new version number to the file VERSION for testing purposes 2024-03-18 20:22:23 +01:00
Heiko August
d5f8a2ae8e Change: delete the old upgrade script update_2.4.19.1-2.5.php 2024-03-18 20:22:23 +01:00
Heiko August
a82d340a16 Change: rename update_2.4.19.1-2.5.dev.php to update_2.4.19-2.5.php 2024-03-18 20:22:23 +01:00
Heiko August
71c4b2c384 Change: add a notice about the fact, that the forum is deactivated
The forum gets deactivated at the beginning of the upgrade and remains deacivated after the upgrade until one activates it again in the settings page.
2024-03-18 20:22:23 +01:00
Heiko August
3767524018 Change: put files to delete into an own array and merge it to the end of the list of files to be updated 2024-03-18 20:22:23 +01:00
Heiko August
80d6b449d6 Fix: set the collation and charset also for the tables, introduced with v2.5 2024-03-18 20:22:23 +01:00
Heiko August
fb2659e70e Fix: alter the collation of the uploads table to utf8mb4_bin in every single upgrade step 2024-03-18 20:22:23 +01:00
Heiko August
785d11f32c Fix: correct a copy'n'paste error on top of a copy'n'paste error 2024-03-18 20:22:23 +01:00
Heiko August
a2fc79e3c4 Change: change charset to utf8mb4 and collation to utf8mb4_bin for the uploads table 2024-03-18 20:22:23 +01:00
Heiko August
47605d44c7 Change: add the charset and collation changes also to the installation script
This affects the tables mlf2_entry_tags and mlf2_bookmark_tags.
2024-03-18 20:22:23 +01:00
Heiko August
deba37269d Change: set the size of mlf2_b8_wordlist.token back to 255 bytes as it was initially when introducing B8 2024-03-18 20:22:23 +01:00
Heiko August
913484bac8 Change: remove the special case of charset utf8(mb3) for the column mlf2_userdata.user_email 2024-03-18 20:22:23 +01:00
Heiko August
24df928fea Change: set the charset to utf8mb4 and the collation to utf8mb4_bin in the new tables while creating them
… and add the keys in mlf2_b8_rating when creating the table and not afterwards.
2024-03-18 20:22:23 +01:00
Heiko August
56a6f5447b Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the user online table 2024-03-18 20:22:23 +01:00
Heiko August
2a227e7f43 Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the temporary information table 2024-03-18 20:22:23 +01:00
Heiko August
26fa69a945 Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the subscriptions table 2024-03-18 20:22:23 +01:00
Heiko August
aa0b84786c Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the smilies table 2024-03-18 20:22:23 +01:00
Heiko August
a8ca416948 Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the read entries table 2024-03-18 20:22:23 +01:00
Heiko August
9470172f6a Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the logincontrol table 2024-03-18 20:22:23 +01:00
Heiko August
b2988e44ab Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the entry tags table 2024-03-18 20:22:23 +01:00
Heiko August
f29e90ff7b Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the bookmark tags table 2024-03-18 20:22:23 +01:00
Heiko August
07ade7a701 Change: alter the charset to utf8mb4 and the collation to utf8mb4_bin in the settings table 2024-03-18 20:22:23 +01:00
Heiko August
19bb31f3ff Fix: remove regex flag g and use the correct variable name
Replace wrong $dbVersion with correct $serverVersion.
2024-03-18 20:22:23 +01:00
Heiko August
fce456c283 Change: replace the variables $databaseVersion with versionInfo 2024-03-18 20:22:23 +01:00
Heiko August
c4c8f8b93f Change: do not unnecessarily copy the variable into another one 2024-03-18 20:22:23 +01:00
Heiko August
d648efbd1c Fix: the result contains every variable in a separate row, loop through the result 2024-03-18 20:22:23 +01:00
Heiko August
2ba0fafaba Change: reformatting of the list of files to upgrade (upgrade starting with 20220517.1 or 20220529.1) 2024-03-18 20:22:23 +01:00
Heiko August
32acfc0b9e Change: add a try-catch block for a database transaction (upgrade starting with 20220517.1 or 20220529.1)
All changes for an upgrade, starting with version 20220517.1 or 20220529.1, are stored in a database transaction. This ensures, that the upgrade will succeed of will fail completely without leaving the forum in an unusable interim state.
2024-03-18 20:22:23 +01:00
Heiko August
e3e8466c05 Change: reformatting of the list of files to upgrade (upgrade starting with 20220508.1) 2024-03-18 20:22:23 +01:00
Heiko August
b29c4d1aab Change: add a try-catch block for a database transaction (upgrade starting with 20220508.1)
All changes for an upgrade, starting with version 20220508.1, are stored in a database transaction. This ensures, that the upgrade will succeed of will fail completely without leaving the forum in an unusable interim state.
2024-03-18 20:22:23 +01:00
Heiko August
16c634aa5d Change: reorder the list of files again and add further information
Upgrade is starting with version 2.4.99.1
2024-03-18 20:22:23 +01:00
Heiko August
862927bc45 Change: reorder the list of files again and add further information (pt. 2)
Upgrade is starting with versdion 2.4.99.0
2024-03-18 20:22:23 +01:00
Heiko August
722b7334a3 Change: reorder the list of files again and add further information
Upgrade starting with a version between 2.4.19 and 2.4.24
2024-03-18 20:22:23 +01:00
Heiko August
45a8950e4c Change: reformatting of the list of files to upgrade (upgrade starting with 2.4.99.2 or 2.4.99.3) 2024-03-18 20:22:23 +01:00
Heiko August
d84e0b52a7 Change: add a try-catch block for a database transaction (upgrade starting with 2.4.99.2 or 2.4.99.3)
All changes for an upgrade, starting with version 2.4.99.1, are stored in a database transaction. This ensures, that the upgrade will succeed of will fail completely without leaving the forum in an unusable interim state.
2024-03-18 20:22:23 +01:00
Heiko August
05695ce4ba Change: reformatting of the list of files to upgrade (upgrade starting with 2.4.99.1) 2024-03-18 20:22:23 +01:00
Heiko August
4d08b4d83b Change: add a try-catch block for a database transaction (upgrade starting with 2.4.99.1)
All changes for an upgrade, starting with version 2.4.99.1, are stored in a database transaction. This ensures, that the upgrade will succeed of will fail completely without leaving the forum in an unusable interim state.
2024-03-18 20:22:23 +01:00
Heiko August
fb86713d03 Change: reformatting of the list of files to upgrade (upgrade starting with 2.4.99.0) 2024-03-18 20:22:23 +01:00
Heiko August
fb77d4b52a Change: add a try-catch block for a database transaction (upgrade starting with 2.4.99.0)
All changes for an upgrade, starting with version 2.4.99.0, are stored in a database transaction. This ensures, that the upgrade will succeed of will fail completely without leaving the forum in an unusable interim state.
2024-03-18 20:22:23 +01:00
Heiko August
baa7570d72 Change: reformatting of the list of files to upgrade (upgrade starting with 2.4.19 to 2.4.24) 2024-03-18 20:22:23 +01:00
Heiko August
d6c9c89a21 Change: add a try-catch block for a database transaction (upgrade starting with 2.4.19 to 2.4.24)
All changes for an upgrade, starting with a stable version of the MLF 2.4 branch, are stored in a database transaction. This ensures, that the upgrade will succeed of will fail completely without leaving the forum in an unusable interim state.
2024-03-18 20:22:23 +01:00
Heiko August
9d54862439 Fix: use the correct variable and array key names 2024-03-18 20:22:23 +01:00
Heiko August
5724cac8df CHange: remove the code for changing the table type from the version specific upgrade sections 2024-03-18 20:22:23 +01:00
Heiko August
22307a8a52 Change: add a block for changing the table engine type
This block queries all tables that are not of type InnoDB and changes their type to Innodb in a loop. If none are found, nothing happens.
2024-03-18 20:22:23 +01:00
Heiko August
0e3dd39c24 Change: remove the check for uniqueness of e-mail-addresses (part 3)
Remove it from the upgrade block for version 2.4.99.1.
2024-03-18 20:22:23 +01:00
Heiko August
ceeba6c696 Change: remove the check for uniqueness of e-mail-addresses (part 2)
Remove it from the upgrade block for version 2.4.99.0.
2024-03-18 20:22:23 +01:00
Heiko August
bf0cd08df3 Change: remove the check for uniqueness of e-mail-addresses (part 1)
Remove it from the upgrade block for versions 2.4.19 to 2.4.24.
2024-03-18 20:22:23 +01:00
Heiko August
75166d9388 Change: separate the verification of e-mail addresses from the upgrade block
Check the uniqueness of e-mail-adresses only once and do not repeat the code in every upgrade block again and again.
2024-03-18 20:22:23 +01:00
Heiko August
7387cdf221 Change: check the database server versions and exit the upgrade in necessary
Because of the index size issue with utf8mb4 in MySQL < 5.7(.7) we need to ensure the database server to fulfill the index size for text columns to be able to store more than 767 Bytes. This was introduced with MySQL 5.7.7 (respective with MariaDB 10.2.2). Cancel the upgrade if this minimum requirement is not met.
2024-03-18 20:22:23 +01:00
Heiko August
d0e73e4996 Change: replace the repeated code for writing the version number with a function 2024-03-18 20:22:23 +01:00
Heiko August
ddb37963cb Change: add code block for upgrade starting from versions 20220517.1 and 20220529.1 2024-03-18 20:22:23 +01:00
Heiko August
89939c52ff Change: add code block for upgrade starting from versions 20220508.1 and 20220509.1 2024-03-18 20:22:23 +01:00
Heiko August
36ede4b147 Change: add code block for upgrade starting from versions 2.4.99.2 and 2.4.99.3 2024-03-18 20:22:23 +01:00
Heiko August
1b56e3b3ca Change: add code block for upgrade starting from version 2.4.99.1 2024-03-18 20:22:23 +01:00
Heiko August
9fe99c6e31 Fix: solve an copy'n'paste error, there is no variable $result in this script 2024-03-18 20:22:23 +01:00
Heiko August
9a9a09b54d Change: add the block for an upgrade, starting from version 2.4.99.0 2024-03-18 20:22:23 +01:00
Heiko August
5824261262 Change: add code block for upgrade starting from versions 2.4.19 to 2.4.24
Different from the now official upgrade script, that starts with version 2.4.19.1, this script also allows version 2.4.19 as starting point. This shouldn't be a problem, because there was no database specific change between 2.4.19 and 2.4.19.1.
2024-03-18 20:22:23 +01:00
Heiko August
6dc4f7d96e Change: add a new upgrade file with the basic infrastructure as its first content
The file will contain separate blocks for every version, one can start an upgrade from. The file will be renamed finally but will be a separate way for now.
2024-03-18 20:22:23 +01:00
Heiko August
02b36249db Change: basic formatting for the HTML-elements <ins>, <del> and <s> 2024-03-17 17:56:40 +01:00
Heiko August
9122a2338a Change: add the new BB-Codes [ins], [del] and [s] to mark subsequent changes
Corresponding HTML-elements: <ins>, <del>, <s>
2024-03-17 17:56:40 +01:00
Heiko August
a39605d7da Change: restrict the size of the column mlf2_logincontrol.ip to 128 bytes
This corresponds to the size of the corresponding columns in the other tables.
2024-03-10 21:58:32 +01:00
Heiko August
368c45bcb6 Fix: enlarge the column mlf2_useronline.ip from 15 to to 128 bytes in the installation code
The column size of 15 bytes was enough to store IPv4 but not to store IPv6 addresses. Additionally change the column type from char to varchar.
2024-03-10 21:58:32 +01:00
Heiko August
6dff9dd748 Change: setting the encoding with mysqli_set_charset and the collation with SET NAMES 2024-03-04 22:45:35 +01:00
Heiko August
762c947780 Fix: being not verbose to visitors with error reporting
fixes #688
2024-02-21 17:12:30 +01:00
Heiko August
9795d8fd99 Change: unify the header blocks including the guide in all language files 2024-02-21 17:02:15 +01:00
Heiko August
c959cc6713 Change: add an empty line between welcome address and the message text 2024-02-21 17:02:15 +01:00
Heiko August
4cc08384d5 Change: further translations, autored by akakima
see https://mylittleforum.net/forum/index.php?id=16845
2024-02-21 17:02:15 +01:00
Heiko August
6a51aa5d1b Change: use the correct punctuation rules for french language
Question marks, exclamation marks and punctuation colons need a leading space.
2024-02-21 17:02:15 +01:00
Heiko August
e9b8b54d5e Change: change further "mail" to "email"
Authored by akakima, see https://mylittleforum.net/forum/index.php?id=16845
2024-02-21 17:02:15 +01:00
Heiko August
18e86e316a Change: change "e-mail" to "email"
Authored by akakima (see https://mylittleforum.net/forum/index.php?id=16845).
2024-02-21 17:02:15 +01:00
Heiko August
675b99e45e Change: change "mail" to "email"
Authored by akakima (see https://mylittleforum.net/forum/index.php?id=16845).
2024-02-21 17:02:15 +01:00
Heiko August
295c24f653 Change: overhaul of the french language file, authorted by akakima 2024-02-08 11:10:58 +01:00
Michael Lösler
e9a13bd6d4
Check variable $categories (#687)
- Check whether $categories exists like in index.inc.php
- https://github.com/My-Little-Forum/mylittleforum/issues/685
2024-02-07 21:34:12 +01:00
fcaspar
f275e7395d
fixed missing double point (#674)
* fixed missing double point

* fixed false sql query

* fixed false sql query
2023-04-26 20:39:45 +02:00
Michael Lösler
43471266b3
Bad Behavior (#672)
- remove outdated module "Bad Behavior"
- https://mylittleforum.net/forum/index.php?id=10734
2023-03-18 16:35:04 +01:00
Heiko August
b327f6880c Change: reformat modules/captcha/captcha_image.php 2023-03-17 10:16:21 +01:00
Heiko August
d9580322ad Change: reformat modules/captcha/captcha.php 2023-03-17 10:16:21 +01:00
Heiko August
a98093b468 Change: prevent using imagerotate because it can break in rare corner cases, replace it with imageflip 2023-03-17 10:16:21 +01:00
vihuna
0c2ab4fc6b
fix: amends email recipient in contact links (#671)
`$recipient_email` must be taken from `recipient_user_id` GET parameter
when there is no post `id` (in `user` and `user_profile` templates).
2023-03-13 17:53:18 +01:00
Víctor Huertas
d8ceca5b31 fix(spanish): clean old unused entries 2023-03-06 09:45:40 +01:00
Víctor Huertas
b5b9bb319e fix(spanish): restores translated variable containers
Restores wrongly translated containers used for replacement with
variables.
2023-03-06 09:45:40 +01:00
Víctor Huertas
b25c9d575d fix(spanish): adds missing closing quotes 2023-03-06 09:45:40 +01:00
Víctor Huertas
0ec4279250 fix(spanish): makes uppercase/lowercase unification
Makes uppercase/lowercase unification of language items, depending on
the context.
2023-03-06 09:45:40 +01:00
Víctor Huertas
bf4b7c1c7c fix(spanish): corrects untranslated, imprecise entries
Improves/Corrects in previous translations: syntactically malformed,
semantically vague and untranslated entries.
2023-03-06 09:45:40 +01:00
Víctor Huertas
da2902b989 fix(spanish): unifies to informal addressing style
Items using a formal manner to address users are translated into an
informal addressing style.
2023-03-06 09:45:40 +01:00
Víctor Huertas
fa4a204bf8 fix(spanish): restores accent marks
Restores accent marks, add opening question marks and corrects some typos.
2023-03-06 09:45:40 +01:00
vihuna
c866f204c0
fix(lang): corrects typo in image bbcode instructions (#670)
Corrects typo in language files for image bbcode instructions, displayed
when javascript is disabled.
2023-03-01 16:14:42 +01:00
Heiko August
a61d6e56bb Change: add lazy loading attribute to img elements in forum entries
closes #666
2023-02-06 23:04:40 +01:00
Heiko August
18ea68f461 Fix: replace the hyphen with a dash where it has been used as such 2023-01-24 21:35:02 +01:00
Heiko August
a6deafeaa2 Fix: prevent the use of so called Deppenbindestrich (stupid hyphen) 2023-01-24 21:35:02 +01:00
Heiko August
0cc329869b Fix: correct the description for key where_to_open_links_all
This user setting activated, all links in a forum entry will open in a new browser window or tab.
2023-01-24 21:35:02 +01:00
Víctor Huertas
c4931b1a06 fix: corrects a typo 2023-01-23 21:24:18 +01:00
Víctor Huertas
c8fb2f86d8 fix: makes some corrections and minor improvements 2023-01-23 21:24:18 +01:00
Víctor Huertas
d4d229006e fix: restore removed/added lines by mistake 2023-01-23 21:24:18 +01:00
Víctor Huertas
56262ac509 lang: completes the spanish language
Completes the remaining `TODO` flags for the spanish language
2023-01-23 21:24:18 +01:00
Heiko August
606aa042bb Change: additional item mentioning the theming support 2023-01-22 18:53:03 +01:00
Heiko August
082b11b693 Fix: orphaned chars, wordings and formattings 2023-01-22 18:53:03 +01:00
Heiko August
b1c814c5cf Change: add a feature list to the readme file 2023-01-22 18:53:03 +01:00
Heiko August
30341735a7 Fix: headings should follow the common Markdown syntax 2023-01-22 18:53:03 +01:00
Heiko August
4e1a594d64 Fix: link to the project page should follow the common Markdown syntax 2023-01-22 18:53:03 +01:00
vihuna
1a99f5dfb3
fix: change date-time format in user administration (#659) 2023-01-03 16:55:21 +01:00
Heiko August
d137c1a406
Fix: wrong date formatting code in the users entries list, follow up of #647 (#657) 2022-12-27 11:04:10 +01:00
Heiko August
dcc8df0543 Change: add class .notice to system messages (error, caution and execution messages) 2022-12-26 22:11:47 +01:00
Heiko August
9b01dca510 Change: enlarge the contrast with a brighter beckground and a darker text colour 2022-12-26 22:11:47 +01:00
Heiko August
691c2b9dc7 Fix: make the selector more specific to apply the definition for margin-left to the first link item 2022-12-26 19:04:14 +01:00
Heiko August
3cb62a3304 Change: little adjustment for the user search bar (padding-bottom) 2022-12-26 19:04:14 +01:00
Heiko August
5d147bed29 Change: remove multiplied declaration of font size and make the selector more specific to make the font size declaration applying 2022-12-26 19:04:14 +01:00
Heiko August
93c346bc5f Change: remove classes pagination-index and pagination-index-table 2022-12-26 19:04:14 +01:00
Heiko August
8017b725cb Change: replace <input> of type submit with <button>, remove unnecessary <br /> 2022-12-26 19:04:14 +01:00
Heiko August
c46cd71c4a Cleanup: a little optimisation of the file size, remove the leading 0 for values < 1 2022-12-26 19:04:14 +01:00
Heiko August
3ebdd9d81c Change: adjustments for elements of class .normalform 2022-12-26 19:04:14 +01:00
Heiko August
e10260dc27 Change: a few adjustments for the pagination list 2022-12-26 19:04:14 +01:00
Heiko August
e937401f69 Change: reformat form and navigation elements in the admin area
- remove the fixed heights from a few elements
- remove floating because the affected elements follow the box content
2022-12-26 19:04:14 +01:00
Heiko August
03aeedda70 Change: exclude the pagination below the users list from the form 2022-12-26 19:04:14 +01:00
Heiko August
49bc9a6224 Change: display the label for the input field in user search form for a better accessibility 2022-12-26 19:04:14 +01:00
Heiko August
d47bb484bc Change: reconstruct the user search form
- put the label for the input field into the form beside the input field
- replace the input for the submit button with a real button
- exclude the hidden fields from the div in the form
- remove the float, that was intended for the form box inside #usernav
2022-12-26 19:04:14 +01:00
Heiko August
561069aef7 Change: clear boxes of id #userpagination, unnecessary after clearing #usernav 2022-12-26 19:04:14 +01:00
Heiko August
ea5e4186e6 Change: clear the box #usernav in all occurences 2022-12-26 19:04:14 +01:00
Heiko August
5531729308 Change: provide a heading for the user lists 2022-12-26 19:04:14 +01:00
Heiko August
cb52600946 Change: display an additional pagination link list at bottom of the uploaded images list 2022-12-26 19:04:14 +01:00
Heiko August
5b0299c308 Change: display an additional pagination link list on top of the users entries list 2022-12-26 19:04:14 +01:00
Michael Lösler
425b165d31
Formated date (#654)
- formated date corrected in user profile
2022-12-13 20:08:12 +01:00
Michael Lösler
304c5cd9cb
Date format (#653)
- Date format corrected in template for reporting SPAM/HAM
2022-11-24 13:18:52 +01:00
Heiko August
0b35c866ae Change: replace the str_replace solution for replacing of control chars with one with a regular expression 2022-11-23 19:12:59 +01:00
Heiko August
4535fade9b Fix: correct the possible field length of the column user_email to 255 chars 2022-11-23 19:12:23 +01:00
Heiko August
962aa1a23a Fix: read multiple times used e-mail-addresses from the database and interrupt the update in this case 2022-11-23 19:12:23 +01:00
Heiko August
f8aa07c1a2 Fix: reset the charset for column user_email after changing the charset of the table
The first repeat of setting of the column size (varchar(255)) is necessary to make the rest of the query (CHARSET SET and COLLATE) working.
The second query in the update procedure ensures the correct charset for the case of an update starting from version 2.4.99.1.
2022-11-23 19:12:23 +01:00
Heiko August
8c055f84d1 Fix: resize the column user_email before the change of the table charset to utf8mb4 2022-11-23 19:12:23 +01:00
Heiko August
9dbbaeab6a Fix: take the create table statements out of the transactions 2022-11-23 19:12:23 +01:00
Heiko August
2fa3340770 Fix: outsource the table drop queries from the table creation code
Dropping tables, that should not exist in this moment can be handled independently from the creation process of the tables.
2022-11-23 19:12:23 +01:00
Heiko August
1d4a34351b Fix: delete remaining tables from previous installations before creating them again
This fixes issues with upgrades of forum scripts from 2.4.x-versions to any 2.5-version, when there was a testing installation of a 2.5-development version, that created these tables before.

Often such testing installations with a following downgrade to a stable version results in remaining, orphaned tables, that breaks the update script in a later run, when it tries to create the tables again.

I put the queries to drop and create the tables into a transaction. Thatswhy I needed to introduce the function mysqli_multi_query to run all four queries per table at once.
2022-11-23 19:12:23 +01:00
Michael Loesler
c1617a7aa0 Comment
- comment corrected
2022-11-11 10:27:36 +01:00
Michael Loesler
dda30f8d39 Date Formatter
- IntlDateFormatter added to format timestamp values w.r.t. locale settings
- see: https://mylittleforum.net/forum/index.php?id=14719
2022-11-11 10:27:36 +01:00
Heiko August
91d9ae85be Fix: prevent passwords from spell checking for the case of displaying them with type="text"
This is necessary in browsers which sends content if input with type text to external spell checking services, as Chrome does with sending the content to a Google service.
2022-10-10 01:29:30 +02:00
Heiko August
498a28644f Fix: don't repeat yourself! corsor: pointer; already exists for label
I added cursor:pointer; for the HTML-element label long time ago. I now added the additional selectors to the existing rule.
2022-09-09 16:24:25 +02:00
Heiko August
dd030cc827 Change: change cursor to pointer when hovering buttons 2022-09-09 16:24:25 +02:00
Michael Lösler
069562f5b2
Mathjax (#637)
* Update MathJax

- MathJax updated to version 3
- Loading of mathjax resources prevented, if unnecessary (e.g. at main page)

* CDN

- CDN to recommended one changed, cf. https://docs.mathjax.org/en/latest/web/start.html
2022-08-09 17:48:33 +02:00
Heiko August
8fe0b4ed02 Fix: correct syntax error 2022-08-03 22:35:18 +02:00
Heiko August
f0737b8566 Change: add the changelog for the new version 20220803.1 2022-08-03 21:23:03 +02:00
Heiko August
0abbf3fa51 Change: add the list of files to update 2022-08-03 21:23:03 +02:00
Heiko August
63582f50dc Change: add version 20220529.1 to the list of updatable versions 2022-08-03 21:23:03 +02:00
Heiko August
6db3be4ede Change: new version number in index.php and config/VERSION 2022-08-03 21:23:03 +02:00
Heiko August
2fba87601e Change: reformatting of the requirements list 2022-08-03 17:01:40 +02:00
Heiko August
da689cb4ef Change: replace the HTML-link with a link in Markdown-syntax 2022-08-03 17:01:40 +02:00
Heiko August
00c76d86ec Change: add an upgrade manual to the readme file 2022-08-03 17:01:40 +02:00
Heiko August
70228e81b4 Fix: remove UNIQUE from the column definitions for user_name and user_email
The uniqueness of these columns is ensured by the key definitions at the end of the query.
2022-08-02 22:49:42 +02:00
Heiko August
bb8d540135 Fix: put the flex items to the end of the flexbox 2022-08-02 21:58:53 +02:00
Heiko August
f13d39ddab Fix: delete superfluous indexes in the userdata table, that was generated by accident 2022-07-25 20:57:31 +02:00
Heiko August
2769c82827 Fix: remove the keyword UNIQUE from the statement because it adds additional identical indexes 2022-07-25 20:57:31 +02:00
Heiko August
50776a9a38 Fix: change charset of column user_email to utf8 to prevent index size error
The charset has to be corrected before the index gets added. The code manipulates the upgrade section for version 2.4.99.2. The identical database query is also part of the upgrade to version 20220517.1. I was not able to produce an error when altering the column definition again with and to the same settings. So I have to assume, that the script will not break.
2022-07-25 20:57:31 +02:00
Heiko August
8b71161057 Fix: distinguish between entries that was locked before and was not classified and others
It was simpler for me to formulate the condition that way even there is no work done in the if-block.
2022-06-17 18:56:40 +02:00
Heiko August
4440cc4405 Change: request the locked status when reading the entry for classifying it as ham 2022-06-17 18:56:40 +02:00
Heiko August
52d73af150 Change: make the button list a flexbox 2022-06-17 18:06:40 +02:00
Heiko August
bbb9b00cc2 Change: replace input type submit with button elements and put only them into the div 2022-06-17 18:06:40 +02:00
Heiko August
7205d2c58d Change: also here is no need for clearing a float anymore 2022-06-12 21:09:15 +02:00
Heiko August
707fab47f8 Change: remove font colour definitions, where it only repeats the definition for the document 2022-06-12 21:09:15 +02:00
Heiko August
d0f70549b4 Change: because of the flexbox that makes the page using the whole viewport height we don't need a min-height for the content box 2022-06-12 21:09:15 +02:00
Heiko August
8a16d51dca Change: put margin and padding definitions for direct children of body into one definition 2022-06-12 21:09:15 +02:00
Heiko August
ccc34fbe01 Change: replace the div.header with the HTML-element header in all entry views 2022-06-07 23:01:45 +02:00
Heiko August
9f4f6d9baa Fix: images should stay inside the entry container
Images overflowed the container and was cut eat the edge because of the use of overflow:hidden; for the posting-content-container.
2022-06-07 23:01:45 +02:00
Heiko August
c0b302ae9f Change: reformat the entry-options-menu in all entry-views 2022-06-07 23:01:45 +02:00
Heiko August
47df7fbb14 Change: make the usermenu being a flexbox, it simplifies things 2022-06-07 23:01:45 +02:00
Heiko August
7367c74562 Fix: closing tag for the options list in the single entry view, was accidently removed a while ago 2022-06-07 23:01:45 +02:00
Heiko August
8b965a6ae8 Change: put the view count into a div instead a span 2022-06-07 23:01:45 +02:00
Heiko August
009be84331 Change: remove the div.info because it is superfluous 2022-06-07 23:01:45 +02:00
Heiko August
eb6159f933 Change: separate the entry footer from the block, that contains the entry content 2022-06-07 23:01:45 +02:00
Heiko August
80e1f06141 Change: make the whole block of an entry a HTML-element article 2022-06-07 23:01:45 +02:00
Heiko August
18bd913a85 Change: make the entry footer a HTML-element footer in every view 2022-06-07 23:01:45 +02:00
Heiko August
3fa12d1ad9 Change: add file extension webp to allow it to be displayed on image upload management page 2022-06-06 17:05:47 +02:00
Heiko August
7a01749112 Change: add file extension "webp" to the list of allowed types for deletion 2022-06-06 17:05:47 +02:00
Heiko August
8e530aca66 Change: add WebP-support to the image upload feature 2022-06-06 17:05:47 +02:00
Heiko August
a9493490ea Change: alter the file type detection for the image upload from getimagesize to mime_content_type 2022-06-06 17:05:47 +02:00
Michael Lösler
f27c4b5d85
Empty search box (#622)
The array `$search_string_array` is not initialised, iff the search box is left empty and cased an error/warning, cf. https://mylittleforum.net/forum/index.php?id=13112
2022-06-02 22:00:56 +02:00
Heiko August
3a94677d93 Change: adapt the HTML-structure of the single-entry-view to the posting preview 2022-06-02 15:29:17 +02:00
Heiko August
904a59239f Fix: put signature reliable below all posting content
Split the signature and tags container from the posting container and apply the necessary CSS rules.
2022-06-02 15:29:17 +02:00
Heiko August
e50e431ead Fix: remove column email_notification if it exists during the upgrade script run 2022-06-02 09:57:30 +02:00
Heiko August
71ed04301f Fix: remove column email_notification from statement in the function deleteUser 2022-06-02 09:57:30 +02:00
Heiko August
a98043099e Fix: remove column email_notification from create table statement 2022-06-02 09:57:30 +02:00
Heiko August
9b1e5fafe6 Change: add the necessary entries for the new version to the changelog 2022-05-29 21:00:27 +02:00
Heiko August
87b6308071 Change: add the new version number 20220529.1 to the main script and to config/VERSION 2022-05-29 21:00:27 +02:00
Heiko August
69ace45be6 Change: add the list of files to replace and to remove to the upgrade script 2022-05-29 21:00:27 +02:00
Heiko August
e3c1d7be69 Change: add version 20220517.1 to the list of upgradable versions 2022-05-29 21:00:27 +02:00
Heiko August
8c4703e56c Fix: remove notification about replies in case of deleting a user account
If the account gets deleted, we can assume, that the user doesn't wand to get further notifications about replies to the own forum entries.
2022-05-29 18:45:37 +02:00
Heiko August
ec55434336 Change: remove the obsolete PNG-images for the gradients 2022-05-29 18:27:49 +02:00
Heiko August
6ac3f668c2 Change: enhance the usability with amended rules for :focus, where they are absent
These rules doubles the rules for :hover. They was absent for *many* elements.
2022-05-29 18:27:49 +02:00
Heiko August
77b860f9ed Change: remove inline style for width of td.c in the spam protection settings 2022-05-29 18:27:49 +02:00
Heiko August
4b28070c3a Change: replace PNG-image based gradient for td.c and enlarge it to a width of 15em 2022-05-29 18:27:49 +02:00
Heiko August
db858986a3 Change: add element thead to tables explicitely, where necessary 2022-05-29 18:27:49 +02:00
Heiko August
8c5f57edd6 Change: add a dotted bottom border to the latest entries list 2022-05-29 18:27:49 +02:00
Heiko August
0da3a34843 Change: replace all remaining occurences of vertical gradients based on PNG-images with CSS-gradients 2022-05-29 18:27:49 +02:00
Heiko August
b4be6085e6 Change: join the rulesets for headings of blocks in #sidebar
… and replace the gradient PNG-image with a CSS linear gradient.
2022-05-29 18:27:49 +02:00
Heiko August
b6ba73297e Change: siplify the rules for .adminmenu 2022-05-29 18:27:49 +02:00
Heiko August
2ebce8cd2f Change: unify rules for child elements of #sidebar and #additiona-admin-info 2022-05-29 18:27:49 +02:00
Heiko August
9d83285644 Change: put #sidebar and #additiona-admin-info to top of the main content on narrow viewports 2022-05-29 18:27:49 +02:00
Heiko August
f53d05a791 Fix: put the icon image into a link element without href to make the Ajax-preview link keeping its position
The Ajax-preview link will be inserted before the first link. If the first link is positioned after the unclassified-icon, the Ajax-preview-link gets sorted in the wrong visual order.
2022-05-28 11:12:23 +02:00
Heiko August
17291852d4 Change: display the new icon if the entry is not yet classified as ham or spam 2022-05-28 11:12:23 +02:00
Heiko August
2fdbda26d0 Change: add the spam check status of an entry to the query and the resulting array
Adding the status to the resulting array under the condition of the requesting user is a moderator or an administrator of the forum.
2022-05-28 11:12:23 +02:00
Heiko August
e7bc8ea3f5 Change: add the query to set the column mlf2_userdata.user_email to charset utf8 (without mb4) 2022-05-17 21:44:24 +02:00
Heiko August
20eee1fe58 Change: document the changes in the changelog 2022-05-17 21:44:24 +02:00
Heiko August
ac29a3df01 Change: add the new version number 2022-05-17 21:44:24 +02:00
Heiko August
a5777451bc Change: add version 20220509.1 to the list of upgradable versions 2022-05-17 21:44:24 +02:00
Heiko August
3ddeb1f5cf Change: add the list of files to be replaced with the new version 2022-05-17 21:44:24 +02:00
Heiko August
d0001160c5 Change: code style (replace tabs with spaces for indentation) 2022-05-17 12:48:13 +02:00
Heiko August
d0b151f97e Change: new rule set for viewport widths >= 48em for the header child elements 2022-05-17 12:48:13 +02:00
Heiko August
5e83b4480c Change: add left padding to all entries in the user menu with exception of the first item 2022-05-17 12:48:13 +02:00
Heiko August
76f8dd42a5 Change: remove "display: inline;" for the search form
The rule had no equivalent in style.css
2022-05-17 12:48:13 +02:00
Heiko August
032b5a11be Change: adjust the bottom margin of the user menu to make the gap to the search box a bit smaller 2022-05-17 12:48:13 +02:00
Heiko August
74303711fe Change: adjust the font size for the main heading (h1) a bit 2022-05-17 12:48:13 +02:00
Heiko August
77cb0c5109 Change: put the main boxes in header directly one below the other 2022-05-17 12:48:13 +02:00
Heiko August
d679c4692f Fix: apply "h1 a" CSS-rules for :hover also to :focus 2022-05-17 12:48:13 +02:00
Heiko August
722d64451a Change: let the header take the necessary height
Let the header take any height and use a css-linear-gradient instead the fix-height-image.
2022-05-17 12:48:13 +02:00
Heiko August
5d0a600e70 Change: adapt the changes for the header search form to CSS 2022-05-17 12:48:13 +02:00
Heiko August
39f03939da Change: rework the search form
- put the hidden field outside the <div>
- display the label for the search field
- change the input-type from text to search
- display the submit button
2022-05-17 12:48:13 +02:00
Heiko August
6de0bfcd14 Fix: define the column user_email with character set utf8 (without mb4)
This prevents the matching index key_user_email to exceed the maximal size of an index on MySQL-server with a version below 5.7.
2022-05-15 21:14:41 +02:00
Heiko August
ab3274b57d Fix: add a forgotten closing bracket to the query
see #601 for the details, thanks to @prbt2016 for the report
2022-05-15 21:14:41 +02:00
Heiko August
3e43de3ba5 Change: stronger limit for the number of inactivity messages
Defines the number of users, that are selected for sending the inactivity messages during one run of the daily actions.
2022-05-15 14:01:59 +02:00
Michael Lösler
07713c11d1
Restrict number of mails (#603)
* Restrict number of mails

- Number of notification mails restricted to 25
- Condition removed that checked the return value of my_mail

* Number of mails

- Number of mails restricted to 20 as suggested by @auge8472
- Condition added
2022-05-12 10:10:46 +02:00
Heiko August
2766a3120f Change: add additional steps to the installation instruction 2022-05-09 22:42:00 +02:00
Heiko August
fbbfd1fdf5 Change: raise the minimal PHP-version from 5.4 to 7.3 2022-05-09 22:41:25 +02:00
Heiko August
001e441b12 Change: add the changelogs for the versions between 2.4.22 and 20220509.1
… ordered by their release dates
2022-05-09 22:30:46 +02:00
Heiko August
596be52ba1 Change: provide the new version number in the copyright notice in index.php 2022-05-09 21:04:26 +02:00
Heiko August
92bd54f9b3 Change: provide the new version number in the file config/VERSION 2022-05-09 21:04:26 +02:00
Heiko August
6e545a07bf Change: add the changelog for the new version 20220509.1 2022-05-09 21:04:26 +02:00
Heiko August
f072b25def Change: add the list of files to replace to the update script 2022-05-09 21:04:26 +02:00
Heiko August
13fd3a6ceb Change: put version 20220508.1 to the list of updatable versions 2022-05-09 21:04:26 +02:00
Heiko August
436dee45e1 Fix: corrected a false friend (German: "aktuell" to wrong English "actual"), correct is "currently" 2022-05-09 20:42:11 +02:00
Heiko August
e718e5903b change: use a flexbox to fix the footer to the bottom of the viewport in every case 2022-05-09 20:24:26 +02:00
Heiko August
c65f5718be Change: use modern, semantic HTML-elements to give the page a base structure
Put the div with the copyright notice into the page footer.
2022-05-09 20:24:26 +02:00
Heiko August
5764cc0788 Change: use 1em as base font size instead the IE6-bug-fixing 100.01% 2022-05-09 20:24:26 +02:00
Heiko August
200bc0ad03 Change: remove CSS fixes for ancient browsers IE 6 and IE7 2022-05-09 20:24:26 +02:00
Prashant Tondale
75e1d87cad Update index.php
Add closing round brace
2022-05-09 14:47:26 +02:00
Heiko August
d049b498ab Change: add the list of changes, updates, fixes and features to the changelog file 2022-05-08 18:07:13 +02:00
Heiko August
7c5d798c19 Change: add the new version number to the introducing comment block in index.php 2022-05-08 18:07:13 +02:00
Heiko August
9e21b01afd Change: add all database changes to the file update/update.sql 2022-05-08 18:07:13 +02:00
Heiko August
0e965f125b Change: new version number inthe file config/VERSION 2022-05-08 18:07:13 +02:00
Heiko August
243a0fd678 Fix: add the lost bracket, it's non existence caused a syntax error 2022-05-08 18:07:13 +02:00
Heiko August
cd962b0fa0 Change: add the list of files to replace to the completed list of versions 2022-05-08 18:07:13 +02:00
Heiko August
2338871205 Change: add the interim versions between 2.4.20 and 2.4.99.0 to the list of versions that are upgradable 2022-05-08 18:07:13 +02:00
Heiko August
a921dcba7b Change: add key creation for B8_spam and B(_training_type to the update and installation script 2022-05-08 18:07:13 +02:00
Heiko August
cd6365bfff Change: add the unique keys that appears in the update script also to the installation script and vice versa 2022-05-08 18:07:13 +02:00
Heiko August
616894bdb8 Change: add the versions between 2.4.20 and 2.4.99.0 to the list of versions to update 2022-05-08 18:07:13 +02:00
Heiko August
3e62ff55be Change: make key_user_name UNIQUE as in the update script
See update_2.4.19.1-2.5.php, block for update up to 2.4.99.3, ALTER TABLE mlf2_userdata
2022-05-08 18:07:13 +02:00
Heiko August
3ec6d7cc1f Cleanup: remove the commented replaced and outdated function calls of strftime 2022-05-01 17:53:56 +02:00
Heiko August
e5ee7fbd40 Change: replace a remaining strftime with date
See Github PR #587
2022-05-01 17:53:56 +02:00
Heiko August
3850208d5d Change: return an empty provided string before starting the processing in the function my_substr 2022-05-01 17:46:00 +02:00
Heiko August
adedc72d7c Change: check variables for content because null value for function (l|r)trim is deprecated with PHP 8.1 2022-05-01 17:46:00 +02:00
Michael Lösler
416119b21d
Check database (#593)
- check if database name is passed
2022-04-29 17:03:27 +02:00
Michael Lösler
b0eb5e2381
Key (#592)
- corrected key as suggested by @auge8472
2022-04-29 16:53:16 +02:00
Michael Lösler
fa5fa08746
Installation routine (#591)
- set `error_reporting = 0` for smarty because this function depends on the php function `error_reporting()`
- check `$db_settings['database']` as suggested by @auge8472 cf. https://mylittleforum.net/forum/index.php?id=12699
- call `mysqli_select_db` function removed
2022-04-29 16:49:55 +02:00
Michael Lösler
13924604fd
get_magic_quotes_gpc removed (#590)
- get_magic_quotes_gpc removed because this function returns alwas false
- get_magic_quotes_gpc is deprecated cf. https://www.php.net/manual/en/function.get-magic-quotes-gpc.php
- see also #552, #553
2022-04-29 16:10:47 +02:00
Heiko August
47f74927f4 Change: move the remaining function call for DragAndDropTable from admin.js to main.js (and .min) and delete admin(.min).js 2022-04-27 12:09:34 +02:00
Heiko August
3820003079 Change: remove strings for confirmation, provided as JS-native confirm dialogue 2022-04-27 12:09:34 +02:00
Heiko August
8c5dfc19fd Change: remove the backup feature related strings from the language files
There is an exception affecting the strings that are meant to get dynamically added to the JS sources.
2022-04-27 12:09:34 +02:00
Heiko August
6b01eb88bd Change: remove Backup.class.php
There was no reference for this class in the whole PHP-code!
2022-04-27 12:09:34 +02:00
Heiko August
a42e1618d8 Change: remove the icon image for the backup feature 2022-04-27 12:09:34 +02:00
Heiko August
0020350ace Change: remove function restore_backup 2022-04-27 12:09:34 +02:00
Heiko August
32cca5deaa Change: remove function create_backup_file 2022-04-27 12:09:34 +02:00
Heiko August
fc4b7fe5da Change: remove the PHP-code for generating the UI of the backup feature 2022-04-27 12:09:34 +02:00
Heiko August
0cc6e5de73 Change: remove last check for a valid delete action for a backup file 2022-04-27 12:09:34 +02:00
Heiko August
5c68f42a79 Change: remove the code for restoring data from a backup file 2022-04-27 12:09:34 +02:00
Heiko August
163504e126 Change: remove the code for running a backup creation 2022-04-27 12:09:34 +02:00
Heiko August
7293d55ea0 Change: remove the code for deleting backup files 2022-04-27 12:09:34 +02:00
Heiko August
eaa347ebdc Change: remove the code for downloading a backup file 2022-04-27 12:09:34 +02:00
Heiko August
b4695747e2 Change: remove the frontend of the backup feature we plan to remove 2022-04-27 12:09:34 +02:00
Heiko August
39a0c3b00b Refactor: code style, use spaces for indentation 2022-04-24 21:56:55 +02:00
Heiko August
f76488f11d Change: let default theme use modern HTML(5) 2022-04-24 21:56:55 +02:00
Michael Lösler
0e62783d9b
strftime (PHP 8) (#587)
- strftime has been dprecated as of PHP 8.1
- replaced by date
2022-04-22 22:05:15 +02:00
Michael Lösler
ef9c673930
isset (#586)
- replaced empty by isset to pass 0
2022-04-22 18:28:14 +02:00
Michael Lösler
b3f1fa4e04
Automatic conversion (#585)
- Automatic conversion of false to array is deprecated in PHP 8
2022-04-22 18:25:46 +02:00
Michael Lösler
332551b15c
Passing null (#584)
- PHP 8.1 PHP Deprecated: implode(): Passing null to parameter #1 ($string) of type string is deprecated
- checked first parameter
2022-04-22 18:13:51 +02:00
Michael Lösler
adc6392686
PHPMailer v6.6.0 (#583)
- updated PHPMailer v6.6.0
2022-04-22 17:55:00 +02:00
Michael Lösler
3ea84709db
Samrty v4.1.0 (#582)
- updated Smarty v4.1.0
2022-04-22 17:16:45 +02:00
Michael Lösler
9b7a803302
create_function (PHP 8) (#581)
- create_function has been removed in PHP 8
- replaced by anonymous function
2022-04-22 14:45:13 +02:00
Michael Lösler
38fc8f5a79
Type Error (#580)
- Uncaught TypeError: Cannot read properties of undefined (reading 'push') was thrown, if compressed version was loaded
- posting.js is compressed (without changes) using https://refresh-sf.com/
2022-04-21 16:47:38 +02:00
Michael Lösler
b8daf951c0
Type Error (#579)
- Uncaught TypeError: Cannot read properties of undefined (reading 'push') was thrown, if compressed version was loaded
- admin.js is compressed (without changes) using https://refresh-sf.com/
2022-04-21 15:55:28 +02:00
Michael Lösler
563eb22ef3
Default target (#578)
- The default target (specified in forum settings by the admin) is used to open links in a dedicated frame
2022-04-21 15:48:28 +02:00
Michael Lösler
d0b85b361f
Typo (#577)
- Typo corrected in i18n file
2022-04-21 14:15:07 +02:00
Heiko August
33842ad3cb Change: prioritise the user setting open_links_in_new_window over the general setting forum_based_link_target 2022-04-20 10:13:29 +02:00
Heiko August
3b1acd2a09 Fix: read the user setting browser_window_target from the correct array
To use the array $usersettings as source is wrong because it is as an interim step to enlive $_SESSION[mlf2_usersettings] in all other cases. So using $_SESSION[mlf2_usersettings]as the source is the right way to go.
2022-04-20 10:13:29 +02:00
Heiko August
bb65829732 Change: print the forum setting link_open_target to the JS-array settings 2022-04-20 10:13:29 +02:00
Heiko August
2ccf978ad4 Fix: put the value of browser_window_target to the usersettings whenever it get read or edited 2022-04-20 10:13:29 +02:00
Heiko August
88b6e3bf0f Fix: correct the logic in the condition 2022-04-20 10:13:29 +02:00
Heiko August
0219b97031 Change: simplify the condition to remove an invalid input for link_open_target 2022-04-20 10:13:29 +02:00
Heiko August
c4d155f3ec Fix: finish a line of code with a semicolon! (dammich nochma) 2022-04-20 10:13:29 +02:00
Heiko August
922ce14809 Fix: order of parameters for in_array (first: needle, second: haystack) 2022-04-20 10:13:29 +02:00
Heiko August
dbbc196ea8 Fix: correct key name for the setting description 2022-04-20 10:13:29 +02:00
Heiko August
07749530ea Fix: space between "{1," and "254}" led the regex to be broken on regex101.com (where I tested it) 2022-04-20 10:13:29 +02:00
Heiko August
81f1ddb5e6 Change: check link target setting for allowed values and replace everything else with an empty string
Allowed values:

- "_self", "_parent", "_top" (comparision with in_array)
- a freely chosen frame name (comparision with a regular expression, maximum length: 255 chars)
2022-04-20 10:13:29 +02:00
Heiko August
541e298112 Fix: remove the not planned value '_blank' from the desscription and fix a few spelling errors 2022-04-20 10:13:29 +02:00
Heiko August
f3bbb7a50e Change: add input and text description for the link-target to the forum settings page 2022-04-20 10:13:29 +02:00
Heiko August
a5e4f0f890 Fix: set the default value for 'link_open_target' to an empty string instead of '0' 2022-04-20 10:13:29 +02:00
Heiko August
c3ad3b5e12 Change: add new setting 'link_open_target' to the update procedure 2022-04-20 10:13:29 +02:00
Heiko August
20537f01ba Change: add new setting 'link_open_target' to the install procedure 2022-04-20 10:13:29 +02:00
Michael Lösler
6cac6fd6c2
Compression (#574)
- compressed main.js using https://refresh-sf.com/
2021-09-21 22:46:03 +02:00
Michael Lösler
17c7ec58bb
Array name (#573)
- changed array name back to avoid confusion
2021-09-21 21:50:32 +02:00
Michael Lösler
880e69f752
Link target (#546)
* Link target

- add or remove link target depending on user preferences given by `user_settings["open_links_in_new_window"]`, cf. https://mylittleforum.net/forum/index.php?id=12381

* IE support

- add includes prototype to support IE

* Typo

- corrected case name, NON --> NONE

* Rename array

- rename array user_settings to settings
- added target argument in function setLinkTarget, cf. https://mylittleforum.net/forum/index.php?id=12611
2021-09-21 21:46:54 +02:00
Heiko August
5c735e1282 Fix: add all relevant keys and strings for browser-window-target user setting to the new language traditional chinese 2021-09-20 20:38:35 +00:00
Heiko August
8e4fae2ef2 Fix: add the case DEFAULT and correct NON to NONE 2021-09-20 19:50:35 +00:00
Heiko August
d222fe24f8 Change: provide corrections, strings, template and processing code for the third setting 2021-09-20 19:50:35 +00:00
Heiko August
658ee54b0e Change: create the JS-array user_settings and store the matching values for the users window target setting 2021-09-20 19:50:35 +00:00
Heiko August
13de96e16e Change: read the new user setting from the user data entry and put it into the array $usersettings 2021-09-20 19:50:35 +00:00
Heiko August
53fe923152 Change: store the new user setting in the table for user data 2021-09-20 19:50:35 +00:00
Heiko August
e8e0abbeb0 Change: read the new setting from the database and populate the matching form elements 2021-09-20 19:50:35 +00:00
Heiko August
405d607a99 Change: create the table column mlf2_userdata.browser_window_target
Default is 0 for opening links in the same window/tab.
2021-09-20 19:50:35 +00:00
Heiko August
6ca899b2fb Change: create form elements for selecting the value for the setting to open links in the same or a new browser window/tab 2021-09-20 19:50:35 +00:00
Heiko August
dd9a9304ed Change: provide strings for the new user setting to open links in a new window or tab 2021-09-20 19:50:35 +00:00
Michael Lösler
fb8206e065
user lock state (#571)
- delete inactive users that are *not* locked by the form admin
2021-09-19 16:58:44 +02:00
Michael Lösler
c08ba33ca2
CSRF (#570)
- remove call of die-function, if csrf token is expired, cf. https://mylittleforum.net/forum/index.php?id=12531
2021-09-03 15:49:49 +02:00
Michael Lösler
55fb445c35
Chinese lang (#569)
Chinese language pack added, cf. https://mylittleforum.net/forum/index.php?id=12595
2021-09-02 22:43:21 +02:00
Michael Loesler
5aad6442e1
Unique values (#567)
- Columns `user_name` and `user_email` are set to `UNIQUE`
2021-03-05 17:25:08 +01:00
Michael Loesler
7dce5cc62b
Email collision (#566)
* Check for collision

- SQL statement modified to check against email collision
- re-format source code

* error massage

- error message is added for key `error_email_collision`
2021-03-03 20:54:17 +01:00
Michael Loesler
2cec4bdfc4
Activation mail (#565)
- Language part for `emails` was not loaded to the user
- ConfigLoad is added, cf. https://github.com/ilosuna/mylittleforum/issues/564
2021-03-03 20:24:21 +01:00
Michael Loesler
454e392dee
B8 spl autoload register (#562)
* B8

- prepare fies for new b8 version

* Update B8

- add new b8 classes

* Update b8.php

- modify spl_autoload_register function to prevent errors
- cf. https://gitlab.com/l3u/b8/-/merge_requests/1
2021-02-28 21:29:12 +01:00
Michael Loesler
5317c6024d
B8 former version (#561)
- switching back to former b8 version
- there are some unsolved conflicts up to now (I don't know the reason yet)
- comment symbol # of former version is replaced by //
- tested on PHP7/8
2021-02-28 13:37:42 +01:00
Michael Loesler
0a95ebc4d9
create_function PHP 7.4 (#560)
- Function create_function() is deprecated in PHP 7.4
- Closure is used to handle anonymous functions in preg_replace_callback
2021-02-27 16:11:01 +01:00
Michael Loesler
0c7055232c
Comments (#559)
- comment symbol '#' is replaced by '//' because a new version is NOT available
- there are a lot of "FIXME"; is it realy a trustworthy module?!
2021-02-27 15:50:05 +01:00
Michael Loesler
d1225f55b8
curly braces (#558)
- Array and string offset access syntax with curly braces is deprecated in PHP 7.4
- Array and string offset access syntax with curly braces is removed in PHP 8
- replaced {} - braces by [] - braces
2021-02-27 15:33:37 +01:00
Michael Loesler
643e9ae96b
Update module (#557)
- update B8 version 0.7
- namespace is added (e.g. b8::HAM --> b8\b8::HAM)
2021-02-27 15:09:52 +01:00
Michael Loesler
91f0b42a5c
Module update (#556)
- smarty version 3.1.39
2021-02-27 14:14:48 +01:00
Michael Loesler
4abb9edbef
Module update (#555)
- VERSION 6.3.0
2021-02-27 14:12:01 +01:00
Michael Loesler
d2a112f35c
Comment symbol (#554)
- # is no longer interpreted as the start of a comment, as this syntax is now used for attributes, cf. https://www.php.net/manual/en/migration80.incompatible.php
- comments are removed, if they are identified as /obsolete fragments/, i.e., former code/debugging code
- comment symbol '#' is replaced by '//'
2021-02-27 13:08:34 +01:00
Michael Loesler
82de4dea4b get_magic_quotes_gpc
- get_magic_quotes_gpc is removed because this function returns alwas false
- get_magic_quotes_gpc is deprecated cf. https://www.php.net/manual/en/function.get-magic-quotes-gpc.php
- see also https://github.com/ilosuna/mylittleforum/issues/552
2021-02-21 17:34:21 +00:00
Michael Loesler
d7b0e9d47b
SPAM postings of a user (#551)
- Postings classified as SPAM are accessible via user-area
- A modified SQL stmt restricts the postings list and filters SPAM postings for normal users
- cf. https://mylittleforum.net/forum/index.php?id=12422
2020-12-10 23:18:54 +01:00
Urfin®
635c4c164b
Update russian.lang (#549)
A literal error fixed
2020-11-06 17:44:06 +01:00
Urfin-Juce
7cc79a1765
Update russian.lang (#548)
Translated all <!-- TODO -->, and some minor fixies for previously translated terms.

WBR, Victor aka Urfin®
2020-11-06 14:21:24 +01:00
Heiko August
bc7c325d4f Change: alter the doctype, change from XHTML 1.0 strict to XHTML 1.0 transitional 2020-10-26 22:29:28 +01:00
Michael Loesler
cba8e70485
DOMContentLoaded (#545)
- use DOMContentLoaded to init scrips on (DOM) load
2020-10-26 21:46:17 +01:00
Michael Loesler
095a098182
main.js (#544)
- clean main.js
2020-10-26 21:33:30 +01:00
Heiko August
48870602f6 Change: let the HTML-structure in the single entry view match the structure in the threaded views
Only exception is the id on div.wrapper that seems to make no sense to me in the context of the single entry view.
2020-10-26 19:16:39 +01:00
Michael Loesler
39753c8604
Clean script files (#543)
- remove out-dated sources
- translate comments of functions
- https://mylittleforum.net/forum/index.php?id=12389
2020-10-26 18:06:14 +01:00
Heiko August
5d8e05ced6 Fix: correct silly typo 2020-10-15 22:07:09 +02:00
Heiko August
32605843ca Change: add necessity of uploading the file config/VERSION to the update notices
Additionally split the notice about uploading the update script from the notice about unpacking the zipped package.
The only exception from the latter action is the tamil language file.
I wasn't able to find the place to cut the notices because of the total absense of tamil language skills.
2020-10-15 22:07:09 +02:00
Heiko August
09920bd1c1 Fix: delete hyperfluous comma 2020-10-12 17:14:00 +02:00
Heiko August
9456cd2330
Unify HTML-structure for RSS links in the entry views (#537)
* Change: add a HTML structure similar to the one in entry.inc.tpl

With the same structure we can use the same CSS-rules instead adding further selectors for different structures.

* Fix: add title attribute to the RSS-link as in the other views

* Fix: don't fix language dependent issues in CSS that takes effect in any language

* Change: remove the additional selectors for the different HTML-structures from CSS
2020-10-12 15:58:56 +02:00
Heiko August
5b9763f164 Change: add field user_type to the thread tree informations and add classes to the user name elements 2020-10-12 12:33:06 +02:00
Michael Loesler
ffbea1564e
CSS for RSS of the Thread (Thread View) (#534)
- added padding to to the link to the rss-feed of the thread (in thread view)
- padding was removed during re-organisation of the footer, cf. #531, #533, but the link is not part of the footer
- see https://mylittleforum.net/forum/index.php?id=12336
2020-10-05 09:28:49 +02:00
Michael Loesler
8378ba034d
CSS for RSS of the Thread (#533)
- added padding to to the link to the rss-feed of the thread (in entry view)
- padding was removed during re-organisation of the footer, cf. https://github.com/ilosuna/mylittleforum/pull/531, but the link is not part of the footer
2020-09-30 12:48:04 +02:00
Michael Loesler
79c49eacf9
Corrected comment (#532)
- corrected comment in i18n files, i.e. replaced `</--` by `<!--`
- see https://github.com/ilosuna/mylittleforum/pull/530
2020-09-30 12:39:15 +02:00
Heiko August
dd80b35c6d
Merge pull request #531 from auge8472/smallfix
Fix for invalid HTML structure introduced in #530
2020-09-29 21:54:07 +02:00
Heiko August
2aced19d4f Change: removed unnecessary semicolons in the last rules in a set 2020-09-29 21:45:57 +02:00
Heiko August
43f3a67e6d Fix: correct invalid HTML structure for the footer menu no. 2
Every link in the menu is now encapsulated in its own list item.
The padding of the links with an icon got realigned.
2020-09-29 21:40:55 +02:00
Heiko August
0f1c21e5eb Change: add link to top of page to every entry and the footer of every page 2020-09-13 21:09:14 +02:00
Michael Loesler
c7eeb1fb9e
Auto delete spam (#528)
* Delete SPAM

- corrected (automated) deleting of SPAM entries via `daily_actions` by calling existing function `delete_posting_recursive`
- see https://mylittleforum.net/forum/index.php?id=12272

* Update TID

- changed order to avoid that `TID != ID`, i.e., if some SQL statements raises an error
- see https://mylittleforum.net/forum/index.php?id=12275
2020-07-04 16:22:17 +02:00
Michael Loesler
39e529952c
remove account (#527)
- the complete code for deleting the account was moved to a function, see function.inc.php::deleteUser, thus, this _new_ function is called here, too
2020-04-29 11:02:53 +02:00
Michael Loesler
cc13b0b054 comment
- removed comment in subject text
- added new comment `# <!-- TODO --> #` above
2020-04-29 10:51:18 +02:00
Michael Loesler
6450b68d42 change phrases
- used the recommended phrase "nicht aktiven" instead of "inaktiven"
2020-04-29 10:51:18 +02:00
Michael Loesler
5571c26fcd corrected phrase
- replaced DSGVO by GDPR (as suggested by Auge)
2020-04-29 10:51:18 +02:00
Michael Loesler
7bf395ab47 format
- added dashes
2020-04-29 10:51:18 +02:00
Michael Loesler
eb21f4647e email text
- added english version of notification message
2020-04-29 10:51:18 +02:00
Michael Loesler
f04a6773bf load emails config
- loaded emails config from  language file as defined in e.g. posting.inc.php
2020-04-29 10:51:18 +02:00
Michael Loesler
7870f026d7 sql changes
- added two options to setting table
  + delete_inactive_users (default 30, unit days)
  + notify_inactive_users (default 3, unit years)
- added new column in user table `inactivity_notification` of type boolean
2020-04-29 10:51:18 +02:00
Michael Loesler
54730b5a42 handle inactive users
- added global var $lang to get access to the lang-file for creating the notification email
- improve SQL stmt
2020-04-29 10:51:18 +02:00
Michael Loesler
5927fd1129 daily actions
- added function call of daily actions to the end of the index.php
2020-04-29 10:51:18 +02:00
Michael Loesler
5c6d7aedd7 email
- corrected some phrases
2020-04-29 10:51:18 +02:00
Michael Loesler
9ddb6d828a daily actions
- remove the call of the daily actions because the lang-file is not loaded yet
- daily action is called at the end of the index.php
2020-04-29 10:51:18 +02:00
Michael Loesler
24d45be4c0 inactive state
- update `inactivity_notification` flag while using auto login
2020-04-29 10:51:18 +02:00
Michael Loesler
912c547f9e handle inactive users
- added function to handle inactive users
2020-04-29 10:51:18 +02:00
Michael Loesler
b12cb3c6c2 flag
- set `inactivity_notification` flag during log-in
2020-04-29 10:51:18 +02:00
Michael Loesler
d66d52eeb6 notification text
- added notification text to german and english i18n file
2020-04-29 10:51:18 +02:00
Michael Loesler
4135a82fbf
access to user area (#525)
- it was impossible for an user to change its own(!) settings or to show its own(!) posting list, if `$settings['user_area_access']` was restricted to mods and admins
- corrected/moved condition to the _right_ place to enable access to user area (if enabled) and to allow for editing user settings
2020-04-28 19:38:17 +02:00
Heiko August
c64697b3e4 Change: revert to regex for e-mail checking with the PHP-7.3-compatible syntax
The function filter_vars is not able to validate e-mail-addresses from Punycode-domains.
2020-04-25 20:03:21 +02:00
Michael Loesler
1253f998ef
Key for error message (#523)
- Key 'error_email_wrong' was not unique and provides error message "Array"
- changed one key in lang-files 'error_email_wrong' --> 'admin_reg_error_email_wrong'
- see https://mylittleforum.net/forum/index.php?id=12205
2020-04-23 11:19:52 +02:00
Michael Loesler
7f54da56de
Store SPAM entry (#522)
- check, if an entry that is classified as SPAM by B8 should stored to the DB (or not)
2020-04-11 19:31:41 +02:00
Michael Loesler
7092ebf0b4
Display spam threads option (#521)
* show SPAM

- removed option to show SPAM, if no SPAM is available

* unset vs. false

- Since we check via isset (and not the value itself), unset is used to remove the option
2020-04-06 13:48:53 +02:00
Michael Loesler
caddfb6b9f
auto delete spam (#520)
- corrected SQL for auto delete spam
- spam is deleted if at least one service classified an entry as spam
2020-04-06 11:08:45 +02:00
Michael Loesler
09bdfc8926
RTL / LTR - tags (#519)
- added bb-code tags [RTL] and [LTR]
- reformatted functions
- see https://mylittleforum.net/forum/index.php?id=12148
2020-03-15 18:00:54 +01:00
Michael Loesler
38db0ff3e0
bad-behavior (#518)
- bad-behavior v.2.2.24
2020-02-22 14:28:54 +01:00
Daniel
5971f28ec9 Update swedish.lang (#514)
Update the swedish language file
2019-10-27 08:59:54 +01:00
Heiko August
2358760939
Change: natural, case insensitive sorting for the tag list on the main page (#512)
Thanks for the proposal goes to Candleman. :-)
2019-10-21 11:02:13 +02:00
Michael Loesler
a806a260b6
update module (#511)
* update module

- update bad-behavior to version 2.2.23

* add changes

- updated files are added to update script
2019-09-28 13:58:48 +02:00
Michael Loesler
69a0ddce0e
display spam (#510)
- if one (an admin/mod) deletes the listed spam entries, one is NOT redirected to the normal view
- the spam counter (`$total_spam`) is used as a further condition
2019-09-26 09:58:58 +02:00
Heiko August
612bec8777 Change: add the new version number to the files config/VERSION and index.php 2019-09-24 22:11:00 +02:00
Heiko August
9433827788 Change: add the changes of version 2.4.99.3 to the changelog 2019-09-24 22:10:16 +02:00
Heiko August
07c0410e0d Change: add the list of files to update for version 2.4.99.3 2019-09-24 21:56:36 +02:00
Heiko August
879d519d37 Change: add version 2.4.99.2 to the list of updatable versions 2019-09-24 21:56:27 +02:00
Heiko August
30ac2a60bc Change: add new tables to uninstall block 2019-09-24 21:51:59 +02:00
Heiko August
1bc84988ee originMerge branch 'master' of origin 2019-09-24 21:38:14 +02:00
Michael Loesler
117261663f
SPAM in tree (#509)
- excluded stored and classified SPAM entries in thread tree (below the entry)
- see https://mylittleforum.net/forum/index.php?id=11936
2019-09-07 15:59:28 +02:00
Heiko August
36ea99ac36 Change: remove update script for version 2.3.5 to version 2.4.x 2019-08-26 22:04:28 +02:00
Heiko August
a1bed6a265 Fix: restrict mlf2_userdata.user_name and mlf2_b8_wordlist.token to 128 characters 2019-08-26 22:01:18 +02:00
Heiko August
888032fe4a Merge branch 'master' of https://github.com/ilosuna/mylittleforum 2019-08-26 21:24:53 +02:00
Heiko August
6f826dd919 Fix: provide table change statement for mlf2_tags also for version change to 2.4.99.2 2019-08-26 21:23:42 +02:00
Michael Loesler
570abbe880
new users (created by admin) (#508)
- corrected error message if the length of the user name is invalid
- corrected setting variable used in if-condition that checks the length (`$settings['username_maxlength']` instead of `$settings['name_maxlength']`, which is used for the real name of the user)
2019-08-18 18:14:36 +02:00
Michael Loesler
414168b8f2
Replace definition of constant array by normal array (#507)
- since PHP 5 doesn't support arrays in define(), the config files are invalid, see https://mylittleforum.net/forum/index.php?id=11912
- removed define() function call and used _normal_ arrays syntax
- created a single instance of B8 instead of using multiple instances (added new include file)
2019-08-17 19:35:42 +02:00
Heiko August
eb24c33d49 Merge remote branch 'master' to commit unknown changes 2019-08-08 15:58:31 +02:00
Heiko August
bf20a5adfe Change: add list of changes to the changelog 2019-08-08 15:56:00 +02:00
Heiko August
5f48894f1e Change: add the queries for altering the table type to InnoDB also to the update script 2019-08-08 15:51:03 +02:00
Heiko August
f436357195 Change: a further code style thingy 2019-08-08 15:50:30 +02:00
Heiko August
28059c1574 Change: add version 2.4.99.1 to the list of updatable versions 2019-08-08 15:07:34 +02:00
Heiko August
182cafaaeb Change: new version number 2.4.99.2 2019-08-08 15:07:12 +02:00
Heiko August
e3d94da3e8 Fix: limit the column size of mlf2_tags.tag to a length of 128 chars
This is because of the limited index size. Analogue to the change in the update script.
2019-08-08 15:04:05 +02:00
Heiko August
364317f65b Change: code style thingamabob 2019-08-08 15:03:27 +02:00
Heiko August
a00ba3643c Fix: column size of mlf2_tags.tag exceeded the possible index size 2019-08-08 15:01:10 +02:00
Heiko August
94ab46a3e2 Change: added index.php as file to update with version 2.4.99.2 2019-08-08 15:00:20 +02:00
Heiko August
22ba3ca0f8 Fix: bring the column for the tag string to max size of 128 chars 2019-08-04 22:24:32 +02:00
Michael Loesler
f3496fc515
Contacting options (#505)
* Contacting options

- added option for user contacting (mod/admin == 0, reg. users == 1, everybody == 2)
- for details see https://github.com/ilosuna/mylittleforum/issues/465

* File list

- added changes to file list
2019-07-21 16:12:46 +02:00
Michael Loesler
5456b3076f
Fix access for reg. users (#504)
* Fix access for reg. users

- if $settings.user_area_access was set to $settings.user_area_access == 2 reg. users don't have access to the user area
- fixed if-stmt for reg. users - https://github.com/ilosuna/mylittleforum/pull/470 , https://github.com/ilosuna/mylittleforum/pull/503

* pull id

- added pull id
2019-07-20 15:29:38 +02:00
Michael Loesler
78a64d9cf1
Fix access for admins/mods (#503)
* Fix access for admins/mods

- if was set to `$settings.user_area_access == 2` admins/mods don't have access to the user area (because admin/mod are users, too)
- fixed if-stmt because admins and mods should always have access to the user area

* added update item

- added update item to file list
2019-07-20 14:59:48 +02:00
Michael Loesler
a143d5a4f6
Missing worst case scenario (#502)
- added else statement to generate an error if config file is located elsewhere
2019-07-20 14:04:08 +02:00
Michael Loesler
32dfc8ce4d
Mail copy to sender (#501)
* Mail copy to sender

- added option to send mail copy to senders email, if sender is a regisered user
- removed option to change the email during contacting (if user is registered)
- see https://github.com/ilosuna/mylittleforum/issues/238 for details
- re-formatted contact.inc.php

* pull id

- added pull id
2019-07-20 12:49:11 +02:00
Michael Loesler
090d8df5a5
Update install and update script (#500)
- Update install and update script for PHPMailer configuration
2019-07-20 10:05:59 +02:00
Michael Loesler
f952a8a29d
clear recipients (#499)
- clearing all recipients of PHPMailer
2019-07-20 10:01:46 +02:00
Michael Loesler
14bdcb9c45
PHPMailer (#498)
* PHPMailer

- added PHPMailer (https://github.com/PHPMailer/PHPMailer) as module to enable SMTP support, see https://github.com/ilosuna/mylittleforum/issues/348

* File/SQL update

- added files to update list
- added SQL property php_mailer (1 == on -> use PHPMailer, 0 == off  -> use php mail function)
2019-07-18 22:15:00 +02:00
Michael Loesler
ab7c478556
B8 unlearn on edit posting (#497)
- to avoid redundantly trainning data on edit a posting, the decision of the original posting is removed from trainning DB
2019-07-14 17:16:33 +02:00
Michael Loesler
cb6c3562ba
Handle mod/admin posting by B8 as HAM (#496)
- flag postings of admin/mod always as HAM (use it also to train the filter)
2019-07-13 14:02:32 +02:00
Michael Loesler
53fa1564b7
SQL (#495)
- correcting SQL statement to display threads, that contains at least one spam posting
- https://github.com/ilosuna/mylittleforum/issues/473
- https://github.com/ilosuna/mylittleforum/pull/488
2019-07-01 23:19:54 +02:00
Michael Loesler
2d2cee8fd6
Tags (#494)
* Tags

- added option to insert tags by 0 == no one, 1 == admin/mod, 2 == reg. users, or 3 == everyone
- https://mylittleforum.net/forum/index.php?id=11835
2019-07-01 22:17:50 +02:00
Michael Loesler
285fb013ef
B8 config file (#493)
- created config file for B8
- see https://github.com/ilosuna/mylittleforum/issues/492
2019-06-24 22:11:00 +02:00
Michael Loesler
2eeffd10a3
SPAM warning message (#491)
* redirect user, if posting is classified as SPAM

If the posting is classified as SPAM, redirect the user to the single entry view, which contains the SPAM warning message
2019-06-16 15:25:27 +02:00
Michael Loesler
d57041ee0e
UI-elements to handle spam/ham postings (#488)
- use default UI elements and implementation to handle spam/ham entries
- remove spam-list links from sidebar
- clean up search.inc.php
2019-06-15 20:40:36 +02:00
Michael Loesler
6bc73d36e2
Remove smarty code (#490)
- removed smarty code, which was added for debugging in https://github.com/ilosuna/mylittleforum/pull/489
2019-06-14 21:06:51 +02:00
Michael Loesler
1448512a40
B8 contact (#489)
* b8 for mail check

- added option to check emails via B8
- added DB entry 'b8_mail_check' (Default: FALSE)
- replace `error_spam_suspicion` by `error_email_spam_suspicion` key
- corrected wrong key `akismet_check_registered` by `spam_check_registered`
2019-06-14 20:58:59 +02:00
rwa
622a98e3c3 remove checkbox for flash (#487) 2019-06-09 17:54:18 +02:00
Heiko August
fb6d9d5230
Merge pull request #486 from guzzisti/sql_innodb
Change: switch storage engine for all tables to InnoDB
2019-06-08 18:37:40 +02:00
rwa
8e28529bce
add alter statements for switch to innodb 2019-06-07 21:01:58 +02:00
rwa
0f96bcc87b
set innodb as default engine 2019-06-07 20:53:55 +02:00
Heiko August
9af7de1eef
Merge pull request #485 from guzzisti/sql_fix
Fix: correct the collation of the wordlist table

author @guzzisti 
fixes #482
2019-06-06 10:07:21 +02:00
rwa
eac21c75a3
set default collation for mlf_b8_wordlist 2019-06-05 19:45:10 +02:00
rwa
7015078967
fix creation of wordlist table 2019-06-05 19:38:10 +02:00
Michael Loesler
23dc93d193
Notification mails (#484)
- check for spam and send notification, if entry was wrongly flagged as spam
- DO NOT send mail, if entry is used for trainning ham messages
2019-06-03 23:07:21 +02:00
Heiko August
c1b9a7263f Change: set the required minimal MySQL version to 5.5.3
This is necessary to be able to use utf8mb4 as charset.
2019-06-01 22:55:02 +02:00
Heiko August
7b88070648 Change: add new version string to index.php 2019-06-01 22:50:00 +02:00
Heiko August
cb1542037a Change: add the list of changed files for version 2.4.99.1 2019-06-01 22:37:20 +02:00
Heiko August
a230fbbac5 Change: add the changelog for version 2.4.99.1 2019-06-01 22:37:20 +02:00
Heiko August
915e9989d2 Change: add the changelog for version 2.4.99.0 2019-06-01 22:37:20 +02:00
Heiko August
71288dc4e5 Change: amend the changelog entries for versions 2.4.9 to 2.4.20 2019-06-01 22:37:20 +02:00
Heiko August
fae3dbfd2b
Use the full width of 4 byte for UTF-8 to store text data in the database (#478)
* Change: set utf8mb4 as charset for most textual columns during installation

Affected tables:

- mlf2_b8_wordlist
- mlf2_banlists
- mlf2_bookmarks
- mlf2_categories
- mlf2_entries
- mlf2_entries_cache
- mlf2_pages
- mlf2_tags
- mlf2_userdata
- mlf2_userdata_cache

* Change: set utf8mb4 as charset for most textual columns during update

Affected tables:

- mlf2_b8_wordlist
- mlf2_banlists
- mlf2_bookmarks
- mlf2_categories
- mlf2_entries
- mlf2_entries_cache
- mlf2_pages
- mlf2_tags
- mlf2_userdata
- mlf2_userdata_cache

* Change: ater the collation of the user_name column from utf_general_ci to the utf8mb4-version

* Change: set the charset of the database connection to utf8mb4

* Change: reformat the function connect_db, remove unused, commented code

* Change: reorganise the database queries for the last changes

Put the following changes into the block for a new version 2.4.99.1.

- new charset utf8mb4 for most of the database tables
- new setting user_area_access, replaces user_area_public

* Change: new version 2.4.99.1
2019-06-01 21:25:26 +02:00
masju1
716915bdb5 Check valid Email
- Used `filter_var($mail, FILTER_VALIDATE_EMAIL)` to check for valid emails instead of using a regexp
2019-06-01 12:48:40 +02:00
Heiko August
3730671a99 Change: style the new button for quote inserting like the link it was before 2019-05-25 11:31:36 +02:00
Heiko August
a9b3635294
Merge pull request #475 from ilosuna/quote
Replace quote-link with a button, fixes #474
2019-05-23 22:30:47 +02:00
Michael Loesler
9f0b88403a Remove blank
- remove blank (style should defined in css)
2019-05-23 22:14:32 +02:00
Michael Loesler
be0f30bd8a button element
replaced input by button element
2019-05-23 19:40:06 +02:00
Heiko August
ef2f119072 Fix: correct the path to images to an absolute URL in the RSS feed
Code was provided by Mardor (https://bauforum.wirklichewelt.de/) and enhanced with htmlspecialchars.
2019-05-23 16:19:12 +02:00
Michael Loesler
7329edac0a Quote-Button
- removed quote link
- added new quote button
- see https://github.com/ilosuna/mylittleforum/issues/474
2019-05-22 22:14:19 +02:00
Heiko August
44c5502003 Cleanup: remove trailing tabs from the end of a code line 2019-05-14 22:10:11 +02:00
Heiko August
ae2e5c6ad4 Fix: take sticky topics from other categories into account when listing topics of a category or a category selection 2019-05-14 22:10:11 +02:00
Heiko August
4de9c00874
Merge pull request #471 from auge8472/sticky
Allow to pin a thread either to a category or to all categories (if at all)
2019-05-14 21:29:13 +02:00
Heiko August
bff9ba67d0 Change: check sticky value for > 0 instead == 1 because 2 is now also a valid value 2019-05-14 21:25:23 +02:00
Heiko August
5fd15c6231 Change: allow values 0, 1, 2 as values for mlf2_entries.sticky, was 0 and 1 before 2019-05-14 21:09:01 +02:00
Heiko August
9aed913a29 Change: new group of radio buttons for choosing the sticky status
It distinguish between the cases of having categories in the forum and to have no categories.
2019-05-14 13:43:28 +02:00
Heiko August
58acc07a86 Change: provide strings for not pinning a thread, pinning it to category and pinning it to all categories 2019-05-14 13:42:25 +02:00
Heiko August
7e47397b7b Make it possible to restrict the access to the users list to admins and mods (#470)
* Change: make it possible to restrict the access to the users list to admins and mods

* Fix: correct the order of setting values in the if-statement

0 is restrictest, 2 is public

* Fix: IDs have to be unique in a HTML document, remove duplication
2019-05-13 12:47:12 +02:00
Michael Loesler
08a51e090e Checking CSRF-token
- checked CSRF on delete posting
2019-05-07 08:53:06 +02:00
Michael Loesler
1be23bd776 CSRF token in delete links
- added CSRF token in template files at delete links
2019-05-07 08:53:06 +02:00
Michael Loesler
443b997b19
Mail encoding (#467)
- removed get_mail_encoding function
- set charset to defined value in i18n file
- reformatted my_mail function
- see https://mylittleforum.net/forum/index.php?id=11715
2019-04-28 19:58:53 +02:00
Michael Loesler
a0d9601e75
missing function (#466)
- remove missing function call, see https://mylittleforum.net/forum/index.php?id=11612 and https://github.com/ilosuna/mylittleforum/pull/437
2019-02-22 17:51:04 +01:00
Michael Loesler
304080db39
B8 (#463)
- update module to version 0.6.2, cf. https://nasauber.de/blog/T/165/b8_0.6.2_out_now
2019-02-13 20:22:55 +01:00
Heiko August
53e4d8fe69 Fix: remove one superfluous parenthese, caused an PHP-error 2019-02-12 12:31:59 +01:00
Heiko August
8d420c9987 Fix: CSS-changes for PR #364 wasn't taken over to the file style.min.css 2019-02-11 22:48:06 +01:00
Heiko August
5d9ef8a670
Merge pull request #460 from auge8472/clean-update
Clean update, rework of the update scripts for master branch
2019-02-11 22:15:40 +01:00
Heiko August
9359bc4f8f Change: set the version number to 2.4.99.0 2019-02-11 22:14:01 +01:00
Heiko August
e3ed30c5ec Fix: remove datasets from INSERT that are introduced with prior versions 2019-02-11 22:09:54 +01:00
Heiko August
caaf050a70 Change: provide a list of columns to fill for the placeholder admin
The working with only the values caused erros in case of a changing table structure again and again. Nothing one want's to run in.
2019-02-11 14:22:25 +01:00
Heiko August
d949320841 Fix: once again, backticks in table name prevents script from replacing the table name prefix 2019-02-11 12:12:20 +01:00
Heiko August
a402ef3ebc Fix: wrong button name in the install script, prevents the installation from running 2019-02-11 12:11:20 +01:00
Heiko August
e3e79a1a45 Fix: replace curly brackets with the correct square brackets 2019-02-11 12:00:11 +01:00
Heiko August
71da3517d5 Change: add uploads management table to the update script 2019-02-10 20:57:32 +01:00
Heiko August
1caa253ca6 Change: correct a few formatting issues 2019-02-10 20:32:49 +01:00
Heiko August
da0701ff09 Change: set the new table names for the first feature, the bayes filter 2019-02-10 20:31:40 +01:00
Heiko August
d9e745b832 Change: set new starting point, we'll begin with version 2.4.19.1 2019-02-10 20:30:32 +01:00
Heiko August
9aa9c20068 Change: remove outdated code from the 2.3.5-to-2.4-update-script 2019-02-08 14:43:56 +01:00
Heiko August
c946faf9a5 Change: add update steps from 2.4.14 to 2.4.19.1 and disable-enable-forum-code 2019-02-08 14:43:09 +01:00
Heiko August
be7b57eabf Change: remove the list of files to update for not supported versions 2019-02-08 14:29:40 +01:00
Heiko August
39ed7c0114 Change: let's start with the current version 2.4.19.1 with the update script to 2.5
There was to many versions (13) inbetween. Beginning with the current version seems to be a clean starting point.
2019-02-08 14:26:00 +01:00
Heiko August
9962a12f18 Change: add list of files to update for all versions since 2.4.8 2019-02-08 14:22:43 +01:00
Heiko August
fc24f674b2 Change: small code style thingamabobs 2019-02-08 13:56:47 +01:00
Heiko August
aa608b5737 Change: use the function compare_versions for version comparision 2019-02-08 13:55:15 +01:00
Heiko August
4f5b437685 Change: disable the forum before upgrading the database and reenable it afterwards 2019-02-08 13:54:23 +01:00
Heiko August
f04c22bcd4 CHange: add function for comparisions of version numbers down to last position 2019-02-08 13:50:37 +01:00
Heiko August
1d1d9ea2a7 Change: inserted the queries for all 2.4-versions starting with 2.4.8 2019-02-08 13:49:29 +01:00
Heiko August
4a83e085e3 Fix: mysqli_fetch_all does not work everywhere, use mysqli_fetch_assoc in a loop instead 2019-02-07 16:21:58 +01:00
Heiko August
b8c091428c Fix: fetching one line of a database request results in a flat array, there is no line 0 2019-02-07 16:21:58 +01:00
Heiko August
9a06fb2836 Fix: provide a column list to prevent the query to break
Number of values to store differs from number of columns in the table.
2019-02-03 22:58:40 +01:00
Heiko August
631c81206a Fix: setting last_changes was and should stay a Unix timestamp 2019-02-03 22:58:40 +01:00
Heiko August
6e771d0854 Fix: use mysqli_fetch_all to get all settings with one request 2019-02-03 22:58:40 +01:00
Heiko August
a93f2bfe0d Fix: use backticks to enclose column names, not apostrophes 2019-02-03 22:58:40 +01:00
Heiko August
bd8ba08d3a Fix: wrong sytax for UPDATE, used AND instead the correct comma 2019-02-01 12:59:06 +01:00
Heiko August
e63149cf1e Change: reformat the code of the installation script 2019-02-01 12:27:16 +01:00
Heiko August
540d2f44a0 Change: new HTML5-based user interface for the installation script 2019-02-01 12:27:16 +01:00
Heiko August
6983018fb3 Change: new HTML head section for the installation script 2019-02-01 12:27:16 +01:00
Heiko August
c9558997ff Fix: no hardcoded table names, dammit! 2019-01-31 20:49:45 +01:00
Heiko August
702fd7e8c9 Fix: add forgotten entries for a few new tables 2019-01-30 22:05:25 +01:00
Heiko August
ad7a4be945 Bugfix: remove backticks around table names, causes break of table name prefix replacement 2019-01-30 22:05:25 +01:00
Heiko August
4012ba9a6e
Merge pull request #451 from auge8472/uploads
Store information about uploads in a database table
2019-01-30 21:49:33 +01:00
Heiko August
c420390255 Change: add new table mlf2_uploads to the installation script and the database settings script 2019-01-30 21:46:55 +01:00
Heiko August
cd66dabdbf Change: add the create query for the new table mlf2_uploads 2019-01-30 21:42:38 +01:00
Heiko August
0dad01beb0 Change: define $user_id with users id or NULL, write entry to database after storing the new image 2019-01-30 21:24:56 +01:00
Heiko August
5bfa5776af Cleanup: a few reformattings, no functional changes 2019-01-30 21:22:29 +01:00
Michael Loesler
912b4b77f0
introduction elements (#450)
- removed introduction elements for BB code button, see https://mylittleforum.net/forum/index.php?id=11318
2019-01-28 23:21:09 +01:00
Heiko August
374b36af53 Change: replace use of $settings with new request for data to exclude temporary infos
A few temporary infos are amended to the settings array for the normal service.
2019-01-28 13:15:49 +01:00
Heiko August
327b03e374 Change: installation queries for moved settings 2019-01-28 13:15:49 +01:00
Heiko August
36b3f5e9b9 Change: move setting version to table mlf2_temp_infos 2019-01-28 13:15:49 +01:00
Heiko August
f67baeec2f Change: move setting access_permission_checks to table mlf2_temp_infos 2019-01-28 13:15:49 +01:00
Heiko August
edb6b59e2d Change: move setting last_changes to the table mlf2_temp_infos 2019-01-28 13:15:49 +01:00
Heiko August
3137da9a96 Change: move setting next_daily_actions to the table mlf2_temp_infos 2019-01-28 13:15:49 +01:00
Heiko August
ea3e0689c4 Change: make the link text for hiding spam from the main view more descriptive 2019-01-23 22:37:33 +01:00
Heiko August
3013b756b4 Fix: set image height to auto because images was elongated in Ajax preview 2019-01-23 22:30:09 +01:00
Heiko August
ee13f000e8
Fix: deleting a posting could leave orphaned subscriptions, delete them too (#446) 2019-01-13 13:58:15 +01:00
Heiko August
adb3f65781
Change: make the link text more descriptiv (#445)
"show spam" was to near to "list spam". The first toggles the visibility in the main view, the latter shows a list of only spam entries. With "display spam in thread list" the purpose of the link function gets more clear.
2019-01-13 13:20:12 +01:00
Heiko August
43eb42f688
Fix: user_id must accept NULL values from unregistered users, index has to be UNIQUE to allow that (#444) 2019-01-13 13:09:27 +01:00
Michael Loesler
81c8318f01
Timestamp (#443)
- added `setReceiptTimestamp()` call to estimate the time span, see https://mylittleforum.net/forum/index.php?id=11230
2019-01-09 21:23:43 +01:00
Heiko August
fe3f5c1874
Fix: thumbnails was elongated to the complete height of the entry (#442) 2019-01-09 09:16:45 +01:00
Michael Loesler
8efbde1a0b
Regexp (#441)
* Improve regexp for passwort check

Improved regexp by lookahead (?=) technique to force the number of (required) letters (but not one after another!), e.g. a password should contain two uppercase letters `MyPassword` is valid but the former expression returns false

* Parenthesis

- added missing parenthesis
2019-01-08 22:14:09 +01:00
Michael Loesler
2ac3d39dc5
Unicode character properties (#439)
- added unicode character properties to reg. exp
2019-01-02 19:18:54 +01:00
Michael Loesler
675cb6548e
Password strength (#438)
* Measuring password strength

- added options to validate password strength during registration
- number of digits (default: 0)
- number of lowercase letters (default: 0)
- number of uppercase letters (default: 0)
- number of special characters (default: 0)

* Measuring password strength

- added options to validate password strength during user changing password
2019-01-01 18:23:56 +01:00
Heiko August
586ac9e938 Change: enforce a new acceptance of the terms of use or privacy agreement for registered users 2018-12-30 01:43:43 +01:00
Heiko August
139296a88a Change: rearrange the german strings for the reset of the terms of use and privacy agreements 2018-12-30 01:43:43 +01:00
Heiko August
4d4a3a91e3 Change: use edit.png as icon for the reset of terms of use and/or privacy agreements 2018-12-30 01:43:43 +01:00
Heiko August
dae17c29e3 Change: add new links for resetting the acceptance of agreements after changes 2018-12-30 01:43:43 +01:00
Heiko August
361f18a8fe Change: new link texts for the reset of the agreements 2018-12-30 01:43:43 +01:00
Heiko August
f035616d5e Change: remove setting of classes and ids for "disabled" form fields 2018-12-30 00:18:05 +01:00
Heiko August
e404c135e5 Change: remove function to gray out unselected radio buttons and checkboxes via CSS-classes 2018-12-30 00:18:05 +01:00
Michael Loesler
9b70c9aa1a
Change user password (#435)
- removed field to confirm changed password in user area
- see: https://github.com/ilosuna/mylittleforum/pull/412, https://github.com/ilosuna/mylittleforum/pull/403
2018-12-24 13:30:30 +01:00
Michael Loesler
2062ad0f38
Remove account (#434)
* Remove user account

- added option _remove user account_ to user area

* Validate password

- requesting password to remove user account

* Remove button/clean code

- removed button as suggested by @auge8472 (https://mylittleforum.net/forum/index.php?id=11181)
- cleaned lang-files and template
2018-12-24 13:05:26 +01:00
Michael Loesler
b728c20711
Comment (#433)
- clean/correct comments
2018-12-22 10:18:00 +01:00
Michael Loesler
d200ac07eb
remove msg (#432)
- removed msg-tag
- extended protocol list for exclusion
2018-12-21 17:17:38 +01:00
Michael Loesler
84ad656a12
msg-tag (#431)
- Extend exclude list for msg-tag
- https://mylittleforum.net/forum/index.php?id=11166
2018-12-20 20:12:36 +01:00
Michael Loesler
c28c12a88c
Bayes-based spam filter (#427)
- add B8 libary for SPAM protection
- add CSRF Token to form element
- created new table `akismet_rating`
- transfered `spam` and `spam_check_status` from entry table
- removed columns `spam` and `spam_check_status` as they are akismet specific columns from entry - - created b8 tables `b8_rating` and `b8_wordlist_table`
- changed SQL statements, which used the (old) `spam` column
- updated install-script
- changed phrases and flag someone for delete
- add B8 configuration to admin area
- clean code
- removed spam columns from backup procedure
- new tables are *NOT* included to the backup procedure because I prefer to remove this function
- added error message for wrong SQLs
- https://github.com/ilosuna/mylittleforum/issues/426
2018-12-19 20:54:01 +01:00
Michael Loesler
816dd522f3
LC_NUMERIC (#429)
- added `setlocale(LC_NUMERIC, "C");` to handle the decimal separator (in case of content switching)
- https://github.com/ilosuna/mylittleforum/issues/428
2018-12-19 20:36:25 +01:00
Michael Loesler
68d3d0659f
max receipt time (#423)
- correcting condition for checking max. receipt_time
- https://github.com/ilosuna/mylittleforum/pull/413
2018-12-15 17:42:00 +01:00
Michael Loesler
ef2315df34
Timespan for form completion (#413)
* Timespan for form completion

- observe timespan for form completion and show an error, if the timespan is below a suitable threshold
- remove hard coded thresholds
- add new database entries for tuning threshold values
- default values: min = 5 sec and max = 10800 sec
- remove "credit time" for uncomplete filled forms
2018-12-10 20:06:14 +01:00
Heiko August
c842cae201 Fix: hardcoded table names will fail in environments with different table name prefixes 2018-12-07 13:16:03 +01:00
Heiko August
87d6c98bc1 Fix: remove linebreak because it breaks not only the line but also the matching style rule "no linebreak" 2018-12-04 22:36:15 +01:00
Popol
c1be0a612b Update VERSION (#418)
* Update VERSION

No line break in this file! Will solve it afterwards
2018-12-04 08:32:49 +01:00
Popol
bad95d5053 Update FR translation (#416)
All remaining strings should now be translated.
2018-12-03 22:11:58 +01:00
Michael Loesler
9083efd5f7
Check NULL value (#419)
- check sql result for NULL value
2018-12-03 21:17:24 +01:00
Heiko August
3e06e35f1f Change: bring the update script for 2.3.5 to 2.4.x from the status of 2.4.7 to 2.4.15 in the master branch 2018-12-02 16:25:48 +01:00
Heiko August
226f98f5d8 Fix: remove occurences of email_notification from several places, repair saving of subscription during posting edit 2018-12-02 16:00:07 +01:00
Michael Loesler
0b713864fd
Remove password field (#412)
- password confirmation field removed (in admin area)
2018-12-01 13:49:06 +01:00
Michael Loesler
ebbe657917
Default prompt (#411)
- Replace "http://" by "https://" in default prompt
- see https://mylittleforum.net/forum/index.php?id=11143
2018-12-01 13:11:17 +01:00
Michael Loesler
68c9e35e97
Remove deprecated function each() (#410)
- replaced deprecated function each() by its foreach representation
- see https://github.com/ilosuna/mylittleforum/issues/409
2018-12-01 12:58:57 +01:00
Heiko August
00e8a9eea4
Change: removed the workaround of using US-locales for a PHP-bug that was solved ages ago with PHP 5.2 (#405)
fixes #361
2018-11-22 21:52:46 +01:00
Heiko August
29cd188b8b
add unsubscribing function for messages about replies (#399)
* Change: add a link to unsubscribe from the e-mails informing about replies to a specific own entry
* Change: processing subscription quitting, code, text and subtemplate
* Change: add a new table for the handling of subscriptions
* Change: remove subscription flag from antres table, set it in subscriptions table instead
* Change: rename the entry-id and the UUID-column, add a timestamp
* Change: remove the GET-parameter checker, is unnecessary
* Change: add query to delete the row of the subscription from the database table
* Change: rebuild the function emailNotification2ParentAuthor
2018-11-17 12:48:48 +01:00
flatnick
a07301c774 Update norwegian.lang (#400)
Added new strings, that was introduced meanwhile (@auge8472).
2018-11-17 12:41:06 +01:00
Michael Loesler
b053582193
Typo (#404)
- replaced hidde by hide
2018-10-24 21:08:23 +02:00
Michael Loesler
f17271221b
Password visibility (#403)
- add a check box behind the passwords field
- add two lang. phrases to display a helpful tooltip
- if the check box is checked, the password is shown in plain text otherwise the text field function for passwords is used (e.g. showing *****) 
- see https://github.com/ilosuna/mylittleforum/pull/402
- remove uri to YUI compressor 
- password confirmation field removed
- `error_pw_conf_wrong` key removed
2018-10-24 16:20:51 +02:00
Michael Loesler
5c0c4ed3f6
underline character (#401)
- underline character in data_privacy_statement removed in lang-files
2018-10-23 09:43:32 +02:00
Michael Loesler
c179c4021a
SVG (#397)
- add svg extension in regexp for imgage files
2018-09-03 19:15:50 +02:00
Michael Loesler
98140cac40
CSRF token (#396)
- add token to admin function to avoid cross site request forgery (CSRF)
- see http://owendarlene.com/csrf-my-little-forum/
2018-08-30 22:13:52 +02:00
Heiko August
94ac9bc5bd Fix: add the code for opening the data privacy statement in a popup to the minimised JS-file 2018-08-05 19:51:15 +02:00
Heiko August
7ac6eefe31 Fix: always set the forum address as sender of an e-mail
Put the e-mail-address a user can provide to the Reply-to header.
2018-07-19 21:43:20 +02:00
Heiko August
61ceeea1c4 Fix: add forgotten minified main.min.js, includes the changes of #392 2018-07-19 21:23:44 +02:00
Heiko August
d2cced0369 Fix: another occurence of single quotes in a string, has to be masked 2018-07-19 21:23:44 +02:00
Heiko August
c078352ffb Cleanup: remove some unnecessary tabs and linebreaks 2018-07-19 21:23:44 +02:00
Heiko August
1526ad48f6 Fix: open the page of the privacy statement per default as popup 2018-07-19 21:08:37 +02:00
Heiko August
262890fad7 Fix: remove no longer existing column 'mlf2_entries.tags' from backup script 2018-07-17 21:05:17 +02:00
Michael Loesler
1615ee4a0a
Flash button (#390)
* Removing flash

- removing the option "FLASH" button
- https://github.com/ilosuna/mylittleforum/issues/376

* Change update script

- add changes to update script
- VERSION array is not correct!!!

* Correction id

- correcting id to #390
2018-07-16 23:15:56 +02:00
Heiko August
adb1ee4434 Fix: values of the birthday column have to be surrounded by quotes 2018-07-16 21:22:53 +02:00
Heiko August
f1cfba4eb5 Fix: add the forgotten new columns, introduced in version 2.4.10, to the backup script 2018-07-16 21:22:53 +02:00
Heiko August
1118bd9372
Fix: applied non-existing variable for the privacy checkbox to the posting template (#388) 2018-07-16 20:56:19 +02:00
Heiko August
1127bd626a Change: several fields in the posting-form get randomised names 2018-07-16 20:31:13 +02:00
Heiko August
4151ae71a0 Change: reorder the input fields of the registration form to prevent unintended prefilled fields in firefox 2018-07-16 20:31:13 +02:00
Heiko August
d24e232329 Change: several fields in the registration-form get randomised names 2018-07-16 20:31:13 +02:00
Michael Loesler
0e19a2fa1d
add missing css class thread-locked (#384)
- adding missing css class `thread-locked` to enable ballon icon for ajax preview
- see https://mylittleforum.net/forum/index.php?id=10873
2018-07-02 21:16:29 +02:00
Heiko August
3f9a8aacd2
Fix: correct wrong settings-key for the terms of use URL (#381) 2018-06-25 15:56:52 +02:00
Heiko August
46b1175028
Fix: removed errorneous and hyperfuid underscore (#380)
Thanks for the hint goes [to Taurec](https://mylittleforum.net/forum/index.php?id=10841).
2018-06-24 21:04:53 +02:00
Heiko August
c75c0afb37
Change: reset the height of the agreement iframe with CSS (#379) 2018-06-13 21:03:35 +02:00
Heiko August
4e3fa11f46
A small fix and a few cleanups (#378)
* Cleanup: remove a few unnecessary spaces
* Change: put meta elemt for charset in front of the title element. This prevents broken displaying of the title in case of a missing charset header from the webserver.
2018-06-13 20:49:53 +02:00
Heiko August
f79d752c9d
Merge pull request #375 from auge8472/gdpr
Change: add settings for an explicit data privacy statement
2018-06-07 18:45:21 +02:00
Heiko August
0cf2ac96ab
Merge branch 'master' into gdpr 2018-06-07 18:44:28 +02:00
Heiko August
ac7060f333 Fix: add checks for the relevant settings to prevent code execution if the named setting is disabled 2018-06-05 22:57:40 +02:00
Heiko August
fa4dbaed00 Change: enforce a redirect to the agreement form if a user hasn't accepted the agreement and tries to send a posting 2018-06-05 22:56:16 +02:00
Heiko August
ca3d59d3ab Change: update the userdata if the user has agreed to the data privacy statement or the terms of use 2018-06-05 22:30:23 +02:00
Heiko August
0e7a528697 Change: set the default height of the iframe to 400 pixels, will be overwritten with CSS 2018-06-05 22:24:09 +02:00
Heiko August
f987fdbd86 Fix: redirect at all 2018-06-05 22:23:12 +02:00
Heiko August
ff1d7ad741 Fix: redirect to the data privacy statement when necessary, not to the terms of use 2018-06-05 22:22:01 +02:00
Heiko August
552b90bd41 Fix: resolve merge conflict because of new LaTeX-formula-rendering (see aeb9afda34) 2018-06-04 22:27:34 +02:00
Heiko August
6587c5927f Fix: add dedicated button strings for agreement and disagreement 2018-06-04 22:22:07 +02:00
Heiko August
d649c3ce7b Change: output the agreement page with the data privacy statement or the terms of use 2018-06-04 22:14:14 +02:00
Heiko August
070d64fe8d Change: prepare the output of the agreement page, otherwise redirect 2018-06-04 22:12:12 +02:00
Heiko August
b9fc3c5764 Change: check for necessary reconfirmation of the data privacy statement or the terms of use 2018-06-04 22:09:51 +02:00
Michael Loesler
2ef12d742a
Tex (#377)
- removed external chart service support for tex
- added MathJax javascript support
- see https://mylittleforum.net/forum/index.php?id=10721
2018-05-18 19:20:17 +02:00
Heiko August
e8ac85968c Fix: use the correct key name for the error message 2018-05-18 12:57:10 +02:00
Heiko August
5430711e59 Change: make accepting of the data privacy statement mandatory to save the entry, if enabled 2018-05-18 12:45:58 +02:00
Heiko August
eec578621a Change: add the checkbox for data privacy statement and the necessary code to the registration form 2018-05-08 19:24:36 +02:00
Heiko August
35be9dfbd7 Change: add timestamp fields for terms of use and data privacy statement to the userdata table 2018-05-08 19:22:03 +02:00
Heiko August
a21bc77a82 Change: add default value for setting data_privacy_agreement for empty checkbox 2018-05-02 21:18:00 +02:00
Heiko August
7add15bf26 Change: add settings for an explicit data privacy statement 2018-05-01 22:48:10 +02:00
Heiko August
8b32031edc Change: set minimal MySQL-version to 5.0 because Bad behavior sets it as required
We do not use MySQL with Bad behavior per default, but it could be configured that way.
2018-05-01 19:41:24 +02:00
Heiko August
9439d1037b Change: update Smarty from version 3.1.30 to version 3.1.32 2018-05-01 19:41:24 +02:00
Heiko August
6cc30d4c1c Change: update Bad Behavior from 2.2.19 to 2.2.20 2018-05-01 19:41:24 +02:00
Heiko August
4c9b48b943 Change: update GesHi from 1.0.8.11 to 1.0.9 2018-05-01 19:41:24 +02:00
Michael Loesler
dc6ac4f694
improve check update (#373)
- replace argument of checkUpdate function
- using last stored version (taken from feed) instead of installed
version
- https://mylittleforum.net/forum/index.php?id=10668
2018-04-21 12:23:29 +02:00
Michael Loesler
438967bf29
Check update function (#372)
due to content changes of github atom feed, the checkUpdate returns
wrong uri
2018-04-16 23:11:48 +02:00
Heiko August
5d58c4c857
Fix(es) for the uploads management (#367)
* Fix: use existing variable instead non exisiting one
* Fix: check for non-emptyness of the array and not for it's existence

I found no further issues.
2018-04-16 19:51:18 +02:00
Heiko August
829b03a154 Fix: three cases of forgotten exclamation mark as part of HTML-comment-syntax 2018-04-16 18:33:38 +02:00
Heiko August
4f3ee7330c Fix: superfluous and erroneous single quotes 2018-04-16 18:33:38 +02:00
Heiko August
b300faf040 Fix: added cursor:pointer; for labels also to the minified CSS file 2018-04-13 16:59:31 +02:00
Heiko August
9e67bb781e Fix: added the changes for notice about automatic e-mails to all language files 2018-04-13 16:59:31 +02:00
Heiko August
7c8e502633
Change: width and height attributes to img tag of uploaded images (#368)
Add width and height attributes to in entries included images with an upload as source.
2018-04-12 20:31:04 +02:00
Heiko August
86861aef46
Merge pull request #364 from ilosuna/uploads
Base of a new page in the admin panel for managing uploads (currently uploaded images).
2018-04-11 17:48:07 +02:00
Heiko August
0737d82843 Fix: put image dependent code into an if-block with the check for image presence 2018-04-11 17:35:11 +02:00
Heiko August
0152a4ec1e Change: add styling rules for the confirmation list 2018-03-30 20:11:28 +02:00
Heiko August
d774095e49
Bugfix, use correct setting name instead name of abandoned setting (#366)
* Fix: used non existing setting for removing read state after X days

The database query for removing the read state from entries after X days was broken.
The query used the setting "read_state_expiration_date" which was itself removed with version 2.4.3.
2018-03-30 13:59:59 +02:00
Heiko August
09687f5096
cursor: pointer; for HTML-element label (#365)
* Change: set the mouse pointer to pointer (hand) when hovering over a label because it's an interactive element.
2018-03-30 13:07:30 +02:00
Heiko August
e6c1f72508 Change: remove the uploads from the file system 2018-03-29 16:08:02 +02:00
Heiko August
0fea8768bc Change: check also the presence of the CSRF-token 2018-03-29 16:07:34 +02:00
Heiko August
d4187e4249 Change: unify the two loops for displaying the image name and setting the hidden input 2018-03-29 16:03:32 +02:00
Heiko August
df3d9c057d Change: cosmetical changes for the section header and the image icon 2018-03-29 16:02:46 +02:00
Heiko August
88023e95e2 Change: new settings uploads_per_page to the install, update and admin scripts 2018-03-29 15:17:37 +02:00
Heiko August
d4760c901b Change: add a link back to the uploads-list to the breadcrumb navigation 2018-03-29 11:31:50 +02:00
Heiko August
2000bd62d8 Change: add confirmation page for deleting uploaded files 2018-03-29 11:12:51 +02:00
Heiko August
423e5be239 Change: rename submit button 2018-03-29 09:58:14 +02:00
Heiko August
80e2e1424d Change: make the height of #usernav independent from a magic number 2018-03-28 14:50:35 +02:00
Heiko August
d9e62e69a2 Change: set an own block formatting context for #usernav 2018-03-25 22:25:28 +02:00
Heiko August
5962dc318e Change: adapt the user list pagination to the upload list 2018-03-25 22:24:38 +02:00
Heiko August
5bd77256b0 Change: basic set of rules for the list of uploads in the admin area 2018-03-22 22:37:49 +01:00
Heiko August
e36a1c81eb Change: add admin view for management of the uploads
It's atually incomplete, no pagination at the moment, even if it's necessary.
2018-03-22 22:35:54 +01:00
Heiko August
41522306e3 Change: add the link to the upload management view to the admin menu 2018-03-22 22:25:38 +01:00
Heiko August
13f3f3133f Merge branch 'master' of https://github.com/ilosuna/mylittleforum 2018-03-20 15:00:34 +01:00
Michael Loesler
ce501e02ff
Date format (#363)
- change date format to prevent encoding problems for special characters
(e.g. März)
- https://mylittleforum.net/forum/index.php?id=10623
2018-03-18 22:08:10 +01:00
Michael Loesler
eeaad29f66
Add email note (#362)
- add notification of generated message
- https://github.com/ilosuna/mylittleforum/issues/358
2018-03-12 22:39:40 +01:00
Michael Loesler
5f8d77da62
Parameter for folding (#360)
- fix type conflict for storing folding state
- https://github.com/ilosuna/mylittleforum/issues/293
- https://mylittleforum.net/forum/index.php?id=10561
2018-03-10 21:36:00 +01:00
Micha
34d75375ad
Change project page link (#357)
- add link to mylittleforum.net
2018-03-01 22:10:48 +01:00
Heiko August
db312a6d90 Merge branch 'master' because of a conflict 2018-02-23 11:08:33 +01:00
Micha
248b1a567b Avatar handling (#353)
- add getAvatar on several placed to handle name convention
- Overwrite https://github.com/ilosuna/mylittleforum/pull/352 because it
is incomplete and due to a conflict in editing this issue
2018-02-23 10:56:18 +01:00
Micha
f1d06a2492
Avatar handling (#353)
- add getAvatar on several placed to handle name convention
- Overwrite https://github.com/ilosuna/mylittleforum/pull/352 because it
is incomplete and due to a conflict in editing this issue
2018-02-22 22:42:32 +01:00
Heiko August
4e135c84aa
Merge pull request #352 from auge8472/bugfix
Bugfix for display of the avatar in the admin user edit form and it's label.

fixes #349
fixes #351
2018-02-22 21:32:48 +01:00
Heiko August
25246a6442 Fix: add missed string for avatar, user edit in the admin panel got no label 2018-02-22 21:27:31 +01:00
Heiko August
1743050af3 Fix: read avatar with the function getAvatar also in the admin panel 2018-02-22 21:25:01 +01:00
Heiko August
fa9375033a
Merge pull request #347 from auge8472/v2.4.8
Add the necessary changes for the release of version 2.4.8
2018-02-18 21:13:56 +01:00
Heiko August
b8cd70eb96 Change: add version number 2.4.8 to the files index.php and VERSION 2018-02-18 21:09:28 +01:00
Heiko August
168be9b49e Change: add the last version 2.4.7 to the array of updatable versions 2018-02-18 21:06:56 +01:00
Heiko August
05e998c48a Change: add the list of changed files 2018-02-18 21:05:36 +01:00
Heiko August
37ec48371d Change: add a further cfix to the changelog 2018-02-18 20:09:16 +01:00
Heiko August
30103ea25c
Fix: remove column "tags" from the create statement for table mlf2_entries (#346) 2018-02-18 20:04:03 +01:00
Heiko August
5fc063cd3e Change: add the changelog for the version 2.4.8 2018-02-18 19:51:57 +01:00
Heiko August
dcc8fabb78 Fix: remove a more or less empty line in the 2.4.7-section 2018-02-18 19:50:54 +01:00
Heiko August
a4dae52ba0 Fix: add the release date of version 2.4.7 to the corresponding section of the changelog 2018-02-18 19:49:41 +01:00
Heiko August
bca457d77f
Change: translate "Bookmark" and it's plural as "Lesezeichen" (#345)
fixes #332
2018-02-11 19:04:14 +01:00
Heiko August
f93987bd2c
Merge pull request #344 from auge8472/addlangs
- new language: Danish
- enhanced translation: Swedish
- a few corrections: English

Especially the swedish translation is a mix of the old translation by Rövarn (rovarn at gmail dot com) and a newer, enhanced translation by Tommy Niellson (tommy at svenska-lok dot se). I fiddled much with online dictionaries to get a feeling for the swedish language and the sentence structure but don't know anything more about it, than I can detect by reading the language file (even german and swedish languages are IMHO very similar). Please have a look at the translation (especially grammar), if you are a swedish speaker/reader and inform us about erros I made during the unification.
2018-02-11 18:53:47 +01:00
Heiko August
0ef709b7fb Change: added translations by Tommy Niellson (tommy@svenska-lok.se) 2018-02-11 18:40:23 +01:00
Heiko August
5ccfff1cf0 Change: add the strings that accrued since 2.4.3 and the changed keys 2018-02-09 12:12:06 +01:00
Heiko August
db5b7c8416 Fix: correct spelling error 2018-02-09 12:11:20 +01:00
Heiko August
0a9e48fdde New: file for danish language, translation by Tommy Nielsson tommy@jernbanen.dk 2018-02-09 11:06:21 +01:00
Heiko August
3bb6045875
Fix: corrected the path to the CSS-files, important for updates from older versions (#342) 2018-02-05 15:08:29 +01:00
Heiko August
b3dbb10dbd
Merge pull request #341 from auge8472/bugfix
Bugfixes for invalid backup-mode-check and disused table column mlf2_entries.tags
2018-02-05 12:16:18 +01:00
Heiko August
cab27fcacd Fix: remove column name "tags", column does no longer exist 2018-02-05 12:11:38 +01:00
Heiko August
e86fa9f14d Fix: allow values greater than 7 up to 10 for backup modes 2018-02-05 12:07:32 +01:00
Mark Hoschek
01792da413
Update README.md 2018-02-03 14:55:24 +01:00
Heiko August
b8d0bf3bb4
Fix: forgotten masking chars for "'" inside strings (#338)
fixes #337
2018-02-02 12:52:33 +01:00
Micha
fd7e3cdc51
CSRF-token (#336)
- adding CSRF-token to editable user area
- https://github.com/ilosuna/mylittleforum/issues/320
2018-01-26 18:15:21 +01:00
Micha
ebc08678eb
Correct variable (#335)
- crorrecting variable in mysqli_free_result
- https://github.com/ilosuna/mylittleforum/issues/334
2018-01-26 17:48:04 +01:00
Heiko August
bb85b0d817
Fix: remove a few empty lines, the first and the two last caused Header-sent-errors (#329) 2018-01-09 23:02:44 +01:00
Heiko August
27cda188ac
Fix: remove the table alias from the ORDER-BY-clause because the name in SELECT as also no alias (#328)
fixes #326
2018-01-09 22:51:27 +01:00
Heiko August
5f39d557b9
Fixes for a few issues in the templates (#327)
* Fix: remove a doubled closing select-tag
* Change: removed a few empty lines from the template
* Fix: remove the size attribute from a input of type submit, makes no sense
2018-01-09 22:41:27 +01:00
Micha
df80e8140b
Correct PHP version
- see https://github.com/ilosuna/mylittleforum/issues/325
2018-01-05 15:41:01 +01:00
Heiko August
4354f5b651
Merge pull request #323 from auge8472/v2.4.7
Changes for the release of version 2.4.7
2018-01-04 23:16:52 +01:00
Heiko August
db530fb1ee Change: add the new version number and date to index.php and number to config/VERSION 2018-01-04 23:03:43 +01:00
Heiko August
b0cc114d48 Fix: corrected vaule of a PR-number 2018-01-04 22:56:31 +01:00
Heiko August
931f00b331 Change; file list refomatted again 2018-01-04 22:54:52 +01:00
Heiko August
288b499b55 Change: added and documented the changed files 2018-01-04 22:51:27 +01:00
Heiko August
565ebfa62c Change: set correct version jump 2018-01-04 22:32:54 +01:00
Heiko August
99af0245bd Change: reformatted all comments for documenting the number of PRs in the list of changed files 2018-01-04 22:32:08 +01:00
Heiko August
9b9ba18936
Fix: set the URL of the interim project page because the original page is not accessible at the moment (#322) 2018-01-04 21:52:43 +01:00
Heiko August
c917efd553 Change: added the code changes for version 2.4.7 to the changelog 2018-01-04 21:45:43 +01:00
Heiko August
824217abf1
Fix: set empty birthday date to NULL instead 0000-00-00, adapt the queries (#321)
fixes #317
2018-01-04 20:48:28 +01:00
Heiko August
bd53748e48
Fix: check for existence of the variable and also for it's non-emptyness (#319)
fixes #316
2018-01-03 19:43:03 +01:00
Heiko August
9548f5b71d
Fix: replace the link to the temporary inaccessible project forum with the one to the interim forum (#318)
The link to the original project forum will be restored, when it's accessible again. See therefore also #314
2018-01-03 11:29:24 +01:00
Heiko August
508222c4a9
Cleanup: remove unused array, corrected a few spelling errors (#315)
see therefore also #288
2017-12-27 21:46:39 +01:00
Micha
df1a5d3b71
Honeypot (#305)
* Add inputs as honey pot
- add csrf-token for postings
- Add files to update script
- add CSS class and label
- add label for honey pot descriptions
2017-12-17 11:01:40 +01:00
Heiko August
1a611241c6
Merge pull request #300 from auge8472/quotes
enclose language strings in single quotes …

Commited via merge because of the load of changes in 12 different files. This fixes #298
2017-12-15 10:35:29 +01:00
Micha
1589ce7fd7
correct label (#304)
- change not defined $lang['error_input_too_long'] to
$lang['error_username_too_long']
2017-12-13 09:53:30 +01:00
Heiko August
6afc638225
Merge branch 'master' into quotes 2017-12-12 23:33:30 +01:00
Heiko August
df8d7f64b6 Fix: removed obsolete string (key: error_bookmark_tags_too_long) 2017-12-12 23:18:45 +01:00
Heiko August
ce23d97b0f Fix: new key-value-pair for limiting the number of bookmark tags 2017-12-12 23:11:08 +01:00
Micha
cd401caf42
Change TAG handling (#297)
* Remove phrase in lang files

- Remove TAG-phrase 'error_bookmark_tags_too_long'
- was added by https://github.com/ilosuna/mylittleforum/pull/287

* Add tables

- tags_table for tag values
- bookmark_tags_table for connection between tags and bookmarks

* Change install/update script

- Add new tables
- Suggestion for transfering old tags from postings to new tag table

* Add tags to bookmark

- adapt SQLs for new TAG-table

* SQL korrigiert

- Klammerausdruck korrigiert

* LEFT-Join

- Correcting SQL JOIN vs. LEFT JOIN
- Replace function call

* Replace Functions

- add/replace functions for TAG handling

* TAGS for postings

- Add Tags for postings

* Add new table

- add binding table for tags and postings

* - Change TAG handling

- search function
- posting
- thread view
- update script
- install script

* Limiting number of Tags

- set tag limit to 10 for bookmarks
- add error message

* Remove BTREE

- reomve USING BTREE clausel as suggested by @auge8472

* Remove BTREE

- remove USING BTREE as suggested by @auge8472
- add new table entry_tags_table

* Remove variable

- remove variable $tagStr

* Remove first tab

- clean up file

* Add InnoDB

- Add ENGINE=InnoDB to new tables

* Add table names

- add table names to install script

* add updated files

- add updated files of issue #297

* add AUTO_INCREMENT

- add AUTO_INCREMENT to 'tags_table' definition

* Correcting table name / check for prior errors

- correct tabel name of entry_tags_table
- check empty property of error-array
- add error message, if b_settings.php is unwriteable

* Store posting tags

- add new sql to store the posting tags in entry_tags table
2017-12-12 22:53:37 +01:00
Heiko August
87e486ad0c Change: set value strings into single quotes (except multi line strings) 2017-12-12 22:51:42 +01:00
Heiko August
bebc2db55e Change: set value strings into single quotes (except multi line strings) 2017-12-12 22:15:06 +01:00
Heiko August
920d9c5c25 Change: set value strings into single quotes (except multi line strings) 2017-12-12 21:40:23 +01:00
Heiko August
6cd6f75b3c Change: set value strings into single quotes (except multi line strings) 2017-12-12 21:01:51 +01:00
Heiko August
b14bc3f179 Fix: enclosing means a quote at the begin AND at the end of the string. 2017-12-11 22:52:03 +01:00
Heiko August
e53cbc95e9 Fix: forgot to add the key-value-pair for word delimiter 2017-12-11 22:51:09 +01:00
Heiko August
2ad8f86ba9 Change: set value strings into single quotes (except multi line strings) 2017-12-11 22:47:22 +01:00
Heiko August
8aa987bb51 Change: set value strings into single quotes (except multi line strings) 2017-12-11 22:09:16 +01:00
Heiko August
31c02359fe Fix: added forgotten word delimiter in croatian language file 2017-12-08 16:18:19 +01:00
Heiko August
1dd2c6d16f Change: dsemi ready translation of e-mail-content from english to french language 2017-12-08 16:17:39 +01:00
Heiko August
d35b024836 Change: set value strings into single quotes (except multi line strings) 2017-12-08 16:17:20 +01:00
Heiko August
212114f6fd Change: set value strings into single quotes (except multi line strings) 2017-12-05 22:28:14 +01:00
Heiko August
31cc55ccd3 Fix: replace "it's" with "it is" because of the conflict with enclosing quotes 2017-12-03 22:53:00 +01:00
Heiko August
a98404c762 Change: set value strings into single quotes (except multi line strings) 2017-12-03 22:38:22 +01:00
Heiko August
c1e8610da7 Change: set value strings into single quotes (except multi line strings) 2017-12-03 21:59:22 +01:00
Heiko August
a57998528a Fix: forgotten opening quotes 2017-12-03 20:03:47 +01:00
Heiko August
e2e08c531d Change: set value strings into single quotes (except multi line strings) 2017-12-03 20:02:25 +01:00
Heiko August
2a9acd567d Change: set value strings into single quotes (except multi line strings) 2017-12-03 19:25:53 +01:00
Heiko August
cb9c536c92
Fix: wrong values in the arrays of allowed values (#296)
Allowed are the values `0` and `1` and not `1` and `2`.
2017-11-28 22:15:06 +01:00
Heiko August
665064228f
Change: fix values for URL-parameter fold_threads (#295)
0 = unfolded threads (default)
1 = folded threads

fixes #293
2017-11-28 22:06:54 +01:00
Heiko August
151d6f0ed2
Change: fix values for URL-parameter toggle_thread_display (#294)
0 = nested view (threaded view, default)
1 = linear view (table view)

fixes #292
2017-11-28 21:50:00 +01:00
Heiko August
2e9f31de49
Change: introduce new URL-parameter to select view of the threads list view (#291)
Change: change the behaviour of `toggle_view` from 'true' to '0' or '1', fixes #283
2017-11-27 09:49:43 +01:00
Heiko August
713bae4f8c
Refactoring of index.inc.php … (#290)
* Change: don't set a value for an integer field into quote signs
* Cleanup: reformatting of the file index.inc.php
2017-11-22 22:37:55 +01:00
Micha
c5ab0b7314
Bookmarktags (#287)
* Tags for Bookmarks

- add tags for user-defined bookmarks
- https://github.com/ilosuna/mylittleforum/issues/254

* Update/Install instructions

- update install and update scripts

* Add GH-IDs

- add GitHub ids

* Remove isset

- remove isset() because it is checked above
2017-11-20 16:03:39 +01:00
Micha
8b493fcdca
Redirect after LogIn (#286)
* Redirect after LogIn

- Redirect user to last visited page after login
- https://github.com/ilosuna/mylittleforum/issues/282
- Refactoring index.php
- https://github.com/ilosuna/mylittleforum/pull/275
2017-11-12 11:16:35 +01:00
Micha
e3c0df31af
Remove entries_read column (#285)
- Removing column entries_read from userdata-table
- https://github.com/ilosuna/mylittleforum/issues/284
2017-11-11 12:48:01 +01:00
Heiko August
16dc507884
Merge pull request #281 from auge8472/v2.4.6
changes for update to version 2.4.6

closes #280
2017-11-05 16:18:52 +01:00
Heiko August
574dc6e4d8 Change: new version number 2.4.6 in index.php and config/VERSION 2017-11-05 16:15:22 +01:00
Heiko August
5fbc0704bc Change: add the list of changed files and directories for version 2.4.6 2017-11-05 16:14:44 +01:00
Heiko August
9f195cbbb4 Change: add version 2.4.5 to the list of updateable versions 2017-11-05 16:14:12 +01:00
Heiko August
e7f9128d08 Change: add the list of changes for version 2.4.6 2017-11-05 16:13:30 +01:00
Heiko August
b282f900d7
Fix: sort users by their names in natural order (case insensitive) (#279)
fixes #274
2017-11-05 15:26:42 +01:00
Heiko August
75d5568d1f
Fix: removed doubled line with key "smilies_disabled" (#278) 2017-11-05 15:03:47 +01:00
Heiko August
4317ca75e0
Fix: corrected database query, was broken mix of SELECT and UPDATE (#277)
fixes #272
2017-11-05 14:56:38 +01:00
Heiko August
3dfa97de21
Fix: broken if-statement, wrong nesting of parenthesis (#276)
fixes #273
2017-11-05 14:12:22 +01:00
Heiko August
31a4a14763
Merge pull request #275 from auge8472/rewrites
Refactoring of the PHP-includes, merge instead squash because of the amount of changed files (one commit per code file).
2017-11-05 14:02:35 +01:00
Heiko August
eb88e30528 Cleanup: reformatting of posting.inc.php 2017-11-05 13:28:17 +01:00
Heiko August
dc3966d902 Cleanup: reformatting of register.inc.php 2017-11-04 22:42:25 +01:00
Heiko August
6bdfc1c2b8 Cleanup: reformatting of search.inc.php 2017-11-04 22:42:04 +01:00
Heiko August
dd3e10e8ae Cleanup: reformatting of rss.inc.php 2017-11-04 22:41:40 +01:00
Heiko August
c86fb16991 CLeanup: reformatting of main.inc.php 2017-11-04 21:37:20 +01:00
Heiko August
c96138f1db Cleanup: reformatting of upload_image.inc.php 2017-11-04 20:57:45 +01:00
Heiko August
338b4a5d6d Cleanup: reformatting of page.inc.php 2017-11-04 20:57:21 +01:00
Heiko August
0370b7db6f Cleanup: reformatting of admin.inc.php 2017-11-02 16:37:25 +01:00
Heiko August
f65feacc34 Cleanup: reformatting of user.inc.php 2017-11-02 16:17:26 +01:00
Heiko August
9a0da28d21 Cleanup: reformatting of login.inc.php 2017-11-01 22:27:36 +01:00
Heiko August
0e6bb12302 Cleanup: reformatting of js_defaults.inc.php 2017-11-01 22:26:41 +01:00
Heiko August
894bfbf851 Cleanup: reformatting of insert_flash.inc.php 2017-11-01 22:25:32 +01:00
Heiko August
4a947d7cbe Cleanup: reformatting of avatar.inc.php 2017-10-31 20:26:10 +01:00
Heiko August
2c5b6dc54c Cleanup: reformatting of account_locked.inc.php 2017-10-31 19:13:54 +01:00
Heiko August
01bd2eb881 Cleanup: remove a few whitespaces, add a few SQL maskings 2017-10-31 19:11:52 +01:00
Heiko August
52bb459967 Cleanup: reformatting of disabled.inc.php 2017-10-31 19:02:00 +01:00
Heiko August
e57ec47dfe Cleanup: reformatting of delete_cookie.inc.php 2017-10-31 19:01:25 +01:00
Heiko August
10b30514e8 Cleanup: reformatting of contact.inc.php, a few additional maskings for database queries 2017-10-31 19:00:29 +01:00
Heiko August
5cbb5e8743
Cleanup: reformatting of the file contact.inc.php (#271)
Code intention with tab instead spaces, no functional change.
2017-10-31 18:28:06 +01:00
Heiko August
bd6ab96da6
Merge pull request #270 from auge8472/cssfix
A few changes to the CSS-files of the default template
2017-10-31 16:08:43 +01:00
Heiko August
d4b8da6642 Fix: remove margin-bottom from sidebar header when not folded 2017-10-31 15:37:40 +01:00
Heiko August
6e17a03076 Change: replace tabs with spaces 2017-10-31 15:24:07 +01:00
Heiko August
ecb6414933 Change: remove doubled rules 2017-10-31 15:23:20 +01:00
Heiko August
372cb1f447 Change: remove obsolete CSS-rules for list of latest entries 2017-10-31 15:12:02 +01:00
Heiko August
4b3a8c8136
Merge pull request #269 from auge8472/latest
Rework of the HTML-structure for the list of latest postings
2017-10-29 19:39:38 +01:00
Heiko August
33b5fbab9d Change: width-definition for #sidebar instead for it's children
This step makes the rules usable for #sidebar and for #bottombar.
2017-10-29 19:21:35 +01:00
Heiko August
aa12cf5b07 Change: add same ids as for #sidebar to #bottombar 2017-10-29 19:15:16 +01:00
Heiko August
c56e36fd89 Fix: set a background-colour for the link itself
No background colour for a :visited link without a background colour for the link.
2017-10-29 16:42:39 +01:00
Heiko August
a67b24daf5 Change: adapt CSS rules to the new HTML-structure, first attempt 2017-10-19 22:33:36 +02:00
Heiko August
45496d690a Change: set class .read for the link instead the span in table views bottombr 2017-10-19 22:32:59 +02:00
Heiko August
d6a6189e6c Change: set class .read for the link instead the span in thread view sidebar 2017-10-19 22:32:04 +02:00
Heiko August
75c04925f8 Merge pull request #267 from Romchik/patch-1
Fixed HTML Validation Errors, thanks goes to @Romchik
2017-10-19 10:12:03 +02:00
Roman
9ab5ee1809 Removed duplicate title 2017-10-19 09:33:20 +02:00
Roman
f9234dd598 Removed duplicate title 2017-10-19 09:32:19 +02:00
Roman
adefdde0dc Fixed 2 HTML Validation Errors
line 7 column 38 - Error: required attribute "content" not specified
line 8 column 43 - Error: required attribute "content" not specified
2017-10-19 09:25:44 +02:00
Heiko August
720be48e17 Fix: add rules for visited, focused and hovered links in the latest entries list (#266) 2017-10-16 18:29:06 +02:00
Micha
d831330a3c Add version (#265)
- version number is added to update-array
- https://github.com/ilosuna/mylittleforum/issues/264
2017-10-10 20:11:41 +02:00
Heiko August
b327c8d729 Merge pull request #263 from auge8472/master
Add changes for version 2.4.5
2017-10-09 22:50:27 +02:00
Heiko August
8989197d2a Change: set the new version number 2017-10-09 22:45:35 +02:00
Heiko August
351951d134 Change: add the list of changes to the changelog 2017-10-09 22:44:22 +02:00
Heiko August
1317ac4edd Change: add the list of updated files to the update script 2017-10-09 22:43:26 +02:00
Heiko August
970b783e58 Change: add next version number (2.4.4) to the array of updateable versions 2017-10-09 22:42:34 +02:00
Heiko August
1f03d65082 Fix: corrected wrong variable name (#262) 2017-10-09 22:29:15 +02:00
Heiko August
d86b4a6d6c Change: small privacy enhancement, don't send always a referrer (#260)
1st meta element: old draft, see https://wiki.whatwg.org/wiki/Meta_referrer
2nd meta element: actual draft, see https://w3c.github.io/webappsec-referrer-policy/
2017-10-09 15:56:17 +02:00
Heiko August
e6faf1425d Change: remove orphaned code for folding threads (#259)
fixes #257
2017-10-03 19:17:11 +02:00
Heiko August
b2c6213b43 Preparations for version 2.4.4 (#258)
* Change: add the array of the changed files to the update script
* Change: add the list of changes to CHANGELOG
* Change: new version string in index.php and in config/VERSION
2017-10-03 18:22:19 +02:00
Heiko August
10384a34d4 Fix: readded lost marking of the opening posting as new … (#256)
* Fix: readded lost marking of the opening posting as new in case of a new answer
* Change: simplify the if- and else-if-statements
    No need for nested if-statements.
    A further simplfication is possible.
    But IMHO it would make the statement more or less unreadable.
* Fix: ensure $fold_threads to be boolean and hand it over to getMessageStatus
2017-10-03 17:21:36 +02:00
Heiko August
49421f2a85 Change: outsourcing of read- and new-status handling into a function (#255)
fixes #245
2017-09-17 21:23:18 +02:00
Micha
9dab3e042d Handling of the read state in entry thread (#251)
Handling of the read state in entry thread by using code from
thread.inc.php

see also #245
2017-09-16 18:37:11 +02:00
Heiko August
a839c58490 Fix: mention the check for the actual version of config/VERSION (#250)
fixes #244
2017-09-15 00:28:03 +02:00
Heiko August
48f2066317 Fix: allow e-mail-addresses with TLDs longer than 4 chars (#249)
The regular expression allows now TLDs with two or more chars. fixes #246
2017-08-31 23:00:10 +02:00
Micha
6b8cad5dc8 Change user_type-argument in js_defaults-query (#248)
- user_type argument is corrected in js_defaults-query
- http://mylittleforum.net/forum/index.php?id=10259
- https://github.com/ilosuna/mylittleforum/issues/247
2017-08-25 17:05:51 +02:00
Heiko August
f8afdd9363 Fix: forgot to add the change in includes/user.inc.php (#243)
... in the update-script
2017-07-10 15:37:28 +02:00
Heiko August
99a9d1050b Merge pull request #236 from auge8472/v2.4.3
preparations for version 2.4.3
2017-07-09 21:52:05 +02:00
Heiko August
5f7b857dc9 Change: add new version string to index.php and config/VERSION 2017-07-09 21:48:11 +02:00
Heiko August
50c2514514 Change: add entries for version 2.4.3 to the changelog 2017-07-09 21:46:11 +02:00
Heiko August
e93157dba4 Fix: rename key for uneven password inputs because of collision with … (#237)
* Fix: rename key for uneven password inputs because of collision with different but same named key
* Fix: use the new key name
2017-05-28 14:32:43 +02:00
Heiko August
39b9de62a1 Merge of PR #235: fixes for a few bugs in the update script
commit with merge because of being able to distinct between the bugs
2017-05-24 15:55:46 +02:00
Heiko August
cc07e2f22b Fix: the function expects one parameter, not two of them 2017-05-24 15:49:50 +02:00
Heiko August
2cdb553edf Fix: hunted a silly bug in string concatenation 2017-05-24 15:49:12 +02:00
Heiko August
dea8985f5b Fix: once again, don't use table names from the testing environment 2017-05-24 15:42:14 +02:00
Heiko August
dd4198a737 Change: add TODO markers to non-english language files (#234) 2017-05-24 15:05:14 +02:00
Heiko August
b2a66abba7 Handling of the read state reset methods and values (#233)
* Change: use new settings for handling of read state
* Change: add new setings to the SQL-files for update and installation
* Change: queries for new settings and removal of outdated settings to the update script
* Change: remove outdated setting from the SQL file for installation
* Change: new form elements and language strings for read status handling
* Fix: add a check for non exisiting setting reset_read_state
* Fix: wrong name of setting in the form elements
* Change: ensure a valid value for the read state reset method
* Fix: correct wrong name for form field and hardcoded value
2017-05-24 15:04:06 +02:00
Heiko August
4ff0fdbb46 Change: list of changed files 2017-05-23 18:56:14 +02:00
Heiko August
1159f67c0d Change: add version 2.4.2 to the list of updateable versions 2017-05-23 18:55:13 +02:00
Heiko August
c680a768b5 change collation for mlf2_userdata.user name to utf8_bin (#227)
* Fix: set collation of "user_name" to utf8_bin to distinguish i.e. between "a" and "ä"
* Fix: change collation for user name to utf8_bin also in the update process
* Change: reorder the list of queries to the correct order
* Change: clarify the description of instructions
2017-05-14 13:48:51 +02:00
Heiko August
f2f89b5376 Fix: wrong file name in the preamble comment (#228) 2017-05-12 14:42:12 +02:00
Heiko August
45d2bf30a2 distinguish between new and not marked as read also for registered users (#219)
* Fix: an entry is only new, if it is, not, if it's unread
* Change: intendation by tab on a few places

fixes #209
2017-05-01 19:58:52 +02:00
Heiko August
5322d1bc06 pre-populate the field for forum-URL with the correct protocol string (#208)
* Change: new function get isProtocolHTTPS
* Change: use the function to distinguish between a request over HTTP or HTTPS

If a forum will be installed over HTTPS, the pre-populated form field for the forum URL should reflect this.
2017-04-24 16:12:26 +02:00
Heiko August
c7eb04da8b Fix: expand further form fields, which was forgotten until now (#210) 2017-04-21 18:55:05 +02:00
Heiko August
de27ceb6c4 Fix: no identification of IE, use universal cache directive instead (#207) 2017-04-20 16:00:11 +02:00
Micha
d96bf2d022 Last reply (#197)
- extend SQL query for 'last_reply' column
- add last_reply to SQL query
 fixes #195
2017-04-11 12:48:38 +02:00
Micha
173fd88ab1 - simplify get_category_ids (#198)
- replace loop over array items by inbuilt function array_keys
2017-04-08 12:17:22 +02:00
Heiko August
ec70486b46 Add further indices to speed up the queries … (#192)
* Change: add indices to the entries table, speeds up the query execution
* Change: add indices to the read status table, speeds up the query execution
* Change: further index for column last_reply
* Change: additional indices for user data table
2017-03-31 16:50:53 +02:00
Micha
18b2131def replace graphic separator (#194)
- replace graphic separators with CSS-text (with :before)
2017-03-25 12:59:36 +01:00
Heiko August
ea6ce021b9 Fix: restore lost CSS-rule for #image-canvas img (#191)
fixes #186
2017-03-19 14:09:13 +01:00
Heiko August
b213544bc7 Fix: replace outdated url of the YUI compressor project page (#190)
fixes #189
2017-03-19 13:58:42 +01:00
Heiko August
dea15a2e9d Merge pull request #185 from auge8472/v2.4.2a
V2.4.2a, last fixes for the update script
2017-03-12 13:57:39 +01:00
Heiko August
8ec1075fa7 Fix: when fetching one line, the counter is wrong 2017-03-12 13:54:10 +01:00
Heiko August
bdeda781ed Fix: wrong string delimiters, used ones for names for the values 2017-03-12 13:54:05 +01:00
Heiko August
78047df9ee Merge pull request #184 from auge8472/v2.4.2
V2.4.2, all necessary changes for the new release
2017-03-12 12:53:46 +01:00
Heiko August
7ff76d4264 Change: add the new version number to index.php and config/VERSION 2017-03-12 12:48:02 +01:00
Heiko August
345119c126 Change: add the changes of version 2.4.2 to the changelog 2017-03-12 12:47:31 +01:00
Heiko August
ebddccbbe6 Change: add the version 2.4.1 to the list of updateable versions 2017-03-12 12:46:58 +01:00
Heiko August
c8a80b33c8 Change: add the list of files which has to be actualised 2017-03-12 12:46:34 +01:00
Heiko August
005e9b33f2 Change: update function for version 2.4.2
Check the structure of settings table. If column 'name' has no PK, set it.
2017-03-12 12:18:43 +01:00
Heiko August
95b1591628 Fix: don't set class .read for not logged in visitors (#183) 2017-03-12 11:15:10 +01:00
Heiko August
cce4483b3f Fix: no-gender radio button also in the admin form for user edit (#181)
fixes #175
2017-03-02 16:58:47 +01:00
Heiko August
fad5db214c Fix: create PK for settings table also when installing (#180)
fixes #179
2017-03-02 16:47:14 +01:00
Micha
911ae16911 Sorting Update List (#178)
- The files as well as the folders are sorted (by php function sort)
- see https://github.com/ilosuna/mylittleforum/issues/177
2017-02-26 20:00:40 +01:00
Heiko August
403be41285 last step to version 2.4.1 (#174)
Infos about v2.4.1
2017-02-20 19:46:09 +01:00
Heiko August
3f4b3b0c22 Change: new version number in version file 2017-02-20 19:41:20 +01:00
Heiko August
2d3edcea26 Change: new version number in the index page 2017-02-20 19:40:13 +01:00
Heiko August
50c9a41b60 Change: add infos about the changes of version 2.4.1 to the changelog 2017-02-20 19:38:06 +01:00
Heiko August
5e0a92a982 Change: add code for the update to version 2.4.1 2017-02-20 19:30:44 +01:00
Heiko August
de3e4ceb16 Fix: add a more descriptive error message for absence of the new file VERSION (#173)
fixes #173
2017-02-20 16:30:31 +01:00
Micha
097e1b4e46 CSS (#171)
- fix problem with read-class
- see http://mylittleforum.net/forum/index.php?id=9827
2017-02-17 21:41:23 +01:00
Micha
56812c67a9 PHP-Object (#170)
- PHP object is initialized by an array-type to be valid with PHP 5.2
and 5.3.
- see https://github.com/ilosuna/mylittleforum/issues/169
- see http://mylittleforum.net/forum/index.php?id=9828
2017-02-17 21:36:21 +01:00
Heiko August
ab2e6b48d1 Merge pull request #168 from ilosuna/v2.4
last changes for new version 2.4
2017-02-16 09:38:03 +01:00
Heiko August
a05f884f90 Remove: old update file for 2.x to 2.3 2017-02-16 09:35:57 +01:00
Heiko August
6908bda953 Change: new version number in file VERSION 2017-02-16 09:32:59 +01:00
Heiko August
c7ea843859 Change: adjust the copyright notice and added the new version number to the index file 2017-02-16 09:25:48 +01:00
Heiko August
f06e9b80cb Change: add list of the changes for version 2.4 to the changelog 2017-02-16 09:20:21 +01:00
Heiko August
a102812e23 Change: make the update script ready for version 2.4 2017-02-16 09:19:03 +01:00
Micha
1c3f95c2e0 Add hidden field for category (#167)
- a hidden field is added, if select is disabled to transfer the category-value
- https://github.com/ilosuna/mylittleforum/issues/166
- http://mylittleforum.net/forum/index.php?id=9779
2017-02-12 18:32:33 +01:00
Micha
2005df442a Extract Download-URI from ATOM-Feed (#165)
- Download/info uri is extracted from ATOM using LINK-element
- RexEx to get the version is updated to match both: '1.2.3' and
'v1.2.3'
- URI is stored in 'temp_infos_table' as 'last_version_uri'
2017-02-05 15:29:07 +01:00
Heiko August
d24c75a7e6 data for new pre release 2.3.99.3 (#164)
* Change: add changes and fixes for version 2.3.99.3
* Change: add the data for version 2.3.99.3
* Change: add the new version number 2.3.99.3
2017-02-05 13:58:09 +01:00
Heiko August
0b4b88b7e7 Change: add radio button to remove specified gender (#163)
fixes #157
2017-02-05 13:15:30 +01:00
Heiko August
fef88d86da Fix: use dirty die instead wrong break (#162)
fixes #158
2017-02-05 12:29:48 +01:00
Heiko August
d0ab56e596 Change: add spans for hideable interpunction (#161)
Additional preparation for responsive themes.
2017-02-05 11:26:42 +01:00
Micha
6889beb723 Check for Null-Value (#160)
- check for Null-Value via COALESCE
- https://github.com/ilosuna/mylittleforum/issues/159
2017-02-04 14:28:25 +01:00
Heiko August
28288031ee Change: new version number (#154)
closes #152
2017-01-24 19:58:19 +01:00
Heiko August
ba42369e62 added the necessary code for a new release (v2.3.99.2) (#153)
* Change: add a block for the updated files of the intern pre release 2.3.99.1
* Change: make intern testing version 2.3.99.1 updateable
* Change: added changelog for the pre release 2.3.99.2

see also #152 
* Change: added the version string to the comment block in the index.php

* Change: added the infos about the co-authors
2017-01-24 19:52:46 +01:00
Heiko August
19f83455db Fix: don't duplicate language keys and include the version number inside smarty (#151)
fixes #147
2017-01-23 21:58:36 +01:00
Heiko August
2a0d0a8086 Fix: the block for stating an entry new or read was outside the loop (#150)
fixes #148
2017-01-22 18:05:09 +01:00
Heiko August
d74f44ea39 Merge pull request #149 from auge8472/master
redo the last merge because of asynchronisms between the trunk and my repo
2017-01-22 17:32:37 +01:00
Heiko August
798d173ccd Fix: a new entry can't be read and a read one can't be new (#144)
* Fix: a new entry can't be read and a read one can't be new
* Fix: set read or new status in one code block

An entry is either new or read but it can't be both. Decide
the status in one block and use the new read status for registered
users and the old cookie based behaviour for not registered visitors.

fixes #128
2017-01-05 23:10:14 +01:00
Heiko August
14c8ae3bf6 Fix: set read or new status in one code block
An entry is either new or read but it can't be both. Decide
the status in one block and use the new read status for registered
users and the old cookie based behaviour for not registered visitors.
2017-01-05 23:05:08 +01:00
Heiko August
a84a4a8b53 Fix: a new entry can't be read and a read one can't be new
An entry is either new or read but it can't be both.
Use the new read status for registered users and the old
cookie based behaviour for not registered visitors.
2017-01-05 22:52:40 +01:00
Heiko August
ae2395f784 Fix: restore old behaviour of smartys config_overwrite
Before issue #11 the value of config_overwrite was false.
To allow overwriting of config items it was changed to true.
That led to bugs with items, that should act as arrays.
2016-12-26 22:49:53 +01:00
Heiko August
2cd8659d47 Fix: add the listing comma to chinese word separators 2016-12-26 22:49:53 +01:00
Micha
34b3dd2b4c restrict the 'edited by' - output (#135)
- restrict the if statement by: $settings['dont_reg_edit_by_admin']==1
as well as $settings['dont_reg_edit_by_mod']==1 in last condition
2016-12-26 15:43:27 +01:00
Micha
379ef3f5b7 Activate and unlock user by admin (#136)
- users can be activated by admins but they are not automated unlocked.
--> Add unlock-condition to activate sql
2016-12-10 10:23:57 +01:00
Micha
9133153112 - check existence of $total_views (#133)
- check existence of $total_views to avoid php warning
2016-12-05 17:19:56 +01:00
Heiko August
e4fe0fb1b0 Merge pull request #131 from auge8472/bugfixing
fixed several bugs
2016-12-04 20:06:11 +01:00
Heiko August
8667351996 Fix: forgot to add the changes of PR #122 to the minified file versions 2016-12-04 20:02:15 +01:00
Heiko August
4dd17c6b0c Fix: correcting wrong parenthesis 2016-12-04 19:37:49 +01:00
Heiko August
5e2fad4217 Fix: use the last release number instead the new one 2016-12-04 19:36:31 +01:00
Heiko August
b9f0f0f3f5 Fix: provide links for backup of the new tables (#130) 2016-12-04 18:07:59 +01:00
Heiko August
cfd62942be take the new tables into account … (#129)
* Change: deleting the new tables in case of uninstalling
* Fix: take new tables into account when executing a backup

fixes #90
2016-12-04 17:31:14 +01:00
Heiko August
62f02ca31d Add the table and a further box in the admin area (#124)
* Change: new table mlf2_temp_infos
* Change: add a box to show the version number of the installed version
* Change: load version info only during daily actions
* Change: simplified release info
* Fix: text change in every language except the base language?!
* Fix: remove superfluous and in some cases script breaking query

close #123
2016-12-04 15:32:34 +01:00
Micha
904772d6fa - remove intval (#127) 2016-12-02 17:17:03 +01:00
Micha
caa437cbde - limit the number of entries in read_entires-table (#126)
- limit the number of entries in read_entires-table by 'max_read_items',
if and only if 'max_read_items' > 0
- max_read_items <= 0 means unlimited storage
- remove intval-call
2016-12-02 17:11:41 +01:00
Micha
ce26048c25 - limit the number of entries in read_entires-table (#125)
- limit the number of entries in read_entires-table by 'max_read_items',
if and only if 'max_read_items' > 0
- max_read_items <= 0 means unlimited storage
2016-12-02 17:05:07 +01:00
Heiko August
6b2602fe06 Change: alter settings table and rewrite the settings (#120)
* Change: alter settings table and rewrite the settings
* Change: tread a simpler path than with the temporary array. Renaming the old and creating a new table with a following INSERT is much more simple.
* Fix: remove the code for deleting the (doubled) setting auto_lock_old_threads
* Fix: add ON DUPLICATE KEY UPDATE to avoid multiple inserts. During the development it's expectable, that an update occurs several times. It would fail in this line because of the new primary key.
* Change: new tables should be of type InnoDB
* Change: a few comments and a bit cosmetic

this fixes #99
2016-12-02 12:01:38 +01:00
Heiko August
1f5df75589 Shrink and disable elements with a class at their parents (#122)
* Change: use a class to toggle entries in nested view

Use it for the parent element instead for every
single element, that should be manipulated.

* Change: toggle sidebar with a class at the parent element
2016-12-01 21:26:47 +01:00
Heiko August
fe5c188387 Change: more space for a few form fields (#121)
Make the fields for image size a bit wider.
2016-11-30 17:59:16 +01:00
Micha
bb56012811 - Replace getAvatar function (#119)
- replace avatar function to be compatible to PHP <5.3
2016-11-29 19:22:56 +01:00
Micha
c676616924 - Used word delimiters (#116)
- Word delimiters added to lang files
- delimiters are used in too_long_word function
- see https://github.com/ilosuna/mylittleforum/issues/105

fixes #105
2016-11-28 19:35:43 +01:00
Micha
1aeecbbd22 - correcting regexp (#118)
* - correcting regexp

- correcting regexp
- check variable via isset() and file_exists()

* - remove isset

- isset is not needed
2016-11-28 00:30:08 +01:00
Micha
aa98794a4c - Transfer read state to new table on update (#117)
- regard number of postings in setting table i.e. 'max_read_items'
- see https://github.com/ilosuna/mylittleforum/issues/77
2016-11-27 15:47:14 +01:00
Micha
28ceff5e15 - Added timestamp to avatar filename (#114)
- a timestamp is added to avatar image file name to avoid caching issues
- https://github.com/ilosuna/mylittleforum/issues/113
2016-11-27 14:17:23 +01:00
Micha
df993f25ad - CSRF-Token (#111)
- add CSRF token to admin form
2016-11-26 10:21:30 +01:00
Micha
01966f62db - Add delimiters to too_long_word-Function (#110)
- adding additional parameter to too_long_word function to specify the
delimiter(s)
2016-11-24 19:57:28 +01:00
Micha
a2d944d17a - too long word check (#109)
- disable the check for too long words, if param '$word_maxlength' is <=
0
2016-11-24 18:39:21 +01:00
Micha
0cbc68d043 Remove item (#108)
- remove duplicate item 'auto_lock_old_threads' in setting table
2016-11-24 18:28:30 +01:00
Heiko August
969a7c21b8 Change: return to advanced settings after sending form data from advanced settings (#107)
fixes #104
2016-11-24 18:25:32 +01:00
Heiko August
7a115dfe96 Fix: trigger login control with all setting values > 0 (#106)
Setting temp_block_ip_after_repeated_failed_logins define the time limit,
if the value is greater than 0. That has to be respected, when triggering the check.

fixes #102
2016-11-24 17:43:23 +01:00
Heiko August
c66b6576dc Fix: remove doubled entry auto_lock_old_threads (#100)
fixes #98
2016-11-23 20:07:43 +01:00
Heiko August
afccebc1cc Fix: again, don't use testing code (#94)
fixes #92
2016-11-21 18:16:28 +01:00
Heiko August
463508935a Fix: use table name from settings, not the static names from testing (#93)
fixes #91
2016-11-21 12:56:24 +01:00
Heiko August
b98140a882 Fix: syntax error (comma and semicolon) (#89)
add a comma, remove a semicolon
2016-11-20 23:09:11 +01:00
Heiko August
8c44a01fb0 set :visited for thread-links (#88)
* Change: set :visited as fallback and base for .read
* Change: use :focus for keyboard users as complement to :hover
* Change: remove '!important' from rule for a.read:active

fixes #87
2016-11-20 22:39:14 +01:00
Heiko August
d792c1e7f3 Read status cleanup (#86)
* Change: remove column 'read_entries' from the database queries
* Change: remove obsolete functions and code for read-status-handling
* Fix: unnecessarily doubled request for column 'ip'
* Cleanup: cosmetic formatting issues

fixes #45
2016-11-20 21:37:26 +01:00
Heiko August
b8b047faf1 Change: set class read with info from read-status-table (#85)
fixes #80
2016-11-20 20:48:40 +01:00
Micha
9f88e86898 Remove read state (#82)
- add new parameter to setting_table called 'read_state_expiration_date'
(default 150 days)
- remove read state if 'auto_lock_old_threads' > 0
- remove read state if 'read_state_expiration_date' > 0
2016-11-18 23:08:39 +01:00
Micha
adbf996962 Transfer read state to new tabel (#81)
- SQL to transfer read state from 'userdata_table' to new table
'read_status_table'
- SQL to remove column 'entries_read' from 'userdata_table'
2016-11-17 21:26:22 +01:00
Heiko August
f54a7c61c6 save read status to table (#78)
Store the value only in the database table and not in a cookie or the session.
Make use of a more descriptive name for the function.
resolves #72

* Change: store read-status in the new table
* Change: new parameter user_id, adapted condition and comment
* Change: save the read-status to the new table
* Fix: use correct variable names and types continuous
* Change: unify the variable names and the behaviour of the two bookmark-blocks
* Change: add read-status-marking to nested view
2016-11-17 17:43:01 +01:00
Micha
9e75d0397a Remove read status of entries on delete (#76)
* Remove read status of entries on delete

- remove "read status" on user delete
- remove "read status" on posting delete

* Primary key

- Remove unique definition and add primary key "read_status_table"
2016-11-16 22:50:21 +01:00
Heiko August
1519b0091d Fix: don't add column id (PK, Auto Increment) when read_per_user is an unique index (#79) 2016-11-16 19:50:05 +01:00
Heiko August
d680aa4757 Create read-status-table (#74)
* Change: new table mlf2_read_entries
* Fix: forgot to add the assembling of the table name in update script
* Change: add column time to store the last request for an entry
* Fix: rename column 'e_id' to 'posting_id' for consistency

fixes #71
2016-11-14 10:56:04 +01:00
Micha
2735994677 consider modified lang files (#69)
- add lang-directory to update routine v2.4
2016-11-06 20:27:49 +01:00
Heiko August
37c03517be put all new strings to all language files in english (default language) (#68)
* Change: add untranslated strings to chinese, croatian and german languages

* Change: put new untranslated english strings into every langauge file
2016-11-06 20:06:38 +01:00
Heiko August
6627539a28 version check from file (#66)
* Change: read new version number from file in case of an update

* Fix: put the version checks into a block, that will only be executed in absence of an error

* Fix: stop update even with equal version numbers of current installation and update version

* Fix: compare the current version with the array of allowed version numbers, not with version number of the update

* Change: replace $update['version'] with $newVersion

It's not part of the given data and will be read from the file VERSION.
Thatswhy it is now a separated variable.

* Change: use the file VERSION to get the version number

* Fix: relative path must be given from the requested script, not the included one
2016-11-06 13:36:04 +01:00
Micha
30c66646d6 Regex (#65)
* Add escape sequence

- modify reg exp and add escape sequence

* Adding \p{Cf} to regexp

- Adding \p{Cf} to regexp to filter soft hyphen
2016-11-03 23:38:54 +01:00
Micha
e4c278ff94 show number of unlocked users (#64)
* show number of unlocked users

- SQL-SELECT is added to count the number of unlocked users
- Number of unlocked users is shown in sidebar
- Issue: https://github.com/ilosuna/mylittleforum/issues/62

* Ckeck register_mode

- register_mode value is checked in SQL

* Overwork CSS, SQL, Templates and Image

- SQL checks for empty activate_code
- rename class to non-activated-users
- rename key in lang-fiels to non_activated_users_link
- add new files to update script
2016-11-03 23:24:57 +01:00
Micha
ca4a8b5867 Overwrite db_settings array (#61)
- override db_settings_array to fix issue
https://github.com/ilosuna/mylittleforum/issues/60
2016-10-26 22:26:55 +02:00
Micha
af1694743b Fix command execution issue (#52), fixes #51
* Fix command execution issue

- Check for HTML tags
- add slashes

* Add warning message

- a warning message is displayed in admin area, if install/index.php
still exists (https://github.com/ilosuna/mylittleforum/issues/51)

* Use new admin-info-box

- use new admin info boy to display warning message
2016-10-25 14:52:40 +02:00
Micha
4af0e88ce4 Update checker (#58)
* Update checker, fixes #44 

- read ATOM feed to get information about a new release
- show info in admin-area

* Multipe ways to get external content

- try to use curl, file_get_contents and fsockopen to get content of
external resource

* correct comment

- correct comment

* add return statment

- add return statment to each branch

* Revert "add return statment"

This reverts commit 0240295501.
2016-10-24 17:20:25 +02:00
Micha
5613288940 Overwrite db_settings on update (#59)
- overwrite the db_settings and add new database table 'bookmarks'
- marked changed files with pull-ids
2016-10-22 16:50:01 +02:00
Micha
96a7c163b1 Chech array elements (#57)
- check if array alements exist
2016-10-22 13:04:15 +02:00
Heiko August
081a1e6df5 Add: a new box with a link to the latest release in the Github repo (#56) 2016-10-21 19:14:51 +02:00
Micha
aeec3ce2d4 Remove Subfolders (#55)
* Remove Subfolders

- remove subfolders from update list, if the parent folder is also in
list, cf. http://mylittleforum.net/forum/index.php?id=9359
2016-10-20 14:32:39 +02:00
Micha
8d43d794a8 Pattern Modifier (#54)
- add modifier u to switch to UTF-8 mode in regexp function in
contains_special_characters to avoid problems with chinese characters,
cf. http://mylittleforum.net/forum/index.php?id=9353
2016-10-19 11:02:07 +02:00
Micha
1f47b8e382 Count number of views of thread in table view (#50)
- Shows the number of *views of the thread* instead of the number of
*views of the posting* in table view.
2016-10-16 14:20:06 +02:00
Micha
a21b131642 prevent 404 error (#49)
- Add path to favicon of the default template to prevent a 404 error
2016-10-16 13:49:04 +02:00
Micha
a6ccd23023 Change tab order (#47)
- BBCode Button will be excluded by tab order
- AjaxPreviewWindow will be excluded by tab order
- Captcha field will be included to tab order

see: http://mylittleforum.net/forum/index.php?id=8601
2016-10-15 13:48:05 +02:00
Micha
41bc27e273 Add Bookmark table (#46)
Add bookmark table to install-script
2016-10-14 19:40:56 +02:00
Heiko August
7451911a8d Merge pull request #42 from auge8472/clean
Cleanup of ancient and obsolete code fragments, fixes #15
2016-10-13 22:36:19 +02:00
Heiko August
52af9dded8 Change: remove ancient code fragment 2016-10-13 22:25:11 +02:00
Heiko August
f44f94841a Change: remove old handling of not accepted words 2016-10-13 22:24:40 +02:00
Heiko August
04ce6011fe Change: remove outdated bb-code replacement for flash 2016-10-13 22:24:08 +02:00
Heiko August
b99f63d9b8 Change: remove outdated check for banned user agents and user names 2016-10-13 22:23:39 +02:00
Heiko August
2f2ec055ed Change: use email address and not the users name 2016-10-13 22:23:00 +02:00
Heiko August
43128e8ffd Change: remove unused mailto-replacement 2016-10-13 22:22:29 +02:00
Heiko August
baf6e26b6f Change: remove a few outdated checks 2016-10-13 22:21:56 +02:00
Heiko August
e7baf0ed5d Change: remove unused signature processing 2016-10-13 22:21:10 +02:00
Heiko August
616de81fb0 Change: remove unused blocks for showing amount of users entries 2016-10-13 22:20:34 +02:00
Heiko August
eeefaff446 Change: remove user data output, could cause privacy leak if activated 2016-10-13 22:19:42 +02:00
Heiko August
049513d93d Change: default forum time should not be shown at that point 2016-10-13 22:19:19 +02:00
Heiko August
8e711c278a Change: remove buggy and by this reason replaced database query 2016-10-13 22:18:29 +02:00
Heiko August
d29bc6e6e1 Change: outdated function calls removed 2016-10-13 22:17:52 +02:00
Heiko August
60177376e8 Change: removed some code fragments from user.inc.php 2016-10-13 22:16:13 +02:00
Heiko August
f4411f4858 Change: removed outdated code from posting.inc.php 2016-10-13 22:08:39 +02:00
Heiko August
3400ebdd88 Change: remove spreaded funtion calls, are unified nowadays 2016-10-13 22:03:55 +02:00
Heiko August
65fe952d86 Change: removed some outdated one-line code fragments 2016-10-13 22:01:23 +02:00
Heiko August
c69cc38bba Change: remove outdated code 2016-10-13 21:53:33 +02:00
Heiko August
6d1790955d Change: remove unused email sending code
Was disabled before because of a possible leak of a forums userdata.
2016-10-13 21:53:11 +02:00
Heiko August
3d05edf1c5 Change: remove old language-overwrite-code 2016-10-13 21:52:46 +02:00
Heiko August
8a05122d6d Change: remove old, unused behaviour for email text formatting 2016-10-13 21:52:13 +02:00
Heiko August
2e5881b35a Change: remove outdated image-size-code 2016-10-13 21:51:40 +02:00
Heiko August
b6420298d6 Change: remove unused code 2016-10-13 21:51:07 +02:00
Heiko August
82cb503bce Change: unused code for mail-header-building 2016-10-13 21:50:34 +02:00
Heiko August
636b0a3c49 Change: remove unused forum-entry-actualisation-queries 2016-10-13 21:50:06 +02:00
Heiko August
e0f09510c4 Change: remove unused search-for-user-query
It has it's more sophisticated successor below.
2016-10-13 21:49:37 +02:00
Heiko August
da80492dc8 Change: remove unused language file check 2016-10-13 21:49:01 +02:00
Heiko August
1ecc3a3064 Change: remove unused md5-function calls, md5 is outdated! 2016-10-13 21:48:32 +02:00
Heiko August
6fd860a5ea Change: remove query to list all entries of a special user
The request lists all entries of an user when these entries should be deleted.
It's not in use anymore.
2016-10-13 21:47:44 +02:00
Heiko August
204c31e8b9 Change: remove outdated check for existing user name
The check is since ages executed a few lines before in another way.
2016-10-13 21:46:45 +02:00
Heiko August
3cc4af4642 Change: remove query to change edited category name in entries-table
The name is only stored in the category-table.
The entries store only the category-ID.
2016-10-13 21:44:31 +02:00
Micha
5c736336c4 Bookmark, JavaScript and CSS, Preview window (#39)
* Bookmark

Add bookmark function to single postings

* Multiple changes

- Add bookmark function, cf.
https://github.com/ilosuna/mylittleforum/issues/38
- Show preview window on hover, if desired(!): set ajax_preview=2, cf.
https://github.com/ilosuna/mylittleforum/pull/37
- Replacing of inline-style elements in JS code by CSS classes, cf.
https://github.com/ilosuna/mylittleforum/pull/18 and
https://github.com/ilosuna/mylittleforum/issues/16

* Update db_settings.php

* Add phrases

Add content for issue https://github.com/ilosuna/mylittleforum/issues/32

* bubble-icon behavior

- Disable bubble-icon if posting is empty
https://github.com/ilosuna/mylittleforum/issues/40
- Add CSS issue https://github.com/ilosuna/mylittleforum/pull/41
2016-10-13 18:29:35 +02:00
Heiko August
5f477e35b8 Change: included the files that changed between v2.3.7beta and the final 2.3.7-release 2016-10-10 13:23:26 +02:00
Heiko August
c328783422 Fix: converted the scope fix (8718955c49) into the main.min.js 2016-10-10 13:20:19 +02:00
Heiko August
bd2b8497e1 Change: added last informations about version 2.3.7 2016-10-10 12:36:35 +02:00
Heiko August
bd1f5a6613 Change: set max-width for images in the ajax-preview (#41)
Images with a great width stuck out of the preview block. Now it's shrinked to the elements size.
2016-10-10 12:18:26 +02:00
Micha
e70650269e Fix: closing behavior (#36)
* Fix: closing behavior

Fix for closing issue, cf.
http://mylittleforum.net/forum/index.php?id=8428 The window will not
close, if the scollbar inside the preview element is clicked.

* Fix: Variable scope

Fix for type error, cf.
https://github.com/ilosuna/mylittleforum/issues/35#issuecomment-252064541
2016-10-07 14:45:15 +02:00
Heiko August
0db01527f7 Change: translated a few strings to german language (#34)
* Change: translated a few strings

* Change: alter one of the translations as suggested by @derletztekick
2016-10-06 17:10:25 +02:00
Heiko August
95617c542a Fix: misspelling in German language file (#33) 2016-10-06 15:50:50 +02:00
Micha
ecf3d53608 Add correct Version (#31)
Add correct version number to index.php
2016-10-05 18:11:02 +02:00
Heiko August
5bc858e7b0 Fix: replace graphic separators with CSS-text (with :before) (#30) 2016-10-05 16:27:43 +02:00
Heiko August
8c8cce952e Fix: missing user name in users entries list (#29)
Reinsert the variable $user_name. The context sensitive handling of it's content stays beside the handover to Smarty. This is because of the clear view in case of a maintenance necessity. fixes #28
2016-10-05 12:47:41 +02:00
Heiko August
6a787e4d88 Change: added changelog for version 2.3.7 (#27) 2016-10-04 20:10:56 +02:00
Heiko August
1a3140f1f8 Change: add update and install routines for version 2.3.7 (#26)
fixes #26
2016-10-04 19:41:40 +02:00
Micha
9a8ae4a277 Fix: update function (#22)
Fix bug in update function, fixes #21
2016-10-04 19:25:38 +02:00
Micha
5eacca5fb3 login blocking configuration (#20)
* login blocking configuration

The setting variable 'temp_block_ip_after_repeated_failed_logins' has
now a new meaning. A zero means off/not used and a value greater than
zero indicates a timespan.

* Version

Add version '2.3.6'
2016-10-04 18:01:01 +02:00
Micha
26bf7b9b93 Update Bad-Behavior (#24)
Update Bad-Behavior to version 2.2.19
2016-10-04 17:54:24 +02:00
Heiko August
6649238b81 Fix: button bar slipped below the textarea because of too little space (#23)
fixes #9
2016-10-04 17:53:27 +02:00
Micha
c24ed047a0 Constructor for PHP7 (#13)
- Add __construct-Function to classes to be valid for PHP7
- Check length of content-string @matchesCriterium-function to avoid a
PHP note
2016-10-02 19:43:54 +02:00
Micha
9c5b4ef657 context sensitive masking of HTML-output (fix #17)
* Fix: context sensitive escaping in user edit form (admin)

* Fix: context sensitive escaping in user register form (admin)

* Fix: context sensitive escaping in users list (admin)

* Fix: context sensitive escaping in e-mail addresses list (admin)

* Fix: context sensitive escaping in the contact form

* Fix: context sensitive escaping in entry output

* Fix: context sensitive escaping when saving an edited entry

* Fix: context sensitive escaping for online status in user list (normal)

* Fix: context sensitive escaping in the user list (normal)

* Fix: context sensitive escaping in an users personal data (normal)

* Fix: context sensitive escaping in an users entries list (normal)

* Fix: context sensitive escaping in the profile edit form (normal)

* context sensitive masking of HTML-output

* Fix: context sensitive escaping for numeric values
2016-10-02 17:13:23 +02:00
Micha
ceb734b9d0 Update Smarty (#12)
Update Smarty to current version 3.1.30
2016-09-28 09:57:49 +02:00
Heiko August
981f29b8ce Merge pull request #11 from ilosuna/error-in-error-messages
Fix: CSRF bug, relative path bug, error in language handling, spelling error

Fixes authored by: @derletztekick
2016-09-26 14:09:20 +02:00
Micha
216217a7a9 Spelling error
Correcting eng. lang file, cf.
http://mylittleforum.net/forum/index.php?id=9216
2016-09-23 21:57:38 +02:00
Micha
c0dd93eda9 error in error messages
Fixing Issues #8, cf. https://github.com/ilosuna/mylittleforum/issues/8
2016-09-22 22:32:47 +02:00
Micha
c71bef80e6 CSS Relative Path Overwrite Protection
The smarty-variable $FORUM_ADDRESS was added to create absolute URIs to
CSS and JS files.
2016-09-20 22:04:34 +02:00
Micha
03064a5c11 CSRF protection
A page token was added to the user-register/change form to avoid an
unauthorized access from external page while an admin is logged in.
2016-09-20 21:59:35 +02:00
Heiko August
17516e3ae9 Merge pull request #7 from auge8472/master
All necessary changes for update etc., that I forgot when I created the tag v2.3.6
2016-08-04 22:17:23 +02:00
Heiko August
3724c802f5 Change: actual version string for the index.php 2016-08-04 22:07:14 +02:00
Heiko August
db137c7a2a Change: actualise the changelog with the infos about v2.3.6 2016-08-04 22:05:13 +02:00
Heiko August
637271a15c Fix: only use mysqli-functions, when updating to 2.3.6
The forum uses since v2.3.5 the mysqli instead the mysql library in PHP.
Thatswhy there can't be an update function from older versions.

There is no update to v2.3.6 without an interim step via version 2.3.5.
2016-08-04 21:44:51 +02:00
Heiko August
ae29e0fca1 Change: update update script, new version strings 2016-08-04 21:09:59 +02:00
Heiko August
0b47232444 Change: set the URL to the new download location 2016-08-04 21:01:36 +02:00
Heiko August
5c528c183c Merge pull request #6 from auge8472/master
Fix: correct some misspellings
2016-07-18 14:52:27 +02:00
Heiko August
1f8cd40a46 Change: use german word "los" instead english "go" 2016-07-18 14:46:10 +02:00
Mark Hoschek
32c76d9483 Merge pull request #5 from auge8472/master
direct link to list of own postings
2016-07-15 17:07:57 +02:00
Heiko August
7415bd2c34 Change: correct formatting, removed a bunch of unnecessary blanks 2016-07-13 11:14:41 +02:00
Heiko August
f9334a15bd Change: better understandable phrasing 2016-07-13 11:13:11 +02:00
Heiko August
d97a8f377d Change: make a "1" to "ein(e/er)"
This is common ine formulations in the German languag.
2016-07-13 11:07:23 +02:00
Heiko August
8f3b2ffcc4 Fix: several spelling and grammar errors 2016-07-13 11:00:56 +02:00
Heiko August
1f670580c4 Fix: double use of key name causes problems with additional templates 2016-07-04 20:15:52 +02:00
Heiko August
3a1b7c0d62 Change: use user_id instead p_user_id, because it's in use anyway 2016-07-04 11:52:26 +02:00
Heiko August
c6622a6636 Fix: use proper masking of ampersands 2016-07-04 11:48:37 +02:00
Heiko August
442509b80b Feature: include link to a list of the logged in users own entries 2016-07-04 11:41:45 +02:00
Mark Hoschek
614958722d Merge pull request #4 from auge8472/master
Fix: error in the cornercase of connecting the database server
2016-06-23 20:36:56 +02:00
Heiko August
aa246404de Fix: error in cornercase of failure while connectiong to database server
The script can't use the connection identifier to report it's absence. Use the correct function for this case.
2016-06-23 10:49:40 +02:00
Mark Hoschek
ebb28d8eed Workaround for Firefox-bug #2 2016-06-22 18:57:34 +02:00
Mark Hoschek
65af7cceb6 Merge pull request #3 from auge8472/master
Fix: field last_login can now store NULL values
2016-06-22 18:43:31 +02:00
Heiko August
dc60c18780 Fix: field last_login can now store NULL values
When a user should be registered, she/he was (in that moment) never logged in. Thatswhy the field last_login should stay empty (NULL) what was forbiddeen by the old table definition.
fixes ilosuna/mylittleforum#1
2016-06-22 13:03:10 +02:00
Alex
2c47d5c73f Update Changelog 2016-06-02 20:47:01 +02:00
Alex
b94e25283c Set empty timestamp values to null for MySQL>=5.6.5 2016-06-02 20:40:09 +02:00
Alex
c9ba3911dc Update changelog 2016-06-02 19:01:01 +02:00
Alex
985cbf893e Add smarty files 2016-06-02 18:52:38 +02:00
Alex
dcf930630a Update changelog and update script 2016-05-31 17:05:05 +02:00
Alex
f3bba070d7 Update reademe file 2016-05-31 16:58:43 +02:00
Alex
d6bfc56e92 Update readme file 2016-05-31 15:10:13 +02:00
Alex
6c845e0a8e Update readme file 2016-05-31 15:09:16 +02:00
Alex
d72686a4f7 Update readme file 2016-05-31 14:51:30 +02:00
Alex
4412573af3 Update readme file 2016-05-31 14:50:08 +02:00
Alex
ff5528c34e Update CHANGELOG 2016-05-31 14:21:19 +02:00
Alex
1fb9f1e08a Update README file 2016-05-31 14:18:35 +02:00
Alex
23e0c4d353 PHP 7 modifications (e.g. replace mysql_* by mysqli_* functions) 2016-05-31 14:08:09 +02:00
Alex
7eb9702031 Sticky thread fix, iOS JS fix, template and translation fixes (http://mylittleforum.net/forum/index.php?id=8512) 2016-03-13 17:49:28 +01:00
Alex
132f119850 Update contains_invalid_string() 2015-02-08 17:53:19 +01:00
Alex
522981ecbc Update changelog and update script 2015-02-08 17:26:18 +01:00
Alex
989c40e27e Fix in contains_invalid_string() function 2015-02-08 17:17:51 +01:00
Alex
80c7f23c90 Update changelog 2015-02-08 11:47:53 +01:00
Alex
000eb668da Update update script 2015-02-08 11:41:25 +01:00
Alex
6fb90b08b0 Update changelog 2015-02-08 11:36:12 +01:00
Alex
b5409de5e7 Smarty update (3.1.21) 2015-02-08 11:28:15 +01:00
Alex
b814a956cb Update version info, install SQL schema and update script 2015-02-08 11:23:11 +01:00
Alex
3bd9526285 Security vulnerability fix (http://mylittleforum.net/forum/index.php?id=8187) 2015-02-08 11:12:12 +01:00
Alex
f2eff202a0 French language file updated 2014-04-12 09:58:07 +02:00
Alex
5f2db4ed60 changelog updated 2014-04-10 21:46:50 +02:00
Alex
b10ccd6af0 deleted old images in default theme folder 2014-04-10 21:35:40 +02:00
Alex
dd62d1d304 update file adjustment 2014-04-10 21:09:27 +02:00
Alex
944186166b bugfix in posting.js/posting.min.js 2014-04-10 20:55:44 +02:00
Alex
442f9ca004 modified update file 2014-03-30 17:28:06 +02:00
Alex
677be3721c update Smarty (3.1.17) 2014-03-30 17:00:21 +02:00
Alex
d79c46036d fix French language file 2014-03-30 16:39:44 +02:00
Alex
8be31c1c28 update Spanish translation 2014-03-30 14:42:12 +02:00
Alex
7deea2a545 bugfix in posting.inc.php 2014-03-13 21:57:51 +01:00
Alex
6ca4006171 language bug fix, theme switch bug fix, Smarty updated, Bad Behavior updated, Swedish language file added 2013-11-23 16:56:36 +01:00
Alex
207cf78ed3 minor language file and template changes 2012-11-28 17:23:50 +01:00
Alex
90deb8fd98 implemented Stop Forum Spam 2012-11-25 16:58:35 +01:00
Alex
fb99e74ae5 implemented list spam function 2012-11-25 16:07:25 +01:00
Alex
4efc21795d removed outdated flash insert function 2012-11-25 11:14:39 +01:00
Alex
06abf7cafc updated update script 2012-11-25 10:50:00 +01:00
Alex
c08afa1687 JavaScript fix ( http://mylittleforum.net/forum/index.php?id=6718 ), Smarty updated, Bad Behavior updated, GeSHi updated, set default time zone to UTC 2012-11-21 10:33:22 +01:00
Alex
ce099e861f Updated Bad Behavior, Changelog and Update script 2011-09-01 11:06:39 +02:00
Alex
24ce49b6d8 minor javascript bugfix 2011-07-25 08:59:32 +02:00
Alex
f93200f736 added admin options to user profile page, added akismet check of registered users 2011-06-17 21:19:17 +02:00
Alex
4a1d57c5fa Smarty updated to version 3.0.8 2011-06-10 10:35:50 +02:00
Alex
71524482d6 minor JavaScript modifications 2011-05-12 10:44:49 +02:00
Alex
f0f7454474 clear userdata bugfix 2011-03-28 10:50:17 -03:00
Alex
904b759e6b replaced ereg() (deprecated as of PHP 5.3.0) by preg_match() 2011-03-18 16:23:37 -03:00
Alex
bc1fc24ecd modifications for Smarty 3 2011-03-16 19:54:47 -03:00
Alex
e878b26e07 removed needless images 2011-03-11 17:27:40 -03:00
Alex
52fc96477a Smarty, Bad Behavior and GeSHi updated 2011-03-11 17:22:33 -03:00
Alex
f918959589 imagecopyresized() replaced by imagecopyresampled(), modifications in stringparser_bbcode class 2011-02-17 11:01:54 -03:00
Alex
ff590a40c9 Timestamp exclusively fetched from database now, minor template modifications 2011-02-13 10:52:06 -03:00
Alex
81ce36f193 Chinese and Croatian language files updated 2010-11-21 17:55:04 -03:00
Alex
97b4316157 JavaScript fix for insert link button 2010-10-27 17:36:07 -03:00
Alex
9e2811ca2f minor CSS and JavaScript modifications 2010-10-25 16:52:09 -03:00
419 changed files with 79132 additions and 35298 deletions

596
CHANGELOG
View file

@ -1,7 +1,601 @@
my little forum changelog
-------------------------
2.2.6 (2011-07-10)
20250323.1 (2025-03-23)
-----------------------
- feature: add database entries for uploaded images that was uploaded before the upload management was introduced, add new icons for it as SVG
- change: change the appearance of the sidebar toggle in its heading, add new icons for it as SVG
- change: replace a few occurences of JS-based focus setting to form fields with the corresponding HTML attributes
- change: all index columns and columns, that stores indexes as foreign keys are unsigned now, this doubles their value range
- change: new appearance of the templates for login, registration and sending forgotten passwords
- fix: added INTL time format strings to all language files according the languages own rules when known
- fix: remove the emtying of a search field when setting the focus to the field
- fix: display MySQL errors in the upgrade script, was broken before
- fix: a user list, restricted to logged-in users, was still displayed after users logout
- fix: several errors in the HTML structure in the posting form template
20241215.1 (2024-12-15)
-----------------------
- change: use modern form elements and field types, where it is appropriate
- change: set autofocus into the first input element of a form after loading the page, where it is appropriate
- change: add attribute required for form fields, that must be completed, this might prevent unnecessarily sending form contents
- change: rearrange the text input field and the formatting buttons in the posting form
- change: make the posting form behaviour better on mobile devices and for screen-reader programs
- change: rework of the popups for uploading images for use in postings and also the form for uploading avatar images
- change: reformatting of the thread tree items with breaking points to behave better in narrow viewports
- change: move the no-text icon from the end of the subject to the icon list after the metadata (author and date)
- change: set the posting date into a time element, enhances the machine readability
- fix: broken SQL query for selecting the postings of a specified category on a thread overview page
- fix: make images of type WebP appear in the uploaded images gallery in the upload images popup
- fix: restrict the sidebar in narrow viewports to its width
- fix: prevent the use of unhidden passwords for the AI training of browser vendors
- fix: added forgotten writing direction aware formatting for form elements
- fix: take the time of a posting and the time of registration of a user into account, when checking for a username collision
- fix: do not check for a username collision when an administrator or moderatior edits a posting of an unregistered forum user
- fix: remove tabindex attributes from form elements which caused a weird tab order on the posting form page
20240827.1 (2024-08-27)
-----------------------
- change: rewrite the styling (CSS) to support languages, written from right to left
- change: far better support of displaying the forum on mobile devices
- change: translate "Sidebar" to "Barre laterale" in italian language
- fix: display hours in 24-hours-format in german language
- fix: display date and time according to the syntax of the PHP DateTimeInterface in arabic language
- fix: include the column mlf2_entries.last_reply into the select, which is used in the ORDER-BY-clause
- fix: a few issues in the upgrade script
20240729.1 (2024-07-29)
-----------------------
- feature: lazy loading of images in forum entries, that are not in the viewport when loading a page with entries
- feature: add BB-codes [ins], [del] and [s], mainly intended to mark subsequent changes
- change: new upgrade script, from now on it is possible to use also version 2.4.19 as starting point of an upgrade
- change: apply database performance enhancements, this was provided by @joeiacoponi1 (thank you)
- change: enhancements and corrections in a few translations (simplified chinese, traditional chinese, danish, english, french, spanish)
- change: add new language arabic, this has been contributed by Abdul Salam in the project forum
- change: unify the use of the pagination link lists (from now on they are shown above and below the page content, where in use)
- change: set the new source URL for the MathJax CDN, that is recommended by the project
- change: remove the spam prevention method Bad Behavior because the projects seems to be dead since a longer time
- change: all tables use now the charset utf8mb4, the previously in some cases used utf8 (a.k.a. utf8mb3) will be deprecated by MySQL in one of the next server main versions
- change: use the SameSite attribute in cookies
- fix: resize the columns mlf2_useronline.ip and mlf2_logincontrol.ip to 128 bytes, mlf2_useronline.ip was 15 bytes long and caused HTTP-500-errors in case of visitors with IPv6
- fix: the mouse cursor should show up as pointer when hovering buttons
- fix: prevent passwords being sent for spell checking to Google when the content of a password field is shown as plain text
- fix: a few occurences of dates and times, that did not follow the new time formatting
- fix: add missing strings for the administration of the Bayes based spam prevention filter (B8)
- fix: correct a few errors in the HTML-structure of several templates
- fix: replace function imagerotate with imageflip in the captcha class because imagerotate failed to work in some cases
- fix: check for existince of a given category before using it in the template
20220803.1 (2022-08-03)
-----------------------
- feature: support the upload of WebP-images
- change: semantic HTML-elements on several places and modern CSS-rules (flexboxes instead floating boxes here and there)
- fix: remove outdated query partsthat tried to access column mlf2_entries.email_notifications
- fix: ensure, that suígnatures are reliably positioned under all content of a forum entry
- fix: putting the cursor into the empty search field in the page header and pressing [Enter] led to a PHP warning
- fix: (partially) When classifying entries in locked threads the get unlocked sometimes, happens more seldom now but there is a remaining corner case to inspect
- fix: wrong order of altering the column mlf2_userdata.user_email, defining the unique-key for this column before changing its charset to utf8 (without 'mb4') leads to the error of a to long index in some MySQL-versions
- fix: remove multiple definitions of unique indexes for the columns mlf2_userdata.user_name and mlf2_userdata.user_email in the installation and update scripts, the indexes does not break the structure but they are superfluous
20220529.1 (2022-05-29)
-----------------------
- feature: show an icon to admins and mods for entries that are not classified as ham or spam, if spam detection service B8 or Akismet is activated
- change: first overhaul of the main section of forum pages, affects mainly the main views (thread listings) and the administration start page
- fix: when deleting a user delete also the notification switch in the entries table, normally we use the subscriptions table for this but in forums with entries that was handled with the old subscription handling it may be possible, that there are old subscriptions for registered users left
20220517.1 (2022-05-17)
-----------------------
- fixed: the feature inactivity notification sent an unlimited number of e-mails, what caused the project domain to get blacklisted; to prevent this for external forum operators, the number of e-mails is now limited to 5 per daily action
- fixed: because of the fixed height of the page header the user menu was inaccessible on narrow viewports since the change from XHTML 1.0 to HTML (5)
- the column `mlf2_userdata.user_email` was to large for using an index with charset utf8mb4 on MySQL 5.5 and 5.6, reset it to charset utf8 (3 byte chars only)
20220509.1 (2022-05-09)
-----------------------
- feature: stick the page footer to the bottom of the viewport with the help of a CSS-flexbox
- changed: removed CSS-fixes for Internet Explorers 6 and 7 (RIP)
- changed: replaced main block elements (<div>) for the page with semantic HTML-elements
- fixed: a syntax error that prevented the update script from working (PR #597)
- fixed: a wrong used English word (a IMHO typical false friend for native German speakers)
20220508.1 (2022-05-08)
-----------------------
- feature: provide a forum wide setting to store a target name for breaking out of a frame or iframe (_self, _parent, _top or a given name of a target frame)
- feature: add BB-code tags for marking text as right-to-left or as left-to-right written
- feature: unify the HTML-structure of a user name to make it possible to style the HTML-element of the user name in every place with the same CSS-rules
- feature: provide a user setting to make it possible for users to open links in a forum entry in a new browser window or tab
- feature: request a reaction of an inactive user or delete the account after an additional waiting time
- featurette: provide a back-to-top-link on every page and every single forum entry
- changed: minimal PHP version 7.3
- changed: compatibility up to PHP 8.1
- changed: removed the compatibility to ancient browsers down to IE6 from the JavaScript sources
- updated: upgrade of the external modules, where one was available
- updated: overhaul of the swedish language file
- added: language file for Traditional Chinese
- fixed: database table columns for user names and e-mail-addresses are set to be unique to prevent the use of similar user names (in the meaning of the MySQL-database-system) or the double use of e-mail-addresses
2.4.24 (2020-10-12)
-------------------
- fixed: broken layout of the links to the RSS-feed of a single thread in thread.inc.tpl and thread_linear.inc.tpl
- fixed: unintended text-transform: lowercase; for the link to top of the page in the options of an entry
- added: add classes for the user type to the thread tree below the entry in the single-entry-view
2.4.23 (2020-09-30)
-------------------
- fixed: wrong formatting of the link for a threads own RSS-feed, got broken by the work on formatting the RSS-links in the page footer
- fixed: the non-English and non-German strings for the to-top-of-page-links had a broken comment part
2.4.22 (2020-09-29)
-------------------
- fixed: broken backup restoring function for the entries table, rework of the backup function for better code readability
- fixed: corrected file size computation for the list of backup files; very small file sizes (up to a few hundred bytes) was shown as "0.00 MB" instead i.e. "0.0006 MB"
- fixed: remove of since PHP 7.2 deprecated function each(), replaced with foreach()
- fixed: wrong key name for error message in admin area about an incorrect e-mail-address
- added: link to top of the page in the page footer and in the options menu of every entry
- added: backup function for subscriptions and tags
- added: natural sorting of the tag list, makes sorting case insensitive
2.4.21 (2020-04-25)
-------------------
- fixed: regex for e-mail-validation followed a lazy syntax style, that invalidated with PRCE2. which was introduced with PHP 7.3; because of that one was unable to register a new account when running MLF 2.4.x under PHP 7.3 or newer
- fixed: image URLs in the RSS-feed was specified with only the local, relative path on the domain, we do need a complete URl with protocol, domain and path because the feed reader requests the feed from outside the domain
2.4.99.3 (2019-09-24)
---------------------
- fixed: show spam entries in the thread tree not for authors of spammy postings
- fixed: delete the new tables when uninstalling the forum
2.4.99.2 (2019-08-08)
---------------------
- feature: send the notification mail about a new entry after an entry was manually classified as ham
- feature: tags can be inserted not only by admins and moderators but also from unregistered and registered users from now on (optional setting)
- feature: e-mails can be sent with a SMTP-class or via PHP's own mail()-function
- feature: a regsitered user can decide, if he is contactable for the forum team, for all registered users or for all users and visitors of a forum
- fixed: the column size of mlf2_tags.tag exceeded the possible index size (768 bytes) when the charset of the column is utf8mb4, limit the column size to 128 chars
- changed: create all tables with the engine InnoDB
- changed: list the spam entries in the main view with all elements for manipulation instead listing the entries in the search view
- changed: when an entry was detected as spam redirect the user to the single-entry-view because the notification can be placed reproducible inside the viewport
2.4.99.1 (2019-06-01)
---------------------
- feature: restrict access to the user list to the forum team (administrators and moderators)
- feature: allow topics to be pinned/sticked to the certain category or to all categories
- feature: change the charset of most of the tables to support 4-byte-characters, i.e. emojis
- fixed: unify mail encoding, was different depending of the checked characters
- fixed: added a CSRF-token to posting delete function calls
- fixed: relative pathes in the src-attribute of images in the RSS feed made the images inaccessible in the feed
- changed: the quote-message-link is now a button
2.4.20 (2019-05-15)
-------------------
- fixed: call for a removed function in the JS-code
- fixed: inconsistend mail encoding, depended on an input string and could therefore result in wrong encoding, now fixed to the encoding, provided in the language file (normally UTF-8)
- fixed: missing CSRF-token in case of deleting postings
2.4.99.0 (2019-02-11)
---------------------
- feature: upload management page in the admin area, list all uploaded images, delete images groupwise
- feature: information about the user who uploads a new image gets stored in a database table
- feature: Bayes based spam filter
- feature: optional TeX support through MathJax library (has to be linked manually)
- removed: optional TeX support through the Google online service, service got abandoned
- removed: flash button and flash bb-code
- fixed: replace while loops with deprecated PHP-function "each" with foreach loops
2.4.19.1 (2019-02-07)
---------------------
- fixed: reading the setting next_daily_action failed because of checking for a wrong structure, caused HTTP-status 500 every when and then
- fixed: function mysqli_fetch_all is not available in every PHP-installation, caused error messages, HTTP-status 500 or white pages in such cases
2.4.19 (2019-02-03)
-------------------
- fixed: when editing a posting, an activated subscription can not be saved in the database because of a syntax error on the database query
- fixed: images, included in a posting, got elongated in the Ajax-preview of a posting
- changed: a few settings moved to the table mlf2_temp_infos because they are no settings at all
2.4.18.1 (2019-01-14)
---------------------
- fixed: table name in install.sql MUST NOT be surrounded by backticks, this makes the prefix replacement during installation impossible; this is only relevant during first installation
2.4.18 (2019-01-13)
-------------------
- fixed: unregistered users was not able to subscribe to their own postings because of field user_id being NOT NULL in the subscriptions table
- fixed: because of failing subscriptions of unregistered users for thread opening postings the thread in itself was broken and not deletable
- fixed: sending e-mails over the contact form failed because of forgotten function call for form time handling
- fixed: deleting a posting with subscriptions left orphaned subscriptions because they got not removed from the database
- fixed: the check for password strength failed when more than one char in a category was required and these chars did not follow one after the other
- fixed: if one used the thumbnail funtion to include an image to a posting, the image got the right width but was elongated to the complete possible height of the posting.
- change: the default protocol, used in the JS-prompts for links and images when creating a posting is from now on "https://" instead "http://"
- change: changed the language strings, key: show_spam_link, for english and german language, led to danger of confusion ("show spam (no. of entries)" vs. "list spam") (enahncement for admins and mods)
- change: the update script disables the forum during the database operations of the update and reenables it afterwards (admin only feature), at the moment it got enabled before one updates the files and folders; @admins: please check the status after an update in the settings page
2.4.17 (2019-01-06)
-------------------
- fixed: set the decimal point as fix char because different decimal separators (i.e. comma in german language) causes errors in floating number operations in PHP
- fixed: the checkbox for the Flash-bb-code-setting got reintroduced (will definitely get removed with version 2.5, change was removed by accident in the 2.4.x-branch)
- fixed: remove the confirm-password-field from the form for change ones own password, function was removed for the other forms in versions 2.4.16
- feature: minimal and maximal time between requesting a form and sending the filled form back to the forum-server as separate settings for posting form, e-mail form and registration form
- feature: a user is from now on able to close her/his own forum account, until now this was only possible for the admin/forum operator
- feature: a by the registered users granted acceptance to the terms of use and/or the data privacy statement can be recalled and a newly acceptance can be enforced for the case of changes in the terms of use and/or the data privacy statement
- feature: further possible requirements for password quality (enforce a number of lowercase and/or capital letters, ciphers and/or "special" chars), disabled by default
- change: removed the JS-function to create the bb-code [msg] for forum entries, it needed a blacklist of not covered exceptions that was incomplete; entries will from now on handled as [link] or [url] like all other links; existing msg-bb-codes will still get interpreted
- change: not selected checkboxes and radio buttons in the settings forms of the admin panel will not grayed out from now on, was a misleading UI-feature because the form fields looked like disabled but was still accessible
2.4.16 (2018-12-07)
-------------------
- fixed: do not create a list item for a non existing bookmark tag for the users bookmark list
- fixed: errorneous use of a hardcoded table name that led to failing read attempts of a users subscriptions
2.4.15 (2018-11-30)
-------------------
- fixed: entries could not be edited
- fixed: subscribung to or unsubscribing from an entry was not possible when saving the edit of an entry
2.4.14 (2018-11-26)
-------------------
- fixed: several forms in the admin area lacked the CSRF-token
- fixed: remove underscores from "data privacy statement" in the language files
- fixed: removed the workaround of setting the language to en-us in the turkish language file, underlying problem was solved with PHP5.2
- feature: add a checkbox to make the password visible for input verification during registration, remove therefore the second password field
- feature: add a unsubscribe link to the e-mails with a notification about a new reply
- feature: add a new table to store the subscriptions independent from the entry in itself
- feature: allow SVG-graphics as smilies, graphics have to be uploaded per FTP
- update: danish language file updated by project-forum-user Tommy Nillson
- update: norwegian language file updated by Github-user @flatnick
2.4.13 (2018-08-12)
-------------------
- fixed: icon for Ajax-preview of an entry was not displayed, if the entry is locked
- fixed: reordering registration-form fields because firefox users could be unable to register dependent from the browser settings (prefilled form fields)
- fixed: status of the checkbox for accepting the data privacy statement got lost when previewing the entry
- fixed: display data privacy statement in a popup like the terms of use in case of an entry from an unregistered user
- fixed: missing fields for the dates of the acceptance of the terms of use and the data privacy statement in the backup script for the user data
- fixed: set a birthday date in single quotes in the backup script for the user data
- fixed: remove field mlf2_entries.tags from the backup script for the forum entries because it does no longer exist
- fixed: masked an occurence of single quotes in the german language file
- fixed: set the forums own e-mail-address as sender of an e-mail in every case, set a possibly given divergent address as Reply-To-header; prevents not sending e-mails because of not matching domain names (forum domain versus domain part of an e-mail-address)
2.4.12 (2018-06-29)
-------------------
- fixed array of update targets for versions 2.4.10 and 2.4.11 because versions from 2.3.5 to 2.3.7 got no update of the table structure
2.4.11 (2018-06-25)
-------------------
- fixed: used the wrong setting for the terms-of-use-URL in the new template user_agreement.inc.tpl because of a copy'n'paste error, one was unable to read the terms of use before accepting it
- fixed: a lost underscore in the admin template
2.4.10 (2018-06-13)
-------------------
- fixed: the russian language had a few syntax errors, introduced with the reformatting of the language files (2.4.7)
- fixed: the version check in the admin panel was broken, when the update was executed before the forum itself found the new version on Github
- fixed: the meta element for the charset definition moved to top of the title to apply also for the title
- feature: make it possible to force an agreement to a data privacy statement in the same manner as with the terms of rules
- feature: store the date of the agreement (data privacy statement and/or terms of use) with the users data
- feature: enforce a new agreement to adata privacy statement and/or terms of use with the deletion of the timestamp of the old agreement (no user interface yet!)
- change: actualised Bad Behavior from 2.2.19 to version 2.2.20
- change: actualised GesHi from 1.0.8.11 to version 1.0.9
- change: actualised Smarty from 3.1.30 to version 3.1.32
- change: because of the minimal system requirement for Bad Behavior the minimal MySQL version raises to 5.0
2.4.9 (2018-04-13)
------------------
- fixed: use the function get_avatar also in the admin panel, used before only the code for the old file name scheme whcih leads to only displaying avatars with names in this old name scheme
- fixed: avatar field in the user data form of the admin panel had no label because of missing string in the language files
- fixed: adapt changed URL-parameter behaviour for folding threads to the JS-sources, didn't work with the switch instead the toggle
- fixed: changed long date format for german language to month as number with leading zero, out written month name "März" can cause encoding problem on some servers
- fixed: the deletion of entries about read postings was broken in the case of deletion after X days, used the old and removed setting name read_state_expiration_date instead read_state_expiration_value
- added: sentence about automatic generation of e-mails to inform about new entries
- added: make the mouse cursor a hand (pointer) when hovering over a (visible) label element
- added: put pixel dimensions of uploaded images into the HTMl source, when included in entries, prevents page jumping during load process for only this case(!)
2.4.8 (2018-02-18)
------------------
- fixed double closing tag of a select in the admin.inc.tpl
- fixed the use of a table alias in a database query that caused a MySQL error
- removed a few empty lines in the code in search.inc.php because some of them caused headers-sent-erros
- fixed the use of a wrong variable name in bookmark.inc.php
- fixed forgotten masking of single quotes, used as apostrophe in the german language file
- fixed wrong cases range for partial backups, the three cases that was introduced in the 2.4-branch wasn't recognised as valid
- fixed the invalid use of column name tags in the entries table because the column no longer exists
- fixed wrong path names of files that have to be updated in the update to version 2.4.7, yet relevant because of updates from earlier versions
- fixed superfluous column name "tags" in create statement of table mlf2_entries
- added the version number of the minimal required PHP-version
- added CSRF-tokens to user_edit.inc.tpl, user_edit_email.inc.tpl, user_edit_pw.inc.tpl and the corresponding code in user.inc.php
- added the links to the original project site and forum again, was changed to the interim site and forum because of the temporary inaccessibility of the original site
- added danish language file, translation by Tommy Nielsson (tommy@jernbanen.dk)
- added a rework of the swedish language file, mainly based on the work of Tommy Nielsson (tommy@svenska-lok.se)
- replace "Bookmarks" with "Lesezeichen" in the german language file
- removed a few line breaks and spaces at a line end in bookmarks.inc.tpl
- removed a size attribute in an input submit button
2.4.7 (2018-01-05)
------------------
- fixed database issue because of the obsolete field *_userdata.entries_read, can cause error in some database configurations
- fixed the use of a wrong string for too long user name in the create-new-user-function of the admin panel
- fixed an check for existence of categories in the main script, can cause error in PHP 7.2 when no categories are present
- fixed handling of not given birthday date, set it to NULL in that case, can cause error in some MySQL-configurations
- added redirect to the last page, one has visited, after the users login
- added the availability of tags to the bookmark function
- added new tables for tag handling, existing tags for postings will be handed over to one of the new tables
- added a few fields as honeypots for spammers to the registration and the posting form
- changed handling of the URL-parameters 'fold_threads', 'toggle_view' and 'toggle_thread_view', are not toggles anymore, fix reproducible behaviour for every value instead
2.4.6 (2017-11-05)
------------------
- fix for displaying the new version number after update in the update script itself
- fix for missing rules for visited links in the list of latest entries
- fix for wrong syntax in the meta element "referrer", that was introduced in version 2.4.5 (author: https://github.com/Romchik)
- removed doubled title attributes (author: https://github.com/Romchik)
- rework of the HTML-structure in the side- and bottombar, removal of a few obsolete CSS-rules
- refactoring of the *.inc.php-files, better readability for future development, no functional changes at that point
- fix for broken toggling of check for banned IPs or user agents, should toggle automatically when listing bans but didn't
- fix broken query for reading user data for notification in case of account creation through the admin
- fix for doubled key in the german language file
- fix for ordering of user data lists when sorted by the user names, collation led to sorting in the order names beginning with numbers, capital letters and in the end low letters, now capitals and low letters are sorted mixed in their natural order
2.4.5 (2017-10-09)
------------------
- fix for wrong variable name in the function getMessageStatus
- removed orphaned code fragment, was never used
- add a meta element named "referrer", that causes not sending a referrer when open an external link or (for older browsers) sending a referrer with onlythe domain part, it's a small contribution for forum users privacy
2.4.4 (2017-10-03)
------------------
- fix for by mistake overwritten user type
- fix for not accepted email addresses with a TLD longer than four chars
- fix for not marking the opening message of a thread as new if the thread is folded and a new answer was posted
- make the error message of the update script for wrong or non existing file config/VERSION more descriptive
2.4.3 (2017-07-09)
------------------
- fix for lost CSS-rule for element #image-canvas
- fix, remove graphical separator for link list
- fix cache handling, newer IE-versions was not taken into account
- fix marking as unread for visited entries which was dropped from the list of visited entries
- fix collation of the user name field to distinguish between "a" and "ä" (examlpe)
- fix doubled key in the language files
- prepopulate the field for the forum-URL in the installation script with the protocol which is actually in use
- add indices to several database tables to speed up the loading time of the forum
- enhanced handling of read status (new setting for selection of handling scheme), in general higher values
2.4.2 (2017-03-12)
------------------
- fixed the installation of the settings table without a PK on the column 'name' (in update procedure since 2.3.99.1)
- fixed the lack of the third gender-radio-button in the user editing form of the admin area
- fixed the undesirably setting of class .read for not registered and not logged in visitors of a forum
- added alphabetical ordering of the list of files and directories that has to be updated
2.4.1 (2017-02-20)
------------------
- fixed a lost 'a' in the defaults template style.css, only relevant, when using style.css instead style.min.css
- fixed compatibility with PHP 5.2, even when an update to (at least) PHP 5.6 is recommended
- fixed a non descriptive error message for the absence of the new file config/VERSION (must be present when installing or updating)
2.4 (2017-02-16)
----------------
- fixed wrong category in select field when editing an entry
- fixed URL for latest release leads now to the page of the release instead to "latest"
2.3.99.3 (pre release of 2.4) (2017-02-05)
------------------
- fixed NULL value for bookmarks table field order_id
- fixed wrong use of PHP construct break in an if-block
- added a form field to the user settings to remove a specified gender
- added a few HTML-elements for housing of interpunctions in the entries meta data
2.3.99.2 (pre release of 2.4) (2017-01-24)
------------------
- fixed accidentally duplicating of settings when installing the forum with a database backup
- fixed the unexpected behaviour of the refresh link and in context the new and read marking of entries
- fixed the view breaking diyplay of images that are wider than the viewport of the browser and the width of the Ajax-preview
- fixed the issue of unnecessarily displaying the Ajax-preview when the entry itself is empty
- fixed a buggy handling of blocked IPs when one tries to log in
- do not add and remove inline styles of HTML-elements with JavaScript, toggle class names instead
- added the possibility to trigger the Ajax-preview by mouse over on the icon
- added a function for bookmarking entries
- added an email message to a user that was activated by an administrator
- added a warning for the forum team about the not from the server removed installation script
- added a notification for the forum team about registered but not activated users
- added a notification for the forum team about the current version number of the installation
- added a notification for the forum team about the actual available release with a link to the download location
- added a link to the releases list for the case, that the query for the actual available release failes
2.3.7 (2016-10-10)
------------------
- fixed further spelling error (German language)
- fixed max-width for images in the ajax-preview
- fixed a warning about variable name, that was used as function parameter and afterwards redeclared as new variable
- fixed unintended closing the ajax-preview by clicking the horizontal scrollbar of the preview
- added translation for two untranslated strings in the German language file
2.3.7beta (1 and 2) (2016-10-04, 2016-10-05)
------------------
- feature, time limit for blocking IP after three failed login attempts is now configurable (`temp_block_ip_after_repeated_failed_logins` > 0)
- fixed security issue, CSRF-protection
- fixed security issue, relative path overwrite protection
- fixed security issue, context-sesitive-masking of strings in HTML
- fixed error in the update function, update over several versions was not possible
- fixed language config, multiple use of a keyword with different text in different blocks
- fixed spelling error (English language)
- use class constructor in the BBCodeClass, old behaviour is deprecated in actual PHP-versions
- update Smarty (3.1.30)
- update Bad Behaviour (2.2.19)
2.3.6.1 (2016-08-04)
--------------------
- Allow last_login to be NULL, NOT NULL caused errors when registering a user
- Database error when one declared a erroneous database login credential during the installation
- Several spelling and grammar errors in german.lang
- Feature: A link to the list of the own postings of the logged in user
2.3.5 (2016-06-02)
------------------
- Smarty update (3.1.29)
- Bad Behavior updated (2.2.18)
- Marked locked thread without opening (http://mylittleforum.net/forum/index.php?id=8721)
- Several minor translation errors in german.lang (http://mylittleforum.net/forum/index.php?id=8549)
- Sticky becomes unstuck when thread is edited-Fix (http://mylittleforum.net/forum/index.php?id=8310)
- JavaScript fix for iOS (http://mylittleforum.net/forum/index.php?id=8393)
- Showing registered users (http://mylittleforum.net/forum/index.php?id=8285)
- Replace mysql_* by mysqli_* functions (http://mylittleforum.net/forum/index.php?id=8942)
- Set empty timestamp values to null for MySQL>=5.6.5
Edited files:
- js/
- modules/smarty/
- modules/bad-behavior/
- lang/german.lang
- themes/default/images/bg_sprite_1.png
- themes/default/subtemplates/entry.inc.tpl
- themes/default/subtemplates/index.inc.tpl
- themes/default/subtemplates/index_table.inc.tpl
- themes/default/subtemplates/thread.inc.tpl
- themes/default/subtemplates/thread_linear.inc.tpl
- themes/default/style.css
- themes/default/style.mini.css
- includes/admin.inc.php
- includes/auto_login.inc.php
- includes/contact.inc.php
- includes/entry.inc.php
- includes/functions.inc.php
- includes/index.inc.php
- includes/login.inc.php
- includes/main.inc.php
- includes/page.inc.php
- includes/posting.inc.php
- includes/register.inc.php
- includes/rss.inc.php
- includes/search.inc.php
- includes/thread.inc.php
- includes/user.inc.php
2.3.4 (2015-02-08)
------------------
- Security vulnerability fix (http://mylittleforum.net/forum/index.php?id=8182)
- Fix in contains_invalid_string() function (http://mylittleforum.net/forum/index.php?id=8169)
- Smarty update (3.1.21)
2.3.3 (2014-04-10)
------------------
- htmlspecialchars warnings bug fix (http://mylittleforum.net/forum/index.php?id=7576)
- more smilies button bug fix (http://mylittleforum.net/forum/index.php?id=7612)
- French language file bug fix (http://mylittleforum.net/forum/index.php?id=7175)
- Spanish translation completed
2.3.2 (2013-11-24)
------------------
- language bug fix: http://mylittleforum.net/forum/index.php?id=7077
- theme switch bug fix: http://mylittleforum.net/forum/index.php?id=7345
- Smarty updated (3.1.15)
- Bad Behavior updated (2.2.14)
- Swedish language file added
2.3.1 (2012-12-01)
------------------
- JavaScript fix: http://mylittleforum.net/forum/index.php?id=6718
- Stop Forum Spam (http://www.stopforumspam.com/) implemented
- list spam feature implemented
- Smarty updated (3.1.12)
- Bad Behavior updated (2.2.11)
- GeSHi updated (1.0.8.11)
- set default time zone to UTC to prevent generating a E_NOTICE
2.3 (2011-09-01)
------------------
- Smarty updated (3.0.8)
- Bad Behavior updated (2.0.44)
- GeSHi updated (1.0.8.10)
- fixed this bug: http://mylittleforum.net/forum/index.php?id=5787
- minor JavaScript modifications
- possibility of akismet spam checking of posts by registered users added
- added administration options to user profile page
Edited files:
- includes/
- js/
- lang/
- modules/bad-behavior/
- modules/geshi/
- modules/smarty/
- themes/default/main.tpl
- themes/default/subtemplats/admin.inc.tpl
- themes/default/subtemplats/entry.inc.tpl
- themes/default/subtemplats/index.inc.tpl
- themes/default/subtemplats/index_table.inc.tpl
- themes/default/subtemplats/thread.inc.tpl
- themes/default/subtemplats/user.inc.tpl
- themes/default/subtemplats/user_profile.inc.tpl
- index.php
Database changes:
- setting "akismet_check_registered" added:
INSERT INTO mlf2_settings VALUES ('akismet_check_registered', '0');
Manual update:
- replace the changed files
- set "version" to "2.3" in Admin --> Forum settings --> Advanced settings
2.2.8 (2011-03-08)
------------------
- the timestamp is exclusively fetched from the database server now
(http://mylittleforum.net/forum/index.php?id=5706)
- imagecopyresized() replaced by imagecopyresampled()
- minor modifications in stringparser_bbcode class to prevent deprecated and
strict standards warning in PHP 5.3
- image-code is directly included into message after upload
- BBCode size button can now be deactivated
Edited files:
- index.php
- includes/
- modules/stringparser_bbcode/
- themes/default/upload_image.tpl
- themes/default/subtemplates/posting.inc.tpl
Database changes:
- no database changes
Manual update:
- replace the changed files
- set "version" to "2.2.8" in Admin --> Forum settings --> Advanced settings
2.2.7 (2010-11-21)
------------------
- minor CSS and JavaScript modifications
- Chinese and Croatian language files updated
Edited files:
- themes/default/style.css
- themes/default/style.min.css
- js/main.js
- js/main.min.js
- lang/chinese.lang
- lang/croatian.lang
Database changes:
- no database changes
Manual update:
- replace the changed files
- set "version" to "2.2.7" in Admin --> Forum settings --> Advanced settings
2.2.6 (2010-07-10)
------------------
- minor template bug fixed (bbcode button "image" was displayed even if
disabled)

18
README
View file

@ -1,18 +0,0 @@
my little forum - http://mylittleforum.net/
REQUIREMENTS:
* Webserver with PHP >= 4.2 and MySQL >= 4.1
INSTALLATION:
* Unzip the script package.
* Upload the complete folder "forum" to your server.
* Depending on your server configuration the write permissions of the
subdirectory templates_c (CHMOD 770, 775 or 777) and the file
config/db_settings.php (CHMOD 666) might need to be changed in order that they
are writable by the script.
* Run the installation script by accessing http://yourdomain.tld/forum/install/
in your web browser and follow the instructions.
LICENSE:
This product is distributed under the GPL. Please read through the file
LICENSE for more informations about this license.

160
README.md Normal file
View file

@ -0,0 +1,160 @@
# my little forum
[my little forum](https://mylittleforum.net/) is a simple PHP and MySQL based internet forum that displays the messages in classical threaded view (tree structure). It is Open Source licensed under the GNU General Public License. The main claim of this web forum is simplicity. Furthermore it should be easy to install and run on a standard server configuration with PHP and MySQL.
* [More about my little forum](https://github.com/My-Little-Forum/mylittleforum/wiki)
* [Demo and project discussion forum](https://mylittleforum.net/forum/)
## System requirements
- Webserver with PHP >= 7.3
- MySQL >= 5.7.7 or MariaDB >= 10.2.2
## Features
### General
- thread based forum script
- optional restriction of access to writing and/or reading entries to registered users only
- user management
- categories
- forum script is highly configurable
- theming support, using [Smarty](https://www.smarty.net/) as template language
- data storage in a MySQL or MariaDB database
- currently 14 available languages (more or less complete) with the strings for the user interface
- arabic (beta)
- simplified chinese
- traditional chinese
- croatian
- danish
- english (default if not set otherwise during the installation)
- french
- german
- italian
- norwegian
- russian
- spanish
- swedish
- tamil
- turkish
- since version 20220508.1 (2.5.0) the forum can store the whole utf-8-range including emojis 🎉
- formatting of entries with BB-codes, most BB-codes are accessible by buttons, the system is extendable
- common text formatting (bold, italic, strike through and so on)
- coloured text, text size
- links
- images
- code exapmles
- preformatted text
- mathematical formulas, realised with LaTex (optional with including the MathJax library)
### Main views
- paginated main view with a configurable count of threads per page
- general and user based configuration for a thread view or a table view, second looking more message board like
- optional list of latest X entries
- optional tag cloud
- management functions for administrators and moderators
### Forum entries
- allowing or forbidding creation of forum posts by unregistered users (restricting it to registered users only)
- allowing or forbidding time based editing of forum posts after their initial saving
- displaying the time of the last editing and the editors user name of a posting, optionally hiding it in case of editing by a moderator or administrator
### Entry view
- three possible views of forum entries
- single entry view with the thread structure shown like in the main views below the entry
- nested entry view with all entries of the thread indented according to their thread nesting level
- flat entry view ordered by their posting dates like in a message board
### Categories
- optional creation of categories
- restricting access to certain categories to registered users or to administrators and moderators
- management of categories
- sorting of the existing categories for the selection in the user interface
- renaming a category
- deleting an category
- changing the access restrictions
### Spam prevention
- optional Bayed based content categorisation as ham or spam for forum posts and/or e-mails, to be sent over the contact form (*local service*)
- ~~optional spam prevention with Bad behavior (*local service*)~~ removed with version 20240729.1 because the project is dead
- optional bad word list (*local service*)
- optional blacklist for certain IPs and IP-ranges (*local service*)
- optional blacklist for user agents (*local service*)
- optional check of e-mail-addresses during the registration process with Stop Forum Spam (*external service*)
- optional content check of forum posts and/or e-mails, to be sent over the contact form, with Akismet (*external service*)
- perform the activated checks only for content of unregistered visitors or also for content of registered users (if check is applicable)
### User account management
- optional user registration
- options to registering an account by one self or by restricting the registration to be done by an administrator
- enforcement of a consent to the terms of use and/or the privacy policy, date of consent will be saved with the user data
- enforcement of a renewed consent in case of changes in one of these documents
- in general three possible user ranks (beside unregistered visitors) with different permissions and restrictions
- registered user
- moderator
- administrator
- user profile with optional …
- … avatar
- … signature
- … profile information
- … website
- … location
- … birthday
- … sex/gender
- technical user settings
- password
- e-mail-address
- deleting the account
- extent of e-mail-contact
- user is contactable only by the forum team
- user is contactable by all registered users
- or the whole forum audience
- user based category selection (if categories are defined)
- user based choice of the user interface language
- user based choice of the time zone
- user based choice of how links are opened
- open all links based on the forum setting (set by the forum administrator)
- open all links in the currently active browser window/tab
- open only links to external sites in a new browser window/tab
- open all links in a new browser window/tab
- for moderators and administrators: e-mail-notification about new forum posts and/or registration of new users
- for administrators: separate user management list with the following functions
- adding new users
- editing the data of a single user
- deleting single users
- deleting uxsers according to definable criteria
- reset previous consents to the terms of use and/or the privacy policy because of changes in one or the other document
### Additional pages
- creation of website pages as supplement to the forum, in example a help page, the terms of use or the privacy policy
- formatting the pages content with HTML and the CSS rules of the applied forum theme
- pages have a fix URL and a link can optionally be displayed in the user menu
## Installation
1. Unzip the script package.
2. Upload the complete folder "forum" to your server.
3. Depending on your server configuration the write permissions of the subdirectory templates_c (CHMOD 770, 775 or 777) and the file config/db_settings.php (CHMOD 666) might need to be changed in order that they are writable by the script.
4. Run the installation script by accessing yourdomain.tld/forum/install/ in your web browser and follow the instructions.
5. Remove the directory "install" from your installation of My Little Forum.
6. Change the write permissions for config/db_settings.php to (CHMOD 440), what prevents reading the files content for unauthorised users
## Upgrade
1. Download the new package.
2. Unzip the script package.
3. Upload the folder "update" into the main folder of the forum installation.
4. Upload the file "config/VERSION" to the folder "config" of the forum installation. An existing file VERSION will be overwritten.
5. Login as forum administrator and go to the admin area
6. Open the link "Update", you will see a list of available update script files below the instructions. It is possible, that there are more than one items listed, because old, outdated update files never got deleted from the server.
7. Open the link to the currently valid update script.
8. Insert the password of your administrator account to confirm the run of the update script.
9. On the following page you'll get the success message for step one of the update (database operations) or an error message. In case of success you'll see a list of all script files that changed between your and the new version. You have to load up all the listed files and directories to your webspace (this is because not every file got altered with every version). After loading all changed files and directories of the new version to your webspace, you are done. If you encountered errors, please report it instantaneously [in the project forum](https://mylittleforum.net/forum/) or open an [issue on Github](https://github.com/My-Little-Forum/mylittleforum/issues).

1
config/VERSION Normal file
View file

@ -0,0 +1 @@
20250323.1

45
config/b8_config.php Normal file
View file

@ -0,0 +1,45 @@
<?php
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
/** config for b8 filter **/
$B8_CONFIG_LEXER = array(
'min_size' => 3,
'max_size' => 30,
'allow_numbers' => FALSE,
'get_html' => TRUE,
'get_uris' => TRUE,
'get_bbcode' => FALSE
);
$B8_CONFIG_DEGENERATOR = array(
'encoding' => isset($lang['charset']) ? $lang['charset'] : 'UTF-8',
'multibyte' => function_exists('mb_strtolower') && function_exists('mb_strtoupper') && function_exists('mb_substr')
);
/** config for new b8 version **/
$B8_CONFIG_DATABASE_TYPE = array(
'storage' => 'mysql'
);
$B8_CONFIG_STORAGE = array(
'resource' => new mysqli($db_settings['host'], $db_settings['user'], $db_settings['password'], $db_settings['database']),
'table' => $db_settings['b8_wordlist_table']
);
/** config for old b8 version **/
$B8_CONFIG_DATABASE = array(
'storage' => 'mysqli'
);
$B8_CONFIG_AUTHENTICATION = array(
'database' => $db_settings['database'],
'table_name' => $db_settings['b8_wordlist_table'],
'host' => $db_settings['host'],
'user' => $db_settings['user'],
'pass' => $db_settings['password']
);
/** config for b8 filter **/
?>

View file

@ -11,16 +11,27 @@ $db_settings['user'] = '';
// Database password:
$db_settings['password'] = '';
// Database tables (normally not necessary to edit):
$db_settings['settings_table'] = 'mlf2_settings';
$db_settings['forum_table'] = 'mlf2_entries';
$db_settings['category_table'] = 'mlf2_categories';
$db_settings['userdata_table'] = 'mlf2_userdata';
$db_settings['smilies_table'] = 'mlf2_smilies';
$db_settings['pages_table'] = 'mlf2_pages';
$db_settings['banlists_table'] = 'mlf2_banlists';
$db_settings['useronline_table'] = 'mlf2_useronline';
$db_settings['login_control_table'] = 'mlf2_logincontrol';
$db_settings['entry_cache_table'] = 'mlf2_entries_cache';
// Database tables (normally not necessary to edit):
$db_settings['settings_table'] = 'mlf2_settings';
$db_settings['forum_table'] = 'mlf2_entries';
$db_settings['category_table'] = 'mlf2_categories';
$db_settings['userdata_table'] = 'mlf2_userdata';
$db_settings['smilies_table'] = 'mlf2_smilies';
$db_settings['pages_table'] = 'mlf2_pages';
$db_settings['banlists_table'] = 'mlf2_banlists';
$db_settings['useronline_table'] = 'mlf2_useronline';
$db_settings['login_control_table'] = 'mlf2_logincontrol';
$db_settings['entry_cache_table'] = 'mlf2_entries_cache';
$db_settings['userdata_cache_table'] = 'mlf2_userdata_cache';
$db_settings['bookmark_table'] = 'mlf2_bookmarks';
$db_settings['read_status_table'] = 'mlf2_read_entries';
$db_settings['temp_infos_table'] = 'mlf2_temp_infos';
$db_settings['tags_table'] = 'mlf2_tags';
$db_settings['bookmark_tags_table'] = 'mlf2_bookmark_tags';
$db_settings['entry_tags_table'] = 'mlf2_entry_tags';
$db_settings['subscriptions_table'] = 'mlf2_subscriptions';
$db_settings['b8_wordlist_table'] = 'mlf2_b8_wordlist';
$db_settings['b8_rating_table'] = 'mlf2_b8_rating';
$db_settings['akismet_rating_table'] = 'mlf2_akismet_rating';
$db_settings['uploads_table'] = 'mlf2_uploads';
?>

23
config/php_mailer.php Normal file
View file

@ -0,0 +1,23 @@
<?php
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
/** config for PHPMailer **/
// Please read https://github.com/PHPMailer/PHPMailer/blob/master/src/PHPMailer.php
// for further configuration properties
$PHP_MAILER_CONFIG = array(
'Mailer' => 'smtp', // 'smtp', 'mail', 'sendmail' or 'qmail'
'Port' => '587', // well-known ports are 25 (default), 587 (TLS) or 465 (SSL)
'SMTPSecure' => 'tls', // '', 'tls' or 'ssl'
'ContentType' => 'text/plain', // 'text/plain' or 'text/html'
'Encoding' => 'quoted-printable', // '8bit', '7bit', 'binary', 'base64', and 'quoted-printable'
'CharSet' => 'utf-8', // 'iso-8859-1' or 'utf-8'
'SMTPAuth' => true, // true, for SMTP authentication via username/password
'Host' => 'smtp.example.org',
'Username' => 'mail@example.org',
'Password' => 'secret password'
);
/** config for PHPMailer **/
?>

View file

@ -1,12 +1,11 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
$smarty->assign('message','user_locked');
$smarty->assign('subnav_location','subnav_locked');
$smarty->assign('subtemplate','info.inc.tpl');
$smarty->assign('message', 'user_locked_message');
$smarty->assign('subnav_location', 'subnav_locked');
$smarty->assign('subtemplate', 'info.inc.tpl');
$template = 'main.tpl';
?>

File diff suppressed because it is too large Load diff

View file

@ -1,119 +1,87 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if(empty($_SESSION[$settings['session_prefix'].'user_id']) && isset($_COOKIE[$settings['session_prefix'].'auto_login']) && isset($settings['autologin']) && $settings['autologin'] == 1)
{
// clear up expired auto_login_codes:
#if($settings['autologin']==1) @mysql_query("UPDATE ".$db_settings['userdata_table']." SET auto_login_code='' WHERE auto_login_code != '' AND last_login < (NOW() - INTERVAL ".$settings['cookie_validity_days']." DAY)", $connid);
if (empty($_SESSION[$settings['session_prefix'].'user_id']) && isset($_COOKIE[$settings['session_prefix'].'auto_login']) && isset($settings['autologin']) && $settings['autologin'] == 1) {
$auto_login_code = substr($_COOKIE[$settings['session_prefix'].'auto_login'], 0, 50);
$auto_login_id = intval(substr($_COOKIE[$settings['session_prefix'].'auto_login'], 50));
if (isset($auto_login_id) && $auto_login_id > 0 && isset($auto_login_code) && trim($auto_login_code) != '') {
$result = mysqli_query($connid, "SELECT user_id, user_name, user_pw, user_type, UNIX_TIMESTAMP(last_login) AS last_login, UNIX_TIMESTAMP(last_logout) AS last_logout, thread_order, user_view, sidebar, fold_threads, thread_display, category_selection, browser_window_target, auto_login_code, activate_code, language, time_zone, time_difference, theme FROM ". $db_settings['userdata_table'] ." WHERE user_id = ". intval($auto_login_id)) or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) == 1) {
$feld = mysqli_fetch_array($result);
if (strlen($feld['auto_login_code']) == 50 && $auto_login_code == $feld['auto_login_code'] && empty($feld['activate_code'])) {
$user_id = $feld['user_id'];
$user_name = $feld['user_name'];
$user_type = $feld['user_type'];
$usersettings['newtime'] = $feld['last_logout'];
$usersettings['user_view'] = $feld['user_view'];
$usersettings['thread_order'] = $feld['thread_order'];
$usersettings['sidebar'] = $feld['sidebar'];
$usersettings['fold_threads'] = $feld['fold_threads'];
$usersettings['thread_display'] = $feld['thread_display'];
$usersettings['browser_window_target'] = $feld['browser_window_target'];
$usersettings['page'] = 1;
$usersettings['category'] = 0;
$usersettings['latest_postings'] = 1;
$auto_login_code = substr($_COOKIE[$settings['session_prefix'].'auto_login'],0,50);
$auto_login_id = intval(substr($_COOKIE[$settings['session_prefix'].'auto_login'],50));
if(isset($auto_login_id) && $auto_login_id>0 && isset($auto_login_code) && trim($auto_login_code)!='')
{
$result = mysql_query("SELECT user_id, user_name, user_pw, user_type, UNIX_TIMESTAMP(last_login) AS last_login, UNIX_TIMESTAMP(last_logout) AS last_logout, thread_order, user_view, sidebar, fold_threads, thread_display, category_selection, auto_login_code, activate_code, language, time_zone, time_difference, theme, entries_read FROM ".$db_settings['userdata_table']." WHERE user_id = ".intval($auto_login_id), $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result)==1)
{
$feld = mysql_fetch_array($result);
if(strlen($feld['auto_login_code'])==50 && $auto_login_code==$feld['auto_login_code'] && trim($feld['activate_code']==''))
{
$user_id = $feld['user_id'];
$user_name = $feld['user_name'];
$user_type = $feld['user_type'];
$usersettings['newtime'] = $feld['last_logout'];
$usersettings['user_view'] = $feld['user_view'];
$usersettings['thread_order'] = $feld['thread_order'];
$usersettings['sidebar'] = $feld['sidebar'];
$usersettings['fold_threads'] = $feld['fold_threads'];
$usersettings['thread_display'] = $feld['thread_display'];
$usersettings['page'] = 1;
$usersettings['category'] = 0;
$usersettings['latest_postings'] = 1;
if(empty($feld['entries_read'])) $usersettings['read'] = array();
else $usersettings['read'] = explode(',',$feld['entries_read']);
if (!is_null($feld['category_selection'])) {
$category_selection = explode(',', $feld['category_selection']);
$usersettings['category_selection'] = $category_selection;
}
if(!is_null($feld['category_selection']))
{
$category_selection = explode(',',$feld['category_selection']);
$usersettings['category_selection'] = $category_selection;
}
if ($feld['language'] != '') {
$languages = get_languages();
if (isset($languages) && in_array($feld['language'], $languages)) {
$usersettings['language'] = $feld['language'];
$language_update = $feld['language'];
}
}
if (empty($language_update)) $language_update = '';
if($feld['language']!='')
{
$languages = get_languages();
if(isset($languages) && in_array($feld['language'], $languages))
{
$usersettings['language'] = $feld['language'];
$language_update = $feld['language'];
}
}
if(empty($language_update)) $language_update = '';
if ($feld['theme'] != '') {
$themes = get_themes();
if(isset($themes) && in_array($feld['theme'], $themes)) {
$usersettings['theme'] = $feld['theme'];
$theme_update = $feld['theme'];
}
}
if (empty($theme_update)) $theme_update = '';
if($feld['theme']!='')
{
$themes = get_themes();
if(isset($themes) && in_array($feld['theme'], $themes))
{
$usersettings['theme'] = $feld['theme'];
$theme_update = $feld['theme'];
}
}
if(empty($theme_update)) $theme_update = '';
if ($feld['time_zone'] != '') {
if (function_exists('date_default_timezone_set') && $time_zones = get_timezones()) {
if (in_array($feld['time_zone'], $time_zones)) {
$usersettings['time_zone'] = $feld['time_zone'];
$time_zone_update = $feld['time_zone'];
}
}
}
if (empty($time_zone_update)) $time_zone_update = '';
if($feld['time_zone']!='')
{
if(function_exists('date_default_timezone_set') && $time_zones = get_timezones())
{
if(in_array($feld['time_zone'], $time_zones))
{
$usersettings['time_zone'] = $feld['time_zone'];
$time_zone_update = $feld['time_zone'];
}
}
}
if(empty($time_zone_update)) $time_zone_update = '';
if (!empty($feld['time_difference'])) $usersettings['time_difference'] = $feld['time_difference'];
if(!empty($feld['time_difference'])) $usersettings['time_difference'] = $feld['time_difference'];
$_SESSION[$settings['session_prefix'].'user_id'] = $user_id;
$_SESSION[$settings['session_prefix'].'user_name'] = $user_name;
$_SESSION[$settings['session_prefix'].'user_type'] = $user_type;
$_SESSION[$settings['session_prefix'].'usersettings'] = $usersettings;
#if(isset($read)) $read_before_logged_in = $read; // get read postings from cookie (read before logged in)
@mysqli_query($connid, "UPDATE ". $db_settings['userdata_table'] ." SET logins=logins+1, last_login=NOW(), last_logout=NOW(), `inactivity_notification` = FALSE, user_ip='". mysqli_real_escape_string($connid, $_SERVER['REMOTE_ADDR']) ."', pwf_code='', language='". mysqli_real_escape_string($connid, $language_update) ."', time_zone='". mysqli_real_escape_string($connid, $time_zone_update) ."', theme='". mysqli_real_escape_string($connid, $theme_update) ."' WHERE user_id=". intval($user_id));
$_SESSION[$settings['session_prefix'].'user_id'] = $user_id;
$_SESSION[$settings['session_prefix'].'user_name'] = $user_name;
$_SESSION[$settings['session_prefix'].'user_type'] = $user_type;
$_SESSION[$settings['session_prefix'].'usersettings'] = $usersettings;
$read = set_read($usersettings['read']);
#if(isset($read_before_logged_in)) $read = set_read($read_before_logged_in); // get read postings from cookie (read before logged in)
save_read(false);
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET logins=logins+1, last_login=NOW(), last_logout=NOW(), user_ip='".mysql_real_escape_string($_SERVER['REMOTE_ADDR'])."', pwf_code='', language='".mysql_real_escape_string($language_update)."', time_zone='".mysql_real_escape_string($time_zone_update)."', theme='".mysql_real_escape_string($theme_update)."' WHERE user_id=".intval($user_id), $connid);
// auto delete spam:
if($user_type>0 && $settings['auto_delete_spam']>0) @mysql_query("DELETE FROM ".$db_settings['forum_table']." WHERE time < (NOW() - INTERVAL ".$settings['auto_delete_spam']." HOUR) AND spam=1", $connid);
setcookie($settings['session_prefix'].'auto_login',$_COOKIE[$settings['session_prefix'].'auto_login'],time()+(3600*24*$settings['cookie_validity_days']));
if($db_settings['useronline_table'] != "")
{
@mysql_query("DELETE FROM ".$db_settings['useronline_table']." WHERE ip = '".$_SERVER['REMOTE_ADDR']."'", $connid);
}
}
else
{
if($settings['temp_block_ip_after_repeated_failed_logins']==1) count_failed_logins();
setcookie($settings['session_prefix'].'auto_login','',0);
}
}
else
{
if($settings['temp_block_ip_after_repeated_failed_logins']==1) count_failed_logins();
setcookie($settings['session_prefix'].'auto_login','',0);
}
}
else
{
if($settings['temp_block_ip_after_repeated_failed_logins']==1) count_failed_logins();
setcookie($settings['session_prefix'].'auto_login','',0);
}
}
setcookie($settings['session_prefix'].'auto_login', $_COOKIE[$settings['session_prefix'].'auto_login'], cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
if ($db_settings['useronline_table'] != "") {
@mysqli_query($connid, "DELETE FROM ". $db_settings['useronline_table'] ." WHERE ip = '". mysqli_real_escape_string($connid, $_SERVER['REMOTE_ADDR']) ."'");
}
} else {
if ($settings['temp_block_ip_after_repeated_failed_logins'] > 0) count_failed_logins();
setcookie($settings['session_prefix'].'auto_login', '', cookie_options(0));
}
} else {
if ($settings['temp_block_ip_after_repeated_failed_logins'] > 0) count_failed_logins();
setcookie($settings['session_prefix'].'auto_login', '', cookie_options(0));
}
} else {
if($settings['temp_block_ip_after_repeated_failed_logins'] > 0) count_failed_logins();
setcookie($settings['session_prefix'].'auto_login','', cookie_options(0));
}
}

View file

@ -1,172 +1,132 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if(!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
// upload folder:
$uploaded_images_path = 'images/avatars/';
if($settings['avatars']>0 && isset($_SESSION[$settings['session_prefix'].'user_id']))
{
if(isset($_GET['delete']))
{
if(file_exists($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.jpg'))
{
@chmod($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.jpg', 0777);
@unlink($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.jpg');
}
if(file_exists($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.png'))
{
@chmod($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.png', 0777);
@unlink($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.png');
}
if(file_exists($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.gif'))
{
@chmod($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.gif', 0777);
@unlink($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.gif');
}
header('Location: index.php?mode=avatar&deleted=true');
exit;
}
if ($settings['avatars'] > 0 && isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$avatarInfo = getAvatar($_SESSION[$settings['session_prefix'].'user_id']);
$filename = $avatarInfo === false ? false : $avatarInfo[1];
if(isset($_FILES['probe']) && $_FILES['probe']['size'] != 0 && !$_FILES['probe']['error'])
{
unset($errors);
$image_info = getimagesize($_FILES['probe']['tmp_name']);
// remove existing avatar
if (isset($_POST['delete'])) {
if ($filename !== false && file_exists($uploaded_images_path.$filename)) {
@chmod($uploaded_images_path.$filename, 0777);
@unlink($uploaded_images_path.$filename);
}
header('Location: index.php?mode=avatar&deleted=true');
exit;
}
if(!is_array($image_info) || $image_info[2] != 1 && $image_info[2] != 2 && $image_info[2] != 3) $errors[] = 'invalid_file_format';
// upload a new avatar
if (isset($_FILES['probe']) && $_FILES['probe']['size'] != 0 && !$_FILES['probe']['error']) {
unset($errors);
$image_info = getimagesize($_FILES['probe']['tmp_name']);
if(empty($errors))
{
if($_FILES['probe']['size'] > $settings['avatar_max_filesize']*1000 || $image_info[0] > $settings['avatar_max_width'] || $image_info[1] > $settings['avatar_max_height'])
{
#$compression = 10;
$width=$image_info[0];
$height=$image_info[1];
if(!is_array($image_info) || $image_info[2] != 1 && $image_info[2] != 2 && $image_info[2] != 3) $errors[] = 'invalid_file_format';
// resize if too large:
if($width != $settings['avatar_max_width'] || $height != $settings['avatar_max_height'])
{
if($width >= $height)
{
$new_width = $settings['avatar_max_width'];
$new_height = intval($height*$new_width/$width);
}
else
{
$new_height = $settings['avatar_max_height'];
$new_width = intval($width*$new_height/$height);
}
#$new_width = $settings['avatar_max_width'];
#$new_height = $settings['avatar_max_height'];
}
else
{
$new_width=$width;
$new_height=$height;
}
if(empty($errors)) {
if($_FILES['probe']['size'] > $settings['avatar_max_filesize']*1000 || $image_info[0] > $settings['avatar_max_width'] || $image_info[1] > $settings['avatar_max_height']) {
$width = $image_info[0];
$height = $image_info[1];
$img_tmp_name = uniqid(rand()).'.tmp';
// resize if too large:
if($width != $settings['avatar_max_width'] || $height != $settings['avatar_max_height']) {
if($width >= $height) {
$new_width = $settings['avatar_max_width'];
$new_height = intval($height*$new_width/$width);
}
else {
$new_height = $settings['avatar_max_height'];
$new_width = intval($width*$new_height/$height);
}
}
else {
$new_width=$width;
$new_height=$height;
}
for($compression = 100; $compression>1; $compression=$compression-10)
{
if(!resize_image($_FILES['probe']['tmp_name'], $uploaded_images_path.$img_tmp_name, $new_width, $new_height, $compression))
{
$file_size = $_FILES['probe']['size']; // @filesize($_FILES['probe']['tmp_name']);
break;
}
$file_size = @filesize($uploaded_images_path.$img_tmp_name);
if($image_info[2]!=2 && $file_size > $settings['avatar_max_filesize']*1000) break;
if($file_size <= $settings['avatar_max_filesize']*1000) break;
}
if($file_size > $settings['avatar_max_filesize']*1000)
{
$smarty->assign('width',$image_info[0]);
$smarty->assign('height',$image_info[1]);
$smarty->assign('filesize',number_format($_FILES['probe']['size']/1000,0,',',''));
$smarty->assign('max_width',$settings['avatar_max_width']);
$smarty->assign('max_height',$settings['avatar_max_height']);
$smarty->assign('max_filesize',$settings['avatar_max_filesize']);
$errors[] = 'file_too_large';
}
if(isset($errors))
{
if(file_exists($uploaded_images_path.$img_tmp_name))
{
@chmod($uploaded_images_path.$img_tmp_name, 0777);
@unlink($uploaded_images_path.$img_tmp_name);
}
}
}
}
$img_tmp_name = uniqid(rand()).'.tmp';
if(empty($errors))
{
$nr = 0;
switch($image_info[2])
{
case 1: $filename = $_SESSION[$settings['session_prefix'].'user_id'].'.gif'; break;
case 2: $filename = $_SESSION[$settings['session_prefix'].'user_id'].'.jpg'; break;
case 3: $filename = $_SESSION[$settings['session_prefix'].'user_id'].'.png'; break;
}
if(isset($img_tmp_name))
{
@rename($uploaded_images_path.$img_tmp_name, $uploaded_images_path.$filename) or $errors[] = 'upload_error';
$smarty->assign('image_downsized',true);
$smarty->assign('new_width',$new_width);
$smarty->assign('new_height',$new_height);
$smarty->assign('new_filesize',number_format($file_size/1000,0,',',''));
}
else
{
@move_uploaded_file($_FILES['probe']['tmp_name'], $uploaded_images_path.$filename) or $errors[] = 'upload_error';
}
}
if(empty($errors))
{
@chmod($uploaded_images_path.$filename, 0644);
$smarty->assign('avatar_uploaded',true);
}
else
{
$smarty->assign('errors',$errors);
$smarty->assign('form',true);
}
}
for($compression = 100; $compression > 1; $compression = $compression - 10) {
if(!resize_image($_FILES['probe']['tmp_name'], $uploaded_images_path.$img_tmp_name, $new_width, $new_height, $compression)) {
$file_size = $_FILES['probe']['size']; // @filesize($_FILES['probe']['tmp_name']);
break;
}
$file_size = @filesize($uploaded_images_path.$img_tmp_name);
if($image_info[2]!=2 && $file_size > $settings['avatar_max_filesize']*1000 || $file_size <= $settings['avatar_max_filesize']*1000)
break;
}
if($file_size > $settings['avatar_max_filesize']*1000) {
$smarty->assign('width',$image_info[0]);
$smarty->assign('height',$image_info[1]);
$smarty->assign('filesize',number_format($_FILES['probe']['size']/1000,0,',',''));
$smarty->assign('max_width',$settings['avatar_max_width']);
$smarty->assign('max_height',$settings['avatar_max_height']);
$smarty->assign('max_filesize',$settings['avatar_max_filesize']);
$errors[] = 'file_too_large';
}
if(isset($errors)) {
if(file_exists($uploaded_images_path.$img_tmp_name)) {
@chmod($uploaded_images_path.$img_tmp_name, 0777);
@unlink($uploaded_images_path.$img_tmp_name);
}
}
}
}
if(file_exists($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.jpg'))
{
$avatar = $uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.jpg';
}
elseif(file_exists($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.png'))
{
$avatar = $uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.png';
}
elseif(file_exists($uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.gif'))
{
$avatar = $uploaded_images_path.$_SESSION[$settings['session_prefix'].'user_id'].'.gif';
}
if(empty($errors)) {
$nr = 0;
switch($image_info[2]) {
case 1: $filename = $_SESSION[$settings['session_prefix'].'user_id'].'_'.time().'.gif'; break;
case 2: $filename = $_SESSION[$settings['session_prefix'].'user_id'].'_'.time().'.jpg'; break;
case 3: $filename = $_SESSION[$settings['session_prefix'].'user_id'].'_'.time().'.png'; break;
}
if(isset($img_tmp_name)) {
@rename($uploaded_images_path.$img_tmp_name, $uploaded_images_path.$filename) or $errors[] = 'upload_error';
$smarty->assign('image_downsized',true);
$smarty->assign('new_width',$new_width);
$smarty->assign('new_height',$new_height);
$smarty->assign('new_filesize',number_format($file_size/1000,0,',',''));
}
else {
@move_uploaded_file($_FILES['probe']['tmp_name'], $uploaded_images_path.$filename) or $errors[] = 'upload_error';
}
}
if(isset($avatar))
{
$avatar .= '?u='.uniqid();
$smarty->assign('avatar', $avatar);
}
else $smarty->assign('upload', 'true');
if (empty($errors)) {
@chmod($uploaded_images_path.$filename, 0644);
$smarty->assign('avatar_uploaded', true);
}
else {
$smarty->assign('errors',$errors);
$smarty->assign('form', true);
}
}
if(isset($_GET['deleted'])) $smarty->assign('avatar_deleted', true);
// show avatar
if ($filename !== false && file_exists($uploaded_images_path.$filename)) {
$avatar = $uploaded_images_path.$filename;
}
if (isset($avatar)) {
//$avatar .= '?u='.uniqid();
$smarty->assign('avatar', $avatar);
} else {
$smarty->assign('upload', 'true');
}
if (isset($_GET['deleted']))
$smarty->assign('avatar_deleted', true);
if(empty($errors) && isset($_FILES['probe']['error']))
{
$smarty->assign('server_max_filesize', ini_get('upload_max_filesize'));
$errors[] = 'upload_error_2';
$smarty->assign('errors',$errors);
}
}
if (empty($errors) && isset($_FILES['probe']['error'])) {
$smarty->assign('server_max_filesize', ini_get('upload_max_filesize'));
$errors[] = 'upload_error_2';
$smarty->assign('errors', $errors);
}
}
$template = 'avatar.tpl';
?>

16
includes/b8.inc.php Normal file
View file

@ -0,0 +1,16 @@
<?php
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
// include B8 php resources
require 'modules/b8/b8.php';
// include config
require 'config/b8_config.php';
// create instance
//$B8_BAYES_FILTER = new b8($B8_CONFIG_DATABASE_TYPE, $B8_CONFIG_AUTHENTICATION, $B8_CONFIG_LEXER, $B8_CONFIG_DEGENERATOR);
$B8_BAYES_FILTER = new b8\b8($B8_CONFIG_DATABASE_TYPE, $B8_CONFIG_STORAGE, $B8_CONFIG_LEXER, $B8_CONFIG_DEGENERATOR);
?>

247
includes/bookmark.inc.php Normal file
View file

@ -0,0 +1,247 @@
<?php
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$user_id = $_SESSION[$settings['session_prefix'].'user_id'];
// Derzeit kann nur reorder von aussen kommen.
if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'reorder')
$action = $_REQUEST['action'];
elseif (isset($_GET['delete_bookmark']))
$action = 'delete_bookmark';
elseif (isset($_POST['delete_bookmark_submit']))
$action = 'delete_bookmark_submit';
elseif (isset($_GET['move_up_bookmark']) || isset($_GET['move_down_bookmark']))
$action = 'move_bookmark';
elseif (isset($_GET['edit_bookmark']))
$action = 'edit_bookmark';
elseif (isset($_POST['edit_bookmark_submit']) && isset($_POST['bookmark']))
$action = 'edit_bookmark_submit';
else {
$action = 'main';
$filter = isset($_GET['filter']) && $_GET['filter'] != '' ? trim(urldecode(trim($_GET['filter']))) : false;
// Taken from search.inc.php
if ($filter !== false) {
// split search query at spaces, but not between double quotes:
$help_pattern = '[!/*/~/?]'; // pattern to hide spaces between quotes
$x_filter = preg_replace_callback(
"#\"(.+?)\"#is",
function ($string) {
global $help_pattern;
return str_replace(" ", $help_pattern,$string[1]);
},
$filter
);
$x_filter_array = explode(' ', my_strtolower($x_filter, $lang['charset']));
foreach($x_filter_array as $item)
$filter_array[] = mysqli_real_escape_string($connid, str_replace($help_pattern, ' ', $item));
$filter_string = "AND LOWER(`".$db_settings['tags_table']."`.`tag`) LIKE '%".implode("%' OR LOWER(".$db_settings['tags_table'].".`tag`) LIKE '%",$filter_array)."%'";
}
}
switch($action) {
case 'main':
$bookmark_result = @mysqli_query($connid, "SELECT `".$db_settings['bookmark_table']."`.`subject`, `".$db_settings['forum_table']."`.`user_id`,
".$db_settings['forum_table'].".`id`, IF (`".$db_settings['forum_table']."`.`user_id` = 0, `name`,
(SELECT `user_name` FROM `".$db_settings['userdata_table']."` WHERE `".$db_settings['userdata_table']."`.`user_id` = `".$db_settings['forum_table']."`.`user_id` ) ) AS `user_name`,
UNIX_TIMESTAMP(`".$db_settings['bookmark_table']."`.`time` + INTERVAL ".$time_difference." MINUTE) AS `bookmark_time`,
UNIX_TIMESTAMP(`".$db_settings['forum_table']."`.`time` + INTERVAL ".$time_difference." MINUTE) AS `disp_time`,
UNIX_TIMESTAMP(`".$db_settings['forum_table']."`.`last_reply` + INTERVAL ".$time_difference." MINUTE) AS `reply_time`,
`".$db_settings['bookmark_table']."`.`id` AS `bid`, `".$db_settings['tags_table']."`.`id` AS `tag_id`, `".$db_settings['tags_table']."`.`tag`
FROM `".$db_settings['bookmark_table']."`
JOIN `".$db_settings['forum_table']."` ON `".$db_settings['forum_table']."`.`id` = `".$db_settings['bookmark_table']."`.`posting_id`
LEFT JOIN `".$db_settings['bookmark_tags_table']."` ON `".$db_settings['bookmark_table']."`.`id` = `".$db_settings['bookmark_tags_table']."`.`bid`
LEFT JOIN `".$db_settings['tags_table']."` ON `".$db_settings['bookmark_tags_table']."`.`tid` = `".$db_settings['tags_table']."`.`id`
WHERE `".$db_settings['bookmark_table']."`.`user_id` = ".intval($user_id)." ".(isset($filter_string) ? $filter_string : "" )."
ORDER BY ".$db_settings['bookmark_table'].".`order_id` ASC") or raise_error('database_error',mysqli_error($connid));
$total_bookmarks = mysqli_num_rows($bookmark_result);
$bookmarkdata = false;
if (empty($row['user_name']))
$row['user_name'] = $lang['unknown_user'];
while ($row = mysqli_fetch_array($bookmark_result)) {
$tag = $row['tag'];
$tags_array = false;
if (!is_null($tag)) {
if (my_strpos($tag, ' ', 0, $lang['charset']))
$tag_escaped='"'.$tag.'"';
else
$tag_escaped = $tag;
$tags_array = [
'escaped' => urlencode($tag_escaped),
'display' => htmlspecialchars($tag),
];
}
$bookmarkdata[$row['bid']]['subject'] = htmlspecialchars($row['subject']);
$bookmarkdata[$row['bid']]['user_name'] = htmlspecialchars($row['user_name']);
$bookmarkdata[$row['bid']]['user_id'] = intval($row['user_id']);
$bookmarkdata[$row['bid']]['id'] = intval($row['id']);
$bookmarkdata[$row['bid']]['bid'] = intval($row['bid']);
$bookmarkdata[$row['bid']]['bookmark_time'] = format_time($lang['time_format_full'], $row['bookmark_time']);
$bookmarkdata[$row['bid']]['posting_time'] = format_time($lang['time_format_full'], $row['disp_time']);
$bookmarkdata[$row['bid']]['reply_time'] = format_time($lang['time_format_full'], $row['reply_time']);
if ($tags_array !== false)
$bookmarkdata[$row['bid']]['tags'][] = $tags_array;
}
mysqli_free_result($bookmark_result);
if ($bookmarkdata)
$smarty->assign('bookmarkdata',$bookmarkdata);
$breadcrumbs[0]['link'] = 'index.php?mode=bookmarks';
$breadcrumbs[0]['linkname'] = 'subnav_bookmarks';
$smarty->assign('breadcrumbs',$breadcrumbs);
$smarty->assign('subnav_location', 'subnav_bookmarks');
$smarty->assign('filter', isset($filter_string));
$smarty->assign('total_bookmarks', $total_bookmarks);
$smarty->assign('action', 'bookmark');
$smarty->assign('subtemplate', 'bookmark.inc.tpl');
$template = 'main.tpl';
break;
case 'move_bookmark':
if (isset($_GET['move_up_bookmark']))
move_item($db_settings['bookmark_table'], intval($_GET['move_up_bookmark']), 'up');
elseif (isset($_GET['move_down_bookmark']))
move_item($db_settings['bookmark_table'], intval($_GET['move_down_bookmark']), 'down');
header("Location: index.php?mode=bookmarks");
exit;
break;
case 'delete_bookmark':
$id = intval($_GET['delete_bookmark']);
$result = @mysqli_query($connid, "SELECT `subject` FROM ".$db_settings['bookmark_table']." WHERE id= ".$id." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if(mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_array($result);
$bookmark['id'] = $id;
$bookmark['title'] = htmlspecialchars($row['subject']);
$smarty->assign('bookmark', $bookmark);
}
mysqli_free_result($result);
$breadcrumbs[0]['link'] = 'index.php?mode=bookmarks';
$breadcrumbs[0]['linkname'] = 'subnav_bookmarks';
$smarty->assign('breadcrumbs',$breadcrumbs);
$smarty->assign('action','delete_bookmark');
$smarty->assign('subnav_location','subnav_delete_bookmark');
$smarty->assign('subtemplate','bookmark.inc.tpl');
$template = 'main.tpl';
break;
case 'delete_bookmark_submit':
$result = @mysqli_query($connid, "SELECT `id` FROM ".$db_settings['bookmark_table']." WHERE `id` = ". intval($_POST['id']) ." AND `user_id` = ". intval($user_id) ." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if(mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_array($result);
deleteBookmark($row['id']);
}
mysqli_free_result($result);
header("Location: index.php?mode=bookmarks");
exit;
break;
case 'edit_bookmark':
$id = intval($_GET['edit_bookmark']);
$tags = getBookmarkTags($id);
$result = @mysqli_query($connid, "SELECT `subject` FROM ".$db_settings['bookmark_table']." WHERE id= ".$id." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_array($result);
$bookmark['id'] = $id;
$bookmark['title'] = htmlspecialchars($row['subject']);
if (!empty($tags))
$bookmark['tags'] = implode(", ", array_filter(array_map('htmlspecialchars', $tags), function($value) { return $value !== ''; }));
$smarty->assign('bookmark', $bookmark);
}
mysqli_free_result($result);
$breadcrumbs[0]['link'] = 'index.php?mode=bookmarks';
$breadcrumbs[0]['linkname'] = 'subnav_bookmarks';
$smarty->assign('breadcrumbs', $breadcrumbs);
$smarty->assign('action', 'edit_bookmark');
$smarty->assign('subnav_location', 'subnav_edit_bookmark');
$smarty->assign('subtemplate', 'bookmark.inc.tpl');
$template = 'main.tpl';
break;
case 'edit_bookmark_submit':
if (empty($_POST['bookmark']))
$errors[] = 'error_no_bookmark_subject';
if (my_strlen(trim($_POST['bookmark']), $lang['charset']) > $settings['subject_maxlength'])
$errors[] = 'error_bookmark_subject_too_long';
if (isset($_POST['tags']) && trim($_POST['tags']) != '') {
$tagsArray = array_filter(array_map('trim', explode(',', $_POST['tags'])), function($value) { return $value !== ''; });
if (count($tagsArray) > 10) {
$errors[] = 'error_bookmark_tags_limit_reached';
}
else {
foreach ($tagsArray as $tag) {
unset($too_long_word);
$too_long_word = too_long_word($tag, $settings['text_word_maxlength'], $lang['word_delimiters']);
if ($too_long_word) {
$errors[] = 'error_bookmark_word_too_long';
break;
}
}
}
}
if (empty($errors)) {
setBookmarkTags($_POST['id'], $tagsArray);
@mysqli_query($connid, "UPDATE ".$db_settings['bookmark_table']." SET `subject` = '". mysqli_real_escape_string($connid, trim($_POST['bookmark'])) ."' WHERE `id` = ". intval($_POST['id']) ." AND `user_id` = ". intval($user_id) ." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
header("Location: index.php?mode=bookmarks");
exit;
}
else {
$bookmark['id'] = intval($_POST['id']);
$bookmark['title'] = htmlspecialchars(trim($_POST['bookmark']));
$bookmark['tags'] = htmlspecialchars(trim($_POST['tags']));
$smarty->assign('bookmark', $bookmark);
$smarty->assign('errors', $errors);
if (isset($too_long_word))
$smarty->assign('word', $too_long_word);
$breadcrumbs[0]['link'] = 'index.php?mode=bookmarks';
$breadcrumbs[0]['linkname'] = 'subnav_bookmarks';
$smarty->assign('breadcrumbs', $breadcrumbs);
$smarty->assign('action', 'edit_bookmark');
$smarty->assign('subnav_location', 'subnav_edit_bookmark');
$smarty->assign('subtemplate', 'bookmark.inc.tpl');
$template = 'main.tpl';
}
break;
case 'reorder':
if (isset($_POST['bookmarks'])) {
$items = array_map(function($item) use($connid) { return mysqli_real_escape_string($connid, $item); }, explode(',', $_POST['bookmarks']));
$order_result = @mysqli_query($connid, "SELECT `id`, `order_id` FROM ".$db_settings['bookmark_table']." WHERE `id` IN (".implode(",", $items).") ORDER BY `order_id` ASC");
$order = false;
while ($row = mysqli_fetch_array($order_result))
$order[] = $row["order_id"];
mysqli_free_result($order_result);
if ($order !== false && count($order) == count($items)) {
for ($i = 0; $i < count($items); $i++) {
$order_id = $order[$i];
$item_id = $items[$i];
@mysqli_query($connid, "UPDATE ".$db_settings['bookmark_table']." SET `order_id` = ". intval($order_id) ." WHERE `id` = ". intval($item_id) ." AND `user_id` = ". intval($user_id) ." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
}
}
}
exit;
break;
default:
header("Location: index.php");
exit;
break;
}
} else {
header("Location: index.php");
exit;
}
?>

View file

@ -1,95 +0,0 @@
<?php
/**
* creates a backup file with buffering every 500 lines
* in order to prevent timeout or exhausting memory size
*/
class Backup
{
var $start_time;
var $check_time;
var $file;
var $dump = '';
var $queries = 0;
var $max_queries = 300;
var $errors = Array();
function Backup()
{
@set_time_limit(30);
$this->start_time = time();
$this->check_time = $this->start_time;
}
function set_max_queries($max_queries=500)
{
$this->max_queries = $max_queries;
}
function set_file($file)
{
$this->file = $file;
}
function assign($data)
{
#$this->dump .= utf8_encode($data);
$this->dump .= $data;
$this->queries++;
$now = time();
if(($now-25) >= $this->check_time)
{
$this->check_time = $now;
@set_time_limit(30);
}
if($this->queries >= $this->max_queries)
{
// buffer:
if(!$this->save()) $buffering_failed = true;
$this->queries = 0;
}
if(empty($buffering_failed))
{
return true;
}
else
{
return false;
}
}
function save()
{
if($this->dump != '')
{
if(empty($this->file))
{
$this->file = 'backup_'.date("YmdHis").'.sql';
}
if($handle = @fopen($this->file, 'a+'))
{
#flock($fp, 2);
@fwrite($handle, $this->dump);
#flock($fp, 3);
@fclose($handle);
$this->dump = '';
}
else
{
$write_error = true;
}
}
if(empty($write_error))
{
return true;
}
else
{
$this->errors[] = 'write_error';
return false;
}
}
}
?>

View file

@ -1,346 +1,305 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
$current_time = time();
if (empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_email'] > 0) {
require('modules/captcha/captcha.php');
$captcha = new Captcha();
}
if(empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_email']>0)
{
require('modules/captcha/captcha.php');
$captcha = new Captcha();
}
if (isset($_REQUEST['action']))
$action = $_REQUEST['action'];
else
$action = 'main';
if(isset($_REQUEST['action'])) $action = $_REQUEST['action'];
else $action = 'main';
if(isset($_POST['message_submit']))
$action = 'message_submit';
if(isset($_POST['message_submit'])) $action = 'message_submit';
$isUser = isset($_SESSION[$settings['session_prefix'].'user_type']) && isset($_SESSION[$settings['session_prefix'].'user_id']);
$isModOrAdmin = $isUser && ($_SESSION[$settings['session_prefix'].'user_type'] == 1 || $_SESSION[$settings['session_prefix'].'user_type'] == 2);
switch($action)
{
case 'main':
// sender:
if(isset($_SESSION[$settings['session_prefix'].'user_id']))
{
$result = @mysql_query("SELECT user_email FROM ".$db_settings['userdata_table']." WHERE user_id = '".intval($_SESSION[$settings['session_prefix'].'user_id'])."' LIMIT 1", $connid) or raise_error('database_error',mysql_error());
$data = mysql_fetch_array($result);
mysql_free_result($result);
$smarty->assign('sender_email',htmlspecialchars($data['user_email']));
}
else
{
$smarty->assign('sender_email','');
}
switch($action) {
case 'main':
// set timestamp for SPAM protection
setReceiptTimestamp();
// sender id
$smarty->assign('user_id', isset($_SESSION[$settings['session_prefix'].'user_id']) ? intval($_SESSION[$settings['session_prefix'].'user_id']) : FALSE);
if(isset($_REQUEST['id']))
{
// contact by entry:
$result = @mysql_query("SELECT user_id, name, email FROM ".$db_settings['forum_table']." WHERE id = ".intval($_REQUEST['id'])." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result)!=1)
{
header('Location: index.php');
exit;
}
$data = mysql_fetch_array($result);
mysql_free_result($result);
if($data['user_id']>0)
{
// registered user, get data from userdata table:
$result = @mysql_query("SELECT user_name, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = ".intval($data['user_id'])." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
$userdata = mysql_fetch_array($result);
mysql_free_result($result);
if($userdata['email_contact']!=1)
{
$smarty->assign('error_message','impossible_to_contact');
}
else
{
$smarty->assign('recipient_name',htmlspecialchars($userdata['user_name']));
$smarty->assign('recipient_user_id',intval($data['user_id']));
}
}
else
{
// not registered user, get data from forum table:
if($data['email']=='')
{
$smarty->assign('error_message','impossible_to_contact');
}
else
{
$smarty->assign('recipient_name',htmlspecialchars($data['name']));
$smarty->assign('id',intval($_REQUEST['id']));
}
}
}
elseif(isset($_REQUEST['user_id']))
{
$result = @mysql_query("SELECT user_name, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = '".intval($_REQUEST['user_id'])."' LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result)!=1)
{
header('Location: index.php');
exit;
}
$userdata = mysql_fetch_array($result);
mysql_free_result($result);
if($userdata['email_contact']!=1)
{
$smarty->assign('error_message','impossible_to_contact');
}
else
{
$smarty->assign('recipient_name',htmlspecialchars($userdata['user_name']));
$smarty->assign('recipient_user_id',intval($_REQUEST['user_id']));
}
}
$_SESSION[$settings['session_prefix'].'formtime'] = $current_time;
break;
case 'message_submit':
if(isset($_POST['id'])) $id = intval($_POST['id']);
if(isset($_POST['user_id'])) $user_id = intval($_POST['user_id']);
if(isset($_POST['sender_email'])) $sender_email = trim(preg_replace("/\r/", "", $_POST['sender_email']));
if(isset($_POST['text'])) $text = trim($_POST['text']);
if(isset($_POST['subject'])) $subject = trim($_POST['subject']);
if (isset($_REQUEST['id'])) {
// contact by entry:
$result = @mysqli_query($connid, "SELECT user_id AS recipient_user_id, name, email FROM ".$db_settings['forum_table']." WHERE id = ".intval($_REQUEST['id'])." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) != 1) {
header('Location: index.php');
exit;
}
$data = mysqli_fetch_array($result);
mysqli_free_result($result);
if ($data['recipient_user_id'] > 0) {
// registered user, get data from userdata table:
$result = @mysqli_query($connid, "SELECT user_name, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = ".intval($data['recipient_user_id'])." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
$userdata = mysqli_fetch_array($result);
mysqli_free_result($result);
if ($isModOrAdmin || $isUser && $userdata['email_contact'] > 0 || $userdata['email_contact'] == 2) {
$smarty->assign('recipient_name', htmlspecialchars($userdata['user_name']));
$smarty->assign('recipient_user_id', intval($data['recipient_user_id']));
} else {
$smarty->assign('error_message', 'impossible_to_contact');
}
} else {
// not registered user, get data from forum table:
if($data['email'] == '') {
$smarty->assign('error_message','impossible_to_contact');
} else {
$smarty->assign('recipient_name', htmlspecialchars($data['name']));
$smarty->assign('id', intval($_REQUEST['id']));
}
}
} elseif (isset($_REQUEST['recipient_user_id'])) {
$result = @mysqli_query($connid, "SELECT user_name, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = '".intval($_REQUEST['recipient_user_id'])."' LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if(mysqli_num_rows($result) != 1) {
header('Location: index.php');
exit;
}
$userdata = mysqli_fetch_array($result);
mysqli_free_result($result);
if ($isModOrAdmin || $isUser && $userdata['email_contact'] > 0 || $userdata['email_contact'] == 2) {
$smarty->assign('recipient_name', htmlspecialchars($userdata['user_name']));
$smarty->assign('recipient_user_id', intval($_REQUEST['recipient_user_id']));
} else {
$smarty->assign('error_message', 'impossible_to_contact');
}
}
break;
case 'message_submit':
if (isset($_POST['id']))
$id = intval($_POST['id']);
if (isset($_POST['recipient_user_id']))
$recipient_user_id = intval($_POST['recipient_user_id']);
if (isset($_POST['text']) && !empty($_POST['text']))
$text = trim($_POST['text']);
if (isset($_POST['subject']) && !empty($_POST['subject']))
$subject = trim($_POST['subject']);
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$result = @mysqli_query($connid, "SELECT user_email FROM ".$db_settings['userdata_table']." WHERE user_id = '".intval($_SESSION[$settings['session_prefix'].'user_id'])."' LIMIT 1") or raise_error('database_error', mysqli_error($connid));
$data = mysqli_fetch_array($result);
mysqli_free_result($result);
$sender_email = $data['user_email']; // email of reg. user taken from profil
$confirmation_mail_to_sender = isset($_POST['confirmation_email']) && intval($_POST['confirmation_email']) == 1 ? TRUE : FALSE;
}
else {
$sender_email = $_POST['sender_email'];
$confirmation_mail_to_sender = FALSE;
}
$sender_email = trim(preg_replace("/\r/", "", $sender_email));
// check form session and time used to complete the form:
if(empty($_SESSION[$settings['session_prefix'].'user_id']))
{
if(empty($_SESSION[$settings['session_prefix'].'formtime'])) $errors[] = 'error_invalid_form';
else
{
$time_need = $current_time - intval($_SESSION[$settings['session_prefix'].'formtime']);
if($time_need<10) $errors[] = 'error_form_sent_too_fast';
elseif($time_need>10800) $errors[] = 'error_form_sent_too_slow';
unset($_SESSION[$settings['session_prefix'].'formtime']);
}
}
// check form session and time used to complete the form:
setReceiptTimestamp();
// if (empty($_SESSION[$settings['session_prefix'].'user_id'])) {
if (!isset($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference']) || intval($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference']) <= 0)
$errors[] = 'error_invalid_form';
else {
if ($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference'] < $settings['min_email_time'])
$errors[] = 'error_form_sent_too_fast';
elseif ($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference'] > $settings['max_email_time'])
$errors[] = 'error_form_sent_too_slow';
}
if(empty($errors))
{
if(empty($sender_email) || $sender_email=='') $errors[] = 'error_no_email';
elseif(!is_valid_email($sender_email)) $errors[] = 'error_email_invalid';
if(empty($subject) || $subject=='') $errors[] = 'error_no_subject';
if(empty($text) || $text=='') $errors[] = 'error_no_text';
if(my_strlen($subject,$lang['charset']) > $settings['email_subject_maxlength']) $errors[] = 'error_email_subject_too_long';
if(my_strlen($text,$lang['charset']) > $settings['email_text_maxlength']) $errors[] = 'error_email_text_too_long';
$smarty->assign('text_length',my_strlen($text,$lang['charset']));
}
if (empty($errors)) {
if (empty($sender_email) || $sender_email == '')
$errors[] = 'error_message_no_email';
elseif (!is_valid_email($sender_email))
$errors[] = 'error_email_invalid';
if (empty($subject) || $subject == '')
$errors[] = 'error_message_no_subject';
if (empty($text) || $text == '')
$errors[] = 'error_message_no_text';
if (my_strlen($subject, $lang['charset']) > $settings['email_subject_maxlength'])
$errors[] = 'error_email_subject_too_long';
if (my_strlen($text, $lang['charset']) > $settings['email_text_maxlength'])
$errors[] = 'error_email_text_too_long';
$smarty->assign('text_length', my_strlen($text,$lang['charset']));
}
if(empty($errors))
{
// check for not accepted words:
$joined_mail = my_strtolower($sender_email.' '.$subject.' '.$text, $lang['charset']);
$not_accepted_words = get_not_accepted_words($joined_mail);
if($not_accepted_words!=false)
{
$not_accepted_words_listing = implode(', ',$not_accepted_words);
if(count($not_accepted_words)==1)
{
$smarty->assign('not_accepted_word',htmlspecialchars($not_accepted_words_listing));
$errors[] = 'error_not_accepted_word';
}
else
{
$smarty->assign('not_accepted_words',htmlspecialchars($not_accepted_words_listing));
$errors[] = 'error_not_accepted_words';
}
}
}
if (empty($errors)) {
// check for not accepted words:
$joined_mail = my_strtolower($sender_email.' '.$subject.' '.$text, $lang['charset']);
$not_accepted_words = get_not_accepted_words($joined_mail);
if ($not_accepted_words != false) {
$not_accepted_words_listing = implode(', ',$not_accepted_words);
if (count($not_accepted_words) == 1) {
$smarty->assign('not_accepted_word', htmlspecialchars($not_accepted_words_listing));
$errors[] = 'error_not_accepted_word';
} else {
$smarty->assign('not_accepted_words', htmlspecialchars($not_accepted_words_listing));
$errors[] = 'error_not_accepted_words';
}
}
}
// CAPTCHA check:
if(empty($errors) && empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_email']>0)
{
if($settings['captcha_email']==2)
{
if(empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_captcha($_SESSION['captcha_session'],$_POST['captcha_code'])!=true) $errors[] = 'captcha_check_failed';
}
else
{
if(empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_math_captcha($_SESSION['captcha_session'][2],$_POST['captcha_code'])!=true) $errors[] = 'captcha_check_failed';
}
unset($_SESSION['captcha_session']);
}
// CAPTCHA check:
if (empty($errors) && empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_email'] > 0) {
if ($settings['captcha_email'] == 2) {
if (empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_captcha($_SESSION['captcha_session'], $_POST['captcha_code']) != true) $errors[] = 'captcha_check_failed';
} else {
if (empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_math_captcha($_SESSION['captcha_session'][2], $_POST['captcha_code']) != true) $errors[] = 'captcha_check_failed';
}
unset($_SESSION['captcha_session']);
}
// Akismet spam check:
if(empty($errors) && $settings['akismet_key']!='' && $settings['akismet_mail_check']==1 && empty($_SESSION[$settings['session_prefix'].'user_id']))
{
require('modules/akismet/akismet.class.php');
$mail_parts = explode("@", $sender_email);
$sender_name = $mail_parts[0];
$check_mail['author'] = $mail_parts[0];
$check_mail['email'] = $sender_email;
#$check_mail['body'] = $subject."\n\n".$text;
$check_mail['body'] = $text;
$akismet = new Akismet($settings['forum_address'], $settings['akismet_key'], $check_mail);
// test for errors
if($akismet->errorsExist())
{
// returns true if any errors exist
if($akismet->isError(AKISMET_INVALID_KEY))
{
$errors[] = 'error_akismet_api_key';
}
elseif($akismet->isError(AKISMET_RESPONSE_FAILED))
{
$errors[] = 'error_akismet_connection';
}
elseif($akismet->isError(AKISMET_SERVER_NOT_FOUND))
{
$errors[] = 'error_akismet_connection';
}
}
else
{
// No errors, check for spam
if($akismet->isSpam())
{
$errors[] = 'error_spam_suspicion';
}
}
}
// Spam check:
if (empty($errors) && (empty($_SESSION[$settings['session_prefix'].'user_id']) || isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type'] == 0 && $settings['spam_check_registered'] == 1)) {
$mail_parts = explode("@", $sender_email);
$sender_name = $mail_parts[0];
$check_mail['author'] = $mail_parts[0];
$check_mail['email'] = $sender_email;
$check_mail['body'] = $text;
// Akismet spam check:
if ($settings['akismet_key'] != '' && $settings['akismet_mail_check'] == 1) {
require('modules/akismet/akismet.class.php');
$akismet = new Akismet($settings['forum_address'], $settings['akismet_key'], $check_mail);
// test for errors
if ($akismet->errorsExist()) {
// returns true if any errors exist
if ($akismet->isError(AKISMET_INVALID_KEY)) {
$errors[] = 'error_akismet_api_key';
} elseif ($akismet->isError(AKISMET_RESPONSE_FAILED)) {
$errors[] = 'error_akismet_connection';
} elseif($akismet->isError(AKISMET_SERVER_NOT_FOUND)) {
$errors[] = 'error_akismet_connection';
}
} else {
// No errors, check for spam
if ($akismet->isSpam()) {
$errors[] = 'error_email_spam_suspicion';
}
}
}
// B8 spam check:
if ($settings['b8_mail_check'] == 1) {
try {
$check_text = implode("\r\n", $check_mail);
$b8_spam_probability = 100.0 * $B8_BAYES_FILTER->classify($check_text);
if ($b8_spam_probability > intval($settings['b8_spam_probability_threshold']))
$errors[] = 'error_email_spam_suspicion';
}
catch(Exception $e) {
raise_error('database_error', $e->getMessage()); // What should we do here?
$b8_spam = 0;
}
}
}
if(isset($id))
{
// get email address from entry:
$result = @mysql_query("SELECT user_id, name, email FROM ".$db_settings['forum_table']." WHERE id = ".intval($id)." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result)!=1)
{
header('Location: index.php');
exit;
}
$data = mysql_fetch_array($result);
mysql_free_result($result);
if($data['user_id']>0)
{
// registered user, get data from userdata table:
$result = @mysql_query("SELECT user_email, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = ".intval($data['user_id'])." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
$userdata = mysql_fetch_array($result);
mysql_free_result($result);
if($userdata['email_contact']!=1)
{
$errors[] = TRUE;
$smarty->assign('error_message','impossible_to_contact');
}
else
{
$smarty->assign('recipient_name',htmlspecialchars($userdata['user_name']));
$recipient_email = $data['user_email'];
}
}
else
{
// not registered user, get data from forum table:
if($data['email']=='')
{
$errors[] = TRUE;
$smarty->assign('error_message','impossible_to_contact');
}
else
{
$recipient_name = htmlspecialchars($data['name']);
$recipient_email = $data['email'];
$smarty->assign('recipient_name',$recipient_name);
}
}
}
elseif(isset($user_id))
{
$result = @mysql_query("SELECT user_name, user_email, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = '".intval($user_id)."' LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result)!=1)
{
header('Location: index.php');
exit;
}
$userdata = mysql_fetch_array($result);
mysql_free_result($result);
if($userdata['email_contact']!=1)
{
$errors[] = TRUE;
$smarty->assign('error_message','impossible_to_contact');
}
else
{
$recipient_name = htmlspecialchars($userdata['user_name']);
$recipient_email = $userdata['user_email'];
$smarty->assign('recipient_name',$recipient_name);
}
}
else
{
$recipient_name = $settings['forum_name'];
$recipient_email = $settings['forum_email'];
}
if (empty($errors)) {
if (isset($id)) {
// get email address from entry:
$result = @mysqli_query($connid, "SELECT user_id AS recipient_user_id, name, email FROM ".$db_settings['forum_table']." WHERE id = ".intval($id)." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if(mysqli_num_rows($result) != 1) {
header('Location: index.php');
exit;
}
$data = mysqli_fetch_array($result);
mysqli_free_result($result);
if ($data['recipient_user_id'] > 0) {
// registered user, get data from userdata table:
$result = @mysqli_query($connid, "SELECT user_email, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = ".intval($data['recipient_user_id'])." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
$userdata = mysqli_fetch_array($result);
mysqli_free_result($result);
if ($isModOrAdmin || $isUser && $userdata['email_contact'] > 0 || $userdata['email_contact'] == 2) {
$smarty->assign('recipient_name', htmlspecialchars($userdata['user_name']));
$recipient_email = $data['user_email'];
} else {
$errors[] = TRUE;
$smarty->assign('error_message', 'impossible_to_contact');
}
} else {
// not registered user, get data from forum table:
if ($data['email'] == '') {
$errors[] = TRUE;
$smarty->assign('error_message','impossible_to_contact');
} else {
$recipient_name = htmlspecialchars($data['name']);
$recipient_email = $data['email'];
$smarty->assign('recipient_name', $recipient_name);
}
}
} elseif (isset($recipient_user_id)) {
$result = @mysqli_query($connid, "SELECT user_name, user_email, email_contact FROM ".$db_settings['userdata_table']." WHERE user_id = '".intval($recipient_user_id)."' LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) != 1) {
header('Location: index.php');
exit;
}
$userdata = mysqli_fetch_array($result);
mysqli_free_result($result);
if ($isModOrAdmin || $isUser && $userdata['email_contact'] > 0 || $userdata['email_contact'] == 2) {
$recipient_name = htmlspecialchars($userdata['user_name']);
$recipient_email = $userdata['user_email'];
$smarty->assign('recipient_name', $recipient_name);
} else {
$errors[] = TRUE;
$smarty->assign('error_message', 'impossible_to_contact');
}
} else {
$recipient_name = $settings['forum_name'];
$recipient_email = $settings['forum_email'];
}
}
if(empty($errors))
{
// load e-mail strings from default language file:
$smarty->config_load($settings['language_file'], 'emails');
$lang = $smarty->get_config_vars();
if($language_file != $settings['language_file']) setlocale(LC_ALL, $lang['locale']);
if(isset($_SESSION[$settings['session_prefix'].'user_name'])) $emailbody = str_replace("[user]", $_SESSION[$settings['session_prefix'].'user_name'], $lang['contact_email_txt_user']);
else $emailbody = $lang['contact_email_txt'];
$emailbody = str_replace("[message]", $text, $emailbody);
$emailbody = str_replace("[forum_address]", $settings['forum_address'], $emailbody);
if(!my_mail($recipient_email, $subject, $emailbody, $sender_email)) $errors[] = 'mail_error';
// reset user language:
$smarty->config_load($language_file);
$lang = $smarty->get_config_vars();
if($language_file != $settings['language_file']) setlocale(LC_ALL, $lang['locale']);
}
if(isset($errors))
{
$_SESSION[$settings['session_prefix'].'formtime'] = $current_time - 7; // 7 seconds credit (form already sent)
$smarty->assign('errors',$errors);
if(isset($id)) $smarty->assign('id',$id);
if(isset($user_id)) $smarty->assign('recipient_user_id',$user_id);
if(isset($sender_email)) $smarty->assign('sender_email',htmlspecialchars($sender_email));
if(isset($text)) $smarty->assign('text',htmlspecialchars($text));
if(isset($subject)) $smarty->assign('subject',htmlspecialchars($subject));
}
else
{
$smarty->assign('sent',TRUE);
// e-mail to sender:
// disabled, see here: http://mylittleforum.net/forum/index.php?id=2485
/*
$emailsubject = str_replace("[subject]", $subject, $lang['contact_notification_sj']);
$emailbody = str_replace("[subject]", $subject, $lang['contact_notification_txt']);
$emailbody = str_replace("[message]", $text, $emailbody);
$emailbody = str_replace("[forum_address]", $settings['forum_address'], $emailbody);
$emailbody = str_replace("[recipient]", $recipient_name, $emailbody);
my_mail($sender_email, $subject, $emailbody);
*/
}
break;
}
if (empty($errors)) {
// load e-mail strings from default language file:
$smarty->configLoad($settings['language_file'], 'emails');
$lang = $smarty->getConfigVars();
if (isset($_SESSION[$settings['session_prefix'].'user_name']))
$emailbody = str_replace("[user]", $_SESSION[$settings['session_prefix'].'user_name'], $lang['contact_email_txt_user']);
else
$emailbody = $lang['contact_email_txt'];
$emailbody = str_replace("[message]", $text, $emailbody);
$emailbody = str_replace("[forum_address]", $settings['forum_address'], $emailbody);
if (!my_mail($recipient_email, $subject, $emailbody, $sender_email))
$errors[] = 'mail_error';
if (isset($_SESSION[$settings['session_prefix'].'user_id']) && $confirmation_mail_to_sender && !my_mail($sender_email, $subject, $emailbody, $sender_email))
$errors[] = 'mail_error';
}
if (isset($errors)) {
$smarty->assign('errors',$errors);
if (isset($id))
$smarty->assign('id', intval($id));
if (isset($recipient_user_id))
$smarty->assign('recipient_user_id', intval($recipient_user_id));
if (isset($sender_email))
$smarty->assign('sender_email', htmlspecialchars($sender_email));
if (isset($text))
$smarty->assign('text', htmlspecialchars($text));
if (isset($subject))
$smarty->assign('subject', htmlspecialchars($subject));
} else {
$smarty->assign('sent', TRUE);
}
break;
}
// CAPTCHA:
if(empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_email']>0)
{
if($settings['captcha_email']==2)
{
$_SESSION['captcha_session'] = $captcha->generate_code();
}
else
{
$_SESSION['captcha_session'] = $captcha->generate_math_captcha();
$captcha_tpl['number_1'] = $_SESSION['captcha_session'][0];
$captcha_tpl['number_2'] = $_SESSION['captcha_session'][1];
}
#$captcha_tpl['session_name'] = session_name();
#$captcha_tpl['session_id'] = session_id();
$captcha_tpl['type'] = $settings['captcha_email'];
$smarty->assign('captcha',$captcha_tpl);
}
if (empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_email'] > 0) {
if($settings['captcha_email'] == 2) {
$_SESSION['captcha_session'] = $captcha->generate_code();
} else {
$_SESSION['captcha_session'] = $captcha->generate_math_captcha();
$captcha_tpl['number_1'] = $_SESSION['captcha_session'][0];
$captcha_tpl['number_2'] = $_SESSION['captcha_session'][1];
}
$captcha_tpl['type'] = $settings['captcha_email'];
$smarty->assign('captcha', $captcha_tpl);
}
if(empty($_SESSION[$settings['session_prefix'].'user_id']))
{
$session['name'] = session_name();
$session['id'] = session_id();
$smarty->assign('session',$session);
}
if (empty($_SESSION[$settings['session_prefix'].'user_id'])) {
$session['name'] = session_name();
$session['id'] = session_id();
$smarty->assign('session', $session);
}
$smarty->assign('subnav_location','subnav_contact');
$smarty->assign('subtemplate','contact.inc.tpl');

View file

@ -1,19 +1,18 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
setcookie($settings['session_prefix'].'userdata','',0);
setcookie($settings['session_prefix'].'userdata', '', cookie_options(0));
if(isset($_POST['method']) && $_POST['method']=='ajax') exit;
if (isset($_POST['method']) && $_POST['method'] == 'ajax') exit;
else {
$smarty->assign('message', 'cookie_deleted');
$smarty->assign('subnav_location', 'subnav_delete_cookie');
$smarty->assign('subtemplate', 'info.inc.tpl');
$template = 'main.tpl';
}
else
{
$smarty->assign('message','cookie_deleted');
$smarty->assign('subnav_location','subnav_delete_cookie');
$smarty->assign('subtemplate','info.inc.tpl');
$template = 'main.tpl';
}
?>

View file

@ -1,21 +1,16 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if($settings['forum_disabled_message']!='')
{
$smarty->assign('custom_message',$settings['forum_disabled_message']);
}
else
{
$smarty->assign('message','forum_disabled');
}
if ($settings['forum_disabled_message'] != '') {
$smarty->assign('custom_message', $settings['forum_disabled_message']);
} else {
$smarty->assign('message', 'forum_disabled');
}
#$smarty->assign('lang_section','info');
$smarty->assign('subnav_location','subnav_disabled');
$smarty->assign('subtemplate','info.inc.tpl');
$smarty->assign('subnav_location', 'subnav_disabled');
$smarty->assign('subtemplate', 'info.inc.tpl');
$template = 'main.tpl';
?>

View file

@ -1,313 +1,375 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if (isset($_REQUEST['id']))
$id = intval($_REQUEST['id']);
else {
header('Location: index.php');
exit;
}
if (isset($_GET['page']))
$page = intval($_GET['page']);
else
$page = 1;
if (isset($_GET['order']) && $_GET['order'] == 'last_reply')
$order = 'last_reply';
else
$order = 'time';
if (isset($_SESSION[$settings['session_prefix'] . 'user_id'])) {
$tmp_user_id = $_SESSION[$settings['session_prefix'] . 'user_id'];
} else {
$tmp_user_id = 0;
}
$isUser = isset($_SESSION[$settings['session_prefix'].'user_type']) && isset($_SESSION[$settings['session_prefix'].'user_id']);
$isModOrAdmin = $isUser && ($_SESSION[$settings['session_prefix'].'user_type'] == 1 || $_SESSION[$settings['session_prefix'].'user_type'] == 2);
if (isset($id) && $id > 0) {
$result = @mysqli_query($connid, "SELECT ft.id, ft.pid, ft.tid, ft.user_id, UNIX_TIMESTAMP(ft.time + INTERVAL " . $time_difference . " MINUTE) AS disp_time,
UNIX_TIMESTAMP(ft.time) AS time, UNIX_TIMESTAMP(edited) as etime, UNIX_TIMESTAMP(edited + INTERVAL " . $time_difference . " MINUTE) AS edit_time,
UNIX_TIMESTAMP(edited - INTERVAL " . $settings['edit_delay'] . " MINUTE) AS edited_diff, edited_by, name, email,
subject, hp, location, ip, text, cache_text, show_signature, category, locked, views, edit_key,
user_name, user_type, user_email, email_contact, user_hp, user_location, signature, cache_signature, rst.user_id AS req_user,
" . $db_settings['akismet_rating_table'] . ".spam AS akismet_spam, spam_check_status,
" . $db_settings['b8_rating_table'] . ".spam AS b8_spam, training_type
FROM " . $db_settings['forum_table'] . " AS ft
LEFT JOIN " . $db_settings['entry_cache_table'] . " ON " . $db_settings['entry_cache_table'] . ".cache_id = ft.id
LEFT JOIN " . $db_settings['userdata_table'] . " ON " . $db_settings['userdata_table'] . ".user_id = ft.user_id
LEFT JOIN " . $db_settings['userdata_cache_table'] . " ON " . $db_settings['userdata_cache_table'] . ".cache_id = " . $db_settings['userdata_table'] . ".user_id
LEFT JOIN " . $db_settings['read_status_table'] . " AS rst ON rst.posting_id = ft.id AND rst.user_id = " . intval($tmp_user_id) . "
LEFT JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['akismet_rating_table'] . ".eid = ft.id
LEFT JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['b8_rating_table'] . ".eid = ft.id
WHERE ft.id = " . intval($id)) or raise_error('database_error', mysqli_error($connid));
if(isset($_REQUEST['id'])) $id = intval($_REQUEST['id']);
else
{
header('Location: index.php');
exit;
}
if (mysqli_num_rows($result) == 1) {
$entrydata = mysqli_fetch_array($result);
mysqli_free_result($result);
$entrydata['ISO_time'] = format_time('YYYY-MM-dd HH:mm:ss', $entrydata['time']);
$entrydata['edit_ISO_time'] = format_time('YYYY-MM-dd HH:mm:ss', $entrydata['etime']);
$entrydata['formated_time'] = format_time($lang['time_format_full'], $entrydata['disp_time']);
$entrydata['tags'] = getEntryTags($id);
// category of this posting accessible by user?
if (is_array($category_ids) && !in_array($entrydata['category'], $category_ids)) {
header("Location: index.php");
exit;
}
if (isset($_SESSION[$settings['session_prefix'] . 'user_id'])) {
// bookmark handling
$user_id = $_SESSION[$settings['session_prefix'] . 'user_id'];
$bookmark_result = mysqli_query($connid, "SELECT TRUE AS 'bookmark' FROM " . $db_settings['bookmark_table'] . " WHERE `user_id` = " . intval($user_id) . " AND `posting_id` = " . intval($id) . "") or raise_error('database_error', mysqli_error($connid));
$bookmark = mysqli_fetch_row($bookmark_result);
mysqli_free_result($bookmark_result);
if (isset($bookmark) && intval($bookmark) == 1)
$entrydata['bookmarkedby'] = intval($user_id);
// read-status handling
$rstatus = save_read_status($connid, $user_id, $id);
}
if ($entrydata['req_user'] !== NULL and is_numeric($entrydata['req_user']))
$entrydata['is_read'] = true;
else
$entrydata['is_read'] = false;
$entrydata['spam'] = $entrydata['akismet_spam'] || $entrydata['b8_spam'] ? 1 : 0;
if(isset($_GET['page'])) $page = intval($_GET['page']);
else $page = 1;
$smarty->assign('is_read', $entrydata['is_read']);
if (isset($settings['count_views']) && $settings['count_views'] == 1)
mysqli_query($connid, "UPDATE " . $db_settings['forum_table'] . " SET time=time, last_reply=last_reply, edited=edited, views=views+1 WHERE id=" . $id);
if ($entrydata['user_id'] > 0) {
if ($settings['avatars'] == 2) {
$avatarInfo = getAvatar($entrydata['user_id']);
$avatar['image'] = $avatarInfo === false ? false : $avatarInfo[2];
if (isset($avatar) && $avatar['image'] !== false) {
$image_info = getimagesize($avatar['image']);
$avatar['width'] = $image_info[0];
$avatar['height'] = $image_info[1];
$smarty->assign('avatar', $avatar);
}
}
$entrydata['email'] = $entrydata['user_email'];
$entrydata['location'] = $entrydata['user_location'];
$entrydata['hp'] = $entrydata['user_hp'];
} else
$entrydata['email_contact'] = 2;
} else {
header("Location: index.php");
exit;
}
} else {
header("Location: index.php");
exit;
}
if ($entrydata['cache_text'] == '') {
// no cached text so parse it and cache it:
$ftext = html_format($entrydata['text']);
// make sure not to make a double entry:
@mysqli_query($connid, "DELETE FROM " . $db_settings['entry_cache_table'] . " WHERE cache_id=" . intval($entrydata['id']));
@mysqli_query($connid, "INSERT INTO " . $db_settings['entry_cache_table'] . " (cache_id, cache_text) VALUES (" . intval($entrydata['id']) . ",'" . mysqli_real_escape_string($connid, $ftext) . "')");
} else {
$ftext = $entrydata['cache_text'];
}
if (isset($_REQUEST['ajax_preview'])) {
header('Content-Type: application/xml; charset=UTF-8');
echo '<?xml version="1.0"?>';
?><posting><content><![CDATA[<?php
echo $ftext;
?>]]></content><locked><?php
echo $entrydata['locked'];
?></locked></posting><?php
exit;
}
// Select data for thread-tree
$thread = $entrydata['tid'];
// Override spam variable, which was set in main.inc.php, to display current message in tree
if ($entrydata['spam'] == 1 && isset($id)) {
$spam_sql_and .= " OR ft.id = " . intval($id);
}
$entry_sql =
"SELECT ft.id, ft.pid, ft.tid, ft.user_id, UNIX_TIMESTAMP(ft.time) AS time, UNIX_TIMESTAMP(ft.time + INTERVAL " . $time_difference . " MINUTE) AS disp_time, UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, user_type, subject, category, marked, text, rst.user_id AS req_user, " . $db_settings['akismet_rating_table'] . ".spam AS akismet_spam, " . $db_settings['b8_rating_table'] . ".spam AS b8_spam, " . $db_settings['akismet_rating_table'] . ".spam_check_status AS akismet_checked, " . $db_settings['b8_rating_table'] . ".training_type AS b8_checked
FROM " . $db_settings['forum_table'] . " AS ft LEFT JOIN " . $db_settings['userdata_table'] . " ON " . $db_settings['userdata_table'] . ".user_id = ft.user_id LEFT JOIN " . $db_settings['read_status_table'] . " AS rst ON rst.posting_id = ft.id AND rst.user_id = " . intval($tmp_user_id) . " LEFT JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['akismet_rating_table'] . ".eid = ft.id LEFT JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['b8_rating_table'] . ".eid = ft.id
LEFT JOIN (SELECT eid AS id FROM " . $db_settings['akismet_rating_table'] . " WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT eid AS id FROM " . $db_settings['b8_rating_table'] . " WHERE " . $db_settings['b8_rating_table'] . ".spam = 1) AS spam_list ON spam_list.id = ft.id
WHERE tid = " . $thread . $spam_sql_and . " ORDER BY time ASC";
$result = mysqli_query($connid, $entry_sql);
if(isset($_GET['order']) && $_GET['order']=='last_reply') $order = 'last_reply';
else $order = 'time';
if (!$result)
raise_error('database_error', mysqli_error($connid));
while ($data = mysqli_fetch_array($result)) {
if ($data['user_id'] > 0) {
if (!$data['user_name'])
$data['name'] = $lang['unknown_user'];
else
$data['name'] = htmlspecialchars($data['user_name']);
} else
$data['name'] = htmlspecialchars($data['name']);
$data['subject'] = htmlspecialchars($data['subject']);
$data['formated_time'] = format_time($lang['time_format'], $data['disp_time']);
$data['ISO_time'] = format_time('YYYY-MM-dd HH:mm:ss', $data['time']);
// set read or new status of messages
$data = getMessageStatus($data, $last_visit);
if ($data['text'] == '')
$data['no_text'] = true;
unset($data['text']);
if (isset($categories[$data['category']]) && $categories[$data['category']] != '')
$data['category_name'] = $categories[$data["category"]];
if ($data['pid'] == $id)
$direct_replies[] = $data['id'];
$last = $data['id'];
if ($data['pid'] > $last)
$last = $data['id'];
// set key 'not_classified_spam_ham' to decide, if an mod or admin should get notified about need of classification with an icon
if ((isset($_SESSION[$settings['session_prefix'].'user_id']) && isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type'] >= 1) && (($settings['akismet_entry_check'] == 1 && $data['akismet_checked'] == 0) || ($settings['b8_entry_check'] == 1 && $data['b8_checked'] == 0))) {
$data['not_classified_spam_ham'] = 1;
} else {
$data['not_classified_spam_ham'] = 0;
}
// flag spam
$data['spam'] = $data['akismet_spam'] || $data['b8_spam'] ? 1 : 0;
$data_array[$data['id']] = $data;
$child_array[$data['pid']][] = $data['id'];
}
if (isset($child_array)) {
$smarty->assign('child_array', $child_array);
get_thread_items($child_array, $entrydata['tid'], $entrydata['id']);
$thread_items_count = count($thread_items);
if ($thread_items_count > 1) {
foreach ($thread_items as $key => $val) {
if ($val == $entrydata['id'])
$current_key = $key;
}
if ($entrydata['id'] != $thread_items[0])
$smarty->assign('link_rel_first', 'index.php?id=' . $thread_items[0]);
if (isset($current_key) && isset($thread_items[$current_key - 1]))
$smarty->assign('link_rel_prev', 'index.php?id=' . $thread_items[$current_key - 1]);
if (isset($current_key) && isset($thread_items[$current_key + 1]))
$smarty->assign('link_rel_next', 'index.php?id=' . $thread_items[$current_key + 1]);
if ($entrydata['id'] != $thread_items[$thread_items_count - 1])
$smarty->assign('link_rel_last', 'index.php?id=' . $thread_items[$thread_items_count - 1]);
}
}
mysqli_free_result($result);
// tags:
if (isset($entrydata['tags']) && $entrydata['tags']) {
$tags_array = array();
$i = 0;
foreach ($entrydata['tags'] as $tag) {
if (my_strpos($tag, ' ', 0, $lang['charset']))
$tag_escaped = '"' . $tag . '"';
else
$tag_escaped = $tag;
$tags_array[$i]['escaped'] = urlencode($tag_escaped);
$tags_array[$i]['display'] = htmlspecialchars($tag);
$keywords[] = htmlspecialchars($tag);
$i++;
}
if (isset($tags_array) && !empty($tags_array))
$smarty->assign('tags', $tags_array);
if (isset($keywords) && !empty($keywords))
$smarty->assign('keywords', implode(', ', $keywords));
}
$category = $category;
$smarty->assign('id', intval($entrydata['id']));
$smarty->assign('tid', intval($entrydata['tid']));
$smarty->assign('pid', intval($entrydata['pid']));
$smarty->assign('posting_user_id', intval($entrydata['user_id']));
$smarty->assign('page_title', htmlspecialchars($entrydata['subject']));
$smarty->assign('subject', htmlspecialchars($entrydata['subject']));
if ($entrydata['user_id'] > 0) {
if (!$entrydata['user_name'])
$name = $lang['unknown_user'];
else
$name = htmlspecialchars($entrydata['user_name']);
} else
$name = htmlspecialchars($entrydata['name']);
$smarty->assign('name', $name);
$smarty->assign('user_type', htmlspecialchars($entrydata['user_type']));
$smarty->assign('disp_time', htmlspecialchars($entrydata['disp_time']));
$smarty->assign('ISO_time', htmlspecialchars($entrydata['ISO_time']));
$smarty->assign('formated_time', htmlspecialchars($entrydata['formated_time']));
$smarty->assign('locked', htmlspecialchars($entrydata['locked']));
$ago['days'] = floor((TIMESTAMP - $entrydata['time']) / 86400);
$ago['hours'] = floor(((TIMESTAMP - $entrydata['time']) / 3600) - ($ago['days'] * 24));
$ago['minutes'] = floor(((TIMESTAMP - $entrydata['time']) / 60) - ($ago['hours'] * 60 + $ago['days'] * 1440));
if ($ago['hours'] > 12)
$ago['days_rounded'] = $ago['days'] + 1;
else
$ago['days_rounded'] = $ago['days'];
$smarty->assign('ago', $ago);
$authorization = get_edit_authorization($id, $entrydata['user_id'], $entrydata['edit_key'], $entrydata['time'], $entrydata['locked']);
if ($authorization['edit'] == true)
$options['edit'] = true;
if ($authorization['delete'] == true)
$options['delete'] = true;
if (isset($direct_replies))
$smarty->assign('direct_replies', $direct_replies);
if ($settings['count_views'] == 1) {
$views = $entrydata['views'] - 1; // this subtracts the first view by the author after posting
if ($views < 0)
$views = 0; // prevents negative number of views
$smarty->assign('views', $entrydata['views']);
}
$smarty->assign('ip', $entrydata['ip']);
if ($entrydata['akismet_spam'] == 1 || $entrydata['b8_spam'] == 1)
$smarty->assign('spam', true);
if (isset($categories[$entrydata["category"]]) && $categories[$entrydata['category']] != '') {
$smarty->assign('category_name', $categories[$entrydata["category"]]);
}
if (empty($entrydata['email_contact']))
$entrydata["email_contact"] = 0;
if ($entrydata['hp'] != '') {
$entrydata['hp'] = add_http_if_no_protocol($entrydata['hp']);
$smarty->assign('hp', $entrydata["hp"]);
}
if ($entrydata['email'] != '' && ($isModOrAdmin || $isUser && $entrydata['email_contact'] > 0 || $entrydata['email_contact'] == 2))
$smarty->assign('email', true);
if ($entrydata['location'] != '')
$smarty->assign('location', htmlspecialchars($entrydata['location']));
$subnav_link = array(
'mode' => 'index',
'name' => 'thread_entry_back_link',
'title' => 'thread_entry_back_title'
);
// edited:
if ($entrydata["edited_diff"] > 0 && $entrydata["edited_diff"] > $entrydata["time"] && $settings['show_if_edited'] == 1) {
$smarty->assign('edited', true);
$smarty->assign('edit_time', htmlspecialchars($entrydata['edit_time']));
$smarty->assign('edit_ISO_time', htmlspecialchars($entrydata['edit_ISO_time']));
$entrydata['formated_edit_time'] = format_time($lang['time_format_full'], $entrydata['edit_time']);
$smarty->assign('formated_edit_time', htmlspecialchars($entrydata['formated_edit_time']));
if ($entrydata['user_id'] == $entrydata['edited_by'])
$edited_by = $name;
else {
$result = @mysqli_query($connid, "SELECT user_name FROM " . $db_settings['userdata_table'] . " WHERE user_id = " . intval($entrydata['edited_by']) . " LIMIT 1");
$edited_data = mysqli_fetch_array($result);
@mysqli_free_result($result);
if (!$edited_data['user_name'])
$edited_by = $lang['unknown_user'];
else
$edited_by = htmlspecialchars($edited_data['user_name']);
}
$smarty->assign('edited_by', $edited_by);
}
if (isset($entrydata['signature']) && $entrydata['signature'] != '' && $entrydata["show_signature"] == 1) {
// user has a signature and wants it to be displayed in this posting. Check if it's already cached:
if ($entrydata['cache_signature'] != '') {
$smarty->assign('signature', $entrydata['cache_signature']);
} else {
$signature = signature_format($entrydata['signature']);
// cache signature:
list($row_count) = @mysqli_fetch_row(mysqli_query($connid, "SELECT COUNT(*) FROM " . $db_settings['userdata_cache_table'] . " WHERE cache_id=" . intval($entrydata['user_id'])));
if ($row_count == 1) {
mysqli_query($connid, "UPDATE " . $db_settings['userdata_cache_table'] . " SET cache_signature='" . mysqli_real_escape_string($connid, $signature) . "' WHERE cache_id=" . intval($entrydata['user_id']));
} else {
@mysqli_query($connid, "DELETE FROM " . $db_settings['userdata_cache_table'] . " WHERE cache_id=" . intval($entrydata['user_id']));
@mysqli_query($connid, "INSERT INTO " . $db_settings['userdata_cache_table'] . " (cache_id, cache_signature, cache_profile) VALUES (" . intval($entrydata['user_id']) . ",'" . mysqli_real_escape_string($connid, $signature) . "','')");
}
$smarty->assign('signature', $signature);
}
}
if (isset($branch))
$smarty->assign('branch', $branch);
if (isset($data_array))
$smarty->assign("data", $data_array);
$smarty->assign('posting', $ftext);
$smarty->assign('subnav_link', $subnav_link);
$smarty->assign('page', $page);
$smarty->assign('order', $order);
$smarty->assign('category', $category);
if (isset($_SESSION[$settings['session_prefix'] . 'user_type']) && $_SESSION[$settings['session_prefix'] . 'user_type'] > 0) {
$options['move'] = true;
$options['lock'] = true;
}
if (isset($_SESSION[$settings['session_prefix'] . 'user_id'])) {
if (isset($entrydata['bookmarkedby']))
$options['delete_bookmark'] = true;
else
$options['add_bookmark'] = true;
}
if (isset($_SESSION[$settings['session_prefix'] . 'user_type']) && $_SESSION[$settings['session_prefix'] . 'user_type'] > 0) {
if (($settings['akismet_key'] != '' && $settings['akismet_entry_check'] == 1 && $entrydata['akismet_spam'] == 0 && $entrydata['spam_check_status'] > 0) || ($settings['b8_entry_check'] == 1 && $entrydata['b8_spam'] == 0 || $entrydata['training_type'] == 0))
$options['report_spam'] = true;
if (($settings['akismet_key'] != '' && $settings['akismet_entry_check'] == 1 && $entrydata['akismet_spam'] == 1 && $entrydata['spam_check_status'] > 0) || ($settings['b8_entry_check'] == 1 && $entrydata['b8_spam'] == 1 || $entrydata['training_type'] == 0))
$options['flag_ham'] = true;
}
if(isset($id) && $id > 0)
{
$result=@mysql_query("SELECT id, pid, tid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS disp_time,
UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(edited + INTERVAL ".$time_difference." MINUTE) AS edit_time,
UNIX_TIMESTAMP(edited - INTERVAL ".$settings['edit_delay']." MINUTE) AS edited_diff, edited_by, name, email,
subject, hp, location, ip, text, cache_text, tags, show_signature, category, locked, ip, views, spam, spam_check_status, edit_key,
user_name, user_type, user_email, email_contact, user_hp, user_location, signature, cache_signature
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['entry_cache_table']." ON ".$db_settings['entry_cache_table'].".cache_id=id
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
LEFT JOIN ".$db_settings['userdata_cache_table']." ON ".$db_settings['userdata_cache_table'].".cache_id=".$db_settings['userdata_table'].".user_id
WHERE id = ".$id, $connid) or raise_error('database_error',mysql_error());
if (isset($options))
$smarty->assign('options', $options);
$smarty->assign('subtemplate', 'entry.inc.tpl');
$template = 'main.tpl';
if(mysql_num_rows($result) == 1)
{
$entrydata = mysql_fetch_array($result);
mysql_free_result($result);
$entrydata['formated_time'] = format_time($lang['time_format_full'],$entrydata['disp_time']);
// category of this posting accessible by user?
if(is_array($category_ids) && !in_array($entrydata['category'], $category_ids))
{
header("Location: index.php");
exit;
}
if(isset($settings['count_views']) && $settings['count_views'] == 1) mysql_query("UPDATE ".$db_settings['forum_table']." SET time=time, last_reply=last_reply, edited=edited, views=views+1 WHERE id=".$id, $connid);
save_read(set_read($id));
if($entrydata['user_id'] > 0)
{
if($settings['avatars']==2)
{
if(file_exists('images/avatars/'.$entrydata['user_id'].'.jpg')) $avatar['image'] = 'images/avatars/'.$entrydata['user_id'].'.jpg';
elseif(file_exists('images/avatars/'.$entrydata['user_id'].'.png')) $avatar['image'] = 'images/avatars/'.$entrydata['user_id'].'.png';
elseif(file_exists('images/avatars/'.$entrydata['user_id'].'.gif')) $avatar['image'] = 'images/avatars/'.$entrydata['user_id'].'.gif';
if(isset($avatar))
{
$image_info = getimagesize($avatar['image']);
$avatar['width'] = $image_info[0];
$avatar['height'] = $image_info[1];
$smarty->assign('avatar', $avatar);
}
}
$entrydata['email'] = $entrydata['user_email'];
#$entrydata['email_contact'] = $userdata['email_contact'];
$entrydata['location'] = $entrydata['user_location'];
$entrydata['hp'] = $entrydata['user_hp'];
}
else $entrydata['email_contact']=1;
}
else
{
header("Location: index.php");
exit;
}
}
else
{
header("Location: index.php");
exit;
}
if($entrydata['cache_text']=='')
{
// no cached text so parse it and cache it:
$ftext = html_format($entrydata['text']);
// make sure not to make a double entry:
@mysql_query("DELETE FROM ".$db_settings['entry_cache_table']." WHERE cache_id=".intval($entrydata['id']), $connid);
@mysql_query("INSERT INTO ".$db_settings['entry_cache_table']." (cache_id, cache_text) VALUES (".intval($entrydata['id']).",'".mysql_real_escape_string($ftext)."')", $connid);
}
else
{
$ftext = $entrydata['cache_text'];
}
if(isset($_REQUEST['ajax_preview']))
{
header('Content-Type: application/xml; charset=UTF-8');
echo '<?xml version="1.0"?>';
?><posting><content><![CDATA[<?php echo $ftext; ?>]]></content><locked><?php echo $entrydata['locked']; ?></locked></posting><?php
exit;
}
// thread-data:
$thread = $entrydata['tid'];
if($entrydata['spam']==1) $display_spam_query_and='';
$result = mysql_query("SELECT id, pid, tid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS disp_time,
UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, subject, category, marked, text, spam FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE tid = ".$thread.$display_spam_query_and." ORDER BY time ASC", $connid);
if(!$result) raise_error('database_error',mysql_error());
while($data = mysql_fetch_array($result))
{
if($data['user_id']>0)
{
if(!$data['user_name']) $data['name'] = $lang['unknown_user'];
else $data['name'] = htmlspecialchars($data['user_name']);
}
else $data['name'] = htmlspecialchars($data['name']);
$data['subject'] = htmlspecialchars($data['subject']);
$data['formated_time'] = format_time($lang['time_format'],$data['disp_time']);
if($data['pid']==0)
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime']) && $_SESSION[$settings['session_prefix'].'usersettings']['newtime']<$data['last_reply'] || $last_visit && $data['last_reply'] > $last_visit) $data['new'] = true;
else $data['new'] = false;
}
else
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime']) && $_SESSION[$settings['session_prefix'].'usersettings']['newtime']<$data['time'] || $last_visit && $data['time'] > $last_visit) $data['new'] = true;
else $data['new'] = false;
}
if($data['text']=='') $data['no_text'] = true;
unset($data['text']);
if(isset($categories[$data['category']]) && $categories[$data['category']]!='') $data['category_name']=$categories[$data["category"]];
$data_array[$data['id']] = $data;
$child_array[$data['pid']][] = $data['id'];
if($data['pid']==$id) $direct_replies[] = $data['id'];
$last = $data['id'];
if($data['pid']>$last) $last = $data['id'];
}
if(isset($child_array))
{
$smarty->assign('child_array',$child_array);
get_thread_items($child_array, $entrydata['tid'], $entrydata['id']);
$thread_items_count = count($thread_items);
if($thread_items_count>1)
{
foreach($thread_items as $key => $val)
{
if($val==$entrydata['id']) $current_key = $key;
}
if($entrydata['id']!=$thread_items[0]) $smarty->assign('link_rel_first', 'index.php?id='.$thread_items[0]);
if(isset($thread_items[$current_key-1])) $smarty->assign('link_rel_prev', 'index.php?id='.$thread_items[$current_key-1]);
if(isset($thread_items[$current_key+1])) $smarty->assign('link_rel_next', 'index.php?id='.$thread_items[$current_key+1]);
if($entrydata['id']!=$thread_items[$thread_items_count-1]) $smarty->assign('link_rel_last', 'index.php?id='.$thread_items[$thread_items_count-1]);
}
}
mysql_free_result($result);
// tags:
$tags = $entrydata['tags'];
if($tags!='')
{
$tags_help_array = explode(';',$tags);
$i=0;
foreach($tags_help_array as $tag)
{
if($tag!='')
{
if(my_strpos($tag, ' ', 0, $lang['charset'])) $tag_escaped='"'.$tag.'"';
else $tag_escaped = $tag;
$tags_array[$i]['escaped'] = urlencode($tag_escaped);
$tags_array[$i]['display'] = htmlspecialchars($tag);
$keywords[] = htmlspecialchars($tag);
$i++;
}
}
if(isset($tags_array)) $smarty->assign('tags',$tags_array);
if(isset($keywords)) $smarty->assign('keywords',implode(', ',$keywords));
}
$category = $category;
$smarty->assign('id',$entrydata['id']);
$smarty->assign('tid',$entrydata['tid']);
$smarty->assign('pid',$entrydata['pid']);
$smarty->assign('posting_user_id',$entrydata['user_id']);
$smarty->assign('page_title',htmlspecialchars($entrydata['subject']));
$smarty->assign('subject',htmlspecialchars($entrydata['subject']));
if($entrydata['user_id']>0)
{
if(!$entrydata['user_name']) $name = $lang['unknown_user'];
else $name = htmlspecialchars($entrydata['user_name']);
}
else $name = htmlspecialchars($entrydata['name']);
$smarty->assign('name',$name);
$smarty->assign('user_type',$entrydata['user_type']);
$smarty->assign('disp_time',$entrydata['disp_time']);
$smarty->assign('formated_time',$entrydata['formated_time']);
$smarty->assign('locked',$entrydata['locked']);
$ago['days'] = floor((time() - $entrydata['time'])/86400);
$ago['hours'] = floor(((time() - $entrydata['time'])/3600)-($ago['days']*24));
$ago['minutes'] = floor(((time() - $entrydata['time'])/60)-($ago['hours']*60+$ago['days']*1440));
if($ago['hours']>12) $ago['days_rounded'] = $ago['days'] + 1;
else $ago['days_rounded'] = $ago['days'];
$smarty->assign('ago',$ago);
$authorization = get_edit_authorization($id, $entrydata['user_id'], $entrydata['edit_key'], $entrydata['time'], $entrydata['locked']);
if($authorization['edit']==true) $options['edit'] = true;
if($authorization['delete']==true) $options['delete'] = true;
if(isset($direct_replies)) $smarty->assign('direct_replies',$direct_replies);
if($settings['count_views'] == 1)
{
$views = $entrydata['views']-1; // this subtracts the first view by the author after posting
if($views<0) $views=0; // prevents negative number of views
$smarty->assign('views',$entrydata['views']);
}
$smarty->assign('ip',$entrydata['ip']);
if($entrydata['spam']==1) $smarty->assign('spam',true);
if (isset($categories[$entrydata["category"]]) && $categories[$entrydata['category']]!='')
{
$smarty->assign('category_name',$categories[$entrydata["category"]]);
}
if(empty($entrydata['email_contact'])) $entrydata["email_contact"]=0;
if ($entrydata['hp']!='')
{
$entrydata['hp'] = add_http_if_no_protocol($entrydata['hp']);
$smarty->assign('hp',$entrydata["hp"]);
}
if($entrydata['email']!='' && $entrydata["email_contact"]==1) $smarty->assign('email',true);
if($entrydata['location'] != '') $smarty->assign('location',htmlspecialchars($entrydata['location']));
$subnav_link = array('mode'=>'index', 'name'=>'thread_entry_back_link', 'title'=>'thread_entry_back_title');
// edited:
if($entrydata["edited_diff"] > 0 && $entrydata["edited_diff"] > $entrydata["time"] && $settings['show_if_edited'] == 1)
{
$smarty->assign('edited',true);
$smarty->assign('edit_time',$entrydata['edit_time']);
$entrydata['formated_edit_time'] = format_time($lang['time_format_full'],$entrydata['edit_time']);
$smarty->assign('formated_edit_time',$entrydata['formated_edit_time']);
if($entrydata['user_id'] == $entrydata['edited_by']) $edited_by = $name;
else
{
$result = @mysql_query("SELECT user_name
FROM ".$db_settings['userdata_table']."
WHERE user_id = ".intval($entrydata['edited_by'])." LIMIT 1", $connid);
$edited_data = mysql_fetch_array($result);
@mysql_free_result($result);
if(!$edited_data['user_name']) $edited_by = $lang['unknown_user'];
else $edited_by = htmlspecialchars($edited_data['user_name']);
}
$smarty->assign('edited_by',$edited_by);
}
if(isset($entrydata['signature']) && $entrydata['signature'] != '' && $entrydata["show_signature"]==1)
{
// user has a signature and wants it to be displaed in this posting. Check if it's already cached:
if($entrydata['cache_signature']!='')
{
$smarty->assign('signature',$entrydata['cache_signature']);
}
else
{
$signature = signature_format($entrydata['signature']);
// cache signature:
list($row_count) = @mysql_fetch_row(mysql_query("SELECT COUNT(*) FROM ".$db_settings['userdata_cache_table']." WHERE cache_id=".intval($entrydata['user_id']), $connid));
if($row_count==1)
{
mysql_query("UPDATE ".$db_settings['userdata_cache_table']." SET cache_signature='".mysql_real_escape_string($signature)."' WHERE cache_id=".intval($entrydata['user_id']), $connid);
}
else
{
@mysql_query("DELETE FROM ".$db_settings['userdata_cache_table']." WHERE cache_id=".intval($entrydata['user_id']), $connid);
@mysql_query("INSERT INTO ".$db_settings['userdata_cache_table']." (cache_id, cache_signature, cache_profile) VALUES (".intval($entrydata['user_id']).",'".mysql_real_escape_string($signature)."','')", $connid);
}
$smarty->assign('signature',$signature);
}
}
if(isset($branch)) $smarty->assign('branch',$branch);
if(isset($data_array)) $smarty->assign("data",$data_array);
$smarty->assign('posting',$ftext);
$smarty->assign('subnav_link',$subnav_link);
$smarty->assign('page',$page);
$smarty->assign('order',$order);
$smarty->assign('category',$category);
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0)
{
$options['move'] = true;
$options['lock'] = true;
}
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0 && $settings['akismet_key']!='' && $settings['akismet_entry_check']==1 && $entrydata['spam']==0 && $entrydata['spam_check_status']>0) $options['report_spam'] = true;
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0 && $entrydata['spam']==1) $options['flag_ham'] = true;
if(isset($options)) $smarty->assign('options', $options);
$smarty->assign('subtemplate','entry.inc.tpl');
$template = 'main.tpl';
?>
?>

File diff suppressed because it is too large Load diff

View file

@ -1,221 +1,246 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if(!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['user_view'])) $user_view = $_SESSION[$settings['session_prefix'].'usersettings']['user_view'];
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$tmp_user_id = $_SESSION[$settings['session_prefix'].'user_id'];
} else {
$tmp_user_id = 0;
}
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['user_view'])) $user_view = $_SESSION[$settings['session_prefix'].'usersettings']['user_view'];
else $user_view = $settings['default_view'];
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'])) $fold_threads = $_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'];
else $fold_threads = $settings['fold_threads'];
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'])) $fold_threads = (boolean) $_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'];
else $fold_threads = (boolean) $settings['fold_threads'];
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['thread_order']))
{
if($_SESSION[$settings['session_prefix'].'usersettings']['thread_order']==0) $thread_order = 0;
else $thread_order = 1;
}
elseif(isset($_GET['thread_order']))
{
if(isset($_GET['thread_order'])) $thread_order = 0;
else $thread_order = 1;
}
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['thread_order'])) {
if ($_SESSION[$settings['session_prefix'].'usersettings']['thread_order'] == 0) $thread_order = 0;
else $thread_order = 1;
} elseif (isset($_GET['thread_order'])) {
if (isset($_GET['thread_order'])) $thread_order = 0;
else $thread_order = 1;
}
else $thread_order = 0;
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['category'])) $category = intval($_SESSION[$settings['session_prefix'].'usersettings']['category']);
elseif(isset($_GET['category'])) $category = intval($_GET['category']);
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['category'])) $category = intval($_SESSION[$settings['session_prefix'].'usersettings']['category']);
elseif (isset($_GET['category'])) $category = intval($_GET['category']);
else $category = 0;
if(isset($_GET['page']))
{
$page = intval($_GET['page']);
$_SESSION[$settings['session_prefix'].'usersettings']['page']=$page;
}
elseif(isset($_SESSION[$settings['session_prefix'].'usersettings']['page']))
{
$page = intval($_SESSION[$settings['session_prefix'].'usersettings']['page']);
}
if(empty($page)) $page = 1;
if (isset($_GET['page'])) {
$page = intval($_GET['page']);
$_SESSION[$settings['session_prefix'].'usersettings']['page']=$page;
} elseif (isset($_SESSION[$settings['session_prefix'].'usersettings']['page'])) {
$page = intval($_SESSION[$settings['session_prefix'].'usersettings']['page']);
}
if (empty($page)) $page = 1;
if($thread_order==0) $db_thread_order = 'time';
else $db_thread_order = 'last_reply';
if ($thread_order == 0) $db_thread_order = 'ft.time';
else $db_thread_order = 'ft.last_reply';
$_SESSION[$settings['session_prefix'].'usersettings']['current_page'] = $page;
$descasc="DESC";
$ul = ($page-1) * $settings['threads_per_page'];
$descasc = "DESC";
$ul = ($page - 1) * $settings['threads_per_page'];
// database request
if($categories == false) // no categories defined
{
$result=mysql_query("SELECT id, tid FROM ".$db_settings['forum_table']." WHERE pid = 0".$display_spam_query_and." ORDER BY sticky DESC, ".$db_thread_order." ".$descasc." LIMIT ".$ul.", ".$settings['threads_per_page'], $connid) or raise_error('database_error',mysql_error());
}
elseif(is_array($categories) && $category <= 0) // there are categories and all categories or category selection should be shown
{
if(isset($category_selection_query) && $category==-1) // category selection
{
$category_ids_query = $category_selection_query;
$pid_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE pid = 0".$display_spam_query_and." AND category IN (".$category_ids_query.")", $connid);
list($total_threads) = mysql_fetch_row($pid_result);
mysql_free_result($pid_result);
}
$result=mysql_query("SELECT id, tid FROM ".$db_settings['forum_table']." WHERE pid = 0".$display_spam_query_and." AND category IN (".$category_ids_query.") ORDER BY sticky DESC, ".$db_thread_order." ".$descasc." LIMIT ".$ul.", ".$settings['threads_per_page'], $connid) or raise_error('database_error',mysql_error());
}
elseif(is_array($categories) && $category > 0) // there are categories and only one category should be shown
{
if(in_array($category, $category_ids))
{
$result=mysql_query("SELECT id, tid FROM ".$db_settings['forum_table']." WHERE category = '".mysql_real_escape_string($category)."' AND pid = 0".$display_spam_query_and." ORDER BY sticky DESC, ".$db_thread_order." ".$descasc." LIMIT ".$ul.", ".$settings['threads_per_page'], $connid) or raise_error('database_error',mysql_error());
// how many entries?
$pid_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE pid = 0".$display_spam_query_and." AND category = '".mysql_real_escape_string($category)."'", $connid);
list($total_threads) = mysql_fetch_row($pid_result);
mysql_free_result($pid_result);
}
else // invalid category
{
header('Location: index.php');
exit;
}
}
if ($categories == false) {
// no categories defined
$page_threads_and = "";
}
elseif (is_array($categories)) {
$page_threads_and = "";
if ($category > 0 && !in_array($category, $category_ids)) { // $category_ids defined in main.inc.php
// invalid category
header('Location: index.php');
exit;
}
// there are categories and only one category should be shown
elseif ($category > 0 && in_array($category, $category_ids)) {
// how many entries?
$page_threads_and = " AND (sticky = 2 OR category = '". mysqli_real_escape_string($connid, $category) ."') ";
}
// there are categories and all categories or category selection should be shown
elseif ($category == -1 && isset($category_selection_query)) { // $category_selection_query defined in main.inc.php
// category selection
$category_ids_query = $category_selection_query; // overwrite $category_ids_query, originally defined in main.inc.php
$page_threads_and = " AND (sticky = 2 OR category IN (". mysqli_real_escape_string($connid, $category_ids_query) .")) ";
}
elseif ($category == 0 && isset($category_ids_query)) { // $category_ids_query defined in main.inc.php
// show all categories (restricted to user type)
$page_threads_and = " AND (sticky = 2 OR category IN (". mysqli_real_escape_string($connid, $category_ids_query) .")) ";
}
if (!empty($page_threads_and)) {
$pid_result_sql =
"SELECT COUNT(*) FROM " . $db_settings['forum_table'] . " AS ft
LEFT JOIN (SELECT eid AS id FROM " . $db_settings['akismet_rating_table'] . " WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT eid AS id FROM " . $db_settings['b8_rating_table'] . " WHERE " . $db_settings['b8_rating_table'] . ".spam = 1) AS spam_list ON spam_list.id = ft.id
WHERE pid = 0";
$display_pid_result = $pid_result_sql . $spam_sql_and . $page_threads_and; // $spam_sql_and defined in main.inc.php
$pid_result = mysqli_query($connid, $display_pid_result);
list($total_threads) = mysqli_fetch_row($pid_result);
mysqli_free_result($pid_result);
}
}
$result_count = @mysql_num_rows($result);
if($result_count > 0)
{
while($zeile = mysql_fetch_array($result))
{
$thread_result = @mysql_query("SELECT id, pid, tid, ".$db_settings['forum_table'].".user_id, user_type, UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(time + INTERVAL ".intval($time_difference)." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, subject, IF(text='',true,false) AS no_text, category, views, marked, locked, sticky, spam
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE tid = ".$zeile['tid'].$display_spam_query_and."
ORDER BY time ASC", $connid) or raise_error('database_error',mysql_error());
// put result into arrays:
while($data = mysql_fetch_array($thread_result))
{
// count replies:
if(!isset($replies[$data['tid']])) $replies[$data['tid']] = 0;
else ++$replies[$data['tid']];
if($settings['count_views'] != 0)
{
$data['views'] = $data['views']-1; // this subtracts the first view by the author after posting
if($data['views']<0) $data['views']=0; // prevents negative number of views
}
$display_page_threads =
"SELECT DISTINCT ft.tid, ft.sticky, ft.time, ft.last_reply FROM ".$db_settings['forum_table']." AS ft
LEFT JOIN (SELECT id, tid FROM " . $db_settings['forum_table'] . " INNER JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['forum_table'] . ".id = " . $db_settings['akismet_rating_table'] . ".eid WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT id, tid FROM " . $db_settings['forum_table'] . " INNER JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['forum_table'] . ".id = " . $db_settings['b8_rating_table'] .".eid WHERE " . $db_settings['b8_rating_table'] . ".spam = 1) spam_list ON spam_list.tid = ft.id
WHERE ft.pid = 0";
if($data['user_id']>0)
{
if(!$data['user_name']) $data['name'] = $lang['unknown_user'];
else $data['name'] = htmlspecialchars($data['user_name']);
}
else $data['name'] = htmlspecialchars($data['name']);
if ($show_spam) {
$page_spam = " AND spam_list.id IS NOT NULL";
} else {
$page_spam = " AND IFNULL(spam_list.id, 0) <> ft.tid";
}
$data['subject'] = htmlspecialchars($data['subject']);
if(isset($categories[$data['category']]) && $categories[$data['category']]!='') $data['category_name']=$categories[$data['category']];
$page_threads_SQL = $display_page_threads . $page_spam . $page_threads_and . " ORDER BY sticky DESC, ". $db_thread_order ." ". $descasc ." LIMIT ". intval($ul) .", ". intval($settings['threads_per_page']);
$result = mysqli_query($connid, $page_threads_SQL) or raise_error('database_error', mysqli_error($connid));
// convert formated time to a utf-8:
$data['formated_time'] = format_time($lang['time_format'],$data['timestamp']);
$result_count = @mysqli_num_rows($result);
if ($result_count > 0) {
while ($zeile = mysqli_fetch_array($result)) {
if($data['pid']==0)
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime']) && $_SESSION[$settings['session_prefix'].'usersettings']['newtime']<$data['last_reply'] || $last_visit && $data['last_reply'] > $last_visit) $data['new'] = true;
else $data['new'] = false;
}
else
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime']) && $_SESSION[$settings['session_prefix'].'usersettings']['newtime']<$data['time'] || $last_visit && $data['time'] > $last_visit) $data['new'] = true;
else $data['new'] = false;
}
if ($show_spam) $thread_spam = "";
else $thread_spam = " AND spam_list.id IS NULL";
if($data['pid']==0) $threads[] = $data['id'];
$data_array[$data['id']] = $data;
$child_array[$data['pid']][] = $data['id'];
}
mysql_free_result($thread_result);
}
@mysql_free_result($result);
}
$thread_result_sql =
"SELECT DISTINCT ft.id, ft.pid, ft.tid, ft.user_id, user_type, ft.time AS rawtime, UNIX_TIMESTAMP(ft.time) AS time, UNIX_TIMESTAMP(ft.time + INTERVAL ".intval($time_difference)." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, subject, IF(text='',true,false) AS no_text, category, views, marked, locked, sticky, rst.user_id AS req_user, " . $db_settings['akismet_rating_table'] . ".spam AS akismet_spam, " . $db_settings['b8_rating_table'] . ".spam AS b8_spam, " . $db_settings['akismet_rating_table'] . ".spam_check_status AS akismet_checked, " . $db_settings['b8_rating_table'] . ".training_type AS b8_checked
FROM ".$db_settings['forum_table']." AS ft LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id = ft.user_id LEFT JOIN ".$db_settings['read_status_table']." AS rst ON rst.posting_id = ft.id AND rst.user_id = ". intval($tmp_user_id) ." LEFT JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['akismet_rating_table'] . ".eid = ft.id LEFT JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['b8_rating_table'] . ".eid = ft.id
LEFT JOIN (SELECT ".$db_settings['forum_table'].".id, ".$db_settings['forum_table'].".tid FROM ".$db_settings['forum_table']." INNER JOIN " . $db_settings['akismet_rating_table'] . " ON ".$db_settings['forum_table'].".id = " . $db_settings['akismet_rating_table'] . ".eid WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT ".$db_settings['forum_table'].".id, ".$db_settings['forum_table'].".tid FROM ".$db_settings['forum_table']." INNER JOIN " . $db_settings['b8_rating_table'] . " ON ".$db_settings['forum_table'].".id = " . $db_settings['b8_rating_table'] . ".eid WHERE " . $db_settings['b8_rating_table'] . ".spam = 1) AS spam_list ON spam_list.id = ft.id
WHERE ft.tid = ".$zeile['tid'] . $thread_spam . "
ORDER BY rawtime ASC";
$thread_result = @mysqli_query($connid, $thread_result_sql) or raise_error('database_error', mysqli_error($connid));
// put result into arrays:
while ($data = mysqli_fetch_array($thread_result)) {
// count replies:
if (!isset($replies[$data['tid']])) $replies[$data['tid']] = 0;
else ++$replies[$data['tid']];
// count number of views of single posting, if option is enabled
if ($settings['count_views'] != 0) {
$data['views'] = max($data['views']-1, 0); // this subtracts the first view by the author after posting and prevents negative number of views
// count total number of views of thread
if (!isset($total_views[$data['tid']])) $total_views[$data['tid']] = 0;
$total_views[$data['tid']] += $data['views'];
}
if ($data['user_id'] > 0) {
if (!$data['user_name']) $data['name'] = $lang['unknown_user'];
else $data['name'] = htmlspecialchars($data['user_name']);
}
else
$data['name'] = htmlspecialchars($data['name']);
$data['subject'] = htmlspecialchars($data['subject']);
if (isset($categories[$data['category']]) && $categories[$data['category']] != '')
$data['category_name']=$categories[$data['category']];
// set read or new status of messages
$data = getMessageStatus($data, $last_visit, $fold_threads);
// convert formated time to a utf-8:
$data['formated_time'] = format_time($lang['time_format'], $data['timestamp']);
$data['ISO_time'] = format_time('YYYY-MM-dd HH:mm:ss', $data['time']);
// set key 'not_classified_spam_ham' to decide, if an mod or admin should get notified about need of classification with an icon
if ((isset($_SESSION[$settings['session_prefix'].'user_id']) && isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type'] >= 1) && (($settings['akismet_entry_check'] == 1 && $data['akismet_checked'] == 0) || ($settings['b8_entry_check'] == 1 && $data['b8_checked'] == 0))) {
$data['not_classified_spam_ham'] = 1;
} else {
$data['not_classified_spam_ham'] = 0;
}
// flag spam
$data['spam'] = $data['akismet_spam'] || $data['b8_spam'] ? 1 : 0;
if ($data['pid'] == 0) $threads[] = $data['id'];
$data_array[$data['id']] = $data;
$child_array[$data['pid']][] = $data['id'];
}
mysqli_free_result($thread_result);
}
@mysqli_free_result($result);
}
// latest postings:
if($settings['latest_postings']>0)
{
if($categories == false)
{
$latest_postings_result = @mysql_query("SELECT id, pid, tid, name, user_name, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(time + INTERVAL ".intval($time_difference)." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, subject, category
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE spam=0
ORDER BY time DESC LIMIT ".$settings['latest_postings'], $connid) or raise_error('database_error',mysql_error());
}
else
{
if($category>0)
{
$latest_postings_result = @mysql_query("SELECT id, pid, tid, name, user_name, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(time + INTERVAL ".intval($time_difference)." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, subject, category
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE spam=0 AND category = ".intval($category)."
ORDER BY time DESC LIMIT ".$settings['latest_postings'], $connid) or raise_error('database_error',mysql_error());
}
else
{
$latest_postings_result = @mysql_query("SELECT id, pid, tid, name, user_name, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(time + INTERVAL ".intval($time_difference)." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, subject, category
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE spam=0 AND category IN (".$category_ids_query.")
ORDER BY time DESC LIMIT ".$settings['latest_postings'], $connid) or raise_error('database_error',mysql_error());
}
}
if(mysql_num_rows($latest_postings_result)>0)
{
$i=0;
while($latest_postings_data = mysql_fetch_array($latest_postings_result))
{
$latest_postings[$i]['id'] = intval($latest_postings_data['id']);
$latest_postings[$i]['tid'] = intval($latest_postings_data['tid']);
$latest_postings[$i]['pid'] = intval($latest_postings_data['pid']);
$latest_postings[$i]['subject'] = htmlspecialchars($latest_postings_data['subject']);
if ($settings['latest_postings'] > 0) {
$latest_postings_body_sql =
"SELECT ft.id, ft.pid, ft.tid, name, user_name, ft.user_id, UNIX_TIMESTAMP(ft.time) AS time, UNIX_TIMESTAMP(ft.time + INTERVAL ".intval($time_difference)." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, subject, category, rst.user_id AS req_user, rst.time AS read_time
FROM ".$db_settings['forum_table']." AS ft LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id = ft.user_id LEFT JOIN ".$db_settings['read_status_table']." AS rst ON rst.posting_id = ft.id AND rst.user_id = ". intval($tmp_user_id) ."
LEFT JOIN (SELECT eid AS id FROM " . $db_settings['akismet_rating_table'] . " WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT eid AS id FROM " . $db_settings['b8_rating_table'] . " WHERE " . $db_settings['b8_rating_table'] . ".spam = 1) AS spam_list ON spam_list.id = ft.id WHERE spam_list.id IS NULL";
$latest_postings_order_by_sql = " ORDER BY ft.time DESC LIMIT " . $settings['latest_postings'];
if ($categories == false) {
$latest_postings_category_sql = "";
} else {
if ($category > 0) {
$latest_postings_category_sql = " AND category = " . intval($category);
} else {
$latest_postings_category_sql = " AND category IN (". mysqli_real_escape_string($connid, $category_ids_query) .")";
}
}
$latest_postings_sql = $latest_postings_body_sql . $latest_postings_category_sql . $latest_postings_order_by_sql;
$latest_postings_result = @mysqli_query($connid, $latest_postings_sql) or raise_error('database_error', mysqli_error($connid));
if($latest_postings_data['user_id']>0)
{
if(!$latest_postings_data['user_name']) $latest_postings[$i]['name'] = $lang['unknown_user'];
else $latest_postings[$i]['name'] = htmlspecialchars($latest_postings_data['user_name']);
}
else
{
$latest_postings[$i]['name'] = htmlspecialchars($latest_postings_data['name']);
}
if (mysqli_num_rows($latest_postings_result) > 0) {
$i = 0;
while ($latest_postings_data = mysqli_fetch_array($latest_postings_result)) {
$latest_postings[$i]['id'] = intval($latest_postings_data['id']);
$latest_postings[$i]['tid'] = intval($latest_postings_data['tid']);
$latest_postings[$i]['pid'] = intval($latest_postings_data['pid']);
$latest_postings[$i]['subject'] = htmlspecialchars($latest_postings_data['subject']);
$latest_postings[$i]['timestamp'] = $latest_postings_data['timestamp'];
$latest_postings[$i]['formated_time'] = format_time($lang['time_format'],$latest_postings_data['timestamp']);
if(isset($categories[$latest_postings_data['category']]) && $categories[$latest_postings_data['category']]!='') $latest_postings[$i]['category_name']=$categories[$latest_postings_data['category']];
if ($latest_postings_data['user_id'] > 0) {
if (!$latest_postings_data['user_name']) $latest_postings[$i]['name'] = $lang['unknown_user'];
else $latest_postings[$i]['name'] = htmlspecialchars($latest_postings_data['user_name']);
} else {
$latest_postings[$i]['name'] = htmlspecialchars($latest_postings_data['name']);
}
if ($latest_postings_data['req_user'] !== NULL and is_numeric($latest_postings_data['req_user'])) {
$latest_postings[$i]['is_read'] = true;
} else {
$latest_postings[$i]['is_read'] = false;
}
$ago['days'] = floor((time() - $latest_postings_data['time'])/86400);
$ago['hours'] = floor(((time() - $latest_postings_data['time'])/3600)-($ago['days']*24));
$ago['minutes'] = floor(((time() - $latest_postings_data['time'])/60)-($ago['hours']*60+$ago['days']*1440));
if($ago['hours']>12) $ago['days_rounded'] = $ago['days'] + 1;
else $ago['days_rounded'] = $ago['days'];
$latest_postings[$i]['ago'] = $ago;
$i++;
}
$smarty->assign('latest_postings',$latest_postings);
}
mysql_free_result($latest_postings_result);
}
$latest_postings[$i]['timestamp'] = $latest_postings_data['timestamp'];
$latest_postings[$i]['formated_time'] = format_time($lang['time_format'], $latest_postings_data['timestamp']);
if (isset($categories[$latest_postings_data['category']]) && $categories[$latest_postings_data['category']] != '') $latest_postings[$i]['category_name'] = $categories[$latest_postings_data['category']];
$ago['days'] = floor((TIMESTAMP - $latest_postings_data['time']) / 86400);
$ago['hours'] = floor(((TIMESTAMP - $latest_postings_data['time']) / 3600) - ($ago['days'] * 24));
$ago['minutes'] = floor(((TIMESTAMP - $latest_postings_data['time']) / 60) - ($ago['hours'] * 60 + $ago['days'] * 1440));
if ($ago['hours'] > 12) $ago['days_rounded'] = $ago['days'] + 1;
else $ago['days_rounded'] = $ago['days'];
$latest_postings[$i]['ago'] = $ago;
$i++;
}
$smarty->assign('latest_postings',$latest_postings);
}
mysqli_free_result($latest_postings_result);
}
// Check for unlock users
if (isset($_SESSION[$settings['session_prefix'].'user_id']) && isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type'] >= 1) {
// Pruefe, ob es registrierte aber bisher nicht freigeschaltete Accounts gibt (Anz. der Logins == 0 && Lock-Status == TRUE)
$unlocked_user_result = mysqli_query($connid, "SELECT count(*) AS 'non_activated_users' FROM ".$db_settings['userdata_table']." WHERE logins = 0 AND user_lock = 1 AND activate_code = '' AND (SELECT TRUE FROM ".$db_settings['settings_table']." WHERE name = 'register_mode' AND value = 1) = TRUE") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($unlocked_user_result) > 0 && $row = mysqli_fetch_assoc($unlocked_user_result)) {
$smarty->assign('number_of_non_activated_users', intval($row['non_activated_users']));
}
mysqli_free_result($unlocked_user_result);
}
// tag cloud:
if($settings['tag_cloud']==1) $smarty->assign("tag_cloud",tag_cloud($settings['tag_cloud_day_period'],$settings['tag_cloud_scale_min'],$settings['tag_cloud_scale_max']));
if ($settings['tag_cloud'] == 1) $smarty->assign("tag_cloud", tag_cloud($settings['tag_cloud_day_period'], $settings['tag_cloud_scale_min'], $settings['tag_cloud_scale_max']));
$page_count = ceil($total_threads / $settings['threads_per_page']);
$subnav_link = array('mode'=>'posting', 'title'=>'new_topic_link_title', 'name'=>'new_topic_link');
if(isset($data_array)) $smarty->assign('data',$data_array);
#if(isset($tree)) $smarty->assign("tree",$tree);
if(isset($threads))
{
$smarty->assign("threads",$threads);
$smarty->assign('replies',$replies);
}
if (isset($data_array)) $smarty->assign('data', $data_array);
if (isset($threads)) {
$smarty->assign("threads", $threads);
$smarty->assign('replies', $replies);
if (isset($total_views))
$smarty->assign('total_views', $total_views);
}
if(isset($child_array)) $smarty->assign("child_array",$child_array);
$smarty->assign("page",$page);
@ -229,28 +254,32 @@ $smarty->assign("thread_order",$thread_order);
$smarty->assign("descasc",$descasc);
$smarty->assign('fold_threads',$fold_threads);
if($category!=0) $cqsa = '&amp;category='.$category;
if ($category != 0) $cqsa = '&amp;category='.$category;
else $cqsa = '';
if($page>1)
{
$smarty->assign('link_rel_first', 'index.php?mode=index&amp;page=1'.$cqsa);
$smarty->assign('link_rel_prev', 'index.php?mode=index&amp;page='.($page-1).$cqsa);
}
if($page<$page_count)
{
$smarty->assign('link_rel_next', 'index.php?mode=index&amp;page='.($page+1).$cqsa);
$smarty->assign('link_rel_last', 'index.php?mode=index&amp;page='.$page_count.$cqsa);
}
if ($page > 1) {
$smarty->assign('link_rel_first', 'index.php?mode=index&amp;page=1'.$cqsa);
$smarty->assign('link_rel_prev', 'index.php?mode=index&amp;page='.($page-1).$cqsa);
}
if ($page < $page_count) {
$smarty->assign('link_rel_next', 'index.php?mode=index&amp;page='.($page+1).$cqsa);
$smarty->assign('link_rel_last', 'index.php?mode=index&amp;page='.$page_count.$cqsa);
}
if($total_spam>0 && isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam']))
{
$smarty->assign('hide_spam_link',true);
$smarty->assign('delete_spam_link',true);
}
elseif(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0 && $total_spam>0) $smarty->assign('show_spam_link',true);
// check if SPAM exists and show a link to switch between HAM and SPAM threads
if ($total_spam > 0) {
if (!isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam']))
$smarty->assign('show_spam_link', true);
else //if(isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam']))
$smarty->assign('hide_spam_link',true);
$smarty->assign('delete_spam_link', true);
}
// if no SPAM exists but the option to show SPAM threads is enabled, remove this option
elseif(isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam'])) {
unset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam']);
}
$smarty->assign("subnav_link",$subnav_link);
if($user_view==1) $smarty->assign('subtemplate','index_table.inc.tpl');
else $smarty->assign('subtemplate','index.inc.tpl');
$smarty->assign("subnav_link", $subnav_link);
if ($user_view == 1) $smarty->assign('subtemplate', 'index_table.inc.tpl');
else $smarty->assign('subtemplate', 'index.inc.tpl');
$template = 'main.tpl';
?>

View file

@ -1,9 +0,0 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if($settings['bbcode_flash']==1) $template = 'insert_flash.tpl';
?>

View file

@ -1,41 +1,39 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['theme']) && $smarty->template_exists($_SESSION[$settings['session_prefix'].'usersettings']['theme'].'/main.tpl')) $theme = $_SESSION[$settings['session_prefix'].'usersettings']['theme'];
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['theme']) && $smarty->templateExists($_SESSION[$settings['session_prefix'].'usersettings']['theme'].'/main.tpl')) $theme = $_SESSION[$settings['session_prefix'].'usersettings']['theme'];
else $theme = $settings['theme'];
$theme_config = parse_ini_file('./'.THEMES_DIR.'/'.$theme.'/js_config.ini');
if(isset($_GET['user_type'])) $user_type = intval($_GET['user_type']);
if(isset($user_type) && $user_type > 2) unset($user_type);
if (isset($_GET['user_type'])) $user_type = intval($_GET['user_type']);
if (isset($user_type) && $user_type > 2) unset($user_type);
$smarty->config_load($language_file, 'general');
$lang = $smarty->get_config_vars();
$smarty->configLoad($language_file, 'general');
$lang = $smarty->getConfigVars();
if($settings['ajax_preview'])
{
$template = 'ajax_preview.tpl';
$smarty->assign('theme',$theme);
$ajax_preview_structure = $smarty->fetch($theme.'/'.$template);
$ajax_preview_structure = addslashes(preg_replace("/\015\012|\015|\012/", "", $ajax_preview_structure));
}
if ($settings['ajax_preview']) {
$template = 'ajax_preview.tpl';
$smarty->assign('theme', $theme);
$ajax_preview_structure = $smarty->fetch($theme.'/'.$template);
$ajax_preview_structure = addslashes(preg_replace("/\015\012|\015|\012/", "", $ajax_preview_structure));
}
$expires = 2592000; // 30 days
header("Pragma: public");
header("Cache-Control: maxage=".$expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
header('Expires: ' . gmdate('D, d M Y H:i:s', TIMESTAMP + $expires) . ' GMT');
header('Content-type: application/javascript');
?>var lang = new Array();
<?php if($settings['ajax_preview']): ?>
lang["ajax_preview_title"] = "<?php echo addslashes($lang['ajax_preview_title']); ?>";
lang["close"] = "<?php echo addslashes($lang['close']); ?>";
lang["no_text"] = "<?php echo addslashes($lang['no_text']); ?>";
lang["reply_link"] = "<?php echo addslashes($lang['reply_link']); ?>";
<?php if ($settings['ajax_preview']): ?>
lang["ajax_preview_title"] = "<?php echo addslashes($lang['ajax_preview_title']); ?>";
lang["close"] = "<?php echo addslashes($lang['close']); ?>";
lang["no_text"] = "<?php echo addslashes($lang['no_text']); ?>";
lang["reply_link"] = "<?php echo addslashes($lang['reply_link']); ?>";
<?php endif; ?>
lang["fold_threads"] = "<?php echo addslashes($lang['fold_threads']); ?>";
lang["fold_threads_linktitle"] = "<?php echo addslashes($lang['fold_threads_linktitle']); ?>";
@ -45,41 +43,43 @@ lang["expand_fold_thread_linktitle"] = "<?php echo addslashes($lang['expand_
lang["fold_posting_title"] = "<?php echo addslashes($lang['fold_posting_title']); ?>";
lang["fold_postings"] = "<?php echo addslashes($lang['fold_postings']); ?>";
lang["fold_postings_title"] = "<?php echo addslashes($lang['fold_postings_title']); ?>";
lang["show_password_title"] = "<?php echo addslashes($lang['show_password_title']); ?>";
lang["hide_password_title"] = "<?php echo addslashes($lang['hide_password_title']); ?>";
<?php if(isset($user_type) && $user_type >= 0): ?>
lang["drag_and_drop_title"] = "<?php echo addslashes($lang['drag_and_drop_title']); ?>";
<?php endif; ?>
<?php if($settings['entries_by_users_only']==0 || isset($user_type)): ?>
lang["quote_label"] = "<?php echo addslashes($lang['quote_label']); ?>";
lang["quote_title"] = "<?php echo addslashes($lang['quote_title']); ?>";
<?php if($settings['bbcode']): ?>
lang["bbcode_link_text"] = "<?php echo addslashes($lang['bbcode_link_text']); ?>";
lang["bbcode_link_url"] = "<?php echo addslashes($lang['bbcode_link_url']); ?>";
lang["bbcode_image_url"] = "<?php echo addslashes($lang['bbcode_image_url']); ?>";
<?php if($settings['bbcode_tex']): ?>
<?php endif; ?>
lang["bbcode_tex_code"] = "<?php echo addslashes($lang['bbcode_tex_code']); ?>";
<?php endif; ?>
<?php if($settings['smilies']): ?>
lang["more_smilies_label"] = "<?php echo addslashes($lang['more_smilies_label']); ?>";
lang["more_smilies_title"] = "<?php echo addslashes($lang['more_smilies_title']); ?>";
<?php endif; ?>
lang["error_no_name"] = "<?php echo addslashes($lang['error_no_name']); ?>";
lang["error_no_subject"] = "<?php echo addslashes($lang['error_no_subject']); ?>";
lang["error_no_text"] = "<?php echo addslashes($lang['error_no_text']); ?>";
lang["terms_of_use_error_posting"] = "<?php echo addslashes($lang['terms_of_use_error_posting']); ?>";
lang["quote_label"] = "<?php echo addslashes($lang['quote_label']); ?>";
lang["quote_title"] = "<?php echo addslashes($lang['quote_title']); ?>";
<?php if($settings['bbcode']): ?>
lang["bbcode_link_text"] = "<?php echo addslashes($lang['bbcode_link_text']); ?>";
lang["bbcode_link_url"] = "<?php echo addslashes($lang['bbcode_link_url']); ?>";
lang["bbcode_image_url"] = "<?php echo addslashes($lang['bbcode_image_url']); ?>";
<?php endif; ?>
<?php if($settings['bbcode_latex'] && !empty($settings['bbcode_latex_uri'])): ?>
lang["bbcode_tex_code"] = "<?php echo addslashes($lang['bbcode_tex_code']); ?>";
<?php endif; ?>
<?php if($settings['smilies']): ?>
lang["more_smilies_label"] = "<?php echo addslashes($lang['more_smilies_label']); ?>";
lang["more_smilies_title"] = "<?php echo addslashes($lang['more_smilies_title']); ?>";
<?php endif; ?>
lang["error_no_name"] = "<?php echo addslashes($lang['error_no_name']); ?>";
lang["error_no_subject"] = "<?php echo addslashes($lang['error_no_subject']); ?>";
lang["error_no_text"] = "<?php echo addslashes($lang['error_no_text']); ?>";
lang["terms_of_use_error_posting"] = "<?php echo addslashes($lang['terms_of_use_error_posting']); ?>";
<?php endif; ?>
<?php if(isset($user_type) && $user_type==0 && $settings['user_edit']>0 || !isset($user_type) && $settings['user_edit']==2): ?>
lang["delete_posting_confirm"] = "<?php echo addslashes($lang['delete_posting_confirm']); ?>";
lang["delete_posting_confirm"] = "<?php echo addslashes($lang['delete_posting_confirm']); ?>";
<?php elseif(isset($user_type) && $user_type>0): ?>
lang["delete_posting_confirm"] = "<?php echo addslashes($lang['delete_posting_replies_confirm']); ?>";
lang["delete_posting_confirm"] = "<?php echo addslashes($lang['delete_posting_replies_confirm']); ?>";
<?php endif; ?>
<?php if(isset($user_type) && $user_type>0): ?>
lang["mark_linktitle"] = "<?php echo addslashes($lang['mark_linktitle']); ?>";
lang["unmark_linktitle"] = "<?php echo addslashes($lang['unmark_linktitle']); ?>";
lang["mark_linktitle"] = "<?php echo addslashes($lang['mark_linktitle']); ?>";
lang["unmark_linktitle"] = "<?php echo addslashes($lang['unmark_linktitle']); ?>";
<?php endif; ?>
<?php if(isset($user_type) && $user_type==2): ?>
lang["check_all"] = "<?php echo addslashes($lang['check_all']); ?>";
lang["uncheck_all"] = "<?php echo addslashes($lang['uncheck_all']); ?>";
lang["delete_backup_confirm"] = "<?php echo addslashes($lang['delete_backup_confirm']); ?>";
lang["delete_sel_backup_confirm"] = "<?php echo addslashes($lang['delete_sel_backup_confirm']); ?>";
lang["drag_and_drop_title"] = "<?php echo addslashes($lang['drag_and_drop_title']); ?>";
lang["check_all"] = "<?php echo addslashes($lang['check_all']); ?>";
lang["uncheck_all"] = "<?php echo addslashes($lang['uncheck_all']); ?>";
<?php endif; ?>
var settings = new Array();
@ -93,28 +93,46 @@ settings["expand_thread_inactive_image"] = "<?php echo $theme_config['expand_thr
settings["terms_of_use_popup_width"] = <?php echo $theme_config['terms_of_use_popup_width']; ?>;
settings["terms_of_use_popup_height"] = <?php echo $theme_config['terms_of_use_popup_height']; ?>;
<?php endif; ?>
<?php if($settings['ajax_preview']): ?>
<?php if ($settings['ajax_preview']): ?>
settings["ajaxPreviewStructure"] = "<?php echo $ajax_preview_structure; ?>";
settings["ajax_preview_image"] = "<?php echo $theme_config['ajax_preview_image']; ?>";
settings["ajax_preview_throbber_image"] = "<?php echo $theme_config['ajax_preview_throbber_image']; ?>";
settings["ajax_preview_onmouseover"] = <?php echo ($settings['ajax_preview'] > 1 ? 'true':'false'); ?>;
<?php endif; ?>
<?php if(isset($user_type) && $user_type>0 && $settings['upload_images'] > 0 || isset($user_type) && $settings['upload_images'] > 1 || $settings['upload_images']>2): ?>
<?php if (isset($user_type) && $user_type>0 && $settings['upload_images'] > 0 || isset($user_type) && $settings['upload_images'] > 1 || $settings['upload_images'] > 2): ?>
settings["upload_popup_width"] = <?php echo $theme_config['upload_popup_width']; ?>;
settings["upload_popup_height"] = <?php echo $theme_config['upload_popup_height']; ?>;
<?php endif; ?>
<?php if($settings['bbcode_flash']): ?>
settings["flash_popup_width"] = <?php echo $theme_config['flash_popup_width']; ?>;
settings["flash_popup_height"] = <?php echo $theme_config['flash_popup_height']; ?>;
<?php endif; ?>
<?php if(isset($user_type) && $settings['avatars']): ?>
<?php if (isset($user_type) && $settings['avatars']): ?>
settings["avatar_popup_width"] = <?php echo $theme_config['avatar_popup_width']; ?>;
settings["avatar_popup_height"] = <?php echo $theme_config['avatar_popup_height']; ?>;
<?php endif; ?>
<?php if(isset($user_type) && $user_type>0): ?>
<?php if (isset($user_type) && $user_type > 0): ?>
settings["mark_process_image"] = "<?php echo $theme_config['mark_process_image']; ?>";
settings["marked_image"] = "<?php echo $theme_config['marked_image']; ?>";
settings["unmarked_image"] = "<?php echo $theme_config['unmarked_image']; ?>";
<?php endif; ?>
<?php if (!empty($settings['link_open_target']) && (in_array($settings['link_open_target'], ['_self', '_parent', '_top']) || preg_match("/^[a-z]{1}[a-z0-9\-\_]{1,254}$/iu", $settings['link_open_target']))): ?>
settings["forum_based_link_target"] = "<?php echo $settings['link_open_target']; ?>";
<?php else: ?>
settings["forum_based_link_target"] = "";
<?php endif; ?>
<?php if (isset ($_SESSION[$settings['session_prefix'].'usersettings']['browser_window_target'])): ?>
var user_settings = new Array();
<?php if ($_SESSION[$settings['session_prefix'].'usersettings']['browser_window_target'] == 1): ?>
user_settings["open_links_in_new_window"] = "NONE";
<?php elseif ($_SESSION[$settings['session_prefix'].'usersettings']['browser_window_target'] == 2): ?>
user_settings["open_links_in_new_window"] = "EXTERNAL";
<?php elseif ($_SESSION[$settings['session_prefix'].'usersettings']['browser_window_target'] == 3): ?>
user_settings["open_links_in_new_window"] = "ALL";
<?php else: ?>
user_settings["open_links_in_new_window"] = "DEFAULT";
<?php endif; ?>
<?php else: ?>
var user_settings = new Array();
user_settings["open_links_in_new_window"] = "DEFAULT";
<?php endif; ?>
<?php if(isset($theme_config['preload'])): ?>
var preload = new Array();

View file

@ -1,342 +1,390 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if(!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if(isset($_REQUEST['action'])) $action = $_REQUEST['action'];
if(isset($_POST['pwf_submit'])) $action = 'pw_forgotten_submitted';
if (isset($_REQUEST['action'])) $action = $_REQUEST['action'];
if (isset($_POST['pwf_submit'])) $action = 'pw_forgotten_submitted';
if (isset($_POST['sort_of_agreement']) && $_POST['sort_of_agreement'] === 'dps_agreement') $action = 'dps_agreement';
if (isset($_POST['sort_of_agreement']) && $_POST['sort_of_agreement'] === 'tou_agreement') $action = 'tou_agreement';
// import posted or got username and password:
if(isset($_POST['username']) && trim($_POST['username'])!='') $request_username = $_POST['username'];
elseif(isset($_GET['username']) && trim($_GET['username'])!='') $request_username = $_GET['username'];
if(isset($_POST['userpw']) && trim($_POST['userpw'])!='') $request_userpw = $_POST['userpw'];
elseif(isset($_GET['userpw']) && trim($_GET['userpw'])!='') $request_userpw = $_GET['userpw'];
if (isset($_POST['username']) && trim($_POST['username']) != '') $request_username = $_POST['username'];
elseif (isset($_GET['username']) && trim($_GET['username']) != '') $request_username = $_GET['username'];
if (isset($_POST['userpw']) && trim($_POST['userpw']) != '') $request_userpw = $_POST['userpw'];
elseif (isset($_GET['userpw']) && trim($_GET['userpw']) != '') $request_userpw = $_GET['userpw'];
// look if session is active, if not: login
if(isset($_SESSION[$settings['session_prefix'].'user_id']) && empty($action))
{
$action = "logout";
}
elseif(empty($_SESSION[$settings['session_prefix'].'user_id']) && isset($request_username) && isset($request_userpw))
{
$action = "do_login";
}
elseif(empty($_SESSION[$settings['session_prefix'].'user_id']) && empty($action) && empty($_GET['activate']))
{
$action = "login";
}
elseif(empty($_SESSION[$settings['session_prefix'].'user_id']) && empty($action) && isset($_GET['activate']))
{
$action = "activate";
}
if (isset($_SESSION[$settings['session_prefix'].'user_id']) && empty($action)) {
$action = "logout";
}
elseif (empty($_SESSION[$settings['session_prefix'].'user_id']) && isset($request_username) && isset($request_userpw)) {
$action = "do_login";
}
elseif (empty($_SESSION[$settings['session_prefix'].'user_id']) && empty($action) && empty($_GET['activate'])) {
$action = "login";
}
elseif (empty($_SESSION[$settings['session_prefix'].'user_id']) && empty($action) && isset($_GET['activate'])) {
$action = "activate";
}
if(isset($_GET['login_message'])) $smarty->assign('login_message',$_GET['login_message']);
if (isset($_GET['login_message'])) $smarty->assign('login_message', $_GET['login_message']);
// clear failed logins and check if there are failed logins from this ip:
if($settings['temp_block_ip_after_repeated_failed_logins']==1)
{
@mysql_query("DELETE FROM ".$db_settings['login_control_table']." WHERE time < (NOW()-INTERVAL 10 MINUTE)", $connid);
$failed_logins_result = @mysql_query("SELECT logins FROM ".$db_settings['login_control_table']." WHERE ip='".mysql_real_escape_string($_SERVER["REMOTE_ADDR"])."'", $connid);
if(mysql_num_rows($failed_logins_result)==1)
{
$data = mysql_fetch_array($failed_logins_result);
if($data['logins']>=3) $action = 'ip_temporarily_blocked';
}
mysql_free_result($failed_logins_result);
}
// a value greater than zero is interpreted as time in minutes.
if ($settings['temp_block_ip_after_repeated_failed_logins'] > 0) {
@mysqli_query($connid, "DELETE FROM ".$db_settings['login_control_table']." WHERE time < (NOW()-INTERVAL (SELECT CONVERT(`value`, UNSIGNED INTEGER) FROM ".$db_settings['settings_table']." WHERE `name` = 'temp_block_ip_after_repeated_failed_logins') MINUTE)");
$failed_logins_result = @mysqli_query($connid, "SELECT logins FROM ".$db_settings['login_control_table']." WHERE ip='". mysqli_real_escape_string($connid, $_SERVER["REMOTE_ADDR"]) ."'");
if (mysqli_num_rows($failed_logins_result) == 1) {
$data = mysqli_fetch_array($failed_logins_result);
if ($data['logins'] >= 3) $action = 'ip_temporarily_blocked';
}
mysqli_free_result($failed_logins_result);
}
switch ($action)
{
case "do_login":
if(isset($request_username) && isset($request_userpw))
{
$result = mysql_query("SELECT user_id, user_name, user_pw, user_type, UNIX_TIMESTAMP(last_login) AS last_login, UNIX_TIMESTAMP(last_logout) AS last_logout, thread_order, user_view, sidebar, fold_threads, thread_display, category_selection, auto_login_code, activate_code, language, time_zone, time_difference, theme, entries_read FROM ".$db_settings['userdata_table']." WHERE lower(user_name) = '".mysql_real_escape_string(my_strtolower($request_username, $lang['charset']))."'", $connid) or raise_error('database_error',mysql_error());
if (mysql_num_rows($result) == 1)
{
$feld = mysql_fetch_array($result);
switch ($action) {
case "do_login":
if (isset($request_username) && isset($request_userpw)) {
$result = mysqli_query($connid, "SELECT user_id, user_name, user_pw, user_type, UNIX_TIMESTAMP(last_login) AS last_login, UNIX_TIMESTAMP(last_logout) AS last_logout, thread_order, user_view, sidebar, fold_threads, thread_display, browser_window_target, category_selection, auto_login_code, activate_code, language, time_zone, time_difference, theme, tou_accepted, dps_accepted FROM ".$db_settings['userdata_table']." WHERE lower(user_name) = '". mysqli_real_escape_string($connid, my_strtolower($request_username, $lang['charset'])) ."'") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) == 1) {
$feld = mysqli_fetch_array($result);
if (is_pw_correct($request_userpw, $feld['user_pw'])) {
if (!empty($feld["activate_code"]) && trim($feld["activate_code"]) != '') {
header("location: index.php?mode=login&login_message=account_not_activated");
exit;
}
if(is_pw_correct($request_userpw,$feld['user_pw']))
{
if(trim($feld["activate_code"]) != '')
{
header("location: index.php?mode=login&login_message=account_not_activated");
exit;
}
if (isset($_POST['autologin_checked']) && isset($settings['autologin']) && $settings['autologin'] == 1) {
if (strlen($feld['auto_login_code']) != 50) {
$auto_login_code = random_string(50);
} else {
$auto_login_code = $feld['auto_login_code'];
}
$auto_login_code_cookie = $auto_login_code . intval($feld['user_id']);
setcookie($settings['session_prefix'].'auto_login', $auto_login_code_cookie, cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
$save_auto_login = true;
} else {
setcookie($settings['session_prefix'].'auto_login', '', cookie_options(0));
}
$user_id = $feld["user_id"];
$user_name = $feld["user_name"];
$user_type = $feld["user_type"];
$usersettings['newtime'] = $feld['last_logout'];
$usersettings['user_view'] = $feld['user_view'];
$usersettings['thread_order'] = $feld['thread_order'];
$usersettings['sidebar'] = $feld['sidebar'];
$usersettings['fold_threads'] = $feld['fold_threads'];
$usersettings['thread_display'] = $feld['thread_display'];
$usersettings['page'] = 1;
$usersettings['category'] = 0;
$usersettings['latest_postings'] = 1;
$usersettings['browser_window_target'] = $feld['browser_window_target'];
if (!is_null($feld['category_selection'])) {
$category_selection = explode(',',$feld['category_selection']);
$usersettings['category_selection'] = $category_selection;
}
if($feld['language'] != '') {
$languages = get_languages();
if (isset($languages) && in_array($feld['language'], $languages)) {
$usersettings['language'] = $feld['language'];
$language_update = $feld['language'];
}
}
if (empty($language_update)) $language_update = '';
if(isset($_POST['autologin_checked']) && isset($settings['autologin']) && $settings['autologin'] == 1)
{
if(strlen($feld['auto_login_code'])!=50)
{
$auto_login_code = random_string(50);
}
else
{
$auto_login_code = $feld['auto_login_code'];
}
$auto_login_code_cookie = $auto_login_code . intval($feld['user_id']);
setcookie($settings['session_prefix'].'auto_login',$auto_login_code_cookie,time()+(3600*24*$settings['cookie_validity_days']));
$save_auto_login = true;
}
else
{
setcookie($settings['session_prefix'].'auto_login','',0);
}
$user_id = $feld["user_id"];
$user_name = $feld["user_name"];
$user_type = $feld["user_type"];
#$usersettings['view'] = $feld["user_view"];
$usersettings['newtime'] = $feld['last_logout'];
$usersettings['user_view'] = $feld['user_view'];
$usersettings['thread_order'] = $feld['thread_order'];
$usersettings['sidebar'] = $feld['sidebar'];
$usersettings['fold_threads'] = $feld['fold_threads'];
$usersettings['thread_display'] = $feld['thread_display'];
$usersettings['page'] = 1;
$usersettings['category'] = 0;
$usersettings['latest_postings'] = 1;
if(empty($feld['entries_read'])) $usersettings['read'] = array();
else $usersettings['read'] = explode(',',$feld['entries_read']);
if(!is_null($feld['category_selection']))
{
$category_selection = explode(',',$feld['category_selection']);
$usersettings['category_selection'] = $category_selection;
}
if($feld['language']!='')
{
$languages = get_languages();
if(isset($languages) && in_array($feld['language'], $languages))
{
$usersettings['language'] = $feld['language'];
$language_update = $feld['language'];
}
}
if(empty($language_update)) $language_update = '';
if ($feld['theme'] != '') {
$themes = get_themes();
if (isset($themes) && in_array($feld['theme'], $themes)) {
$usersettings['theme'] = $feld['theme'];
$theme_update = $feld['theme'];
}
}
if (empty($theme_update)) $theme_update = '';
if($feld['theme']!='')
{
$themes = get_themes();
if(isset($themes) && in_array($feld['theme'], $themes))
{
$usersettings['theme'] = $feld['theme'];
$theme_update = $feld['theme'];
}
}
if(empty($theme_update)) $theme_update = '';
if ($feld['time_zone'] != '') {
if (function_exists('date_default_timezone_set') && $time_zones = get_timezones()) {
if (in_array($feld['time_zone'], $time_zones)) {
$usersettings['time_zone'] = $feld['time_zone'];
$time_zone_update = $feld['time_zone'];
}
}
}
if (empty($time_zone_update)) $time_zone_update = '';
if($feld['time_zone']!='')
{
if(function_exists('date_default_timezone_set') && $time_zones = get_timezones())
{
if(in_array($feld['time_zone'], $time_zones))
{
$usersettings['time_zone'] = $feld['time_zone'];
$time_zone_update = $feld['time_zone'];
}
}
}
if(empty($time_zone_update)) $time_zone_update = '';
if (!empty($feld['time_difference'])) $usersettings['time_difference'] = $feld['time_difference'];
if(!empty($feld['time_difference'])) $usersettings['time_difference'] = $feld['time_difference'];
if (isset($read)) $read_before_logged_in = $read; // get read postings from cookie (read before logged in)
if(isset($read)) $read_before_logged_in = $read; // get read postings from cookie (read before logged in)
$_SESSION[$settings['session_prefix'].'user_id'] = $user_id;
$_SESSION[$settings['session_prefix'].'user_name'] = $user_name;
$_SESSION[$settings['session_prefix'].'user_type'] = $user_type;
$_SESSION[$settings['session_prefix'].'usersettings'] = $usersettings;
$_SESSION[$settings['session_prefix'].'user_id'] = $user_id;
$_SESSION[$settings['session_prefix'].'user_name'] = $user_name;
$_SESSION[$settings['session_prefix'].'user_type'] = $user_type;
$_SESSION[$settings['session_prefix'].'usersettings'] = $usersettings;
if(isset($save_auto_login)) {
@mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET logins = logins + 1, last_login = NOW(), last_logout = NOW(), inactivity_notification = FALSE, user_ip = '". mysqli_real_escape_string($connid, $_SERVER['REMOTE_ADDR']) ."', auto_login_code = '". mysqli_real_escape_string($connid, $auto_login_code) ."', pwf_code = '', language = '". mysqli_real_escape_string($connid, $language_update) ."', time_zone = '". mysqli_real_escape_string($connid, $time_zone_update) ."', theme = '". mysqli_real_escape_string($connid, $theme_update) ."' WHERE user_id = ". intval($user_id));
} else {
@mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET logins = logins + 1, last_login = NOW(), last_logout = NOW(), inactivity_notification = FALSE, user_ip = '". mysqli_real_escape_string($connid, $_SERVER['REMOTE_ADDR']) ."', pwf_code = '', language = '". mysqli_real_escape_string($connid, $language_update) ."', time_zone = '". mysqli_real_escape_string($connid, $time_zone_update) ."', theme = '". mysqli_real_escape_string($connid, $theme_update) ."' WHERE user_id = ".intval($user_id));
}
$read = set_read($usersettings['read']);
if(isset($read_before_logged_in)) $read = set_read($read_before_logged_in); // get read postings from cookie (read before logged in)
save_read(false);
if ($db_settings['useronline_table'] != "") {
@mysqli_query($connid, "DELETE FROM ".$db_settings['useronline_table']." WHERE ip = '". mysqli_real_escape_string($connid, $_SERVER['REMOTE_ADDR']) ."'");
}
if(isset($save_auto_login))
{
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET logins=logins+1, last_login=NOW(), last_logout=NOW(), user_ip='".mysql_real_escape_string($_SERVER['REMOTE_ADDR'])."', auto_login_code='".mysql_real_escape_string($auto_login_code)."', pwf_code='', language='".mysql_real_escape_string($language_update)."', time_zone='".mysql_real_escape_string($time_zone_update)."', theme='".mysql_real_escape_string($theme_update)."', entries_read='".mysql_real_escape_string(implode(',',$read))."' WHERE user_id=".intval($user_id), $connid);
}
else
{
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET logins=logins+1, last_login=NOW(), last_logout=NOW(), user_ip='".mysql_real_escape_string($_SERVER['REMOTE_ADDR'])."', pwf_code='', language='".mysql_real_escape_string($language_update)."', time_zone='".mysql_real_escape_string($time_zone_update)."', theme='".mysql_real_escape_string($theme_update)."', entries_read='".mysql_real_escape_string(implode(',',$read))."' WHERE user_id=".intval($user_id), $connid);
}
if ($settings['data_privacy_agreement'] == 1 && $feld['dps_accepted'] === NULL) {
$redir = 'index.php?mode=login&action=dps';
} else if ($settings['terms_of_use_agreement'] == 1 && $feld['tou_accepted'] === NULL) {
$redir = 'index.php?mode=login&action=tou';
} else if (isset($_SESSION[$settings['session_prefix'].'last_visited_uri'])) {
$redir = $_SESSION[$settings['session_prefix'].'last_visited_uri'];
} else if (isset($_POST['back']) && isset($_POST['id'])) {
$redir = 'index.php?mode='.$_POST['back'].'&id='.$_POST['id'].'&back=entry';
} elseif (isset($_POST['back'])) {
$redir = 'index.php?mode='.$_POST['back'];
} elseif (isset($_POST['id'])) {
$redir = 'index.php?id='.$_POST['id'].'&back=entry';
} else {
$redir = 'index.php';
}
// auto delete spam:
if($user_type>0 && $settings['auto_delete_spam']>0) @mysql_query("DELETE FROM ".$db_settings['forum_table']." WHERE time < (NOW() - INTERVAL ".$settings['auto_delete_spam']." HOUR) AND spam=1", $connid);
header('Location: '.$redir);
exit;
} else {
if ($settings['temp_block_ip_after_repeated_failed_logins'] > 0) count_failed_logins();
$action = 'login';
$login_message = 'login_failed';
}
} else {
if ($settings['temp_block_ip_after_repeated_failed_logins'] > 0) count_failed_logins();
$action = 'login';
$login_message = 'login_failed';
}
} else {
if ($settings['temp_block_ip_after_repeated_failed_logins'] > 0) count_failed_logins();
$action = 'login';
$login_message = 'login_failed';
}
break;
case "logout":
log_out($_SESSION[$settings['session_prefix'].'user_id']);
header("location: index.php");
exit;
break;
case "dps":
// the user has to accept (again) the data privacy statement
if ($settings['data_privacy_agreement'] == 1 && isset($_SESSION[$settings['session_prefix'].'user_id'])) {
// user is logged in and accepting of the data privacy statement is necessary
$resultDPS = mysqli_query($connid, "SELECT dps_accepted, tou_accepted FROM ".$db_settings['userdata_table']." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or raise_error('database_error', mysqli_error($connid));
$feld = mysqli_fetch_assoc($resultDPS);
if ($feld['dps_accepted'] === NULL) {
// display the form for accepting the data privacy statement
$action = 'show_dps';
} else {
// data privacy statement was accepted before, redirect
if ($settings['terms_of_use_agreement'] == 1 && $feld['tou_accepted'] === NULL) {
$redir = 'index.php?mode=login&action=tou';
} else if (isset($_SESSION[$settings['session_prefix'].'last_visited_uri'])) {
$redir = $_SESSION[$settings['session_prefix'].'last_visited_uri'];
} else {
$redir = 'index.php';
}
header('Location: '.$redir);
exit;
}
} else {
// redirect to the index view
header("location: index.php");
exit;
}
break;
case "tou":
// the user has to accept (again) the terms of use
if ($settings['terms_of_use_agreement'] == 1 && isset($_SESSION[$settings['session_prefix'].'user_id'])) {
// user is logged in and accepting of the terms of use agreement is necessary
$resultTOU = mysqli_query($connid, "SELECT dps_accepted, tou_accepted FROM ".$db_settings['userdata_table']." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or raise_error('database_error', mysqli_error($connid));
$feld = mysqli_fetch_assoc($resultTOU);
if ($feld['tou_accepted'] === NULL) {
// display the form for accepting the terms of use agreement
$action = 'show_tou';
} else {
// terms of use agreement was accepted before, redirect
if ($settings['data_privacy_agreement'] == 1 && $feld['dps_accepted'] === NULL) {
$redir = 'index.php?mode=login&action=dps';
} else if (isset($_SESSION[$settings['session_prefix'].'last_visited_uri'])) {
$redir = $_SESSION[$settings['session_prefix'].'last_visited_uri'];
} else {
$redir = 'index.php';
}
header('Location: '.$redir);
exit;
}
} else {
// redirect to the index view
header("location: index.php");
exit;
}
break;
case "dps_agreement":
if ($settings['data_privacy_agreement'] == 1 && isset($_POST['agreed']) && isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$resultDPS = mysqli_query($connid, "SELECT dps_accepted, tou_accepted FROM ".$db_settings['userdata_table']." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or raise_error('database_error', mysqli_error($connid));
$feld = mysqli_fetch_assoc($resultDPS);
if ($feld['dps_accepted'] === NULL) {
$writeDPS = mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET dps_accepted = NOW() WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or raise_error('database_error', mysqli_error($connid));
}
// data privacy statement got accepted, redirect
if ($settings['terms_of_use_agreement'] == 1 && $feld['tou_accepted'] === NULL) {
$redir = 'index.php?mode=login&action=tou';
} else if (isset($_SESSION[$settings['session_prefix'].'last_visited_uri'])) {
$redir = $_SESSION[$settings['session_prefix'].'last_visited_uri'];
} else {
$redir = 'index.php';
}
header('Location: '.$redir);
exit;
} else {
if (isset($_SESSION[$settings['session_prefix'].'last_visited_uri'])) {
$redir = $_SESSION[$settings['session_prefix'].'last_visited_uri'];
} else {
$redir = 'index.php';
}
header('Location: '.$redir);
exit;
}
break;
case "tou_agreement":
if ($settings['terms_of_use_agreement'] == 1 && isset($_POST['agreed']) && isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$resultTOU = mysqli_query($connid, "SELECT dps_accepted, tou_accepted FROM ".$db_settings['userdata_table']." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or raise_error('database_error', mysqli_error($connid));
$feld = mysqli_fetch_assoc($resultTOU);
if ($feld['tou_accepted'] === NULL) {
$writeTOU = mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET tou_accepted = NOW() WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or raise_error('database_error', mysqli_error($connid));
}
// terms of use got accepted, redirect
if ($settings['data_privacy_agreement'] == 1 && $feld['dps_accepted'] === NULL) {
$redir = 'index.php?mode=login&action=dps';
} else if (isset($_SESSION[$settings['session_prefix'].'last_visited_uri'])) {
$redir = $_SESSION[$settings['session_prefix'].'last_visited_uri'];
} else {
$redir = 'index.php';
}
header('Location: '.$redir);
exit;
} else {
if (isset($_SESSION[$settings['session_prefix'].'last_visited_uri'])) {
$redir = $_SESSION[$settings['session_prefix'].'last_visited_uri'];
} else {
$redir = 'index.php';
}
header('Location: '.$redir);
exit;
}
break;
case "pw_forgotten_submitted":
if (!empty($_POST['pwf_email']) && trim($_POST['pwf_email']) == '') $error = true;
if (empty($error)) {
$pwf_result = @mysqli_query($connid, "SELECT user_id, user_name, user_email FROM ".$db_settings['userdata_table']." WHERE user_email = '". mysqli_real_escape_string($connid, $_POST['pwf_email']) ."' LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($pwf_result) != 1) $error = true;
else $field = mysqli_fetch_array($pwf_result);
mysqli_free_result($pwf_result);
}
if (empty($error)) {
$pwf_code = random_string(20);
$pwf_code_hash = generate_pw_hash($pwf_code);
$update_result = mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET last_login = last_login, registered = registered, pwf_code = '". mysqli_real_escape_string($connid, $pwf_code_hash) ."' WHERE user_id = ". intval($field['user_id']) ." LIMIT 1");
// send mail with activating link:
$smarty->configLoad($settings['language_file'], 'emails');
$lang = $smarty->getConfigVars();
$lang['pwf_activating_email_txt'] = str_replace("[name]", $field["user_name"], $lang['pwf_activating_email_txt']);
$lang['pwf_activating_email_txt'] = str_replace("[forum_address]", $settings['forum_address'], $lang['pwf_activating_email_txt']);
$lang['pwf_activating_email_txt'] = str_replace("[activating_link]", $settings['forum_address'].basename($_SERVER['PHP_SELF'])."?mode=login&activate=".$field["user_id"]."&code=".$pwf_code, $lang['pwf_activating_email_txt']);
if ($db_settings['useronline_table'] != "")
{
@mysql_query("DELETE FROM ".$db_settings['useronline_table']." WHERE ip = '".$_SERVER['REMOTE_ADDR']."'", $connid);
}
if (my_mail($field["user_email"], $lang['pwf_activating_email_sj'], $lang['pwf_activating_email_txt'])) {
header("location: index.php?mode=login&login_message=mail_sent");
exit;
} else {
header("Location: index.php?mode=login&login_message=mail_error");
exit;
}
}
header("Location: index.php?mode=login&login_message=pwf_failed");
exit;
break;
case "activate":
if (isset($_GET['activate']) && trim($_GET['activate']) != "" && isset($_GET['code']) && trim($_GET['code']) != "") {
$pwf_result = mysqli_query($connid, "SELECT user_id, user_name, user_email, pwf_code FROM ".$db_settings['userdata_table']." WHERE user_id = ". intval($_GET["activate"]));
if (!$pwf_result) raise_error('database_error', mysqli_error($connid));
$field = mysqli_fetch_array($pwf_result);
mysqli_free_result($pwf_result);
if (!empty($field['pwf_code']) && trim($field['pwf_code']) != '' && $field['user_id'] == $_GET['activate'] && is_pw_correct($_GET['code'],$field['pwf_code'])) {
// generate new password:
if ($settings['min_pw_length'] < 8) $pwl = 8;
else $pwl = $settings['min_pw_length'];
$new_pw = random_string($pwl);
$pw_hash = generate_pw_hash($new_pw);
$update_result = mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET last_login = last_login, registered = registered, user_pw = '". mysqli_real_escape_string($connid, $pw_hash) ."', pwf_code = '' WHERE user_id = ". intval($field["user_id"]) ." LIMIT 1");
if(isset($_POST['back']) && isset($_POST['id']))
{
$redir_qs = '?mode='.$_POST['back'].'&id='.$_POST['id'].'&back=entry';;
}
elseif(isset($_POST['back']))
{
$redir_qs = '?mode='.$_POST['back'];
}
elseif(isset($_POST['id']))
{
$redir_qs = '?id='.$_POST['id'].'&back=entry';
}
else
{
$redir_qs = '';
}
// send new password:
$smarty->configLoad($settings['language_file'], 'emails');
$lang = $smarty->getConfigVars();
header('Location: index.php'.$redir_qs);
exit;
}
else
{
if($settings['temp_block_ip_after_repeated_failed_logins']==1) count_failed_logins();
#header("location: index.php?mode=login&login_message=login_failed");
#exit;
$action = 'login';
$login_message='login_failed';
}
}
else
{
if($settings['temp_block_ip_after_repeated_failed_logins']==1) count_failed_logins();
#header("location: index.php?mode=login&login_message=login_failed");
#exit;
$action = 'login';
$login_message='login_failed';
}
}
else
{
if($settings['temp_block_ip_after_repeated_failed_logins']==1) count_failed_logins();
#header("location: index.php?mode=login&login_message=login_failed");
#exit;
$action = 'login';
$login_message='login_failed';
}
break;
$lang['new_pw_email_txt'] = str_replace("[name]", $field['user_name'], $lang['new_pw_email_txt']);
$lang['new_pw_email_txt'] = str_replace("[password]", $new_pw, $lang['new_pw_email_txt']);
$lang['new_pw_email_txt'] = str_replace("[login_link]", $settings['forum_address'].basename($_SERVER['PHP_SELF'])."?mode=login&username=". urlencode($field['user_name']) ."&userpw=".$new_pw, $lang['new_pw_email_txt']);
$lang['new_pw_email_txt'] = $lang['new_pw_email_txt'];
case "logout":
log_out($_SESSION[$settings['session_prefix'].'user_id']);
header("location: index.php");
exit;
break;
case "pw_forgotten_submitted":
if(trim($_POST['pwf_email'])=='') $error=true;
if(empty($error))
{
$pwf_result = @mysql_query("SELECT user_id, user_name, user_email FROM ".$db_settings['userdata_table']." WHERE user_email = '".mysql_real_escape_string($_POST['pwf_email'])."' LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($pwf_result)!=1) $error=true;
else $field = mysql_fetch_array($pwf_result);
mysql_free_result($pwf_result);
}
if(empty($error))
{
$pwf_code = random_string(20);
$pwf_code_hash = generate_pw_hash($pwf_code);
$update_result = mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_login=last_login, registered=registered, pwf_code='".mysql_real_escape_string($pwf_code_hash)."' WHERE user_id = ".intval($field['user_id'])." LIMIT 1", $connid);
// send mail with activating link:
$smarty->config_load($settings['language_file'],'emails');
$lang = $smarty->get_config_vars();
$lang['pwf_activating_email_txt'] = str_replace("[name]", $field["user_name"], $lang['pwf_activating_email_txt']);
$lang['pwf_activating_email_txt'] = str_replace("[forum_address]", $settings['forum_address'], $lang['pwf_activating_email_txt']);
$lang['pwf_activating_email_txt'] = str_replace("[activating_link]", $settings['forum_address'].basename($_SERVER['PHP_SELF'])."?mode=login&activate=".$field["user_id"]."&code=".$pwf_code, $lang['pwf_activating_email_txt']);
if(my_mail($field["user_email"], $lang['pwf_activating_email_sj'], $lang['pwf_activating_email_txt']))
{
header("location: index.php?mode=login&login_message=mail_sent");
exit;
}
else
{
header("Location: index.php?mode=login&login_message=mail_error");
exit;
}
}
header("Location: index.php?mode=login&login_message=pwf_failed");
exit;
break;
case "activate":
if(isset($_GET['activate']) && trim($_GET['activate']) != "" && isset($_GET['code']) && trim($_GET['code']) != "")
{
$pwf_result = mysql_query("SELECT user_id, user_name, user_email, pwf_code FROM ".$db_settings['userdata_table']." WHERE user_id = '".intval($_GET["activate"])."'", $connid);
if (!$pwf_result) raise_error('database_error',mysql_error());
$field = mysql_fetch_array($pwf_result);
mysql_free_result($pwf_result);
if(trim($field['pwf_code'])!='' && $field['user_id'] == $_GET['activate'] && is_pw_correct($_GET['code'],$field['pwf_code']))
{
// generate new password:
if($settings['min_pw_length']<8) $pwl = 8;
else $pwl = $settings['min_pw_length'];
$new_pw = random_string($pwl);
$pw_hash = generate_pw_hash($new_pw);
$update_result = mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_login=last_login, registered=registered, user_pw='".mysql_real_escape_string($pw_hash)."', pwf_code='' WHERE user_id='".$field["user_id"]."' LIMIT 1", $connid);
// send new password:
$smarty->config_load($settings['language_file'],'emails');
$lang = $smarty->get_config_vars();
$lang['new_pw_email_txt'] = str_replace("[name]", $field['user_name'], $lang['new_pw_email_txt']);
$lang['new_pw_email_txt'] = str_replace("[password]", $new_pw, $lang['new_pw_email_txt']);
$lang['new_pw_email_txt'] = str_replace("[login_link]", $settings['forum_address'].basename($_SERVER['PHP_SELF'])."?mode=login&username=".urlencode($field['user_name'])."&userpw=".$new_pw, $lang['new_pw_email_txt']);
$lang['new_pw_email_txt'] = $lang['new_pw_email_txt'];
#$header = "From: ".my_mb_encode_mimeheader($settings['forum_name'], CHARSET, "Q")." <".$settings['forum_email'].">". MAIL_HEADER_SEPARATOR;
#$header .= "Content-Type: text/plain; charset=" . CHARSET . MAIL_HEADER_SEPARATOR;
#$header .= "Content-transfer-encoding: 8bit". MAIL_HEADER_SEPARATOR;
if(my_mail($field['user_email'], $lang['new_pw_email_sj'], $lang['new_pw_email_txt']))
{
header("location: index.php?mode=login&login_message=pw_sent");
exit;
}
else
{
echo $lang['mail_error'];
exit;
}
}
else
{
header("location: index.php?mode=login&login_message=code_invalid");
exit;
}
}
else
{
header("location: index.php?mode=login&login_message=code_invalid");
exit;
}
break;
}
if (my_mail($field['user_email'], $lang['new_pw_email_sj'], $lang['new_pw_email_txt'])) {
header("location: index.php?mode=login&login_message=pw_sent");
exit;
} else {
echo $lang['mail_error'];
exit;
}
} else {
header("location: index.php?mode=login&login_message=code_invalid");
exit;
}
} else {
header("location: index.php?mode=login&login_message=code_invalid");
exit;
}
break;
}
$smarty->assign('action',$action);
switch($action)
{
case "login":
$smarty->assign('subnav_location','subnav_login');
$smarty->assign('subtemplate','login.inc.tpl');
if(isset($login_message)) $smarty->assign('login_message',$login_message);
if(isset($_REQUEST['id'])) $smarty->assign('id',intval($_REQUEST['id']));
if(isset($_REQUEST['back'])) $smarty->assign('back',htmlspecialchars($_REQUEST['back']));
$template = 'main.tpl';
break;
case "pw_forgotten":
$breadcrumbs[0]['link'] = 'index.php?mode=login';
$breadcrumbs[0]['linkname'] = 'subnav_login';
$smarty->assign('breadcrumbs',$breadcrumbs);
$smarty->assign('subnav_location','subnav_pw_forgotten');
$smarty->assign('subtemplate','login_pw_forgotten.inc.tpl');
$template = 'main.tpl';
break;
case "ip_temporarily_blocked":
$smarty->assign('ip_temporarily_blocked',true);
$smarty->assign('subnav_location','subnav_login');
$smarty->assign('subtemplate','login.inc.tpl');
$template = 'main.tpl';
break;
}
switch($action) {
case "login":
$smarty->assign('subnav_location', 'subnav_login');
$smarty->assign('subtemplate', 'login.inc.tpl');
if (isset($login_message)) $smarty->assign('login_message', $login_message);
if (isset($_REQUEST['id'])) $smarty->assign('id', intval($_REQUEST['id']));
if (isset($_REQUEST['back'])) $smarty->assign('back', htmlspecialchars($_REQUEST['back']));
$template = 'main.tpl';
break;
case "pw_forgotten":
$breadcrumbs[0]['link'] = 'index.php?mode=login';
$breadcrumbs[0]['linkname'] = 'subnav_login';
$smarty->assign('breadcrumbs', $breadcrumbs);
$smarty->assign('subnav_location', 'subnav_pw_forgotten');
$smarty->assign('subtemplate', 'login_pw_forgotten.inc.tpl');
$template = 'main.tpl';
break;
case "ip_temporarily_blocked":
$smarty->assign('ip_temporarily_blocked', true);
$smarty->assign('subnav_location', 'subnav_login');
$smarty->assign('subtemplate', 'login.inc.tpl');
$template = 'main.tpl';
break;
case "show_dps":
$smarty->assign('show_dps_page', true);
$smarty->assign('subnav_location', 'subnav_accept_dps');
$smarty->assign('subtemplate', 'user_agreement.inc.tpl');
$template = 'main.tpl';
break;
case "show_tou":
$smarty->assign('show_tou_page', true);
$smarty->assign('subnav_location', 'subnav_accept_tou');
$smarty->assign('subtemplate', 'user_agreement.inc.tpl');
$template = 'main.tpl';
break;
}
?>

33
includes/mailer.inc.php Normal file
View file

@ -0,0 +1,33 @@
<?php
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
//Import the PHPMailer class into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
//use PHPMailer\PHPMailer\OAuthTokenProvider;
//use PHPMailer\PHPMailer\OAuth;
//use PHPMailer\PHPMailer\POP3;
// include php resources
require 'modules/phpmailer/PHPMailer.php';
require 'modules/phpmailer/Exception.php';
require 'modules/phpmailer/SMTP.php';
//require 'modules/phpmailer/OAuthTokenProvider.php';
//require 'modules/phpmailer/OAuth.php';
//require 'modules/phpmailer/POP3.php';
// include config
require 'config/php_mailer.php';
// create instance
$PHP_MAILER = new PHPMailer();
// add specified properties
foreach($PHP_MAILER_CONFIG as $key => $value) {
$PHP_MAILER->set($key, $value);
}
?>

View file

@ -1,376 +1,293 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
// set current time:
$current_time = time();
// stripslashes on GPC if magic_quotes_gpc is enabled:
if(get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
$value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
return $value;
}
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
// database connection:
$connid = connect_db($db_settings['host'], $db_settings['user'], $db_settings['password'], $db_settings['database']);
// set current timestamp:
list($timestamp) = mysqli_fetch_row(mysqli_query($connid, "SELECT UNIX_TIMESTAMP(NOW())"));
define('TIMESTAMP', $timestamp);
// get settings:
$settings = get_settings();
// get read postings:
$read = get_read();
// CSRF protection token
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = $uniqid = uniqid('', true);
}
// auto login:
if(!isset($_SESSION[$settings['session_prefix'].'user_id']) && isset($_COOKIE[$settings['session_prefix'].'auto_login']) && isset($settings['autologin']) && $settings['autologin'] == 1)
{
include('includes/auto_login.inc.php');
}
// Bad Behavior check:
if($settings['bad_behavior']==1 && !isset($_SESSION[$settings['session_prefix'].'user_id']))
{
require_once("modules/bad-behavior/bad-behavior-generic.php");
}
if (!isset($_SESSION[$settings['session_prefix'].'user_id']) && isset($_COOKIE[$settings['session_prefix'].'auto_login']) && isset($settings['autologin']) && $settings['autologin'] == 1) {
include('includes/auto_login.inc.php');
}
// access permission checks for not registered users:
if($settings['access_permission_checks']==1 && !isset($_SESSION[$settings['session_prefix'].'user_id']))
{
// look if IP or user agent is banned:
$ip_result=mysql_query("SELECT name, list FROM ".$db_settings['banlists_table']." WHERE name = 'ips' OR name = 'user_agents'", $connid) or raise_error('database_error',mysql_error());
while($data = mysql_fetch_array($ip_result))
{
if($data['name'] == 'ips') $ips = $data['list'];
if($data['name'] == 'user_agents') $user_agents = $data['list'];
}
mysql_free_result($ip_result);
if(isset($ips) && trim($ips) != '')
{
#$banned_ips = preg_split('/\015\012|\015|\012/',$ips);
$banned_ips = explode("\n",$ips);
if(is_ip_banned($_SERVER['REMOTE_ADDR'], $banned_ips)) raise_error('403');
}
if(isset($user_agents) && trim($user_agents) != '')
{
#$banned_user_agents = preg_split('/\015\012|\015|\012/',$user_agents);
$banned_user_agents = explode("\n",$user_agents);
if(is_user_agent_banned($_SERVER['HTTP_USER_AGENT'], $banned_user_agents)) raise_error('403');
}
}
if ($settings['access_permission_checks'] == 1 && !isset($_SESSION[$settings['session_prefix'].'user_id'])) {
// look if IP or user agent is banned:
$ip_result = mysqli_query($connid, "SELECT name, list FROM ".$db_settings['banlists_table']." WHERE name = 'ips' OR name = 'user_agents'") or raise_error('database_error', mysqli_error($connid));
while ($data = mysqli_fetch_array($ip_result)) {
if ($data['name'] == 'ips') $ips = $data['list'];
if ($data['name'] == 'user_agents') $user_agents = $data['list'];
}
mysqli_free_result($ip_result);
if (isset($ips) && !empty($ips) && trim($ips) != '') {
$banned_ips = explode("\n",$ips);
if (is_ip_banned($_SERVER['REMOTE_ADDR'], $banned_ips)) raise_error('403');
}
if (isset($user_agents) && !empty($user_agents) && trim($user_agents) != '') {
$banned_user_agents = explode("\n", $user_agents);
if (is_user_agent_banned($_SERVER['HTTP_USER_AGENT'], $banned_user_agents)) raise_error('403');
}
}
// look if user blocked:
if(isset($_SESSION[$settings['session_prefix'].'user_id']))
{
$block_result=mysql_query("SELECT user_lock FROM ".$db_settings['userdata_table']." WHERE user_id = ".intval($_SESSION[$settings['session_prefix'].'user_id'])." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
$data = mysql_fetch_array($block_result);
mysql_free_result($block_result);
if($data['user_lock']==1)
{
log_out($_SESSION[$settings['session_prefix'].'user_id'],'account_locked');
}
}
// do daily actions:
daily_actions($current_time);
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$block_result = mysqli_query($connid, "SELECT user_lock FROM ".$db_settings['userdata_table']." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id']) ." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
$data = mysqli_fetch_array($block_result);
mysqli_free_result($block_result);
if ($data['user_lock'] == 1) {
log_out($_SESSION[$settings['session_prefix'].'user_id'], 'account_locked');
}
}
// set time zone:
if(function_exists('date_default_timezone_set'))
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['time_zone']) && $_SESSION[$settings['session_prefix'].'usersettings']['time_zone']!='')
{
date_default_timezone_set($_SESSION[$settings['session_prefix'].'usersettings']['time_zone']);
$forum_time_zone = $_SESSION[$settings['session_prefix'].'usersettings']['time_zone'];
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['time_difference']) && $_SESSION[$settings['session_prefix'].'usersettings']['time_difference']!=0)
{
if($_SESSION[$settings['session_prefix'].'usersettings']['time_difference']>0) $uds = '+'; else $uds = '-';
$udm = abs($_SESSION[$settings['session_prefix'].'usersettings']['time_difference']);
$udh = floor($udm / 60);
$udmr = $udm - $udh*60;
if($udmr<10) $udmr = '0'.$udmr;
$udf = $uds.$udh.':'.$udmr;
$forum_time_zone = $_SESSION[$settings['session_prefix'].'usersettings']['time_zone'].' '.$udf;
}
else
{
$forum_time_zone = $_SESSION[$settings['session_prefix'].'usersettings']['time_zone'];
}
}
elseif($settings['time_zone']!='')
{
date_default_timezone_set($settings['time_zone']);
$forum_time_zone = $settings['time_zone'];
}
}
if (function_exists('date_default_timezone_set')) {
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['time_zone']) && $_SESSION[$settings['session_prefix'].'usersettings']['time_zone'] != '') {
date_default_timezone_set($_SESSION[$settings['session_prefix'].'usersettings']['time_zone']);
$forum_time_zone = $_SESSION[$settings['session_prefix'].'usersettings']['time_zone'];
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['time_difference']) && $_SESSION[$settings['session_prefix'].'usersettings']['time_difference'] != 0) {
if ($_SESSION[$settings['session_prefix'].'usersettings']['time_difference'] > 0) $uds = '+'; else $uds = '-';
$udm = abs($_SESSION[$settings['session_prefix'].'usersettings']['time_difference']);
$udh = floor($udm / 60);
$udmr = $udm - $udh * 60;
if ($udmr < 10) $udmr = '0'.$udmr;
$udf = $uds.$udh.':'.$udmr;
$forum_time_zone = $_SESSION[$settings['session_prefix'].'usersettings']['time_zone'].' '.$udf;
} else {
$forum_time_zone = $_SESSION[$settings['session_prefix'].'usersettings']['time_zone'];
}
} elseif($settings['time_zone'] != '') {
date_default_timezone_set($settings['time_zone']);
$forum_time_zone = $settings['time_zone'];
} else {
date_default_timezone_set('UTC');
$forum_time_zone = 'UTC';
}
}
// do daily actions:
//daily_actions(TIMESTAMP);
$categories = get_categories();
$category_ids = get_category_ids($categories);
if($category_ids!=false) $category_ids_query = implode(', ', $category_ids);
if(empty($category)) $category=0;
if ($category_ids != false) $category_ids_query = implode(', ', $category_ids);
if (empty($category)) $category = 0;
// user settings:
if(isset($_COOKIE[$settings['session_prefix'].'usersettings']))
{
$usersettings_cookie = explode('.',$_COOKIE[$settings['session_prefix'].'usersettings']);
}
if (isset($_COOKIE[$settings['session_prefix'].'usersettings'])) {
$usersettings_cookie = explode('.', $_COOKIE[$settings['session_prefix'].'usersettings']);
}
if(empty($_SESSION[$settings['session_prefix'].'usersettings']))
{
if(isset($usersettings_cookie[0]))
{
$usersettings['user_view'] = $usersettings_cookie[0]==1 ? 1 : 0;
}
else
{
$usersettings['user_view'] = $settings['default_view'];
}
$usersettings['thread_order'] = isset($usersettings_cookie[1]) && $usersettings_cookie[1]==1 ? 1 : 0;
$usersettings['sidebar'] = isset($usersettings_cookie[2]) && $usersettings_cookie[2]==0 ? 0 : 1;
if(isset($usersettings_cookie[3]))
{
$usersettings['fold_threads'] = $usersettings_cookie[3]==1 ? 1 : 0;
}
else
{
$usersettings['fold_threads'] = $settings['fold_threads'];
}
$usersettings['thread_display'] = isset($usersettings_cookie[4]) && $usersettings_cookie[4]==1 ? 1 : 0;
$usersettings['page'] = 1;
$usersettings['category'] = 0;
$_SESSION[$settings['session_prefix'].'usersettings'] = $usersettings;
setcookie($settings['session_prefix'].'usersettings',$_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'],time()+(3600*24*$settings['cookie_validity_days']));
}
if (empty($_SESSION[$settings['session_prefix'].'usersettings'])) {
if (isset($usersettings_cookie[0])) {
$usersettings['user_view'] = $usersettings_cookie[0] == 1 ? 1 : 0;
} else {
$usersettings['user_view'] = $settings['default_view'];
}
$usersettings['thread_order'] = isset($usersettings_cookie[1]) && $usersettings_cookie[1] == 1 ? 1 : 0;
$usersettings['sidebar'] = isset($usersettings_cookie[2]) && $usersettings_cookie[2] == 0 ? 0 : 1;
if(isset($usersettings_cookie[3])) {
$usersettings['fold_threads'] = $usersettings_cookie[3] == 1 ? 1 : 0;
} else {
$usersettings['fold_threads'] = $settings['fold_threads'];
}
$usersettings['thread_display'] = isset($usersettings_cookie[4]) && $usersettings_cookie[4] == 1 ? 1 : 0;
$usersettings['page'] = 1;
$usersettings['category'] = 0;
$_SESSION[$settings['session_prefix'].'usersettings'] = $usersettings;
setcookie($settings['session_prefix'].'usersettings', $_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'], cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
}
if(isset($_REQUEST['toggle_sidebar']))
{
if(empty($_SESSION[$settings['session_prefix'].'usersettings']['sidebar'])) $_SESSION[$settings['session_prefix'].'usersettings']['sidebar']=1;
else $_SESSION[$settings['session_prefix'].'usersettings']['sidebar']=0;
setcookie($settings['session_prefix'].'usersettings',$_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'],time()+(3600*24*$settings['cookie_validity_days']));
// update database for registered users:
if(isset($_SESSION[$settings['session_prefix'].'user_id']))
{
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_login=last_login, last_logout=last_logout, registered=registered, sidebar = ".intval($_SESSION[$settings['session_prefix'].'usersettings']['sidebar'])." WHERE user_id=".intval($_SESSION[$settings['session_prefix'].'user_id']), $connid);
}
if (isset($_REQUEST['toggle_sidebar'])) {
if (empty($_SESSION[$settings['session_prefix'].'usersettings']['sidebar'])) $_SESSION[$settings['session_prefix'].'usersettings']['sidebar'] = 1;
else $_SESSION[$settings['session_prefix'].'usersettings']['sidebar'] = 0;
setcookie($settings['session_prefix'].'usersettings', $_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'], cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
// update database for registered users:
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
@mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET last_login = last_login, last_logout = last_logout, registered = registered, sidebar = ". intval($_SESSION[$settings['session_prefix'].'usersettings']['sidebar']) ." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id']));
}
if(isset($_POST['toggle_sidebar'])) exit; // AJAX request
if (isset($_POST['toggle_sidebar'])) exit; // AJAX request
if(isset($_GET['category']) && isset($_GET['page']) && isset($_GET['order'])) $q = '?page='.$_GET['page'].'&category='.$_GET['category'].'&order='.$_GET['order']; else $q = '';
header('location: index.php'.$q);
exit;
}
if (isset($_GET['category']) && isset($_GET['page']) && isset($_GET['order'])) $q = '?page='.$_GET['page'].'&category='.$_GET['category'].'&order='.$_GET['order']; else $q = '';
header('location: index.php'.$q);
exit;
}
if(isset($_GET['thread_order']) && isset($_SESSION[$settings['session_prefix'].'usersettings']['thread_order']))
{
$page = 1;
if($_GET['thread_order']==1) $thread_order = 1;
else $thread_order = 0;
if($thread_order != $_SESSION[$settings['session_prefix'].'usersettings']['thread_order'])
{
$_SESSION[$settings['session_prefix'].'usersettings']['page']=1;
$_SESSION[$settings['session_prefix'].'usersettings']['thread_order']=$thread_order;
setcookie($settings['session_prefix'].'usersettings',$_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$thread_order.'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'],time()+(3600*24*$settings['cookie_validity_days']));
if(isset($_SESSION[$settings['session_prefix'].'user_id'])) @mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_login=last_login, last_logout=last_logout, registered=registered, thread_order=".intval($thread_order)." WHERE user_id='".intval($_SESSION[$settings['session_prefix'].'user_id'])."'", $connid);
}
}
if (isset($_GET['thread_order']) && isset($_SESSION[$settings['session_prefix'].'usersettings']['thread_order'])) {
$page = 1;
if ($_GET['thread_order'] == 1) $thread_order = 1;
else $thread_order = 0;
if ($thread_order != $_SESSION[$settings['session_prefix'].'usersettings']['thread_order']) {
$_SESSION[$settings['session_prefix'].'usersettings']['page'] = 1;
$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'] = $thread_order;
setcookie($settings['session_prefix'].'usersettings', $_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$thread_order.'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'], cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) @mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET last_login = last_login, last_logout = last_logout, registered = registered, thread_order = ". intval($thread_order) ." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id']));
}
}
if (isset($_SESSION[$settings['session_prefix'].'usersettings']) && isset($_GET['toggle_view']) && in_array($_GET['toggle_view'], array(0, 1))) {
$_SESSION[$settings['session_prefix'].'usersettings']['user_view'] = intval($_GET['toggle_view']);
setcookie($settings['session_prefix'].'usersettings', $_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'], cookie_options(TIMESTAMP+(3600*24*$settings['cookie_validity_days'])));
// update database for registered users:
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
@mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET last_login = last_login, last_logout = last_logout, registered = registered, user_view = ". intval($_SESSION[$settings['session_prefix'].'usersettings']['user_view']) ." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or die(mysqli_error($connid));
}
if (isset($_GET['category']) && isset($_GET['page']) && isset($_GET['order'])) $q = '&page='.$_GET['page'].'&category='.$_GET['category'].'&order='.$_GET['order']; else $q = '';
header('location: index.php?mode=index'.$q);
exit;
}
if (isset($_SESSION[$settings['session_prefix'].'usersettings']) && isset($_GET['toggle_thread_display']) && in_array($_GET['toggle_thread_display'], array(0, 1)) && isset($_GET['id'])) {
$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'] = intval($_GET['toggle_thread_display']);
setcookie($settings['session_prefix'].'usersettings', $_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'], cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
// update database for registered users:
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
@mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET last_login = last_login, last_logout = last_logout, registered = registered, thread_display = ". intval($_SESSION[$settings['session_prefix'].'usersettings']['thread_display']) ." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or die(mysqli_error($connid));
}
header('location: index.php?mode=thread&id='.intval($_GET['id']));
exit;
}
if(isset($_GET['toggle_view']))
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']) && $_SESSION[$settings['session_prefix'].'usersettings']['user_view'] == 0)
{
$_SESSION[$settings['session_prefix'].'usersettings']['user_view'] = 1;
setcookie($settings['session_prefix'].'usersettings','1.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'],time()+(3600*24*$settings['cookie_validity_days']));
}
elseif(isset($_SESSION[$settings['session_prefix'].'usersettings']) && $_SESSION[$settings['session_prefix'].'usersettings']['user_view'] == 1)
{
$_SESSION[$settings['session_prefix'].'usersettings']['user_view'] = 0;
setcookie($settings['session_prefix'].'usersettings','0.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'],time()+(3600*24*$settings['cookie_validity_days']));
}
// update database for registered users:
if(isset($_SESSION[$settings['session_prefix'].'user_id']))
{
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_login=last_login, last_logout=last_logout, registered=registered, user_view = ".intval($_SESSION[$settings['session_prefix'].'usersettings']['user_view'])." WHERE user_id='".intval($_SESSION[$settings['session_prefix'].'user_id'])."'", $connid) or die(mysql_error());
}
#$clear_cache=true;
if(isset($_GET['category']) && isset($_GET['page']) && isset($_GET['order'])) $q = '&page='.$_GET['page'].'&category='.$_GET['category'].'&order='.$_GET['order']; else $q = '';
header('location: index.php?mode=index'.$q);
exit;
}
if (isset($_SESSION[$settings['session_prefix'].'usersettings']) && isset($_GET['fold_threads']) && in_array($_GET['fold_threads'], array(0, 1))) {
$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'] = intval($_GET['fold_threads']);
setcookie($settings['session_prefix'].'usersettings', $_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'], cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
// update database for registered users:
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) {
@mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET last_login = last_login, last_logout = last_logout, registered = registered, fold_threads = ". intval($_SESSION[$settings['session_prefix'].'usersettings']['fold_threads']) ." WHERE user_id = ". intval($_SESSION[$settings['session_prefix'].'user_id'])) or die(mysqli_error($connid));
}
if (isset($_GET['category']) && isset($_GET['page']) && isset($_GET['order'])) $q = '&page='.$_GET['page'].'&category='.$_GET['category'].'&order='.$_GET['order']; else $q = '';
if (isset($_GET['ajax'])) exit;
header('Location: index.php?mode=index'.$q);
exit;
}
if(isset($_GET['toggle_thread_display']) && isset($_GET['id']))
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']) && $_SESSION[$settings['session_prefix'].'usersettings']['thread_display'] == 0)
{
$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'] = 1;
setcookie($settings['session_prefix'].'usersettings',$_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.1',time()+(3600*24*$settings['cookie_validity_days']));
}
elseif(isset($_SESSION[$settings['session_prefix'].'usersettings']) && $_SESSION[$settings['session_prefix'].'usersettings']['thread_display'] == 1)
{
$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'] = 0;
setcookie($settings['session_prefix'].'usersettings',$_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'].'.0',time()+(3600*24*$settings['cookie_validity_days']));
}
// update database for registered users:
if(isset($_SESSION[$settings['session_prefix'].'user_id']))
{
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_login=last_login, last_logout=last_logout, registered=registered, thread_display = ".intval($_SESSION[$settings['session_prefix'].'usersettings']['thread_display'])." WHERE user_id='".intval($_SESSION[$settings['session_prefix'].'user_id'])."'", $connid) or die(mysql_error());
}
#$clear_cache=true;
header('location: index.php?mode=thread&id='.intval($_GET['id']));
exit;
}
if(isset($_GET['refresh'])) {
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime'])) {
$_SESSION[$settings['session_prefix'].'usersettings']['newtime'] = TIMESTAMP;
}
setcookie($settings['session_prefix'].'last_visit', TIMESTAMP.".".TIMESTAMP, cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
setcookie($settings['session_prefix'].'read', '', cookie_options(0));
header('location: index.php?mode=index');
exit;
}
if(isset($_GET['fold_threads']))
{
if($_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'] == 0)
{
$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'] = 1;
setcookie($settings['session_prefix'].'usersettings',$_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.1.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'],time()+(3600*24*$settings['cookie_validity_days']));
}
else
{
$_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'] = 0;
setcookie($settings['session_prefix'].'usersettings',$_SESSION[$settings['session_prefix'].'usersettings']['user_view'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_order'].'.'.$_SESSION[$settings['session_prefix'].'usersettings']['sidebar'].'.0.'.$_SESSION[$settings['session_prefix'].'usersettings']['thread_display'],time()+(3600*24*$settings['cookie_validity_days']));
}
#$clear_cache=true;
// update database for registered users:
if(isset($_SESSION[$settings['session_prefix'].'user_id']))
{
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_login=last_login, last_logout=last_logout, registered=registered, fold_threads = ".intval($_SESSION[$settings['session_prefix'].'usersettings']['fold_threads'])." WHERE user_id='".intval($_SESSION[$settings['session_prefix'].'user_id'])."'", $connid) or die(mysql_error());
}
if(isset($_GET['category']) && isset($_GET['page']) && isset($_GET['order'])) $q = '&page='.$_GET['page'].'&category='.$_GET['category'].'&order='.$_GET['order']; else $q = '';
if(isset($_GET['ajax'])) exit;
header('Location: index.php?mode=index'.$q);
exit;
}
if(isset($_GET['refresh']))
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime']))
{
$_SESSION[$settings['session_prefix'].'usersettings']['newtime'] = $current_time;
$_SESSION[$settings['session_prefix'].'usersettings']['read'] = array();
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET last_logout=NOW(), entries_read='' WHERE user_id='".intval($_SESSION[$settings['session_prefix'].'user_id'])."'", $connid);
}
setcookie($settings['session_prefix'].'last_visit',$current_time.".".$current_time,$current_time+(3600*24*$settings['cookie_validity_days']));
setcookie($settings['session_prefix'].'read','',0);
header('location: index.php?mode=index');
exit;
}
if(isset($_GET['show_spam']) && isset($_SESSION[$settings['session_prefix'].'user_id']) && $_SESSION[$settings['session_prefix'].'user_id']>0)
{
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam'])) unset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam']);
else $_SESSION[$settings['session_prefix'].'usersettings']['show_spam'] = true;
header('location: index.php?mode=index');
exit;
}
if (isset($_GET['show_spam']) && isset($_SESSION[$settings['session_prefix'].'user_id']) && $_SESSION[$settings['session_prefix'].'user_id'] > 0) {
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam'])) unset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam']);
else $_SESSION[$settings['session_prefix'].'usersettings']['show_spam'] = true;
header('location: index.php?mode=index');
exit;
}
// determine last visit:
if(empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['remember_last_visit'] == 1)
{
if(isset($_COOKIE[$settings['session_prefix'].'last_visit']))
{
$c_last_visit = explode(".", $_COOKIE[$settings['session_prefix'].'last_visit']);
if(isset($c_last_visit[0])) $c_last_visit[0] = intval(trim($c_last_visit[0])); else $c_last_visit[0] = time();
if(isset($c_last_visit[1])) $c_last_visit[1] = intval(trim($c_last_visit[1])); else $c_last_visit[1] = time();
if($c_last_visit[1] < (time() - 600))
{
$c_last_visit[0] = $c_last_visit[1];
$c_last_visit[1] = time();
setcookie($settings['session_prefix'].'last_visit',$c_last_visit[0].".".$c_last_visit[1],time()+(3600*24*$settings['cookie_validity_days']));
}
}
else setcookie($settings['session_prefix'].'last_visit',time().".".time(),time()+(3600*24*$settings['cookie_validity_days']));
}
if(isset($c_last_visit)) $last_visit = intval($c_last_visit[0]); else $last_visit = time();
if (empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['remember_last_visit'] == 1) {
if (isset($_COOKIE[$settings['session_prefix'].'last_visit'])) {
$c_last_visit = explode(".", $_COOKIE[$settings['session_prefix'].'last_visit']);
if (isset($c_last_visit[0])) $c_last_visit[0] = intval(trim($c_last_visit[0])); else $c_last_visit[0] = TIMESTAMP;
if (isset($c_last_visit[1])) $c_last_visit[1] = intval(trim($c_last_visit[1])); else $c_last_visit[1] = TIMESTAMP;
if ($c_last_visit[1] < (TIMESTAMP - 600)) {
$c_last_visit[0] = $c_last_visit[1];
$c_last_visit[1] = TIMESTAMP;
setcookie($settings['session_prefix'].'last_visit', $c_last_visit[0].".".$c_last_visit[1], cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
}
}
else
setcookie($settings['session_prefix'].'last_visit', TIMESTAMP.".".TIMESTAMP, cookie_options(TIMESTAMP + (3600 * 24 * $settings['cookie_validity_days'])));
}
if(isset($_GET['category']))
{
$category = intval($_GET['category']);
$_SESSION[$settings['session_prefix'].'usersettings']['category']=$category;
$_SESSION[$settings['session_prefix'].'usersettings']['page']=1;
}
if (isset($c_last_visit)) $last_visit = intval($c_last_visit[0]); else $last_visit = TIMESTAMP;
if(isset($category_ids) && isset($_SESSION[$settings['session_prefix'].'usersettings']['category_selection']))
{
$category_selection = filter_category_selection($_SESSION[$settings['session_prefix'].'usersettings']['category_selection'], $category_ids);
if(!empty($category_selection)) $category_selection_query = implode(', ', $category_selection);
}
if (isset($_GET['category'])) {
$category = intval($_GET['category']);
$_SESSION[$settings['session_prefix'].'usersettings']['category'] = $category;
$_SESSION[$settings['session_prefix'].'usersettings']['page'] = 1;
}
// show spam?
$display_spam_query_and = ' AND spam = 0';
$display_spam_query_where = ' WHERE spam = 0';
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam']))
{
$display_spam_query_and = '';
$display_spam_query_where = '';
}
if (isset($category_ids) && isset($_SESSION[$settings['session_prefix'].'usersettings']['category_selection'])) {
$category_selection = filter_category_selection($_SESSION[$settings['session_prefix'].'usersettings']['category_selection'], $category_ids);
if (!empty($category_selection)) $category_selection_query = implode(', ', $category_selection);
}
// count spam:
$count_spam_sql =
"SELECT COUNT(*) FROM " . $db_settings['forum_table'] . " AS ft INNER JOIN (SELECT eid FROM " . $db_settings['akismet_rating_table'] . " WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT eid FROM " . $db_settings['b8_rating_table'] . " WHERE " . $db_settings['b8_rating_table'] . ".spam = 1) AS spam_list ON spam_list.eid = ft.id";
$count_spam_result = mysqli_query($connid, $count_spam_sql);
list($total_spam) = mysqli_fetch_row($count_spam_result);
mysqli_free_result($count_spam_result);
// show spam? NOTE: variables are used in several php files, i.e. index.inc.php, thread.inc.php, entry.inc.php
$show_spam = false;
$spam_sql_and = " AND spam_list.id IS NULL";
if ($total_spam > 0 && isset($_SESSION[$settings['session_prefix'].'usersettings']['show_spam'])) {
$show_spam = true;
$spam_sql_and = " AND spam_list.id IS NOT NULL";
}
// count postings, threads, users and users online:
if($categories == false) // no categories defined
{
$count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE pid = 0".$display_spam_query_and, $connid);
list($total_threads) = mysql_fetch_row($count_result);
mysql_free_result($count_result);
$count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table'].$display_spam_query_where, $connid);
list($total_postings) = mysql_fetch_row($count_result);
mysql_free_result($count_result);
}
else // there are categories
{
$count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE pid = 0".$display_spam_query_and." AND category IN (".$category_ids_query.")", $connid);
list($total_threads) = mysql_fetch_row($count_result);
mysql_free_result($count_result);
$count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE category IN (".$category_ids_query.")".$display_spam_query_and, $connid);
list($total_postings) = mysql_fetch_row($count_result);
mysql_free_result($count_result);
}
// count spam:
$count_spam_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE spam = 1", $connid);
list($total_spam) = mysql_fetch_row($count_spam_result);
mysql_free_result($count_spam_result);
$total_threads_postings_body =
"SELECT COUNT(DISTINCT ft.id) FROM " . $db_settings['forum_table'] . " AS ft LEFT JOIN (SELECT ".$db_settings['forum_table'].".id, ".$db_settings['forum_table'].".tid FROM ".$db_settings['forum_table']." INNER JOIN " . $db_settings['akismet_rating_table'] . " ON ".$db_settings['forum_table'].".id = " . $db_settings['akismet_rating_table'] . ".eid WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT ".$db_settings['forum_table'].".id, ".$db_settings['forum_table'].".tid FROM ".$db_settings['forum_table']." INNER JOIN " . $db_settings['b8_rating_table'] . " ON ".$db_settings['forum_table'].".id = " . $db_settings['b8_rating_table'] . ".eid WHERE " . $db_settings['b8_rating_table'] . ".spam = 1)";
$threads_check_sql = " AND pid = 0";
if ($show_spam) {
$spam_totals = " AS spam_list ON spam_list.tid = ft.tid WHERE spam_list.id IS NOT NULL";
} else {
$spam_totals = " AS spam_list ON spam_list.id = ft.id WHERE spam_list.id IS NULL";
}
if ($categories == false) {
$total_postings_category = "";
} else {
// there are categories
$total_postings_category = " AND category IN (" . $category_ids_query . ")";
}
$total_threads_sql = $total_threads_postings_body . $spam_totals . $total_postings_category . $threads_check_sql;
$count_result = mysqli_query($connid, $total_threads_sql);
list($total_threads) = mysqli_fetch_row($count_result);
mysqli_free_result($count_result);
$total_postings_sql = $total_threads_postings_body . $spam_totals . $total_postings_category;
$count_result = mysqli_query($connid, $total_postings_sql);
list($total_postings) = mysqli_fetch_row($count_result);
mysqli_free_result($count_result);
$count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['userdata_table']." WHERE activate_code=''", $connid);
list($registered_users) = mysql_fetch_row($count_result);
$count_result = mysqli_query($connid, "SELECT COUNT(*) FROM " . $db_settings['userdata_table'] . " WHERE activate_code = ''");
list($registered_users) = mysqli_fetch_row($count_result);
if($settings['count_users_online']>0)
{
user_online($settings['count_users_online']);
$count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['useronline_table']." WHERE user_id > 0", $connid);
list($registered_users_online) = mysql_fetch_row($count_result);
$count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['useronline_table']." WHERE user_id = 0", $connid);
list($unregistered_users_online) = mysql_fetch_row($count_result);
$total_users_online = $unregistered_users_online + $registered_users_online;
}
mysql_free_result($count_result);
if ($settings['count_users_online'] > 0) {
user_online($settings['count_users_online']);
$count_result = mysqli_query($connid, "SELECT COUNT(*) FROM ".$db_settings['useronline_table']." WHERE user_id > 0");
list($registered_users_online) = mysqli_fetch_row($count_result);
$count_result = mysqli_query($connid, "SELECT COUNT(*) FROM ".$db_settings['useronline_table']." WHERE user_id = 0");
list($unregistered_users_online) = mysqli_fetch_row($count_result);
$total_users_online = $unregistered_users_online + $registered_users_online;
}
mysqli_free_result($count_result);
if(isset($settings['time_difference'])) $time_difference = intval($settings['time_difference']);
if (isset($settings['time_difference'])) $time_difference = intval($settings['time_difference']);
else $time_difference = 0;
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['time_difference'])) $time_difference = $_SESSION[$settings['session_prefix'].'usersettings']['time_difference']+$time_difference;
#elseif (isset($_COOKIE['user_time_difference'])) $time_difference = $_COOKIE['user_time_difference']+$time_difference;
if (isset($_SESSION[$settings['session_prefix'].'usersettings']['time_difference'])) $time_difference = $_SESSION[$settings['session_prefix'].'usersettings']['time_difference'] + $time_difference;
// page menu:
if(isset($_SESSION[$settings['session_prefix'].'user_id'])) $menu_result = @mysql_query("SELECT id, menu_linkname FROM ".$db_settings['pages_table']." WHERE menu_linkname!='' ORDER BY order_id ASC", $connid) or raise_error('database_error',mysql_error());
else $menu_result = @mysql_query("SELECT id, menu_linkname FROM ".$db_settings['pages_table']." WHERE menu_linkname!='' AND access=0 ORDER BY order_id ASC", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($menu_result)>0)
{
$i=0;
while($pages_data = mysql_fetch_array($menu_result))
{
$menu[$i]['id'] = $pages_data['id'];
$menu[$i]['linkname'] = $pages_data['menu_linkname'];
$i++;
}
}
mysql_free_result($menu_result);
if (isset($_SESSION[$settings['session_prefix'].'user_id'])) $menu_result = @mysqli_query($connid, "SELECT id, menu_linkname FROM ".$db_settings['pages_table']." WHERE menu_linkname != '' ORDER BY order_id ASC") or raise_error('database_error', mysqli_error($connid));
else $menu_result = @mysqli_query($connid, "SELECT id, menu_linkname FROM ".$db_settings['pages_table']." WHERE menu_linkname != '' AND access = 0 ORDER BY order_id ASC") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($menu_result) > 0) {
$i = 0;
while ($pages_data = mysqli_fetch_array($menu_result)) {
$menu[$i]['id'] = $pages_data['id'];
$menu[$i]['linkname'] = $pages_data['menu_linkname'];
$i++;
}
}
mysqli_free_result($menu_result);
?>

View file

@ -1,38 +1,33 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if(isset($_GET['id']))
{
$id = intval($_GET['id']);
$result = @mysql_query("SELECT id, title, content, access FROM ".$db_settings['pages_table']." WHERE id= ".$id." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result)>0)
{
$data = mysql_fetch_array($result);
if($data['access']==0||isset($_SESSION[$settings['session_prefix'].'user_id']))
{
$page['id'] = intval($data['id']);
$page['access'] = intval($data['access']);
$page['title'] = $data['title'];
$page['content'] = $data['content'];
$smarty->assign('page',$page);
}
else $smarty->assign('no_authorisation',true);
}
else $smarty->assign('page_doesnt_exist',true);
mysql_free_result($result);
}
if (isset($_GET['id'])) {
$id = intval($_GET['id']);
$result = @mysqli_query($connid, "SELECT id, title, content, access FROM ".$db_settings['pages_table']." WHERE id= ". intval($id) ." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) > 0) {
$data = mysqli_fetch_array($result);
if ($data['access'] == 0 || isset($_SESSION[$settings['session_prefix'].'user_id'])) {
$page['id'] = intval($data['id']);
$page['access'] = intval($data['access']);
$page['title'] = $data['title'];
$page['content'] = $data['content'];
$smarty->assign('page', $page);
}
else $smarty->assign('no_authorisation', true);
}
else $smarty->assign('page_doesnt_exist', true);
mysqli_free_result($result);
}
if(isset($page))
{
$smarty->assign('subnav_location','subnav_page');
$smarty->assign('subnav_location_var',$page['title']);
}
else $smarty->assign('subnav_location','subnav_page_error');
if(isset($page)) {
$smarty->assign('subnav_location', 'subnav_page');
$smarty->assign('subnav_location_var', $page['title']);
}
else $smarty->assign('subnav_location', 'subnav_page_error');
$smarty->assign('subtemplate','page.inc.tpl');
$smarty->assign('subtemplate', 'page.inc.tpl');
$template = 'main.tpl';
?>

File diff suppressed because it is too large Load diff

View file

@ -1,235 +1,290 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
$smarty->config_load($settings['language_file'], 'emails');
$lang = $smarty->get_config_vars();
$smarty->configLoad($settings['language_file'], 'emails');
$lang = $smarty->getConfigVars();
// remove not activated user accounts:
@mysql_query("DELETE FROM ".$db_settings['userdata_table']." WHERE registered < (NOW() - INTERVAL 24 HOUR) AND activate_code != '' AND logins=0", $connid);
@mysqli_query($connid, "DELETE FROM ".$db_settings['userdata_table']." WHERE registered < (NOW() - INTERVAL 24 HOUR) AND activate_code != '' AND logins = 0");
if(empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_register']>0)
{
require('modules/captcha/captcha.php');
$captcha = new Captcha();
}
if(empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_register'] > 0) {
require('modules/captcha/captcha.php');
$captcha = new Captcha();
}
if(isset($_REQUEST['action'])) $action = $_REQUEST['action'];
else $action = 'main';
if (isset($_REQUEST['action']))
$action = $_REQUEST['action'];
else
$action = 'main';
if(isset($_POST['register_submit'])) $action = 'register_submitted';
if(isset($_GET['key'])) $action = 'activate';
if (isset($_POST['register_submit']))
$action = 'register_submitted';
if (isset($_GET['key']))
$action = 'activate';
switch($action)
{
case 'main':
if($settings['register_mode']<2)
{
if($settings['terms_of_use_agreement']==1) $smarty->assign("terms_of_use_agreement",true);
$smarty->assign('subnav_location','subnav_register');
$smarty->assign('subtemplate','register.inc.tpl');
$template = 'main.tpl';
}
else
{
$smarty->assign('lang_section','register');
$smarty->assign('message','register_only_by_admin');
$smarty->assign('subnav_location','subnav_register');
$smarty->assign('subtemplate','info.inc.tpl');
$template = 'main.tpl';
}
break;
case 'register_submitted':
if($settings['register_mode']>1) die('No authorisation!');
else
{
$new_user_name = trim($_POST['new_user_name']);
$new_user_email = trim($_POST['new_user_email']);
$reg_pw = $_POST['reg_pw'];
$reg_pw_conf = $_POST['reg_pw_conf'];
if(isset($_POST['terms_of_use_agree']) && $_POST['terms_of_use_agree']==1) $terms_of_use_agree=1; else $terms_of_use_agree=0;
$fname_user = hash("sha256", 'new_user_name' . $_SESSION['csrf_token']);
$fname_email = hash("sha256", 'new_user_email' . $_SESSION['csrf_token']);
$fname_pword = hash("sha256", 'reg_pw' . $_SESSION['csrf_token']);
$fname_phone = hash("sha256", 'phone' . $_SESSION['csrf_token']);
$fname_repemail = hash("sha256", 'repeat_email' . $_SESSION['csrf_token']);
// form complete?
if($new_user_name=='' || $new_user_email=='' || $reg_pw=='' || $reg_pw_conf=='') $errors[] = 'error_form_uncomplete';
switch ($action) {
case 'main':
// set timestamp for SPAM protection
setReceiptTimestamp();
if ($settings['register_mode'] < 2) {
if ($settings['terms_of_use_agreement'] == 1)
$smarty->assign("terms_of_use_agreement", true);
if ($settings['data_privacy_agreement'] == 1)
$smarty->assign("data_privacy_agreement", true);
$smarty->assign('subnav_location', 'subnav_register');
$smarty->assign('subtemplate', 'register.inc.tpl');
$smarty->assign('fld_user_name', $fname_user);
$smarty->assign('fld_user_email', $fname_email);
$smarty->assign('fld_pword', $fname_pword);
$smarty->assign('fld_phone', $fname_phone);
$smarty->assign('fld_repeat_email', $fname_repemail);
$template = 'main.tpl';
} else {
$smarty->assign('lang_section', 'register');
$smarty->assign('message', 'register_only_by_admin');
$smarty->assign('subnav_location', 'subnav_register');
$smarty->assign('subtemplate', 'info.inc.tpl');
$template = 'main.tpl';
}
break;
case 'register_submitted':
if ($settings['register_mode'] > 1 || !isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token'])
die('No authorisation!');
else {
$new_user_name = (!empty($_POST[$fname_user])) ? trim($_POST[$fname_user]) : '';
$new_user_email = (!empty($_POST[$fname_email])) ? trim($_POST[$fname_email]) : '';
$reg_pw = $_POST[$fname_pword];
$terms_of_use_agree = (isset($_POST['terms_of_use_agree']) && $_POST['terms_of_use_agree'] == 1) ? 1 : 0;
$data_privacy_statement_agree = (isset($_POST['data_privacy_statement_agree']) && $_POST['data_privacy_statement_agree'] == 1) ? 1 : 0;
if(empty($errors))
{
// password too short?
if(my_strlen($reg_pw, $lang['charset']) < $settings['min_pw_length']) $errors[] = 'error_password_too_short';
// password and repeatet Password equal?
if($reg_pw != $reg_pw_conf) $errors[] = 'error_pw_conf_wrong';
// name too long?
if(my_strlen($new_user_name, $lang['charset']) > $settings['username_maxlength']) $errors[] = 'error_name_too_long';
// e-mail address too long?
if(my_strlen($new_user_email, $lang['charset']) > $settings['email_maxlength']) $errors[] = 'error_email_too_long';
// form complete and are honey pot fields empty?
if ($new_user_name == '' || $new_user_email == '' || $new_user_name == $new_user_email || $reg_pw == '' || !isset($_POST[$fname_repemail]) || !empty($_POST[$fname_repemail]) || !isset($_POST[$fname_phone]) || !empty($_POST[$fname_phone]))
$errors[] = 'error_form_uncomplete';
if (empty($errors)) {
setReceiptTimestamp();
if (!isset($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference']) || intval($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference']) <= 0)
$errors[] = 'error_invalid_form';
else {
if ($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference'] < $settings['min_register_time'])
$errors[] = 'error_form_sent_too_fast';
elseif ($_SESSION[$settings['session_prefix'] . 'receipt_timestamp_difference'] > $settings['max_register_time'])
$errors[] = 'error_form_sent_too_slow';
}
}
// word in username too long?
$too_long_word = too_long_word($new_user_name,$settings['name_word_maxlength']);
if($too_long_word) $errors[] = 'error_word_too_long';
if (empty($errors)) {
$min_password_length_by_restrictions = intval($settings['min_pw_digits']) + intval($settings['min_pw_lowercase_letters']) + intval($settings['min_pw_uppercase_letters']) + intval($settings['min_pw_special_characters']);
// password too short?
if ($min_password_length_by_restrictions < intval($settings['min_pw_length']) && my_strlen($reg_pw, $lang['charset']) < intval($settings['min_pw_length']))
$errors[] = 'error_password_too_short';
// see: http://php.net/manual/en/regexp.reference.unicode.php
// \p{N} == numbers
// [\p{Ll}\p{Lm}\p{Lo}] == lowercase, modifier, other letters
// [\p{Lu}\p{Lt}] == uppercase, titlecase letters
// [\p{S}\p{P}\p{Z}] == symbols, punctuations, separator
// password contains numbers?
if ($settings['min_pw_digits'] > 0 && !preg_match("/(?=(.*\p{N}){" . intval($settings['min_pw_digits']) . ",})/u", $reg_pw))
$errors[] = 'error_pw_needs_digit';
// password contains lowercase letter?
if ($settings['min_pw_lowercase_letters'] > 0 && !preg_match("/(?=(.*[\p{Ll}\p{Lm}\p{Lo}]){" . intval($settings['min_pw_lowercase_letters']) . ",})/u", $reg_pw))
$errors[] = 'error_pw_needs_lowercase_letter';
// password contains uppercase letter?
if ($settings['min_pw_uppercase_letters'] > 0 && !preg_match("/(?=(.*[\p{Lu}\p{Lt}]){" . intval($settings['min_pw_uppercase_letters']) . ",})/u", $reg_pw))
$errors[] = 'error_pw_needs_uppercase_letter';
// password contains special character?
if ($settings['min_pw_special_characters'] > 0 && !preg_match("/(?=(.*[\p{S}\p{P}\p{Z}]){" . intval($settings['min_pw_special_characters']) . ",})/u", $reg_pw))
$errors[] = 'error_pw_needs_special_character';
// name too long?
if (my_strlen($new_user_name, $lang['charset']) > $settings['username_maxlength'])
$errors[] = 'error_name_too_long';
// e-mail address too long?
if (my_strlen($new_user_email, $lang['charset']) > $settings['email_maxlength'])
$errors[] = 'error_email_too_long';
// word in username too long?
$too_long_word = too_long_word($new_user_name,$settings['name_word_maxlength']);
if ($too_long_word)
$errors[] = 'error_word_too_long';
// look if name already exists:
$name_result = mysql_query("SELECT user_name FROM ".$db_settings['userdata_table']." WHERE lower(user_name) = '".mysql_real_escape_string(my_strtolower($new_user_name, $lang['charset']))."'", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($name_result)>0) $errors[] = 'user_name_already_exists';
mysql_free_result($name_result);
// look if name already exists:
$name_result = mysqli_query($connid, "SELECT user_name FROM ".$db_settings['userdata_table']." WHERE lower(user_name) = '". mysqli_real_escape_string($connid, my_strtolower($new_user_name, $lang['charset'])) ."'") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($name_result) > 0)
$errors[] = 'user_name_already_exists';
mysqli_free_result($name_result);
// look, if e-mail already exists:
$email_result = mysql_query("SELECT user_email FROM ".$db_settings['userdata_table']." WHERE lower(user_email) = '".mysql_real_escape_string(my_strtolower($new_user_email, $lang['charset']))."'", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($email_result)>0) $errors[] = 'error_email_alr_exists';
mysql_free_result($email_result);
// look, if e-mail already exists:
$email_result = mysqli_query($connid, "SELECT user_email FROM ".$db_settings['userdata_table']." WHERE lower(user_email) = '". mysqli_real_escape_string($connid, my_strtolower($new_user_email, $lang['charset'])) ."'") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($email_result) > 0)
$errors[] = 'error_email_alr_exists';
mysqli_free_result($email_result);
// e-mail correct?
if(!is_valid_email($new_user_email)) $errors[] = 'error_email_wrong';
// e-mail correct?
if (!is_valid_email($new_user_email))
$errors[] = 'error_email_wrong';
if($settings['terms_of_use_agreement']==1 && $terms_of_use_agree!=1) $errors[] = 'terms_of_use_error_register';
if ($settings['terms_of_use_agreement'] == 1 && $terms_of_use_agree != 1)
$errors[] = 'terms_of_use_error_register';
if ($settings['data_privacy_agreement'] == 1 && $data_privacy_statement_agree != 1)
$errors[] = 'data_priv_statement_error_reg';
if(contains_special_characters($new_user_name)) $errors[] = 'error_username_invalid_chars';
}
if (contains_special_characters($new_user_name))
$errors[] = 'error_username_invalid_chars';
}
// check for not accepted words:
$checkstring = my_strtolower($new_user_name.' '.$new_user_email, $lang['charset']);
$not_accepted_words = get_not_accepted_words($checkstring);
if($not_accepted_words!=false)
{
$errors[] = 'error_reg_not_accepted_word';
}
// check for not accepted words:
$checkstring = my_strtolower($new_user_name.' '.$new_user_email, $lang['charset']);
$not_accepted_words = get_not_accepted_words($checkstring);
if ($settings['stop_forum_spam'] == 1)
$infamous_email = isInfamousEmail($new_user_email);
else
$infamous_email = false;
if ($not_accepted_words != false || $infamous_email)
$errors[] = 'error_reg_not_accepted_word';
// CAPTCHA check:
if(empty($errors) && empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_register']>0)
{
if($settings['captcha_register']==2)
{
if(empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_captcha($_SESSION['captcha_session'],$_POST['captcha_code'])!=true) $errors[] = 'captcha_check_failed';
}
else
{
if(empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_math_captcha($_SESSION['captcha_session'][2],$_POST['captcha_code'])!=true) $errors[] = 'captcha_check_failed';
}
unset($_SESSION['captcha_session']);
}
// CAPTCHA check:
if (empty($errors) && empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_register'] > 0) {
if ($settings['captcha_register'] == 2) {
if (empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_captcha($_SESSION['captcha_session'], $_POST['captcha_code']) != true)
$errors[] = 'captcha_check_failed';
}
else {
if (empty($_SESSION['captcha_session']) || empty($_POST['captcha_code']) || $captcha->check_math_captcha($_SESSION['captcha_session'][2], $_POST['captcha_code']) != true)
$errors[] = 'captcha_check_failed';
}
unset($_SESSION['captcha_session']);
}
// save user if no errors:
if(empty($errors))
{
$pw_hash = generate_pw_hash($reg_pw);
$activate_code = random_string(20);
$activate_code_hash = generate_pw_hash($activate_code);
if($settings['register_mode']==1) $user_lock = 1;
else $user_lock = 0;
@mysql_query("INSERT INTO ".$db_settings['userdata_table']." (user_type, user_name, user_real_name, user_pw, user_email, user_hp, user_location, signature, profile, email_contact, last_login, last_logout, user_ip, registered, user_view, fold_threads, user_lock, auto_login_code, pwf_code, activate_code, entries_read) VALUES (0,'".mysql_real_escape_string($new_user_name)."','','".mysql_real_escape_string($pw_hash)."','".mysql_real_escape_string($new_user_email)."','','','','',".$settings['default_email_contact'].",NOW(),NOW(),'".mysql_real_escape_string($_SERVER["REMOTE_ADDR"])."',NOW(),".intval($settings['default_view']).", ".intval($settings['fold_threads']).", ".$user_lock.", '', '', '".mysql_real_escape_string($activate_code_hash)."', '')", $connid) or raise_error('database_error',mysql_error());
// save user if no errors:
if (empty($errors)) {
$pw_hash = generate_pw_hash($reg_pw);
$activate_code = random_string(20);
$activate_code_hash = generate_pw_hash($activate_code);
if ($settings['register_mode'] == 1)
$user_lock = 1;
else
$user_lock = 0;
@mysqli_query($connid, "INSERT INTO ".$db_settings['userdata_table']." (user_type, user_name, user_real_name, user_pw, user_email, user_hp, user_location, signature, profile, email_contact, last_login, last_logout, user_ip, registered, user_view, fold_threads, user_lock, auto_login_code, pwf_code, activate_code, tou_accepted, dps_accepted) VALUES (0, '". mysqli_real_escape_string($connid, $new_user_name) ."', '', '". mysqli_real_escape_string($connid, $pw_hash) ."', '". mysqli_real_escape_string($connid, $new_user_email) ."', '', '', '', '', ".$settings['default_email_contact'].", NULL, NOW(), '". mysqli_real_escape_string($connid, $_SERVER["REMOTE_ADDR"]) ."', NOW(), ". intval($settings['default_view']) .", ". intval($settings['fold_threads']) .", ". $user_lock .", '', '', '". mysqli_real_escape_string($connid, $activate_code_hash) ."', ". ($terms_of_use_agree == 1 ? "NOW()" : "NULL") .", ". ($data_privacy_statement_agree == 1 ? "NOW()" : "NULL") .")") or raise_error('database_error', mysqli_error($connid));
// get new user ID:
$new_user_id_result = mysql_query("SELECT user_id FROM ".$db_settings['userdata_table']." WHERE user_name = '".mysql_real_escape_string($new_user_name)."' LIMIT 1", $connid);
if (!$new_user_id_result) raise_error('database_error',mysql_error());
$field = mysql_fetch_array($new_user_id_result);
$new_user_id = $field['user_id'];
mysql_free_result($new_user_id_result);
// get new user ID:
$new_user_id_result = mysqli_query($connid, "SELECT user_id FROM ".$db_settings['userdata_table']." WHERE user_name = '". mysqli_real_escape_string($connid, $new_user_name) ."' LIMIT 1");
if (!$new_user_id_result)
raise_error('database_error', mysqli_error($connid));
$field = mysqli_fetch_array($new_user_id_result);
$new_user_id = $field['user_id'];
mysqli_free_result($new_user_id_result);
// send e-mail with activation key to new user:
$lang['new_user_email_txt'] = str_replace("[name]", $new_user_name, $lang['new_user_email_txt']);
$lang['new_user_email_txt'] = str_replace("[activate_link]", $settings['forum_address']."index.php?mode=register&id=".$new_user_id."&key=".$activate_code, $lang['new_user_email_txt']);
// send e-mail with activation key to new user:
$lang['new_user_email_txt'] = str_replace("[name]", $new_user_name, $lang['new_user_email_txt']);
$lang['new_user_email_txt'] = str_replace("[activate_link]", $settings['forum_address']."index.php?mode=register&id=".$new_user_id."&key=".$activate_code, $lang['new_user_email_txt']);
if(my_mail($new_user_email, $lang['new_user_email_sj'], $lang['new_user_email_txt'])) $smarty->assign('message','registered');
else $smarty->assign('message','registered_send_error');
if (my_mail($new_user_email, $lang['new_user_email_sj'], $lang['new_user_email_txt']))
$smarty->assign('message', 'registered');
else
$smarty->assign('message', 'registered_send_error');
$smarty->assign('lang_section','register');
$smarty->assign('var',htmlspecialchars($new_user_email));
$smarty->assign('subnav_location','subnav_register');
$smarty->assign('subtemplate','info.inc.tpl');
$template = 'main.tpl';
}
else
{
$smarty->assign('errors',$errors);
if(isset($too_long_word)) $smarty->assign('word',$too_long_word);
$smarty->assign('subnav_location','subnav_register');
$smarty->assign('subtemplate','register.inc.tpl');
$smarty->assign('new_user_name',htmlspecialchars($new_user_name));
$smarty->assign('new_user_email',htmlspecialchars($new_user_email));
if($settings['terms_of_use_agreement']==1) $smarty->assign("terms_of_use_agreement",true);
$template = 'main.tpl';
}
}
break;
case 'activate':
if(isset($_GET['id'])) $id = intval($_GET['id']); else $error = TRUE;
if(isset($_GET['key'])) $key = trim($_GET['key']); else $error = TRUE;
if(empty($error))
{
if($id==0) $error = TRUE;
if($key=='') $error = TRUE;
}
if(empty($error))
{
$result = mysql_query("SELECT user_name, user_email, logins, activate_code FROM ".$db_settings['userdata_table']." WHERE user_id = ".intval($id)." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result) != 1) $errors[] = true;
$data = mysql_fetch_array($result);
mysql_free_result($result);
}
if(empty($error))
{
if(trim($data['activate_code']) == '') $error = true;
}
if(empty($error))
{
if(is_pw_correct($key,$data['activate_code']))
{
@mysql_query("UPDATE ".$db_settings['userdata_table']." SET activate_code = '' WHERE user_id=".intval($id), $connid) or raise_error('database_error',mysql_error());
$smarty->assign('lang_section', 'register');
$smarty->assign('var', htmlspecialchars($new_user_email));
$smarty->assign('subnav_location', 'subnav_register');
$smarty->assign('subtemplate', 'info.inc.tpl');
$template = 'main.tpl';
} else {
$smarty->assign('errors', $errors);
if (isset($too_long_word))
$smarty->assign('word', $too_long_word);
$smarty->assign('subnav_location', 'subnav_register');
$smarty->assign('subtemplate', 'register.inc.tpl');
$smarty->assign('fld_user_name', $fname_user);
$smarty->assign('fld_user_email', $fname_email);
$smarty->assign('fld_pword', $fname_pword);
$smarty->assign('fld_phone', $fname_phone);
$smarty->assign('fld_repeat_email', $fname_repemail);
$smarty->assign('new_user_name', htmlspecialchars($new_user_name));
$smarty->assign('new_user_email', htmlspecialchars($new_user_email));
$smarty->assign('honey_pot_email', htmlspecialchars(isset($_POST[$fname_repemail]) ? $_POST[$fname_repemail] : ''));
$smarty->assign('honey_pot_phone', htmlspecialchars(isset($_POST[$fname_phone]) ? $_POST[$fname_phone] : ''));
if ($settings['terms_of_use_agreement'] == 1)
$smarty->assign("terms_of_use_agreement", true);
if ($settings['data_privacy_agreement'] == 1)
$smarty->assign("data_privacy_agreement", true);
$template = 'main.tpl';
}
}
break;
case 'activate':
if (isset($_GET['id'])) $id = intval($_GET['id']); else $error = TRUE;
if (isset($_GET['key']) && !empty($_GET['key'])) $key = trim($_GET['key']); else $error = TRUE;
if (empty($error)) {
if ($id == 0) $error = TRUE;
if ($key == '') $error = TRUE;
}
if (empty($error)) {
$result = mysqli_query($connid, "SELECT user_name, user_email, logins, activate_code FROM ".$db_settings['userdata_table']." WHERE user_id = ". intval($id) ." LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) != 1) $errors[] = true;
$data = mysqli_fetch_array($result);
mysqli_free_result($result);
}
if (empty($error)) {
if (!empty($data['activate_code']) && trim($data['activate_code']) == '') $error = true;
}
if (empty($error)) {
if (is_pw_correct($key,$data['activate_code'])) {
@mysqli_query($connid, "UPDATE ".$db_settings['userdata_table']." SET activate_code = '' WHERE user_id = ". intval($id)) or raise_error('database_error', mysqli_error($connid));
// E-mail notification to mods and admins:
if($data['logins']==0) // if != 0 user has changed his e-mail address
{
if($settings['register_mode']==1) $new_user_notif_txt = $lang['new_user_notif_txt_locked'];
else $new_user_notif_txt = $lang['new_user_notif_txt'];
$new_user_notif_txt = str_replace("[name]", $data['user_name'], $new_user_notif_txt);
$new_user_notif_txt = str_replace("[email]", $data['user_email'], $new_user_notif_txt);
$new_user_notif_txt = str_replace("[user_link]", $settings['forum_address']."index.php?mode=user&show_user=".$id, $new_user_notif_txt);
// E-mail notification to mods and admins:
if ($data['logins'] == 0) {
// if != 0 user has changed his e-mail address
if ($settings['register_mode'] == 1) $new_user_notif_txt = $lang['new_user_notif_txt_locked'];
else $new_user_notif_txt = $lang['new_user_notif_txt'];
$new_user_notif_txt = str_replace("[name]", $data['user_name'], $new_user_notif_txt);
$new_user_notif_txt = str_replace("[email]", $data['user_email'], $new_user_notif_txt);
$new_user_notif_txt = str_replace("[user_link]", $settings['forum_address']."index.php?mode=user&show_user=".$id, $new_user_notif_txt);
// who gets a notification?
$admin_result = @mysql_query("SELECT user_name, user_email FROM ".$db_settings['userdata_table']." WHERE user_type>0 AND new_user_notification=1", $connid);
if(!$admin_result) raise_error('database_error',mysql_error());
while($admin_array = mysql_fetch_array($admin_result))
{
$ind_reg_emailbody = str_replace("[recipient]", $admin_array['user_name'], $new_user_notif_txt);
$admin_mailto = my_mb_encode_mimeheader($admin_array['user_name'], CHARSET, "Q")." <".$admin_array['user_email'].">";
my_mail($admin_mailto, $lang['new_user_notif_sj'], $ind_reg_emailbody);
}
}
if($settings['register_mode']==1) header("Location: index.php?mode=login&login_message=account_activated_but_locked");
else header("Location: index.php?mode=login&login_message=account_activated");
exit;
}
else $error = true;
}
if(isset($error))
{
$smarty->assign('lang_section','register');
$smarty->assign('message','activation_failed');
$smarty->assign('subnav_location','subnav_register');
$smarty->assign('subtemplate','info.inc.tpl');
$template = 'main.tpl';
}
break;
}
// who gets a notification?
$admin_result = @mysqli_query($connid, "SELECT user_name, user_email FROM ".$db_settings['userdata_table']." WHERE user_type > 0 AND new_user_notification = 1");
if (!$admin_result) raise_error('database_error', mysqli_error($connid));
while ($admin_array = mysqli_fetch_array($admin_result)) {
$ind_reg_emailbody = str_replace("[recipient]", $admin_array['user_name'], $new_user_notif_txt);
$admin_mailto = my_mb_encode_mimeheader($admin_array['user_name'], CHARSET, "Q")." <".$admin_array['user_email'].">";
my_mail($admin_mailto, $lang['new_user_notif_sj'], $ind_reg_emailbody);
}
}
if ($settings['register_mode'] == 1) header("Location: index.php?mode=login&login_message=account_activated_but_locked");
else header("Location: index.php?mode=login&login_message=account_activated");
exit;
}
else $error = true;
}
if(isset($error)) {
$smarty->assign('lang_section', 'register');
$smarty->assign('message', 'activation_failed');
$smarty->assign('subnav_location', 'subnav_register');
$smarty->assign('subtemplate', 'info.inc.tpl');
$template = 'main.tpl';
}
break;
}
// CAPTCHA:
if(empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_register']>0)
{
if($settings['captcha_register']==2)
{
$_SESSION['captcha_session'] = $captcha->generate_code();
}
else
{
$_SESSION['captcha_session'] = $captcha->generate_math_captcha();
$captcha_tpl['number_1'] = $_SESSION['captcha_session'][0];
$captcha_tpl['number_2'] = $_SESSION['captcha_session'][1];
}
$captcha_tpl['session_name'] = session_name();
$captcha_tpl['session_id'] = session_id();
$captcha_tpl['type'] = $settings['captcha_register'];
$smarty->assign('captcha',$captcha_tpl);
}
if (empty($_SESSION[$settings['session_prefix'].'user_id']) && $settings['captcha_register'] > 0) {
if ($settings['captcha_register'] == 2) {
$_SESSION['captcha_session'] = $captcha->generate_code();
} else {
$_SESSION['captcha_session'] = $captcha->generate_math_captcha();
$captcha_tpl['number_1'] = $_SESSION['captcha_session'][0];
$captcha_tpl['number_2'] = $_SESSION['captcha_session'][1];
}
$captcha_tpl['session_name'] = session_name();
$captcha_tpl['session_id'] = session_id();
$captcha_tpl['type'] = $settings['captcha_register'];
$smarty->assign('captcha', $captcha_tpl);
}
?>

View file

@ -1,97 +1,79 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if($settings['rss_feed'] == 1 && $settings['forum_enabled']==1)
{
if(isset($_GET['items']) && $_GET['items']=='thread_starts')
{
$query_addition = ' AND pid=0';
$thread_starts = true;
$smarty->assign('thread_starts',true);
if(isset($_GET['category'])) $query_addition .= ' AND category='.intval($_GET['category']);
}
elseif(isset($_GET['thread']))
{
$query_addition = ' AND tid='.intval($_GET['thread']);
$smarty->assign('thread',true);
}
elseif(isset($_GET['replies']))
{
$query_addition = ' AND tid='.intval($_GET['replies']).' AND pid!=0';
$smarty->assign('replies',true);
}
else
{
$query_addition = '';
if(isset($_GET['category'])) $query_addition .= ' AND category='.intval($_GET['category']);
}
// database request
if($categories == false)
{
$result = @mysql_query("SELECT id, pid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS timestamp, UNIX_TIMESTAMP(time) AS pubdate_timestamp, name, user_name, subject, text, cache_text
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['entry_cache_table']." ON ".$db_settings['entry_cache_table'].".cache_id=id
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE spam=0".$query_addition."
ORDER BY time DESC LIMIT ".$settings['rss_feed_max_items'], $connid) or raise_error('database_error',mysql_error());
if(!$result) raise_error('database_error',mysql_error());
}
else
{
$result = @mysql_query("SELECT id, pid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS timestamp, UNIX_TIMESTAMP(time) AS pubdate_timestamp, name, user_name, category, subject, text, cache_text
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['entry_cache_table']." ON ".$db_settings['entry_cache_table'].".cache_id=id
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE category IN (".$category_ids_query.") AND spam=0".$query_addition."
ORDER BY time DESC LIMIT ".$settings['rss_feed_max_items'], $connid) or raise_error('database_error',mysql_error());
}
$result_count = mysql_num_rows($result);
if ($settings['rss_feed'] == 1 && $settings['forum_enabled'] == 1) {
if (isset($_GET['items']) && $_GET['items'] == 'thread_starts') {
$query_addition = ' AND pid = 0';
$thread_starts = true;
$smarty->assign('thread_starts', true);
if (isset($_GET['category'])) $query_addition .= ' AND category='.intval($_GET['category']);
} elseif (isset($_GET['thread'])) {
$query_addition = ' AND tid = '. intval($_GET['thread']);
$smarty->assign('thread', true);
} elseif (isset($_GET['replies'])) {
$query_addition = ' AND tid = '. intval($_GET['replies']) .' AND pid != 0';
$smarty->assign('replies', true);
} else {
$query_addition = '';
if (isset($_GET['category'])) $query_addition .= ' AND category = '. intval($_GET['category']);
}
// database request
if ($categories == false) {
$result = @mysqli_query($connid, "SELECT id, pid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS timestamp, UNIX_TIMESTAMP(time) AS pubdate_timestamp, name, user_name, subject, text, cache_text
FROM ".$db_settings['forum_table']."
LEFT JOIN " . $db_settings['entry_cache_table'] . " ON " . $db_settings['entry_cache_table'] . ".cache_id = id
LEFT JOIN " . $db_settings['userdata_table'] . " ON " . $db_settings['userdata_table'] . ".user_id = ".$db_settings['forum_table'].".user_id
LEFT JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['akismet_rating_table'] . ".`eid` = `".$db_settings['forum_table']."`.`id`
LEFT JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['b8_rating_table'] . ".`eid` = `".$db_settings['forum_table']."`.`id`
WHERE (" . $db_settings['akismet_rating_table'] . ".spam = 0 AND " . $db_settings['b8_rating_table'] . ".spam = 0) ".$query_addition."
ORDER BY time DESC LIMIT ".$settings['rss_feed_max_items']) or raise_error('database_error', mysqli_error($connid));
if (!$result) raise_error('database_error', mysqli_error($connid));
} else {
$result = @mysqli_query($connid, "SELECT id, pid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS timestamp, UNIX_TIMESTAMP(time) AS pubdate_timestamp, name, user_name, category, subject, text, cache_text
FROM ".$db_settings['forum_table']."
LEFT JOIN " . $db_settings['entry_cache_table'] . " ON " . $db_settings['entry_cache_table'] . ".cache_id = id
LEFT JOIN " . $db_settings['userdata_table'] . " ON " . $db_settings['userdata_table'] . ".user_id = ".$db_settings['forum_table'].".user_id
LEFT JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['akismet_rating_table'] . ".`eid` = `".$db_settings['forum_table']."`.`id`
LEFT JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['b8_rating_table'] . ".`eid` = `".$db_settings['forum_table']."`.`id`
WHERE category IN (".$category_ids_query.") AND (" . $db_settings['akismet_rating_table'] . ".spam = 0 AND " . $db_settings['b8_rating_table'] . ".spam = 0) ".$query_addition."
ORDER BY time DESC LIMIT ".$settings['rss_feed_max_items']) or raise_error('database_error', mysqli_error($connid));
}
$result_count = mysqli_num_rows($result);
if($result_count > 0)
{
$i=0;
while ($row = mysql_fetch_array($result))
{
if($row['pid']!=0) $rss_items[$i]['reply'] = true;
if($row['cache_text']=='')
{
$rss_items[$i]['text'] = html_format($row['text']);
@mysql_query("DELETE FROM ".$db_settings['entry_cache_table']." WHERE cache_id=".intval($row['id']), $connid);
@mysql_query("INSERT INTO ".$db_settings['entry_cache_table']." (cache_id, cache_text) VALUES (".intval($row['id']).",'".mysql_real_escape_string($rss_items[$i]['text'])."')", $connid);
}
else
{
$rss_items[$i]['text'] = $row['cache_text'];
}
#$text = html_format($row['text']);
#$rss_items[$i]['text'] = $text;
$rss_items[$i]['title'] = htmlspecialchars(filter_control_characters($row['subject']));
if ($result_count > 0) {
$i = 0;
while ($row = mysqli_fetch_array($result)) {
if ($row['pid'] != 0) $rss_items[$i]['reply'] = true;
if ($row['cache_text'] == '') {
$rss_items[$i]['text'] = html_format($row['text']);
@mysqli_query($connid, "DELETE FROM ".$db_settings['entry_cache_table']." WHERE cache_id = ". intval($row['id']));
@mysqli_query($connid, "INSERT INTO ".$db_settings['entry_cache_table']." (cache_id, cache_text) VALUES (". intval($row['id']) .",'". mysqli_real_escape_string($connid, $rss_items[$i]['text']) ."')");
} else {
$rss_items[$i]['text'] = $row['cache_text'];
}
$rss_items[$i]['text'] = str_replace('src="images', 'src="'. htmlspecialchars($settings['forum_address']) .'images', $rss_items[$i]['text']);
$rss_items[$i]['title'] = htmlspecialchars(filter_control_characters($row['subject']));
if($categories!=false && isset($categories[$row['category']]) && $categories[$row['category']]!='') $rss_items[$i]['category'] = $categories[$row['category']];
if ($categories != false && isset($categories[$row['category']]) && $categories[$row['category']] != '') $rss_items[$i]['category'] = $categories[$row['category']];
if($row['user_id']>0)
{
if(!$row['user_name']) $rss_items[$i]['name'] = $lang['unknown_user'];
else $rss_items[$i]['name'] = htmlspecialchars(filter_control_characters($row['user_name']));
}
else $rss_items[$i]['name'] = htmlspecialchars(filter_control_characters($row['name']));
if ($row['user_id'] > 0) {
if (!$row['user_name']) $rss_items[$i]['name'] = $lang['unknown_user'];
else $rss_items[$i]['name'] = htmlspecialchars(filter_control_characters($row['user_name']));
}
else $rss_items[$i]['name'] = htmlspecialchars(filter_control_characters($row['name']));
$rss_items[$i]['link'] = $settings['forum_address']."index.php?id=".$row['id'];
if(isset($thread_starts)) $rss_items[$i]['commentRss'] = $settings['forum_address']."index.php?mode=rss&amp;replies=".$row['id'];
$rss_items[$i]['timestamp'] = $row['timestamp'];
$rss_items[$i]['formated_time'] = format_time($lang['time_format_full'],$row['timestamp']);
$rss_items[$i]['pubdate'] = gmdate('r', $row['pubdate_timestamp']);
$i++;
}
$smarty->assign("rss_items",$rss_items);
}
}
$rss_items[$i]['link'] = $settings['forum_address']."index.php?id=".$row['id'];
if (isset($thread_starts)) $rss_items[$i]['commentRss'] = $settings['forum_address']."index.php?mode=rss&amp;replies=".$row['id'];
$rss_items[$i]['timestamp'] = $row['timestamp'];
$rss_items[$i]['formated_time'] = format_time($lang['time_format_full'],$row['timestamp']);
$rss_items[$i]['pubdate'] = gmdate('r', $row['pubdate_timestamp']);
$i++;
}
$smarty->assign("rss_items",$rss_items);
}
}
$template = 'rss.tpl';
?>

View file

@ -1,157 +1,208 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if(isset($_GET['search']))
{
$search = urldecode($_GET['search']);
if(isset($_GET['p_category'])) $p_category = intval($_GET['p_category']);
else $p_category = 0;
if(isset($_GET['method']) && $_GET['method']=='tags') $method = 'tags';
elseif(isset($_GET['method']) && $_GET['method']=='fulltext_or') $method = 'fulltext_or';
else $method = 'fulltext';
$search = trim($search);
if (isset($_SESSION[$settings['session_prefix'] . 'user_id'])) {
$tmp_user_id = $_SESSION[$settings['session_prefix'] . 'user_id'];
} else {
$tmp_user_id = 0;
}
// split search query at spaces, but not between double quotes:
$help_pattern = '[!/*/~/?]'; // pattern to hide spaces between quotes
#$search = str_replace($help_pattern,$search);
$x_search = preg_replace_callback("#\"(.+?)\"#is", create_function('$string','global $help_pattern; return str_replace(" ",$help_pattern,$string[1]);'), $search);
if (isset($_GET['search'])) {
// regular serach:
$search = urldecode($_GET['search']);
if (isset($_GET['p_category']))
$p_category = intval($_GET['p_category']);
else
$p_category = 0;
if (isset($_GET['method']) && $_GET['method'] == 'tags')
$method = 'tags';
elseif (isset($_GET['method']) && $_GET['method'] == 'fulltext_or')
$method = 'fulltext_or';
else
$method = 'fulltext';
if (!empty($search)) $search = trim($search);
// split search query at spaces, but not between double quotes:
$help_pattern = '[!/*/~/?]'; // pattern to hide spaces between quotes
$x_search = preg_replace_callback(
"#\"(.+?)\"#is",
function ($string) {
global $help_pattern;
return str_replace(" ", $help_pattern,$string[1]);
},
$search
);
$x_search_array = explode(' ', my_strtolower($x_search, $lang['charset']));
foreach ($x_search_array as $item) {
$search_array[] = mysqli_real_escape_string($connid, str_replace($help_pattern, ' ', $item));
}
$search_array = array_filter(array_map('trim', $search_array), function($value) { return $value !== ''; });
// limit to 3 words:
if (count($search_array) > 3) {
for ($i = 0; $i < 3; ++$i) {
$stripped_search_array[] = $search_array[$i];
}
$search_array = $stripped_search_array;
}
$search_string_array = array();
foreach ($search_array as $item) {
if (my_strpos($item, ' ', 0, CHARSET)) {
$item = '"' . $item . '"';
}
$search_string_array[] = $item;
}
$search = implode(' ', $search_string_array);
// search...
$ham_filter = " (`" . $db_settings['akismet_rating_table'] . "`.`spam` = 0 AND `" . $db_settings['b8_rating_table'] . "`.`spam` = 0) ";
if ($method == 'fulltext_or') {
// fulltext or
$search_string = "CONCAT(LOWER(`subject`), LOWER(IF(`ft`.`user_id` > 0, (SELECT `user_name` FROM `" . $db_settings['userdata_table'] . "` WHERE `user_id` = `ft`.`user_id`), `name`)), LOWER(`text`), IFNULL(LOWER(`tag`), '')) LIKE '%" . implode("%' OR " . $ham_filter . " AND CONCAT(LOWER(`subject`), LOWER(IF(`ft`.`user_id` > 0, (SELECT `user_name` FROM `" . $db_settings['userdata_table'] . "` WHERE `user_id` = `ft`.`user_id`), `name`)), LOWER(`text`), IFNULL(LOWER(`tag`), '')) LIKE '%", $search_array) . "%'";
} elseif ($method == 'tags') {
// tags
$search_string = "(IFNULL(LOWER(`tag`), '') LIKE '%" . implode("%' OR IFNULL(LOWER(`tag`), '') LIKE '%", $search_array) . "%') ";
} else {
// fulltext
$search_string = "CONCAT(LOWER(`subject`), LOWER(IF(`ft`.`user_id` > 0, (SELECT `user_name` FROM `" . $db_settings['userdata_table'] . "` WHERE `user_id` = `ft`.`user_id`), `name`)), LOWER(`text`), IFNULL(LOWER(`tag`), '')) LIKE '%" . implode("%' AND CONCAT(LOWER(`subject`), LOWER(IF(`ft`.`user_id` > 0, (SELECT `user_name` FROM `" . $db_settings['userdata_table'] . "` WHERE `user_id` = `ft`.`user_id`), `name`)), LOWER(`text`), IFNULL(LOWER(`tag`), '')) LIKE '%", $search_array) . "%' ";
}
$search_string = $ham_filter . " AND " . $search_string;
// restrict to category
if (isset($p_category) && $p_category != 0)
$search_string = "category = " . $p_category . " AND " . $search_string;
// count results:
if ($search != '') {
$sql = "SELECT COUNT(DISTINCT `ft`.`id`)
FROM `" . $db_settings['forum_table'] . "` AS `ft`
LEFT JOIN `" . $db_settings['entry_tags_table'] . "` ON `" . $db_settings['entry_tags_table'] . "`.`bid` = `ft`.`id`
LEFT JOIN `" . $db_settings['tags_table'] . "` ON `" . $db_settings['entry_tags_table'] . "`.`tid` = `" . $db_settings['tags_table'] . "`.`id`
LEFT JOIN `" . $db_settings['akismet_rating_table'] . "` ON `" . $db_settings['akismet_rating_table'] . "`.`eid` = `ft`.`id`
LEFT JOIN `" . $db_settings['b8_rating_table'] . "` ON `" . $db_settings['b8_rating_table'] . "`.`eid` = `ft`.`id`
WHERE ";
$x_search_array = explode(' ', my_strtolower($x_search, $lang['charset']));
foreach($x_search_array as $item)
{
$search_array[] = mysql_real_escape_string(str_replace($help_pattern,' ',$item));
}
if ($categories != false)
$count_result = @mysqli_query($connid, $sql . $search_string . " AND `category` IN (" . $category_ids_query . ")");
else
$count_result = @mysqli_query($connid, $sql . $search_string);
// limit to 3 words:
if(count($search_array)>3)
{
for($i=0;$i<3;++$i)
{
$stripped_search_array[] = $search_array[$i];
}
$search_array = $stripped_search_array;
}
foreach($search_array as $item)
{
if(my_strpos($item, ' ', 0, CHARSET))
{
$item = '"'.$item.'"';
}
$serch_string_array[] = $item;
}
$search = implode(' ',$serch_string_array);
list($search_results_count) = mysqli_fetch_row($count_result);
}
else
$search_results_count = 0;
$total_pages = ceil($search_results_count / $settings['search_results_per_page']);
if (isset($_GET['page']))
$page = intval($_GET['page']);
else
$page = 1;
if ($page < 1)
$page = 1;
if ($page > $total_pages)
$page = $total_pages;
$ul = ($page - 1) * $settings['search_results_per_page'];
// data for browse navigation:
$page_browse['page'] = $page;
$page_browse['total_items'] = $search_results_count;
$page_browse['items_per_page'] = $settings['search_results_per_page'];
$page_browse['browse_array'][] = 1;
if ($page > 5)
$page_browse['browse_array'][] = 0;
for ($browse = $page - 3; $browse < $page + 4; $browse++) {
if ($browse > 1 && $browse < $total_pages)
$page_browse['browse_array'][] = $browse;
}
if ($page < $total_pages - 4)
$page_browse['browse_array'][] = 0;
if ($total_pages > 1)
$page_browse['browse_array'][] = $total_pages;
if ($page < $total_pages)
$page_browse['next_page'] = $page + 1;
else
$page_browse['next_page'] = 0;
if ($page > 1)
$page_browse['previous_page'] = $page - 1;
else
$page_browse['previous_page'] = 0;
$smarty->assign('page_browse', $page_browse);
// search...
if($method == 'fulltext_or')
{
if(isset($p_category) && $p_category != 0) $search_string = "category=".$p_category." AND spam=0 AND concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%".implode("%' OR category=".$p_category." AND spam=0 AND concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%",$search_array)."%'";
else $search_string = "spam=0 AND concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%".implode("%' OR spam=0 AND concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%",$search_array)."%'";
}
elseif ($method == 'tags')
{
if(isset($p_category) && $p_category != 0) $search_string = "lower(tags) LIKE '%;".implode(";%' AND lower(tags) LIKE '%",$search_array)."%' AND category=".$p_category." AND spam=0";
else $search_string = "lower(tags) LIKE '%;".implode(";%' AND lower(tags) LIKE '%;",$search_array).";%' AND spam=0";
}
else // fulltext
{
if(isset($p_category) && $p_category != 0) $search_string = "concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%".implode("%' AND concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%",$search_array)."%' AND category=".$p_category." AND spam=0";
else $search_string = "concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%".implode("%' AND concat(lower(subject), lower(name), lower(text), lower(tags)) LIKE '%",$search_array)."%' AND spam=0";
}
if ($search_results_count > 0) {
if ($categories != false) {
$result = @mysqli_query($connid, "SELECT DISTINCT ft.id, ft.pid, ft.tid, ft.user_id, UNIX_TIMESTAMP(ft.time) AS time, UNIX_TIMESTAMP(ft.time + INTERVAL " . $time_difference . " MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, subject, IF(text='',true,false) AS no_text, category, marked, sticky, rst.user_id AS req_user
FROM " . $db_settings['forum_table'] . " AS ft
LEFT JOIN " . $db_settings['userdata_table'] . " ON " . $db_settings['userdata_table'] . ".user_id = ft.user_id
LEFT JOIN " . $db_settings['read_status_table'] . " AS rst ON rst.posting_id = ft.id AND rst.user_id = " . intval($tmp_user_id) . "
LEFT JOIN `" . $db_settings['entry_tags_table'] . "` ON `" . $db_settings['entry_tags_table'] . "`.`bid` = `ft`.`id`
LEFT JOIN `" . $db_settings['tags_table'] . "` ON `" . $db_settings['entry_tags_table'] . "`.`tid` = `" . $db_settings['tags_table'] . "`.`id`
LEFT JOIN `" . $db_settings['akismet_rating_table'] . "` ON `" . $db_settings['akismet_rating_table'] . "`.`eid` = `ft`.`id`
LEFT JOIN `" . $db_settings['b8_rating_table'] . "` ON `" . $db_settings['b8_rating_table'] . "`.`eid` = `ft`.`id`
WHERE " . $search_string . " AND category IN (" . $category_ids_query . ")
ORDER BY tid DESC, time ASC LIMIT " . $ul . ", " . $settings['search_results_per_page']) or die(mysqli_error($connid));
} else {
$result = @mysqli_query($connid, "SELECT DISTINCT ft.id, ft.pid, ft.tid, ft.user_id, UNIX_TIMESTAMP(ft.time) AS time, UNIX_TIMESTAMP(ft.time + INTERVAL " . $time_difference . " MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, subject, IF(text='',true,false) AS no_text, category, marked, sticky, rst.user_id AS req_user
FROM " . $db_settings['forum_table'] . " AS ft
LEFT JOIN " . $db_settings['userdata_table'] . " ON " . $db_settings['userdata_table'] . ".user_id = ft.user_id
LEFT JOIN " . $db_settings['read_status_table'] . " AS rst ON rst.posting_id = ft.id AND rst.user_id = " . intval($tmp_user_id) . "
LEFT JOIN `" . $db_settings['entry_tags_table'] . "` ON `" . $db_settings['entry_tags_table'] . "`.`bid` = `ft`.`id`
LEFT JOIN `" . $db_settings['tags_table'] . "` ON `" . $db_settings['entry_tags_table'] . "`.`tid` = `" . $db_settings['tags_table'] . "`.`id`
LEFT JOIN `" . $db_settings['akismet_rating_table'] . "` ON `" . $db_settings['akismet_rating_table'] . "`.`eid` = `ft`.`id`
LEFT JOIN `" . $db_settings['b8_rating_table'] . "` ON `" . $db_settings['b8_rating_table'] . "`.`eid` = `ft`.`id`
WHERE " . $search_string . "
ORDER BY tid DESC, time ASC LIMIT " . $ul . ", " . $settings['search_results_per_page']) or die(mysqli_error($connid));
}
// count results:
if($search!='')
{
if($categories!=false) $count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE ".$search_string." AND category IN (".$category_ids_query.")", $connid);
else $count_result = mysql_query("SELECT COUNT(*) FROM ".$db_settings['forum_table']." WHERE ".$search_string, $connid);
list($search_results_count) = mysql_fetch_row($count_result);
}
else $search_results_count = 0;
$i = 0;
while ($row = mysqli_fetch_array($result)) {
$search_results[$i]['id'] = intval($row['id']);
$search_results[$i]['pid'] = intval($row['pid']);
if ($row['user_id'] > 0) {
if (!$row['user_name'])
$search_results[$i]['name'] = $lang['unknown_user'];
else
$search_results[$i]['name'] = htmlspecialchars($row['user_name']);
} else
$search_results[$i]['name'] = htmlspecialchars($row['name']);
$search_results[$i]['subject'] = htmlspecialchars($row['subject']);
$search_results[$i]['timestamp'] = $row['timestamp'];
$search_results[$i]['no_text'] = $row['no_text'];
$search_results[$i]['formated_time'] = format_time($lang['time_format'], $row['timestamp']);
if (isset($categories[$row["category"]]) && $categories[$row['category']] != '') {
$search_results[$i]['category'] = $row["category"];
$search_results[$i]['category_name'] = $categories[$row["category"]];
}
if ($row['req_user'] !== NULL and is_numeric($row['req_user'])) {
$search_results[$i]['is_read'] = true;
} else {
$search_results[$i]['is_read'] = false;
}
$i++;
}
mysqli_free_result($result);
}
$total_pages = ceil($search_results_count / $settings['search_results_per_page']);
if(isset($_GET['page'])) $page = intval($_GET['page']); else $page = 1;
if($page < 1) $page = 1;
if($page > $total_pages) $page = $total_pages;
$ul = ($page-1) * $settings['search_results_per_page'];
// data for browse navigation:
$page_browse['page'] = $page;
$page_browse['total_items'] = $search_results_count;
$page_browse['items_per_page'] = $settings['search_results_per_page'];
$page_browse['browse_array'][] = 1;
if($page > 5) $page_browse['browse_array'][] = 0;
for($browse=$page-3; $browse<$page+4; $browse++)
{
if ($browse > 1 && $browse < $total_pages) $page_browse['browse_array'][] = $browse;
}
if($page < $total_pages-4) $page_browse['browse_array'][] = 0;
if($total_pages > 1) $page_browse['browse_array'][] = $total_pages;
if($page < $total_pages) $page_browse['next_page'] = $page + 1; else $page_browse['next_page'] = 0;
if($page > 1) $page_browse['previous_page'] = $page - 1; else $page_browse['previous_page'] = 0;
$smarty->assign('page_browse',$page_browse);
$smarty->assign('search_results_count', $search_results_count);
if (isset($search_results))
$smarty->assign('search_results', $search_results);
$smarty->assign('search', htmlspecialchars($_GET['search']));
$smarty->assign('search_encoded', urlencode($search));
$smarty->assign('p_category', $p_category);
$smarty->assign('method', $method);
$smarty->assign('subnav_location', 'subnav_search');
} else {
$smarty->assign('p_category', 0);
$smarty->assign('method', 'fulltext');
}
if($search_results_count>0)
{
if($categories!=false)
{
$result = @mysql_query("SELECT id, pid, tid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, subject, IF(text='',true,false) AS no_text, category, marked, sticky
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE ".$search_string." AND category IN (".$category_ids_query.")
ORDER BY tid DESC, time ASC LIMIT ".$ul.", ".$settings['search_results_per_page'], $connid) or die(mysql_error());
}
else
{
$result = @mysql_query("SELECT id, pid, tid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(time + INTERVAL ".$time_difference." MINUTE) AS timestamp, UNIX_TIMESTAMP(last_reply) AS last_reply, name, user_name, subject, IF(text='',true,false) AS no_text, category, marked, sticky
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
WHERE ".$search_string."
ORDER BY tid DESC, time ASC LIMIT ".$ul.", ".$settings['search_results_per_page'], $connid) or die(mysql_error());
}
$i=0;
while($row = mysql_fetch_array($result))
{
$search_results[$i]['id'] = intval($row['id']);
$search_results[$i]['pid'] = intval($row['pid']);
if($row['user_id']>0)
{
if(!$row['user_name']) $search_results[$i]['name'] = $lang['unknown_user'];
else $search_results[$i]['name'] = htmlspecialchars($row['user_name']);
}
else $search_results[$i]['name'] = htmlspecialchars($row['name']);
$search_results[$i]['subject'] = htmlspecialchars($row['subject']);
$search_results[$i]['timestamp'] = $row['timestamp'];
$search_results[$i]['no_text'] = $row['no_text'];
$search_results[$i]['formated_time'] = format_time($lang['time_format'],$row['timestamp']);
if(isset($categories[$row["category"]]) && $categories[$row['category']]!='')
{
$search_results[$i]['category']=$row["category"];
$search_results[$i]['category_name']=$categories[$row["category"]];
}
$i++;
}
mysql_free_result($result);
}
$smarty->assign('search_results_count',$search_results_count);
if(isset($search_results)) $smarty->assign('search_results',$search_results);
$smarty->assign('search',htmlspecialchars($_GET['search']));
$smarty->assign('search_encoded',urlencode($search));
$smarty->assign('p_category',$p_category);
$smarty->assign('method',$method);
}
else
{
$smarty->assign('p_category',0);
$smarty->assign('method','fulltext');
}
$smarty->assign('subnav_location','subnav_search');
$smarty->assign('subtemplate','search.inc.tpl');
$smarty->assign('subtemplate', 'search.inc.tpl');
$template = 'main.tpl';
?>

View file

@ -1,274 +1,294 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if(isset($_REQUEST['id']))
{
$id = intval($_REQUEST['id']);
}
if(empty($id))
{
header('location: index.php');
exit;
}
if (!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['thread_display'])) $thread_display = $_SESSION[$settings['session_prefix'].'usersettings']['thread_display'];
else $thread_display = 0;
if (isset($_REQUEST['id'])) {
$id = intval($_REQUEST['id']);
}
if(isset($_GET['page'])) $page = intval($_GET['page']);
else $page = 1;
if (empty($id)) {
header('location: index.php');
exit;
}
if(isset($_GET['order']) && $_GET['order']=='last_reply') $order = 'last_reply';
else $order = 'time';
if (isset($_SESSION[$settings['session_prefix'] . 'user_id'])) {
$tmp_user_id = $_SESSION[$settings['session_prefix'] . 'user_id'];
} else {
$tmp_user_id = 0;
}
if (isset($_SESSION[$settings['session_prefix'] . 'usersettings']['thread_display']))
$thread_display = $_SESSION[$settings['session_prefix'] . 'usersettings']['thread_display'];
else
$thread_display = 0;
if (isset($_GET['page']))
$page = intval($_GET['page']);
else
$page = 1;
if (isset($_GET['order']) && $_GET['order'] == 'last_reply')
$order = 'last_reply';
else
$order = 'time';
$isUser = isset($_SESSION[$settings['session_prefix'].'user_type']) && isset($_SESSION[$settings['session_prefix'].'user_id']);
$isModOrAdmin = $isUser && ($_SESSION[$settings['session_prefix'].'user_type'] == 1 || $_SESSION[$settings['session_prefix'].'user_type'] == 2);
// tid, subject and category of starting posting:
$result=mysql_query("SELECT tid, subject, category FROM ".$db_settings['forum_table']." WHERE id = ".intval($id)." LIMIT 1", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result)!=1)
{
header('Location: index.php');
exit;
}
else
{
$data = mysql_fetch_array($result);
mysql_free_result($result);
}
$result = mysqli_query($connid, "SELECT tid, subject, category FROM " . $db_settings['forum_table'] . " WHERE id = " . intval($id) . " LIMIT 1") or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) != 1) {
header('Location: index.php');
exit;
} else {
$data = mysqli_fetch_array($result);
mysqli_free_result($result);
}
// category of this posting accessible by user?
if(is_array($category_ids) && !in_array($data['category'], $category_ids))
{
header("location: index.php");
exit;
}
elseif($data['tid'] != $id)
{
// it wasn't the id of the thread start
header('Location: index.php?mode=thread&id='.$data['tid'].'#p'.$id);
exit;
}
else
{
$tid = $data['tid'];
$smarty->assign("tid",$tid);
// category of this posting accessible by user?
if (is_array($category_ids) && !in_array($data['category'], $category_ids)) {
header("location: index.php");
exit;
} elseif ($data['tid'] != $id) {
// it wasn't the id of the thread start
header('Location: index.php?mode=thread&id=' . $data['tid'] . '#p' . $id);
exit;
} else {
$tid = $data['tid'];
$smarty->assign("tid", $tid);
if (isset($settings['count_views']) && $settings['count_views'] == 1)
@mysqli_query($connid, "UPDATE " . $db_settings['forum_table'] . " SET time=time, last_reply=last_reply, edited=edited, views=views+1 WHERE tid=" . $id);
$smarty->assign('page_title', htmlspecialchars($data['subject']));
if (isset($categories[$data['category']]) && $categories[$data['category']] != '')
$smarty->assign('category_name', $categories[$data["category"]]);
if ($show_spam) {
$thread_spam = " AS spam_list ON spam_list.tid = ft.tid WHERE spam_list.id IS NOT NULL";
} else {
$thread_spam = " AS spam_list ON spam_list.id = ft.id WHERE spam_list.id IS NULL";
}
// get all postings of thread:
$thread_sql =
"SELECT ft.id, ft.pid, ft.tid, ft.user_id, UNIX_TIMESTAMP(ft.time + INTERVAL " . intval($time_difference) . " MINUTE) AS disp_time,
UNIX_TIMESTAMP(last_reply + INTERVAL " . intval($time_difference) . " MINUTE) AS last_reply,
UNIX_TIMESTAMP(ft.time) AS time, UNIX_TIMESTAMP(edited) AS edited_time, UNIX_TIMESTAMP(edited + INTERVAL " . intval($time_difference) . " MINUTE) AS e_time,
UNIX_TIMESTAMP(edited - INTERVAL " . $settings['edit_delay'] . " MINUTE) AS edited_diff, edited_by, name, email,
subject, hp, location, ip, text, cache_text, show_signature, views, category, locked, ip,
user_name, user_type, user_email, email_contact, user_hp, user_location, signature, cache_signature, edit_key, rst.user_id AS req_user,
" . $db_settings['akismet_rating_table'] . ".spam AS akismet_spam, spam_check_status,
" . $db_settings['b8_rating_table'] . ".spam AS b8_spam, training_type
FROM " . $db_settings['forum_table'] . " AS ft
LEFT JOIN " . $db_settings['entry_cache_table'] . " ON " . $db_settings['entry_cache_table'] . ".cache_id = ft.id
LEFT JOIN " . $db_settings['userdata_table'] . " ON " . $db_settings['userdata_table'] . ".user_id = ft.user_id
LEFT JOIN " . $db_settings['userdata_cache_table'] . " ON " . $db_settings['userdata_cache_table'] . ".cache_id = " . $db_settings['userdata_table'] . ".user_id
LEFT JOIN " . $db_settings['read_status_table'] . " AS rst ON rst.posting_id = ft.id AND rst.user_id = " . intval($tmp_user_id) . "
LEFT JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['akismet_rating_table'] . ".eid = ft.id
LEFT JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['b8_rating_table'] . ".eid = ft.id
LEFT JOIN (SELECT " . $db_settings['forum_table'] . ".id, " . $db_settings['forum_table'] . ".tid FROM " . $db_settings['forum_table'] . " INNER JOIN " . $db_settings['akismet_rating_table'] . " ON " . $db_settings['forum_table'] . ".id = " . $db_settings['akismet_rating_table'] . ".eid WHERE " . $db_settings['akismet_rating_table'] . ".spam = 1 UNION SELECT " . $db_settings['forum_table'] . ".id, " . $db_settings['forum_table'] . ".tid FROM " . $db_settings['forum_table'] . " INNER JOIN " . $db_settings['b8_rating_table'] . " ON " . $db_settings['forum_table'] . ".id = " . $db_settings['b8_rating_table'] . ".eid WHERE " . $db_settings['b8_rating_table'] . ".spam = 1)
" . $thread_spam . " AND ft.tid = " . $tid . " ORDER BY ft.time ASC";
$result = mysqli_query($connid, $thread_sql) or raise_error('database_error', mysqli_error($connid));
if (mysqli_num_rows($result) > 0) {
while ($data = mysqli_fetch_array($result)) {
// tags:
$tags = getEntryTags($data['id']);
if (!empty($tags)) {
unset($tags_array);
$i=0;
foreach ($tags as $tag) {
if (my_strpos($tag, ' ', 0, $lang['charset']))
$tag_escaped = '"' . $tag . '"';
else
$tag_escaped = $tag;
$tags_array[$i]['escaped'] = urlencode($tag_escaped);
$tags_array[$i]['display'] = htmlspecialchars($tag);
$i++;
}
if (isset($tags_array))
$data['tags'] = $tags_array;
}
$data['formated_time'] = format_time($lang['time_format_full'], $data['disp_time']);
$data['ISO_time'] = format_time('YYYY-MM-dd HH:mm:ss', $data['time']);
$ago['days'] = floor((TIMESTAMP - $data['time']) / 86400);
$ago['hours'] = floor(((TIMESTAMP - $data['time']) / 3600) - ($ago['days'] * 24));
$ago['minutes'] = floor(((TIMESTAMP - $data['time']) / 60) - ($ago['hours'] * 60 + $ago['days'] * 1440));
if ($ago['hours'] > 12)
$ago['days_rounded'] = $ago['days'] + 1;
else
$ago['days_rounded'] = $ago['days'];
$data['ago'] = $ago;
if ($data['user_id'] > 0) {
if (!$data['user_name'])
$data['name'] = $lang['unknown_user'];
else
$data['name'] = htmlspecialchars($data['user_name']);
} else
$data['name'] = htmlspecialchars($data['name']);
$data['subject'] = htmlspecialchars($data['subject']);
$authorization = get_edit_authorization($data['id'], $data['user_id'], $data['edit_key'], $data['time'], $data['locked']);
if ($authorization['edit'] == true)
$data['options']['edit'] = true;
if ($authorization['delete'] == true)
$data['options']['delete'] = true;
if ($data['user_id'] > 0) {
$data['email'] = $data['user_email'];
$data['location'] = $data['user_location'];
$data['hp'] = $data['user_hp'];
if ($settings['avatars'] == 2) {
$avatarInfo = getAvatar($data['user_id']);
$avatar['image'] = $avatarInfo === false ? false : $avatarInfo[2];
if (isset($avatar) && $avatar['image'] !== false) {
$image_info = getimagesize($avatar['image']);
$avatar['width'] = $image_info[0];
$avatar['height'] = $image_info[1];
$data['avatar'] = $avatar;
unset($avatar);
}
}
} else {
$data["email_contact"] = 2;
}
if ($data['edited_diff'] > 0 && $data["edited_diff"] > $data["time"] && $settings['show_if_edited'] == 1) {
$data['edited'] = true;
$data['formated_edit_time'] = format_time($lang['time_format_full'], $data['e_time']);
$data['ISO_edit_time'] = format_time('YYYY-MM-dd HH:mm:ss', $data['edited_time']);
if ($data['user_id'] == $data['edited_by'])
$data['edited_by'] = $data['name'];
else {
$edited_result = @mysqli_query($connid, "SELECT user_name FROM " . $db_settings['userdata_table'] . " WHERE user_id = " . intval($data['edited_by']) . " LIMIT 1");
$edited_data = mysqli_fetch_array($edited_result);
@mysqli_free_result($edited_result);
if (!$edited_data['user_name'])
$data['edited_by'] = $lang['unknown_user'];
else
$data['edited_by'] = htmlspecialchars($edited_data['user_name']);
}
}
if ($data['cache_text'] == '') {
// no cached text so parse it and cache it:
$data['posting'] = html_format($data['text']);
// make sure not to make a double entry:
@mysqli_query($connid, "DELETE FROM " . $db_settings['entry_cache_table'] . " WHERE cache_id=" . intval($data['id']));
@mysqli_query($connid, "INSERT INTO " . $db_settings['entry_cache_table'] . " (cache_id, cache_text) VALUES (" . intval($data['id']) . ",'" . mysqli_real_escape_string($connid, $data['posting']) . "')");
} else {
$data['posting'] = $data['cache_text'];
}
if (isset($data['signature']) && $data['signature'] != '' && $data["show_signature"] == 1) {
// user has a signature and wants it to be displayed in this posting. Check if it's already cached:
if ($data['cache_signature'] != '') {
$data['signature'] = $data['cache_signature'];
} else {
$s_result = @mysqli_query($connid, "SELECT cache_signature FROM " . $db_settings['userdata_cache_table'] . " WHERE cache_id=" . intval($data['user_id']) . " LIMIT 1");
$s_data = mysqli_fetch_array($s_result);
if ($s_data['cache_signature'] != '') {
$data['signature'] = $s_data['cache_signature'];
} else {
$data['signature'] = signature_format($data['signature']);
// cache signature:
$xxx = mysqli_query($connid, "SELECT COUNT(*) FROM " . $db_settings['userdata_cache_table'] . " WHERE cache_id=" . intval($data['user_id'])) or die(mysqli_error($connid));
list($row_count) = mysqli_fetch_row($xxx);
if ($row_count == 1) {
@mysqli_query($connid, "UPDATE " . $db_settings['userdata_cache_table'] . " SET cache_signature='" . mysqli_real_escape_string($connid, $data['signature']) . "' WHERE cache_id=" . intval($data['user_id']));
} else {
@mysqli_query($connid, "DELETE FROM " . $db_settings['userdata_cache_table'] . " WHERE cache_id=" . intval($data['user_id']));
@mysqli_query($connid, "INSERT INTO " . $db_settings['userdata_cache_table'] . " (cache_id, cache_signature, cache_profile) VALUES (" . intval($data['user_id']) . ",'" . mysqli_real_escape_string($connid, $data['signature']) . "','')");
}
}
}
} else {
unset($data['signature']);
}
if (empty($data["email_contact"]))
$data["email_contact"] = 0;
if ($data['hp'] != '') {
$data['hp'] = add_http_if_no_protocol($data['hp']);
}
if ($data['email'] != '' && ($isModOrAdmin || $isUser && $data['email_contact'] > 0 || $data['email_contact'] == 2))
$data['email'] = true;
else
$data['email'] = false;
if ($data['location'] != '')
$data['location'] = htmlspecialchars($data['location']);
if (isset($_SESSION[$settings['session_prefix'] . 'user_type']) && $_SESSION[$settings['session_prefix'] . 'user_type'] > 0) {
$data['options']['move'] = true;
$data['options']['lock'] = true;
if (($settings['akismet_key'] != '' && $settings['akismet_entry_check'] == 1 && $data['akismet_spam'] == 0 && $data['spam_check_status'] > 0) || ($settings['b8_entry_check'] == 1 && $data['b8_spam'] == 0 || $data['training_type'] == 0))
$data['options']['report_spam'] = true;
if (($settings['akismet_key'] != '' && $settings['akismet_entry_check'] == 1 && $data['akismet_spam'] == 1 && $data['spam_check_status'] > 0) || ($settings['b8_entry_check'] == 1 && $data['b8_spam'] == 1 || $data['training_type'] == 0))
$data['options']['flag_ham'] = true;
}
if ($settings['count_views'] == 1) {
$views = $data['views'] - 1; // this subtracts the first view by the author after posting
if ($views < 0)
$views = 0; // prevents negative number of views
$data['views'] = $views;
} else
$data['views'] = 0;
if (isset($_SESSION[$settings['session_prefix'] . 'user_id'])) {
// bookmark handling
$user_id = $_SESSION[$settings['session_prefix'] . 'user_id'];
$bookmark_result = mysqli_query($connid, "SELECT TRUE AS 'bookmark' FROM " . $db_settings['bookmark_table'] . " WHERE `user_id` = " . intval($user_id) . " AND `posting_id` = " . intval($data['id']) . "") or raise_error('database_error', mysqli_error($connid));
$bookmark = mysqli_fetch_row($bookmark_result);
mysqli_free_result($bookmark_result);
if (isset($bookmark) && intval($bookmark) == 1) {
$data['bookmarkedby'] = intval($user_id);
$data['options']['delete_bookmark'] = true;
} else
$data['options']['add_bookmark'] = true;
// read-status handling
$rstatus = save_read_status($connid, $user_id, $data['id']);
}
// set read or new status of messages
$data = getMessageStatus($data, $last_visit);
$data_array[$data["id"]] = $data;
$child_array[$data["pid"]][] = $data["id"];
}
mysqli_free_result($result);
} else {
header("location: index.php");
exit;
}
$subnav_link = array(
'mode' => 'index',
'name' => 'thread_entry_back_link',
'title' => 'thread_entry_back_title'
);
$smarty->assign('id', $id);
$smarty->assign('data', $data_array);
if (isset($child_array))
$smarty->assign('child_array', $child_array);
$smarty->assign('subnav_link', $subnav_link);
$smarty->assign('page', $page);
$smarty->assign('order', $order);
$smarty->assign('category', $category);
if ($thread_display == 0)
$smarty->assign('subtemplate', 'thread.inc.tpl');
else
$smarty->assign('subtemplate', 'thread_linear.inc.tpl');
$template = 'main.tpl';
}
if(isset($settings['count_views']) && $settings['count_views'] == 1) @mysql_query("UPDATE ".$db_settings['forum_table']." SET time=time, last_reply=last_reply, edited=edited, views=views+1 WHERE tid=".$id, $connid);
$smarty->assign('page_title',htmlspecialchars($data['subject']));
$smarty->assign('category_name',$categories[$data["category"]]);
// get all postings of thread:
$result = mysql_query("SELECT id, pid, tid, ".$db_settings['forum_table'].".user_id, UNIX_TIMESTAMP(time + INTERVAL ".intval($time_difference)." MINUTE) AS disp_time,
UNIX_TIMESTAMP(time) AS time, UNIX_TIMESTAMP(edited + INTERVAL ".intval($time_difference)." MINUTE) AS e_time,
UNIX_TIMESTAMP(edited - INTERVAL ".$settings['edit_delay']." MINUTE) AS edited_diff, edited_by, name, email,
subject, hp, location, ip, text, cache_text, tags, show_signature, views, spam, spam_check_status, category, locked, ip,
user_name, user_type, user_email, email_contact, user_hp, user_location, signature, cache_signature, edit_key
FROM ".$db_settings['forum_table']."
LEFT JOIN ".$db_settings['entry_cache_table']." ON ".$db_settings['entry_cache_table'].".cache_id=id
LEFT JOIN ".$db_settings['userdata_table']." ON ".$db_settings['userdata_table'].".user_id=".$db_settings['forum_table'].".user_id
LEFT JOIN ".$db_settings['userdata_cache_table']." ON ".$db_settings['userdata_cache_table'].".cache_id=".$db_settings['userdata_table'].".user_id
WHERE tid = ".$tid.$display_spam_query_and." ORDER BY time ASC", $connid) or raise_error('database_error',mysql_error());
if(mysql_num_rows($result) > 0)
{
while($data = mysql_fetch_array($result))
{
$new_read[] = $data['id'];
// tags:
unset($tags_array);
$tags = $data['tags'];
if($tags!='')
{
$tags_help_array = explode(';',$tags);
$i=0;
foreach($tags_help_array as $tag)
{
if($tag!='')
{
if(my_strpos($tag, ' ', 0, $lang['charset'])) $tag_escaped='"'.$tag.'"';
else $tag_escaped = $tag;
$tags_array[$i]['escaped'] = urlencode($tag_escaped);
$tags_array[$i]['display'] = htmlspecialchars($tag);
$i++;
}
}
if(isset($tags_array)) $data['tags'] = $tags_array;
}
$data['formated_time'] = format_time($lang['time_format_full'],$data['disp_time']);
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime']) && $_SESSION[$settings['session_prefix'].'usersettings']['newtime']<$data['time'] || $last_visit && $data['time'] > $last_visit) $data['new'] = true;
else $data['new'] = false;
$ago['days'] = floor((time() - $data['time'])/86400);
$ago['hours'] = floor(((time() - $data['time'])/3600)-($ago['days']*24));
$ago['minutes'] = floor(((time() - $data['time'])/60)-($ago['hours']*60+$ago['days']*1440));
if($ago['hours']>12) $ago['days_rounded'] = $ago['days'] + 1;
else $ago['days_rounded'] = $ago['days'];
$data['ago'] = $ago;
if($data['user_id']>0)
{
if(!$data['user_name']) $data['name'] = $lang['unknown_user'];
else $data['name'] = htmlspecialchars($data['user_name']);
}
else $data['name'] = htmlspecialchars($data['name']);
$data['subject'] = htmlspecialchars($data['subject']);
$authorization = get_edit_authorization($data['id'], $data['user_id'], $data['edit_key'], $data['time'], $data['locked']);
if($authorization['edit']==true) $data['options']['edit']=true;
if($authorization['delete']==true) $data['options']['delete']=true;
if($data['user_id'] > 0)
{
$data['email'] = $data['user_email'];
$data['location'] = $data['user_location'];
$data['hp'] = $data['user_hp'];
if($settings['avatars']==2)
{
if(file_exists('images/avatars/'.$data['user_id'].'.jpg')) $avatar['image'] = 'images/avatars/'.$data['user_id'].'.jpg';
elseif(file_exists('images/avatars/'.$data['user_id'].'.png')) $avatar['image'] = 'images/avatars/'.$data['user_id'].'.png';
elseif(file_exists('images/avatars/'.$data['user_id'].'.gif')) $avatar['image'] = 'images/avatars/'.$data['user_id'].'.gif';
if(isset($avatar))
{
$image_info = getimagesize($avatar['image']);
$avatar['width'] = $image_info[0];
$avatar['height'] = $image_info[1];
$data['avatar'] = $avatar;
unset($avatar);
}
}
}
else
{
$data["email_contact"]=1;
}
if($data['edited_diff'] > 0 && $data["edited_diff"] > $data["time"] && $settings['show_if_edited'] == 1)
{
$data['edited'] = true;
$data['formated_edit_time'] = format_time($lang['time_format_full'],$data['e_time']);
if($data['user_id'] == $data['edited_by']) $data['edited_by'] = $data['name'];
else
{
$edited_result = @mysql_query("SELECT user_name
FROM ".$db_settings['userdata_table']."
WHERE user_id = ".intval($data['edited_by'])." LIMIT 1", $connid);
$edited_data = mysql_fetch_array($edited_result);
@mysql_free_result($edited_result);
if(!$edited_data['user_name']) $data['edited_by'] = $lang['unknown_user'];
else $data['edited_by'] = htmlspecialchars($edited_data['user_name']);
}
}
if($data['cache_text']=='')
{
// no cached text so parse it and cache it:
$data['posting'] = html_format($data['text']);
// make sure not to make a double entry:
@mysql_query("DELETE FROM ".$db_settings['entry_cache_table']." WHERE cache_id=".intval($data['id']), $connid);
@mysql_query("INSERT INTO ".$db_settings['entry_cache_table']." (cache_id, cache_text) VALUES (".intval($data['id']).",'".mysql_real_escape_string($data['posting'])."')", $connid);
}
else
{
$data['posting'] = $data['cache_text'];
}
#if(isset($data['signature']) && $data['signature'] != '' && $data["show_signature"]==1) $data['signature'] = signature_format($data['signature']);
#else unset($data['signature']);
if(isset($data['signature']) && $data['signature'] != '' && $data["show_signature"]==1)
{
// user has a signature and wants it to be displaed in this posting. Check if it's already cached:
if($data['cache_signature']!='')
{
$data['signature'] = $data['cache_signature'];
}
else
{
$s_result = @mysql_query("SELECT cache_signature FROM ".$db_settings['userdata_cache_table']." WHERE cache_id=".intval($data['user_id'])." LIMIT 1", $connid);
$s_data = mysql_fetch_array($s_result);
if($s_data['cache_signature']!='')
{
$data['signature'] = $s_data['cache_signature'];
}
else
{
$data['signature'] = signature_format($data['signature']);
// cache signature:
$xxx = mysql_query("SELECT COUNT(*) FROM ".$db_settings['userdata_cache_table']." WHERE cache_id=".intval($data['user_id']), $connid) or die(mysql_error());
list($row_count) = mysql_fetch_row($xxx);
#echo 'row count: '.$row_count.' user_id: '.$data['user_id'].'<br />';
if($row_count==1)
{
@mysql_query("UPDATE ".$db_settings['userdata_cache_table']." SET cache_signature='".mysql_real_escape_string($data['signature'])."' WHERE cache_id=".intval($data['user_id']), $connid);
}
else
{
@mysql_query("DELETE FROM ".$db_settings['userdata_cache_table']." WHERE cache_id=".intval($data['user_id']), $connid);
@mysql_query("INSERT INTO ".$db_settings['userdata_cache_table']." (cache_id, cache_signature, cache_profile) VALUES (".intval($data['user_id']).",'".mysql_real_escape_string($data['signature'])."','')", $connid);
}
}
}
}
else
{
unset($data['signature']);
}
if(empty($data["email_contact"])) $data["email_contact"]=0;
if($data['hp']!='')
{
$data['hp'] = add_http_if_no_protocol($data['hp']);
}
if($data['email']!='' && $data['email_contact']==1) $data['email']=true;
else $data['email']=false;
if($data['location'] != '') $data['location']=htmlspecialchars($data['location']);
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0)
{
$data['options']['move']=true;
$data['options']['lock'] = true;
}
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0 && $settings['akismet_key']!='' && $settings['akismet_entry_check']==1 && $data['spam']==0 && $data['spam_check_status']>0) $data['options']['report_spam']=true;
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0 && $data['spam']==1) $data['options']['flag_ham']=true;
if($settings['count_views'] == 1)
{
$views = $data['views']-1; // this subtracts the first view by the author after posting
if($views<0) $views=0; // prevents negative number of views
$data['views'] = $views;
}
else $data['views']=0;
$data_array[$data["id"]] = $data;
$child_array[$data["pid"]][] = $data["id"];
}
mysql_free_result($result);
save_read(set_read($new_read));
}
else
{
header("location: index.php");
exit;
}
$subnav_link = array('mode'=>'index', 'name'=>'thread_entry_back_link', 'title'=>'thread_entry_back_title');
$smarty->assign('id',$id);
$smarty->assign('data',$data_array);
if(isset($child_array)) $smarty->assign('child_array', $child_array);
$smarty->assign('subnav_link',$subnav_link);
$smarty->assign('page',$page);
$smarty->assign('order',$order);
$smarty->assign('category',$category);
if($thread_display==0) $smarty->assign('subtemplate','thread.inc.tpl');
else $smarty->assign('subtemplate','thread_linear.inc.tpl');
$template = 'main.tpl';
}
?>

View file

@ -1,196 +1,165 @@
<?php
if(!defined('IN_INDEX'))
{
header('Location: ../index.php');
exit;
}
if(!defined('IN_INDEX')) {
header('Location: ../index.php');
exit;
}
// upload folder:
$uploaded_images_path = 'images/uploaded/';
$images_per_page = 5;
if(($settings['upload_images']==1 && isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0)||($settings['upload_images']==2 && isset($_SESSION[$settings['session_prefix'].'user_id']))||($settings['upload_images']==3))
{
// upload:image:
if(isset($_FILES['probe']) && $_FILES['probe']['size'] != 0 && !$_FILES['probe']['error'])
{
unset($errors);
$image_info = getimagesize($_FILES['probe']['tmp_name']);
if (($settings['upload_images'] == 1 && isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type'] > 0) || ($settings['upload_images'] == 2 && isset($_SESSION[$settings['session_prefix'].'user_id'])) || ($settings['upload_images'] == 3)) {
// upload:image:
if (isset($_FILES['probe']) && $_FILES['probe']['size'] != 0 && !$_FILES['probe']['error']) {
unset($errors);
$user_id = (isset($_SESSION[$settings['session_prefix'].'user_id'])) ? intval($_SESSION[$settings['session_prefix'].'user_id']) : NULL;
$image_info = getimagesize($_FILES['probe']['tmp_name']);
$imageMIME = mime_content_type($_FILES['probe']['tmp_name']);
if (!is_array($image_info) || !in_array($imageMIME, ['image/gif', 'image/jpeg', 'image/png', 'image/webp']))
$errors[] = 'invalid_file_format';
if(!is_array($image_info) || $image_info[2] != 1 && $image_info[2] != 2 && $image_info[2] != 3) $errors[] = 'invalid_file_format';
if (empty($errors)) {
if ($_FILES['probe']['size'] > $settings['upload_max_img_size'] * 1000 || $image_info[0] > $settings['upload_max_img_width'] || $image_info[1] > $settings['upload_max_img_height']) {
$width = $image_info[0];
$height = $image_info[1];
// resize if too large:
if ($width > $settings['upload_max_img_width'] || $height > $settings['upload_max_img_height']) {
if ($width >= $height) {
$new_width = $settings['upload_max_img_width'];
$new_height = intval($height*$new_width/$width);
} else {
$new_height = $settings['upload_max_img_height'];
$new_width = intval($width*$new_height/$height);
}
} else {
$new_width = $width;
$new_height = $height;
}
$img_tmp_name = uniqid(rand()).'.tmp';
for ($compression = 100; $compression > 1; $compression = $compression - 10) {
if (!resize_image($_FILES['probe']['tmp_name'], $uploaded_images_path.$img_tmp_name, $new_width, $new_height, $compression)) {
$file_size = $_FILES['probe']['size']; // @filesize($_FILES['probe']['tmp_name']);
break;
}
$file_size = @filesize($uploaded_images_path.$img_tmp_name);
if ($imageMIME != 'image/jpeg' && $file_size > $settings['upload_max_img_size'] * 1000) break;
if ($file_size <= $settings['upload_max_img_size'] * 1000) break;
}
if ($file_size > $settings['upload_max_img_size'] * 1000) {
$smarty->assign('width', $image_info[0]);
$smarty->assign('height', $image_info[1]);
$smarty->assign('filesize', number_format($_FILES['probe']['size'] / 1000, 0, ',', ''));
$smarty->assign('max_width', $settings['upload_max_img_width']);
$smarty->assign('max_height', $settings['upload_max_img_height']);
$smarty->assign('max_filesize', $settings['upload_max_img_size']);
$errors[] = 'file_too_large';
}
if (isset($errors)) {
if (file_exists($uploaded_images_path.$img_tmp_name)) {
@chmod($uploaded_images_path.$img_tmp_name, 0777);
@unlink($uploaded_images_path.$img_tmp_name);
}
}
}
}
if(empty($errors))
{
if($_FILES['probe']['size'] > $settings['upload_max_img_size']*1000 || $image_info[0] > $settings['upload_max_img_width'] || $image_info[1] > $settings['upload_max_img_height'])
{
#$compression = 10;
$width=$image_info[0];
$height=$image_info[1];
if (empty($errors)) {
$filename = gmdate("YmdHis").uniqid('');
switch($imageMIME) {
case 'image/gif':
$filename .= '.gif';
break;
case 'image/jpeg':
$filename .= '.jpg';
break;
case 'image/png':
$filename .= '.png';
break;
case 'image/webp':
$filename .= '.webp';
break;
}
if (isset($img_tmp_name)) {
@rename($uploaded_images_path.$img_tmp_name, $uploaded_images_path.$filename) or $errors[] = 'upload_error';
$smarty->assign('image_downsized', true);
$smarty->assign('new_width', $new_width);
$smarty->assign('new_height', $new_height);
$smarty->assign('new_filesize', number_format($file_size / 1000, 0, ',', ''));
} else {
@move_uploaded_file($_FILES['probe']['tmp_name'], $uploaded_images_path.$filename) or $errors[] = 'upload_error';
}
}
if (empty($errors)) {
@chmod($uploaded_images_path.$filename, 0644);
// $user_id can be NULL (see around line #15), because of that do not handle it with intval()
// see therefore variable definition of $user_id around line 15 of this script
$qSetUpload = "INSERT INTO " . $db_settings['uploads_table'] . " (uploader, pathname, tstamp) VALUES (". $user_id .", '" . mysqli_real_escape_string($connid, $filename) . "', NOW())";
mysqli_query($connid, $qSetUpload);
$smarty->assign('uploaded_file', $filename);
} else {
$smarty->assign('errors', $errors);
$smarty->assign('form', true);
}
}
// resize if too large:
if($width > $settings['upload_max_img_width'] || $height > $settings['upload_max_img_height'])
{
if($width >= $height)
{
$new_width = $settings['upload_max_img_width'];
$new_height = intval($height*$new_width/$width);
}
else
{
$new_height = $settings['upload_max_img_height'];
$new_width = intval($width*$new_height/$height);
}
}
else
{
$new_width=$width;
$new_height=$height;
}
// delete image:
elseif (isset($_REQUEST['delete']) && isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type'] > 0) {
if (empty($_REQUEST['delete_confirm'])) {
$smarty->assign('delete_confirm', true);
$smarty->assign('delete', htmlspecialchars($_REQUEST['delete']));
if (isset($_REQUEST['current'])) $smarty->assign('current', intval($_REQUEST['current']));
} else {
if (preg_match('/^([a-z0-9]+)\.(gif|jpg|png|webp)$/', $_REQUEST['delete']) && file_exists($uploaded_images_path.$_REQUEST['delete'])) {
@chmod($uploaded_images_path.$_REQUEST['delete'], 0777);
@unlink($uploaded_images_path.$_REQUEST['delete']);
}
if (isset($_REQUEST['current'])) $bi = '&browse_images='.intval($_REQUEST['current']);
else $bi = '&browse_images=1';
header('Location: index.php?mode=upload_image'.$bi);
exit;
}
}
$img_tmp_name = uniqid(rand()).'.tmp';
// browse uploaded images:
elseif (isset($_GET['browse_images'])) {
$images = array();
$browse_images = intval($_GET['browse_images']);
if ($browse_images < 1) $browse_images = 1;
$handle = opendir($uploaded_images_path);
while ($file = readdir($handle)) {
if (preg_match('/\.(gif|png|jpe?g|svg|webp)$/i', $file)) {
$images[] = $file;
}
}
closedir($handle);
if ($images) {
rsort($images);
$images_count = count($images);
if ($browse_images > ceil($images_count / $images_per_page)) $browse_images = ceil($images_count / $images_per_page);
$start = $browse_images * $images_per_page - $images_per_page;
$show_images_to = $browse_images * $images_per_page;
if ($show_images_to > $images_count) $show_images_to = $images_count;
}
else $images_count = 0;
$smarty->assign('current',$browse_images);
if ($browse_images*$images_per_page < $images_count) $smarty->assign('next', $browse_images + 1);
if ($browse_images > 1) $smarty->assign('previous', $browse_images - 1);
$smarty->assign('browse_images', true);
$smarty->assign('images_per_page', $images_per_page);
if (isset($images)) $smarty->assign('images', $images);
if (isset($start)) $smarty->assign('start', $start);
}
for($compression = 100; $compression>1; $compression=$compression-10)
{
if(!resize_image($_FILES['probe']['tmp_name'], $uploaded_images_path.$img_tmp_name, $new_width, $new_height, $compression))
{
$file_size = $_FILES['probe']['size']; // @filesize($_FILES['probe']['tmp_name']);
break;
}
$file_size = @filesize($uploaded_images_path.$img_tmp_name);
if($image_info[2]!=2 && $file_size > $settings['upload_max_img_size']*1000) break;
if($file_size <= $settings['upload_max_img_size']*1000) break;
}
if($file_size > $settings['upload_max_img_size']*1000)
{
$smarty->assign('width',$image_info[0]);
$smarty->assign('height',$image_info[1]);
$smarty->assign('filesize',number_format($_FILES['probe']['size']/1000,0,',',''));
$smarty->assign('max_width',$settings['upload_max_img_width']);
$smarty->assign('max_height',$settings['upload_max_img_height']);
$smarty->assign('max_filesize',$settings['upload_max_img_size']);
$errors[] = 'file_too_large';
}
if(isset($errors))
{
if(file_exists($uploaded_images_path.$img_tmp_name))
{
@chmod($uploaded_images_path.$img_tmp_name, 0777);
@unlink($uploaded_images_path.$img_tmp_name);
}
}
}
}
if(empty($errors))
{
$filename = gmdate("YmdHis").uniqid('');
switch($image_info[2])
{
case 1:
$filename .= '.gif';
break;
case 2:
$filename .= '.jpg';
break;
case 3:
$filename .= '.png';
break;
}
if(isset($img_tmp_name))
{
@rename($uploaded_images_path.$img_tmp_name, $uploaded_images_path.$filename) or $errors[] = 'upload_error';
$smarty->assign('image_downsized',true);
$smarty->assign('new_width',$new_width);
$smarty->assign('new_height',$new_height);
$smarty->assign('new_filesize',number_format($file_size/1000,0,',',''));
}
else
{
@move_uploaded_file($_FILES['probe']['tmp_name'], $uploaded_images_path.$filename) or $errors[] = 'upload_error';
}
}
if(empty($errors))
{
@chmod($uploaded_images_path.$filename, 0644);
$smarty->assign('uploaded_file',$filename);
}
else
{
$smarty->assign('errors',$errors);
$smarty->assign('form',true);
}
}
// delete image:
elseif(isset($_REQUEST['delete']) && isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']>0)
{
if(empty($_REQUEST['delete_confirm']))
{
$smarty->assign('delete_confirm',true);
$smarty->assign('delete',htmlspecialchars($_REQUEST['delete']));
if(isset($_REQUEST['current'])) $smarty->assign('current',intval($_REQUEST['current']));
}
else
{
if(preg_match('/^([a-z0-9]+)\.(gif|jpg|png)$/', $_REQUEST['delete']) && file_exists($uploaded_images_path.$_REQUEST['delete']))
{
@chmod($uploaded_images_path.$_REQUEST['delete'], 0777);
@unlink($uploaded_images_path.$_REQUEST['delete']);
}
if(isset($_REQUEST['current'])) $bi = '&browse_images='.intval($_REQUEST['current']);
else $bi = '&browse_images=1';
header('Location: index.php?mode=upload_image'.$bi);
exit;
}
}
// browse uploaded images:
elseif(isset($_GET['browse_images']))
{
$browse_images = intval($_GET['browse_images']);
if($browse_images<1)$browse_images=1;
$handle=opendir($uploaded_images_path);
while ($file = readdir($handle))
{
if(preg_match('/\.jpg$/i', $file) || preg_match('/\.png$/i', $file) || preg_match('/\.gif$/i', $file))
{
$images[] = $file;
}
}
closedir($handle);
if(isset($images))
{
rsort($images);
$images_count = count($images);
if($browse_images > ceil($images_count/$images_per_page)) $browse_images=ceil($images_count/$images_per_page);
$start = $browse_images * $images_per_page - $images_per_page;
$show_images_to = $browse_images * $images_per_page;
if($show_images_to>$images_count) $show_images_to = $images_count;
}
else $images_count = 0;
$smarty->assign('current',$browse_images);
if($browse_images*$images_per_page < $images_count) $smarty->assign('next',$browse_images+1);
if($browse_images > 1) $smarty->assign('previous',$browse_images-1);
$smarty->assign('browse_images',true);
$smarty->assign('images_per_page',$images_per_page);
if(isset($images)) $smarty->assign('images',$images);
if(isset($start)) $smarty->assign('start',$start);
}
// display form to upload image:
elseif(empty($_GET['browse_images']))
{
$smarty->assign('form',true);
}
if(empty($errors) && isset($_FILES['probe']['error']))
{
$smarty->assign('server_max_filesize', ini_get('upload_max_filesize'));
$errors[] = 'upload_error_2';
$smarty->assign('errors',$errors);
}
}
// display form to upload image:
elseif (empty($_GET['browse_images'])) {
$smarty->assign('form',true);
}
if (empty($errors) && isset($_FILES['probe']['error'])) {
$smarty->assign('server_max_filesize', ini_get('upload_max_filesize'));
$errors[] = 'upload_error_2';
$smarty->assign('errors', $errors);
}
}
$template = 'upload_image.tpl';
?>

File diff suppressed because it is too large Load diff

337
index.php
View file

@ -1,12 +1,14 @@
<?php
/**
* my little forum - a simple PHP and MySQL based web forum that displays the
* messages in classical threaded view
* my little forum - a simple PHP and MySQL based internet forum that displays
* the messages in classical threaded view
*
* @author Mark Alexander Hoschek < alex at mylittleforum dot net >
* @copyright 2006-2010 Mark Alexander Hoschek
* @version 2.2.6 (2010-07-10)
* @link http://mylittleforum.net/
* @author Michael Lösler (https://github.com/loesler)
* @author Heiko August (https://github.com/auge8472)
* @copyright 2006-2025 Mark Alexander Hoschek
* @version 20250323.1 (2025-03-23)
* @link https://mylittleforum.net/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,7 +17,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@ -26,189 +28,206 @@ define('IN_INDEX', true);
define('LANG_DIR', 'lang');
define('THEMES_DIR', 'themes');
session_set_cookie_params(['samesite' => 'strict']);
session_start();
include('config/db_settings.php');
include('includes/mailer.inc.php');
include('includes/functions.inc.php');
include('includes/main.inc.php');
require('modules/smarty/Smarty.class.php'); // requires plugin compiler.defun.php
$smarty = new Smarty;
$smarty->template_dir = THEMES_DIR;
require('modules/smarty/Smarty.class.php');
$smarty = new Smarty;
$smarty->error_reporting = '0'; //'E_ALL & ~E_NOTICE';
$smarty->template_dir = THEMES_DIR;
$smarty->assign('THEMES_DIR', THEMES_DIR);
$smarty->compile_dir = 'templates_c';
$smarty->config_dir = LANG_DIR;
$smarty->config_overwrite = false;
$smarty->assign('CSRF_TOKEN', $_SESSION['csrf_token']);
$smarty->assign('FORUM_ADDRESS', rtrim($settings['forum_address'], "/"));
$smarty->compile_dir = 'templates_c';
$smarty->config_dir = LANG_DIR;
$smarty->config_overwrite = false;
$smarty->config_booleanize = false;
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['language']) && file_exists(LANG_DIR.'/'.$_SESSION[$settings['session_prefix'].'usersettings']['language']))
{
$language_file = $_SESSION[$settings['session_prefix'].'usersettings']['language'];
}
else
{
$language_file = $settings['language_file'];
}
if (isset($_SESSION[$settings['session_prefix'] . 'usersettings']['language']) && file_exists(LANG_DIR . '/' . $_SESSION[$settings['session_prefix'] . 'usersettings']['language'])) {
$language_file = $_SESSION[$settings['session_prefix'] . 'usersettings']['language'];
} else {
$language_file = $settings['language_file'];
}
$smarty->assign('language_file', $language_file);
$smarty->config_load($language_file);
$lang = $smarty->get_config_vars();
$smarty->configLoad($language_file, 'default');
$lang = $smarty->getConfigVars();
define('CHARSET', $lang['charset']);
if($lang['locale_charset']!=$lang['charset']) define('LOCALE_CHARSET', $lang['locale_charset']);
if ($lang['locale_charset'] != $lang['charset'])
define('LOCALE_CHARSET', $lang['locale_charset']);
@ini_set('default_charset', $lang['charset']);
setlocale(LC_ALL, $lang['locale']);
setlocale(LC_NUMERIC, "C");
include('includes/b8.inc.php');
$smarty->assign('settings', $settings);
$smarty->assign('forum_time', format_time($lang['time_format'],time()+intval($time_difference)*60));
if(isset($forum_time_zone)) $smarty->assign('forum_time_zone', htmlspecialchars($forum_time_zone));
$smarty->assign('forum_time', format_time($lang['time_format'], TIMESTAMP + intval($time_difference) * 60));
if (isset($forum_time_zone))
$smarty->assign('forum_time_zone', htmlspecialchars($forum_time_zone));
if(isset($_SESSION[$settings['session_prefix'].'usersettings'])) $smarty->assign('usersettings', $_SESSION[$settings['session_prefix'].'usersettings']);
if (isset($_SESSION[$settings['session_prefix'] . 'usersettings']))
$smarty->assign('usersettings', $_SESSION[$settings['session_prefix'] . 'usersettings']);
#$smarty->assign('category', $category);
if(isset($categories))
{
$smarty->assign('categories', $categories);
$smarty->assign('number_of_categories', count($categories)-1);
}
if(isset($category_selection))
{
$smarty->assign('category_selection', true);
}
if (isset($categories) and !empty($categories)) {
$smarty->assign('categories', $categories);
$smarty->assign('number_of_categories', count($categories) - 1);
}
if (isset($category_selection)) {
$smarty->assign('category_selection', true);
}
$smarty->assign('total_postings', $total_postings);
$smarty->assign('total_spam', $total_spam);
$smarty->assign('total_threads', $total_threads);
$smarty->assign('registered_users', $registered_users);
if(isset($total_users_online))
{
$smarty->assign('total_users_online', $total_users_online);
$smarty->assign('unregistered_users_online', $unregistered_users_online);
$smarty->assign('registered_users_online', $registered_users_online);
}
if (isset($total_users_online)) {
$smarty->assign('total_users_online', $total_users_online);
$smarty->assign('unregistered_users_online', $unregistered_users_online);
$smarty->assign('registered_users_online', $registered_users_online);
}
if(isset($_SESSION[$settings['session_prefix'].'user_id']) && isset($_SESSION[$settings['session_prefix'].'user_name']))
{
$smarty->assign('user_id', $_SESSION[$settings['session_prefix'].'user_id']);
$smarty->assign('user', htmlspecialchars($_SESSION[$settings['session_prefix'].'user_name']));
$smarty->assign('user_type', intval($_SESSION[$settings['session_prefix'].'user_type']));
}
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']==1) $smarty->assign('mod', true);
if(isset($_SESSION[$settings['session_prefix'].'user_type']) && $_SESSION[$settings['session_prefix'].'user_type']==2) $smarty->assign('admin', true);
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['newtime'])) $smarty->assign('newtime', $_SESSION[$settings['session_prefix'].'usersettings']['newtime']);
if(isset($last_visit)) $smarty->assign('last_visit',$last_visit);
if(isset($menu)) $smarty->assign('menu',$menu);
if(isset($read)) $smarty->assign('read',$read);
if (isset($_SESSION[$settings['session_prefix'] . 'user_id']) && isset($_SESSION[$settings['session_prefix'] . 'user_name'])) {
$smarty->assign('user_id', $_SESSION[$settings['session_prefix'] . 'user_id']);
$smarty->assign('user', htmlspecialchars($_SESSION[$settings['session_prefix'] . 'user_name']));
$smarty->assign('user_type', intval($_SESSION[$settings['session_prefix'] . 'user_type']));
}
if (isset($_SESSION[$settings['session_prefix'] . 'user_type']) && $_SESSION[$settings['session_prefix'] . 'user_type'] == 1)
$smarty->assign('mod', true);
if (isset($_SESSION[$settings['session_prefix'] . 'user_type']) && $_SESSION[$settings['session_prefix'] . 'user_type'] == 2)
$smarty->assign('admin', true);
if (isset($_SESSION[$settings['session_prefix'] . 'usersettings']['newtime']))
$smarty->assign('newtime', $_SESSION[$settings['session_prefix'] . 'usersettings']['newtime']);
if (isset($last_visit))
$smarty->assign('last_visit', $last_visit);
if (isset($menu))
$smarty->assign('menu', $menu);
if (isset($read))
$smarty->assign('read', $read);
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : '';
if($settings['access_for_users_only'] == 1 && empty($_SESSION[$settings['session_prefix'].'user_id']))
{
if(empty($mode) || $mode!='account_locked' && $mode!='register' && $mode!='page' && $mode!='js_defaults') $mode = 'login';
}
if($settings['forum_enabled']!=1 && (empty($_SESSION[$settings['session_prefix'].'user_type']) || $_SESSION[$settings['session_prefix'].'user_type']<2))
{
if(empty($mode) || $mode!='disabled' && $mode!='rss' && $mode!='login' && $mode!='js_defaults') $mode = 'disabled';
}
if(empty($mode) && isset($_REQUEST['id'])) $mode = 'entry';
if ($settings['access_for_users_only'] == 1 && empty($_SESSION[$settings['session_prefix'] . 'user_id'])) {
if (empty($mode) || $mode != 'account_locked' && $mode != 'register' && $mode != 'page' && $mode != 'js_defaults')
$mode = 'login';
}
if ($settings['forum_enabled'] != 1 && (empty($_SESSION[$settings['session_prefix'] . 'user_type']) || $_SESSION[$settings['session_prefix'] . 'user_type'] < 2)) {
if (empty($mode) || $mode != 'disabled' && $mode != 'rss' && $mode != 'login' && $mode != 'js_defaults')
$mode = 'disabled';
}
if (empty($mode) && isset($_REQUEST['id']))
$mode = 'entry';
if(empty($mode))
{
// set user settings to default values if index page is requested
$_SESSION[$settings['session_prefix'].'usersettings']['page']=1;
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['category_selection'])) $_SESSION[$settings['session_prefix'].'usersettings']['category']=-1;
else $_SESSION[$settings['session_prefix'].'usersettings']['category']=0;
$smarty->assign('top', true);
$mode = 'index';
}
switch($mode)
{
case 'index':
include('includes/index.inc.php');
break;
case 'admin':
include('includes/admin.inc.php');
break;
case 'contact':
include('includes/contact.inc.php');
break;
case 'delete_cookie':
include('includes/delete_cookie.inc.php');
break;
case 'login':
include('includes/login.inc.php');
break;
case 'posting':
include('includes/posting.inc.php');
break;
case 'register':
include('includes/register.inc.php');
break;
case 'rss':
include('includes/rss.inc.php');
break;
case 'search':
include('includes/search.inc.php');
break;
case 'entry':
include('includes/entry.inc.php');
break;
case 'thread':
include('includes/thread.inc.php');
break;
case 'user':
include('includes/user.inc.php');
break;
case 'page':
include('includes/page.inc.php');
break;
case 'js_defaults':
include('includes/js_defaults.inc.php');
break;
case 'upload_image':
include('includes/upload_image.inc.php');
break;
case 'insert_flash':
include('includes/insert_flash.inc.php');
break;
case 'avatar':
include('includes/avatar.inc.php');
break;
case 'account_locked':
include('includes/account_locked.inc.php');
break;
case 'disabled':
include('includes/disabled.inc.php');
break;
default:
$mode='index';
include('includes/index.inc.php');
}
if (empty($mode)) {
// set user settings to default values if index page is requested
$_SESSION[$settings['session_prefix'] . 'usersettings']['page'] = 1;
if (isset($_SESSION[$settings['session_prefix'] . 'usersettings']['category_selection']))
$_SESSION[$settings['session_prefix'] . 'usersettings']['category'] = -1;
else
$_SESSION[$settings['session_prefix'] . 'usersettings']['category'] = 0;
$smarty->assign('top', true);
$mode = 'index';
}
switch ($mode) {
case 'index':
include('includes/index.inc.php');
break;
case 'admin':
include('includes/admin.inc.php');
break;
case 'bookmarks':
include('includes/bookmark.inc.php');
break;
case 'contact':
include('includes/contact.inc.php');
break;
case 'delete_cookie':
include('includes/delete_cookie.inc.php');
break;
case 'login':
include('includes/login.inc.php');
break;
case 'posting':
include('includes/posting.inc.php');
break;
case 'register':
include('includes/register.inc.php');
break;
case 'rss':
include('includes/rss.inc.php');
break;
case 'search':
include('includes/search.inc.php');
break;
case 'entry':
include('includes/entry.inc.php');
break;
case 'thread':
include('includes/thread.inc.php');
break;
case 'user':
include('includes/user.inc.php');
break;
case 'page':
include('includes/page.inc.php');
break;
case 'js_defaults':
include('includes/js_defaults.inc.php');
break;
case 'upload_image':
include('includes/upload_image.inc.php');
break;
case 'avatar':
include('includes/avatar.inc.php');
break;
case 'account_locked':
include('includes/account_locked.inc.php');
break;
case 'disabled':
include('includes/disabled.inc.php');
break;
default:
$mode = 'index';
include('includes/index.inc.php');
}
$smarty->assign('mode', $mode);
if(empty($template))
{
header('Location: index.php');
exit;
}
if (empty($template)) {
header('Location: index.php');
exit;
}
if($mode=='rss')
{
header("Content-Type: text/xml; charset=".$lang['charset']);
}
else
{
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')===false)
{
// do not send cache-control header to Internet Explorer
// causes problems when toggeling views or folding threads
header('Cache-Control: public, max-age=300');
}
header('Content-Type: text/html; charset='.$lang['charset']);
}
if ($mode == 'rss') {
header("Content-Type: text/xml; charset=" . $lang['charset']);
} else {
header('Cache-Control: private, no-cache="set-cookie"');
header('Content-Type: text/html; charset=' . $lang['charset']);
$currentURI = (isProtocolHTTPS() ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
if ($mode != 'login' && (!isset($_SESSION[$settings['session_prefix'] . 'last_visited_uri']) || $_SESSION[$settings['session_prefix'] . 'last_visited_uri'] != $currentURI))
$_SESSION[$settings['session_prefix'] . 'last_visited_uri'] = $currentURI;
}
if(isset($_SESSION[$settings['session_prefix'].'usersettings']['theme']) && $smarty->template_exists($_SESSION[$settings['session_prefix'].'usersettings']['theme'].'/'.$template)) $theme = $_SESSION[$settings['session_prefix'].'usersettings']['theme'];
else $theme = $settings['theme'];
$smarty->assign('theme',$theme);
$smarty->display($theme.'/'.$template);
?>
if (isset($_SESSION[$settings['session_prefix'] . 'usersettings']['theme']) && $smarty->templateExists($_SESSION[$settings['session_prefix'] . 'usersettings']['theme'] . '/' . $template)) {
$theme = $_SESSION[$settings['session_prefix'] . 'usersettings']['theme'];
} else {
$theme = $settings['theme'];
}
$smarty->assign('theme', $theme);
$smarty->display($theme . '/' . $template);
// daily actions needs content from lang-file to create email
// load e-mail strings from language file:
$smarty->configLoad($settings['language_file'], 'emails');
$lang = $smarty->getConfigVars();
if ($language_file != $settings['language_file'])
setlocale(LC_ALL, $lang['locale']);
// do daily actions:
daily_actions(TIMESTAMP);
?>

File diff suppressed because it is too large Load diff

View file

@ -1,16 +1,27 @@
# note: the installation script expects one query per line!
CREATE TABLE mlf2_banlists (name varchar(255) NOT NULL default '', list text NOT NULL) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_categories (id int(11) NOT NULL auto_increment, order_id int(11) NOT NULL default '0', category varchar(255) NOT NULL default '', description varchar(255) NOT NULL default '',accession tinyint(4) NOT NULL default '0', PRIMARY KEY (id)) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_entries (id int(11) NOT NULL auto_increment, pid int(11) NOT NULL default '0', tid int(11) NOT NULL default '0', uniqid varchar(255) NOT NULL default '', time timestamp NOT NULL default CURRENT_TIMESTAMP, last_reply timestamp NOT NULL default '0000-00-00 00:00:00', edited timestamp NOT NULL default '0000-00-00 00:00:00', edited_by int(11) default NULL, user_id int(11) default '0', name varchar(255) NOT NULL default '', subject varchar(255) NOT NULL default '',category int(11) NOT NULL default '0', email varchar(255) NOT NULL default '', hp varchar(255) NOT NULL default '', location varchar(255) NOT NULL default '', ip varchar(128) NOT NULL default '', text text NOT NULL, tags varchar(255) NOT NULL default '', show_signature tinyint(4) default '0', email_notification tinyint(4) default '0', marked tinyint(4) default '0', locked tinyint(4) default '0', sticky tinyint(4) default '0', views int(11) default '0', spam tinyint(4) default '0', spam_check_status tinyint(4) default '0', edit_key varchar(255) NOT NULL default '', PRIMARY KEY (id), UNIQUE KEY id (id), KEY tid (tid),KEY category (category), KEY pid (pid), KEY sticky (sticky)) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_settings (name varchar(255) NOT NULL default '', value varchar(255) NOT NULL default '') CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_smilies (id int(11) NOT NULL auto_increment, order_id int(11) NOT NULL default '0', file varchar(100) NOT NULL default '', code_1 varchar(50) NOT NULL default '', code_2 varchar(50) NOT NULL default '', code_3 varchar(50) NOT NULL default '', code_4 varchar(50) NOT NULL default '', code_5 varchar(50) NOT NULL default '', title varchar(255) NOT NULL default '', PRIMARY KEY (id)) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_userdata (user_id int(11) NOT NULL auto_increment, user_type tinyint(4) NOT NULL default '0', user_name varchar(255) NOT NULL default '', user_real_name varchar(255) NOT NULL default '', gender tinyint(4) NOT NULL default '0', birthday date NOT NULL default '0000-00-00', user_pw varchar(255) NOT NULL default '', user_email varchar(255) NOT NULL default '', email_contact tinyint(4) default '0', user_hp varchar(255) NOT NULL default '', user_location varchar(255) NOT NULL default '', signature varchar(255) NOT NULL default '', profile text NOT NULL, logins int(11) NOT NULL default '0', last_login timestamp NOT NULL default CURRENT_TIMESTAMP, last_logout timestamp NOT NULL default '0000-00-00 00:00:00', user_ip varchar(128) NOT NULL default '', registered timestamp NOT NULL default '0000-00-00 00:00:00', category_selection varchar(255) DEFAULT NULL, thread_order tinyint(4) NOT NULL default '0', user_view tinyint(4) NOT NULL default '0', sidebar tinyint(4) NOT NULL default '1', fold_threads tinyint(4) NOT NULL default '0', thread_display tinyint(4) NOT NULL default '0', new_posting_notification tinyint(4) default '0', new_user_notification tinyint(4) default '0', user_lock tinyint(4) default '0', auto_login_code varchar(50) NOT NULL default '', pwf_code varchar(50) NOT NULL, activate_code varchar(50) NOT NULL default '', language VARCHAR(255) NOT NULL DEFAULT '', time_zone VARCHAR(255) NOT NULL DEFAULT '', time_difference smallint(4) default '0', theme VARCHAR(255) NOT NULL DEFAULT '', entries_read TEXT NOT NULL, PRIMARY KEY (user_id)) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_pages (id int(11) NOT NULL auto_increment,order_id int(11) NOT NULL, title varchar(255) NOT NULL default '', content text NOT NULL, menu_linkname varchar(255) NOT NULL default '', access tinyint(4) NOT NULL default '0', PRIMARY KEY (id)) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_useronline (ip char(15) NOT NULL default '',time int(14) NOT NULL default '0',user_id int(11) default '0') CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_logincontrol (time timestamp NOT NULL default CURRENT_TIMESTAMP, ip varchar(255) NOT NULL default '', logins int(11) NOT NULL default '0') CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_entries_cache (cache_id int(11) NOT NULL, cache_text mediumtext NOT NULL, PRIMARY KEY (cache_id)) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_userdata_cache (cache_id int(11) NOT NULL, cache_signature text NOT NULL, cache_profile text NOT NULL, PRIMARY KEY (cache_id)) CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE mlf2_banlists (name varchar(255) NOT NULL, list text NOT NULL, PRIMARY KEY (name)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_categories (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, order_id int(11) NOT NULL default '0', category varchar(255) NOT NULL default '', description varchar(255) NOT NULL default '', accession tinyint(4) NOT NULL default '0', PRIMARY KEY (id)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_entries (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, pid int(11) UNSIGNED NOT NULL default '0', tid int(11) UNSIGNED NOT NULL default '0', uniqid varchar(255) NOT NULL default '', time timestamp NOT NULL default CURRENT_TIMESTAMP, last_reply timestamp NULL DEFAULT NULL, edited timestamp NULL DEFAULT NULL, edited_by int(11) UNSIGNED default NULL, user_id int(11) UNSIGNED default '0', name varchar(255) NOT NULL default '', subject varchar(255) NOT NULL default '',category int(11) UNSIGNED NOT NULL default '0', email varchar(255) NOT NULL default '', hp varchar(255) NOT NULL default '', location varchar(255) NOT NULL default '', ip varchar(128) NOT NULL default '', text text NOT NULL, show_signature tinyint(4) default '0', marked tinyint(4) default '0', locked tinyint(4) default '0', sticky tinyint(4) default '0', views int(11) UNSIGNED default '0', edit_key varchar(255) NOT NULL default '', PRIMARY KEY (id), UNIQUE KEY id (id), KEY tid (tid),KEY category (category), KEY pid (pid), KEY sticky (sticky), KEY user_id (user_id), KEY time (time), KEY last_reply (last_reply)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_settings (name varchar(255) NOT NULL, value varchar(255) NOT NULL default '', PRIMARY KEY (name)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE mlf2_smilies (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, order_id int(11) NOT NULL default '0', file varchar(100) NOT NULL default '', code_1 varchar(50) NOT NULL default '', code_2 varchar(50) NOT NULL default '', code_3 varchar(50) NOT NULL default '', code_4 varchar(50) NOT NULL default '', code_5 varchar(50) NOT NULL default '', title varchar(255) NOT NULL default '', PRIMARY KEY (id)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_userdata (user_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, user_type tinyint(4) NOT NULL default '0', user_name varchar(128) NOT NULL COLLATE utf8mb4_bin, user_real_name varchar(255) NOT NULL default '', gender tinyint(4) NOT NULL default '0', birthday date NULL default NULL, user_pw varchar(255) NOT NULL default '', user_email varchar(255) NOT NULL, email_contact tinyint(4) default '0', user_hp varchar(255) NOT NULL default '', user_location varchar(255) NOT NULL default '', signature varchar(255) NOT NULL default '', profile text NOT NULL, logins int(11) NOT NULL default '0', last_login timestamp NULL default CURRENT_TIMESTAMP, last_logout timestamp NULL DEFAULT NULL, user_ip varchar(128) NOT NULL default '', registered timestamp NULL DEFAULT NULL, category_selection varchar(255) DEFAULT NULL, thread_order tinyint(4) NOT NULL default '0', user_view tinyint(4) NOT NULL default '0', sidebar tinyint(4) NOT NULL default '1', fold_threads tinyint(4) NOT NULL default '0', thread_display tinyint(4) NOT NULL default '0', new_posting_notification tinyint(4) default '0', new_user_notification tinyint(4) default '0', user_lock tinyint(4) default '0', browser_window_target tinyint(4) NOT NULL default '0', auto_login_code varchar(50) NOT NULL default '', pwf_code varchar(50) NOT NULL, activate_code varchar(50) NOT NULL default '', language VARCHAR(255) NOT NULL DEFAULT '', time_zone VARCHAR(255) NOT NULL DEFAULT '', time_difference smallint(4) default '0', theme VARCHAR(255) NOT NULL DEFAULT '', tou_accepted DATETIME NULL DEFAULT NULL, dps_accepted DATETIME NULL DEFAULT NULL, inactivity_notification BOOLEAN NOT NULL DEFAULT FALSE, PRIMARY KEY (user_id), KEY key_user_type (user_type), UNIQUE KEY key_user_name (user_name), UNIQUE KEY key_user_email (user_email)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_pages (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, order_id int(11) NOT NULL, title varchar(255) NOT NULL default '', content text NOT NULL, menu_linkname varchar(255) NOT NULL default '', access tinyint(4) NOT NULL default '0', PRIMARY KEY (id)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_useronline (ip varchar(128) NOT NULL default '', time int(14) NOT NULL default '0', user_id int(11) UNSIGNED default '0') ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_logincontrol (time timestamp NOT NULL default CURRENT_TIMESTAMP, ip varchar(128) NOT NULL default '', logins int(11) NOT NULL default '0') ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_entries_cache (cache_id int(11) NOT NULL, cache_text mediumtext NOT NULL, PRIMARY KEY (cache_id)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_userdata_cache (cache_id int(11) NOT NULL, cache_signature text NOT NULL, cache_profile text NOT NULL, PRIMARY KEY (cache_id)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_bookmarks (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, user_id int(11) UNSIGNED NOT NULL, posting_id int(11) UNSIGNED NOT NULL, time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, subject varchar(255) NOT NULL, order_id int(11) NOT NULL DEFAULT '0', PRIMARY KEY (id), UNIQUE KEY UNIQUE_uid_pid (user_id,posting_id)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_read_entries (user_id int(11) UNSIGNED NOT NULL, posting_id int(11) UNSIGNED NOT NULL, time timestamp NOT NULL, PRIMARY KEY (user_id, posting_id), KEY `user_id` (`user_id`), KEY `posting_id` (`posting_id`)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_temp_infos (name varchar(50) NOT NULL, value varchar(255) NOT NULL, time timestamp NULL DEFAULT NULL, PRIMARY KEY (name)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE mlf2_entry_tags (`bid` int(11) NOT NULL, `tid` int(11) NOT NULL, PRIMARY KEY (`bid`,`tid`)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_bookmark_tags (`bid` int(11) NOT NULL, `tid` int(11) NOT NULL, PRIMARY KEY (`bid`,`tid`)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_tags (`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `tag` varchar(128) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `tag` (`tag`)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_subscriptions (`user_id` int(12) UNSIGNED NULL, `eid` int(12) UNSIGNED NOT NULL, `unsubscribe_code` varchar(36) NOT NULL, `tstamp` datetime DEFAULT NULL, UNIQUE `user_thread` (`user_id`, `eid`) USING HASH, INDEX `hash` (`unsubscribe_code`)) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_b8_rating (`eid` int(11) NOT NULL, `spam` tinyint(1) NOT NULL DEFAULT '0', `training_type` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`eid`), KEY `b8_spam` (`spam`), KEY `B8_training_type` (`training_type`)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_akismet_rating (`eid` int(11) NOT NULL, `spam` tinyint(1) NOT NULL DEFAULT '0', `spam_check_status` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`eid`), KEY `akismet_spam` (`spam`), KEY spam_check_status (spam_check_status)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE mlf2_b8_wordlist (`token` varchar(255) NOT NULL, `count_ham` int unsigned default NULL, `count_spam` int unsigned default NULL, PRIMARY KEY (`token`)) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE mlf2_uploads (`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `uploader` int(10) UNSIGNED NULL, `pathname` varchar(128) NOT NULL, `tstamp` datetime NULL, PRIMARY KEY (id), UNIQUE KEY `pathname` (`pathname`), CONSTRAINT `smbl_mlf2_uploader` FOREIGN KEY `fk_uploader` (`uploader`) REFERENCES mlf2_userdata(`user_id`) ON UPDATE CASCADE ON DELETE SET NULL) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
INSERT INTO mlf2_banlists VALUES ('user_agents', '');
INSERT INTO mlf2_banlists VALUES ('ips', '');
@ -28,7 +39,7 @@ INSERT INTO mlf2_settings VALUES ('access_for_users_only', '0');
INSERT INTO mlf2_settings VALUES ('entries_by_users_only', '0');
INSERT INTO mlf2_settings VALUES ('register_mode', '0');
INSERT INTO mlf2_settings VALUES ('default_email_contact', '0');
INSERT INTO mlf2_settings VALUES ('user_area_public', '0');
INSERT INTO mlf2_settings VALUES ('user_area_access', '1');
INSERT INTO mlf2_settings VALUES ('rss_feed', '1');
INSERT INTO mlf2_settings VALUES ('rss_feed_max_items', '20');
INSERT INTO mlf2_settings VALUES ('session_prefix', 'mlf2_');
@ -50,10 +61,6 @@ INSERT INTO mlf2_settings VALUES ('bbcode_img', '1');
INSERT INTO mlf2_settings VALUES ('bbcode_color', '1');
INSERT INTO mlf2_settings VALUES ('bbcode_size', '1');
INSERT INTO mlf2_settings VALUES ('bbcode_code', '0');
INSERT INTO mlf2_settings VALUES ('bbcode_tex', '0');
INSERT INTO mlf2_settings VALUES ('bbcode_flash', '0');
INSERT INTO mlf2_settings VALUES ('flash_default_width', '425');
INSERT INTO mlf2_settings VALUES ('flash_default_height', '344');
INSERT INTO mlf2_settings VALUES ('upload_images', '0');
INSERT INTO mlf2_settings VALUES ('smilies', '1');
INSERT INTO mlf2_settings VALUES ('autolink', '1');
@ -89,15 +96,15 @@ INSERT INTO mlf2_settings VALUES ('forum_enabled', '1');
INSERT INTO mlf2_settings VALUES ('forum_readonly', '0');
INSERT INTO mlf2_settings VALUES ('forum_disabled_message', '');
INSERT INTO mlf2_settings VALUES ('page_browse_range', '10');
INSERT INTO mlf2_settings VALUES ('page_browse_show_last', '1');
INSERT INTO mlf2_settings VALUES ('page_browse_show_last', '0');
INSERT INTO mlf2_settings VALUES ('deep_reply', '15');
INSERT INTO mlf2_settings VALUES ('very_deep_reply', '30');
INSERT INTO mlf2_settings VALUES ('users_per_page', '20');
INSERT INTO mlf2_settings VALUES ('username_maxlength', '40');
INSERT INTO mlf2_settings VALUES ('bad_behavior', '0');
INSERT INTO mlf2_settings VALUES ('akismet_entry_check', '0');
INSERT INTO mlf2_settings VALUES ('akismet_mail_check', '0');
INSERT INTO mlf2_settings VALUES ('akismet_key', '');
INSERT INTO mlf2_settings VALUES ('stop_forum_spam', '0');
INSERT INTO mlf2_settings VALUES ('tags', '1');
INSERT INTO mlf2_settings VALUES ('tag_cloud', '0');
INSERT INTO mlf2_settings VALUES ('tag_cloud_day_period', '30');
@ -110,7 +117,7 @@ INSERT INTO mlf2_settings VALUES ('syntax_highlighter', '0');
INSERT INTO mlf2_settings VALUES ('save_spam', '1');
INSERT INTO mlf2_settings VALUES ('auto_delete_spam', '168');
INSERT INTO mlf2_settings VALUES ('auto_lock', '0');
INSERT INTO mlf2_settings VALUES ('temp_block_ip_after_repeated_failed_logins', '1');
INSERT INTO mlf2_settings VALUES ('temp_block_ip_after_repeated_failed_logins', '10');
INSERT INTO mlf2_settings VALUES ('flood_prevention_minutes', '2');
INSERT INTO mlf2_settings VALUES ('fold_threads', '0');
INSERT INTO mlf2_settings VALUES ('avatars', '0');
@ -122,15 +129,37 @@ INSERT INTO mlf2_settings VALUES ('captcha_email', '0');
INSERT INTO mlf2_settings VALUES ('captcha_register', '0');
INSERT INTO mlf2_settings VALUES ('min_pw_length', '8');
INSERT INTO mlf2_settings VALUES ('cookie_validity_days', '30');
INSERT INTO mlf2_settings VALUES ('access_permission_checks', '0');
INSERT INTO mlf2_settings VALUES ('daily_actions_time', '3:30');
INSERT INTO mlf2_settings VALUES ('next_daily_actions', '0');
INSERT INTO mlf2_settings VALUES ('auto_lock_old_threads', '0');
INSERT INTO mlf2_settings VALUES ('max_read_items', '200');
INSERT INTO mlf2_settings VALUES ('delete_ips', '0');
INSERT INTO mlf2_settings VALUES ('last_changes', '0');
INSERT INTO mlf2_settings VALUES ('ajax_preview', '1');
INSERT INTO mlf2_settings VALUES ('version', '2.2.6');
INSERT INTO mlf2_settings VALUES ('read_state_expiration_value', '500');
INSERT INTO mlf2_settings VALUES ('read_state_expiration_method', '0');
INSERT INTO mlf2_settings VALUES ('uploads_per_page', '20');
INSERT INTO mlf2_settings VALUES ('data_privacy_agreement', '0');
INSERT INTO mlf2_settings VALUES ('data_privacy_statement_url', '');
INSERT INTO mlf2_settings VALUES ('bbcode_latex', '0');
INSERT INTO mlf2_settings VALUES ('bbcode_latex_uri', 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js');
INSERT INTO mlf2_settings VALUES ('min_posting_time', '5');
INSERT INTO mlf2_settings VALUES ('min_register_time', '5');
INSERT INTO mlf2_settings VALUES ('min_email_time', '5');
INSERT INTO mlf2_settings VALUES ('max_posting_time', '10800');
INSERT INTO mlf2_settings VALUES ('max_register_time', '10800');
INSERT INTO mlf2_settings VALUES ('max_email_time', '10800');
INSERT INTO mlf2_settings VALUES ('b8_entry_check', '1');
INSERT INTO mlf2_settings VALUES ('b8_auto_training', '1');
INSERT INTO mlf2_settings VALUES ('b8_mail_check', '0');
INSERT INTO mlf2_settings VALUES ('b8_spam_probability_threshold', '80');
INSERT INTO mlf2_settings VALUES ('spam_check_registered', '0');
INSERT INTO mlf2_settings VALUES ('min_pw_digits', '0');
INSERT INTO mlf2_settings VALUES ('min_pw_lowercase_letters', '0');
INSERT INTO mlf2_settings VALUES ('min_pw_uppercase_letters', '0');
INSERT INTO mlf2_settings VALUES ('min_pw_special_characters', '0');
INSERT INTO mlf2_settings VALUES ('php_mailer', '0');
INSERT INTO mlf2_settings VALUES ('delete_inactive_users', '30');
INSERT INTO mlf2_settings VALUES ('notify_inactive_users', '3');
INSERT INTO mlf2_settings VALUES ('link_open_target', '');
INSERT INTO mlf2_temp_infos (`name`, `value`) VALUES ('access_permission_checks', '0'), ('last_changes', '0'), ('next_daily_actions', '0');
INSERT INTO mlf2_smilies VALUES (1, 1, 'smile.png', ':-)', '', '', '', '', '');
INSERT INTO mlf2_smilies VALUES (2, 2, 'wink.png', ';-)', '', '', '', '', '');
@ -139,4 +168,8 @@ INSERT INTO mlf2_smilies VALUES (4, 4, 'biggrin.png', ':-D', '', '', '', '', '')
INSERT INTO mlf2_smilies VALUES (5, 5, 'neutral.png', ':-|', '', '', '', '', '');
INSERT INTO mlf2_smilies VALUES (6, 6, 'frown.png', ':-(', '', '', '', '', '');
INSERT INTO mlf2_userdata VALUES (1, 2, 'admin', '', 0, '0000-00-00', 'c3ccb88dc0a985b9b5da20bb9333854194dfbc7767d91c6936', 'admin@example.com', 1, '', '', '', '', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '', NOW(), NULL, 0, 0, 1, 0, 0, 0, 0, 0, '', '', '', '', '', 0, '', '');
INSERT INTO mlf2_b8_wordlist (`token`, `count_ham`, `count_spam`) VALUES ('b8*dbversion', '3', NULL), ('b8*texts', '0', '0');
INSERT INTO mlf2_userdata (user_type, user_name, user_pw, user_email, email_contact, profile, logins, last_login, last_logout, registered, pwf_code, theme) VALUES (2, 'admin', 'c3ccb88dc0a985b9b5da20bb9333854194dfbc7767d91c6936', 'admin@example.com', 1, '', 0, NULL, NULL, NOW(), '', '');

View file

@ -1,315 +0,0 @@
/***********************************************************************
* MyLittleJavaScript *
************************************************************************
* Created by Michael Loesler <http://derletztekick.com> *
* *
* This script is part of my little forum <http://mylittleforum.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***********************************************************************/
/***********************************************************************
* NOTICE: In order to reduce bandwidth usage, a minimized version of *
* this script is used by default (admin.min.js). Changes in this file *
* do not have any effect unless it is loaded by the template *
* (themes/[THEME FOLDER]/main.tpl). *
* The minimized version was created with the YUI Compressor *
* <http://developer.yahoo.com/yui/compressor/>. *
***********************************************************************/
/**
* Kleiner Feature im Adminbereich werden
* von diesem Objekt realisiert.
* Hauptsaechlich handelt es sich um Sicherheitsabfragen
*/
function MyLittleAdmin() {
/**
* Initialisiert in den globalen Einstellungen
* den CSS-Klassenwechsel bei RADIO und CHECKBOX
*/
var initGlobalSettings = function() {
var f = document.getElementById("settings");
if (!f)
return;
var changeClassName = function(id, active) {
if (id && document.getElementById(id+"_label"))
document.getElementById(id+"_label").className = active?"active":"inactive";
};
var changeCollectionClassName = function(col) {
for (var i=0; i<col.length; i++)
changeClassName(col[i].id, col[i].checked);
};
for (var i=0; i<f.elements.length; i++) {
var el = f.elements[i];
if (el.type == "checkbox" || el.type == "radio") {
el.onchange = function(e) {
var els = f.elements[this.name];
if (els) {
if (typeof els.length != "number")
els = [els];
changeCollectionClassName(els);
}
};
}
}
};
/**
* Initialisiert die Backup-Loesch-Abfragen
*
*/
var initBackupControls = function() {
var el = document.getElementById("selectioncontrols");
var f = document.getElementById("selectform")
if (!el || !f)
return;
var cb = f.elements["delete_backup_files[]"];
// Elements liefert bei einem Element leider kein Array sondern nur das Element.
if (cb && typeof cb.length != "number")
cb = [cb];
var links = f.getElementsByTagName("a");
for (var i=0; i<links.length; i++) {
if (links[i].href.search("delete_backup_files") != -1) {
links[i].onclick = function(e) {
var confirmed = window.confirm( lang["delete_backup_confirm"] );
if (confirmed)
this.href += "&delete_backup_files_confirm="+true;
this.blur();
return confirmed;
};
}
}
var selectAll = function(s) {
for (var i=0; i<cb.length; i++)
cb[i].checked = s;
};
f.onsubmit = function(e) {
// Pruefe, ob ein File geloescht werden soll
var c = false;
for (var i=0; i<cb.length; i++)
if ((c = cb[i].checked) != false)
break;
if (!c)
return false;
c = window.confirm( lang["delete_sel_backup_confirm"] );
if (c && this.elements["delete_backup_files_confirm"])
this.elements["delete_backup_files_confirm"].value = true;
return c;
}
var wrapperEl = document.createElementWithAttributes("span", [["className", "checkall"]], el);
var checkAll = document.createElementWithAttributes("a", [["onclick", function(e) {selectAll(this.setSelect); return false;} ], ["href", "#"], ["setSelect", true]], wrapperEl);
wrapperEl.appendChild(document.createTextNode(" / "));
var checkNone = document.createElementWithAttributes("a", [["onclick", function(e) {selectAll(this.setSelect); return false;} ], ["href", "#"], ["setSelect", false]], wrapperEl);
checkAll.appendChild( document.createTextNode( lang["check_all"] ));
checkNone.appendChild( document.createTextNode( lang["uncheck_all"] ));
};
/**
* Initialisiert die moeglichen Admin-Funktionen
*/
(function() {
initGlobalSettings();
initBackupControls();
}());
}
/**
* DragAndDropTable ermoeglicht das Tauschen von
* Zeilen (TR) innerhalb von TBODY
*
* @param table
* @see http://www.isocra.com/2007/07/dragging-and-dropping-table-rows-in-javascript/
*/
function DragAndDropTable(table) {
if (!table)
return;
var isChanged = false;
var rows = table.tBodies[0].rows;
var dragObject = null;
var oldOnMouseUpFunc = window.document.onmouseup;
var oldOnMouseMoveFunc = window.document.onmousemove;
var tableTop = 0;
var rowList = [];
var getLocationQueryByParameter = function(par) {
var q = window.document.location.search.substring(1).split('&');
if(!q.length)
return false;
for(var i=0; i<q.length; i++){
var v = q[i].split('=');
if (decodeURIComponent(v[0]) == par)
return v.length>1?decodeURIComponent(v[1]):"";
}
};
var saveNewOrder = function() {
if (!isChanged)
return;
var page = getLocationQueryByParameter("action");
var order = getRowOrder();
if (!page || !order)
return;
var querys = [
new Query("mode", "admin"),
new Query("action", "reorder"),
new Query(page, order)
];
new Request("index.php", "POST", querys);
};
var updateClasses = function() {
for (var i=0; i<rows.length; i++)
rows[i].className = (i%2==0)?"a":"b";
};
var getRowOrder = function() {
var order = "";
for (var i=0; i<rows.length; i++)
if (rows[i].id.length > 3)
order += rows[i].id.substring(3) + ",";
return order.substr(0, order.length-1);
};
var ondrag = function(row) {
if (!row)
return;
};
var ondrop = function(row) {
if (!row)
return;
updateClasses();
saveNewOrder();
};
var start = function() {
window.document.onmousemove = function(e) {
if (typeof oldOnMouseMoveFunc == "function")
oldOnMouseMoveFunc(e);
if (!dragObject)
return;
var mPos = document.getMousePos(e);
var currentTop = mPos.top - dragObject.handlePos.top + dragObject.elementPos.top;
var currentRow = findDropTargetRow( currentTop );
if (tableTop != currentTop && currentRow && dragObject != currentRow) {
var movingDown = currentTop > tableTop;
tableTop = currentTop;
if (movingDown)
currentRow = currentRow.nextSibling;
dragObject.parentNode.insertBefore(dragObject, currentRow);
isChanged = true;
ondrag(dragObject);
}
if(e && e.preventDefault)
e.preventDefault();
return false;
};
window.document.onmouseup = function (e) {
window.document.onmouseup = window.document.onmousemove = null;
if (typeof oldOnMouseUpFunc == "function")
oldOnMouseUpFunc(e);
if (typeof oldOnMouseMoveFunc == "function")
window.document.onmousemove = oldOnMouseMoveFunc;
ondrop(dragObject);
dragObject = null;
isChanged = false;
return false;
};
};
var findDropTargetRow = function(top) {
for (var i=0; i<rows.length; i++) {
var rowPoSi = document.getElementPoSi(rows[i]);
var h = rowPoSi.height;
if (h == 0 && row[i].firstChild) {
rowPoSi = document.getElementPoSi(row[i].firstChild);
h = row[i].firstChild.offsetHeight;
}
h /= 2;
if ((top >= (rowPoSi.top - h)) && (top < (rowPoSi.top + h))) {
return rows[i];
}
}
return null;
};
var add = function(row) {
row.style.cursor = "move";
row.title = lang["drag_and_drop_title"];
row.onmousedown = function(e){
isChanged = false;
var obj = document.getTarget(e);
if (obj && obj.className.search(/control/) != -1)
return false;
this.className = "drag";
this.elementPos = document.getElementPoSi(this);
this.handlePos = document.getMousePos(e);
dragObject = this;
start();
return false;
};
var links = row.cells[row.cells.length-1].getElementsByTagName("a");
if (links && links.length > 0) {
for (var i=0; i<links.length; i++) {
if (links[i].href.search(/move_up/) != -1)
links[i].onclick = function(e) {
row.parentNode.insertBefore(row, rows[Math.max(row.rowIndex-2,0)]);
isChanged = true;
updateClasses();
saveNewOrder();
return false;
};
else if (links[i].href.search(/move_down/) != -1)
links[i].onclick = function(e) {
row.parentNode.insertBefore(row, rows[Math.min(row.rowIndex+1, rows.length)]);
updateClasses();
isChanged = true;
saveNewOrder();
return false;
};
}
}
};
(function() {
for (var i=0; i<rows.length; i++){
add(rows[i]);
}
}());
}
window.ready.push(function() {
new MyLittleAdmin();
new DragAndDropTable(document.getElementById("sortable"));
});

1
js/admin.min.js vendored
View file

@ -1 +0,0 @@
function MyLittleAdmin(){var a=function(){var g=document.getElementById("settings");if(!g){return}var h=function(i,f){if(i&&document.getElementById(i+"_label")){document.getElementById(i+"_label").className=f?"active":"inactive"}};var c=function(f){for(var j=0;j<f.length;j++){h(f[j].id,f[j].checked)}};for(var d=0;d<g.elements.length;d++){var e=g.elements[d];if(e.type=="checkbox"||e.type=="radio"){e.onchange=function(i){var f=g.elements[this.name];if(f){if(typeof f.length!="number"){f=[f]}c(f)}}}}};var b=function(){var c=document.getElementById("selectioncontrols");var j=document.getElementById("selectform");if(!c||!j){return}var g=j.elements["delete_backup_files[]"];if(g&&typeof g.length!="number"){g=[g]}var l=j.getElementsByTagName("a");for(var h=0;h<l.length;h++){if(l[h].href.search("delete_backup_files")!=-1){l[h].onclick=function(f){var i=window.confirm(lang.delete_backup_confirm);if(i){this.href+="&delete_backup_files_confirm="+true}this.blur();return i}}}var e=function(n){for(var f=0;f<g.length;f++){g[f].checked=n}};j.onsubmit=function(n){var o=false;for(var f=0;f<g.length;f++){if((o=g[f].checked)!=false){break}}if(!o){return false}o=window.confirm(lang.delete_sel_backup_confirm);if(o&&this.elements.delete_backup_files_confirm){this.elements.delete_backup_files_confirm.value=true}return o};var k=document.createElementWithAttributes("span",[["className","checkall"]],c);var m=document.createElementWithAttributes("a",[["onclick",function(f){e(this.setSelect);return false}],["href","#"],["setSelect",true]],k);k.appendChild(document.createTextNode(" / "));var d=document.createElementWithAttributes("a",[["onclick",function(f){e(this.setSelect);return false}],["href","#"],["setSelect",false]],k);m.appendChild(document.createTextNode(lang.check_all));d.appendChild(document.createTextNode(lang.uncheck_all))};(function(){a();b()}())}function DragAndDropTable(p){if(!p){return}var m=false;var q=p.tBodies[0].rows;var d=null;var h=window.document.onmouseup;var j=window.document.onmousemove;var k=0;var e=[];var c=function(t){var u=window.document.location.search.substring(1).split("&");if(!u.length){return false}for(var s=0;s<u.length;s++){var r=u[s].split("=");if(decodeURIComponent(r[0])==t){return r.length>1?decodeURIComponent(r[1]):""}}};var l=function(){if(!m){return}var t=c("action");var r=g();if(!t||!r){return}var s=[new Query("mode","admin"),new Query("action","reorder"),new Query(t,r)];new Request("index.php","POST",s)};var f=function(){for(var r=0;r<q.length;r++){q[r].className=(r%2==0)?"a":"b"}};var g=function(){var r="";for(var s=0;s<q.length;s++){if(q[s].id.length>3){r+=q[s].id.substring(3)+","}}return r.substr(0,r.length-1)};var o=function(r){if(!r){return}};var i=function(r){if(!r){return}f();l()};var b=function(){window.document.onmousemove=function(u){if(typeof j=="function"){j(u)}if(!d){return}var v=document.getMousePos(u);var s=v.top-d.handlePos.top+d.elementPos.top;var t=a(s);if(k!=s&&t&&d!=t){var r=s>k;k=s;if(r){t=t.nextSibling}d.parentNode.insertBefore(d,t);m=true;o(d)}if(u&&u.preventDefault){u.preventDefault()}return false};window.document.onmouseup=function(r){window.document.onmouseup=window.document.onmousemove=null;if(typeof h=="function"){h(r)}if(typeof j=="function"){window.document.onmousemove=j}i(d);d=null;m=false;return false}};var a=function(u){for(var r=0;r<q.length;r++){var t=document.getElementPoSi(q[r]);var s=t.height;if(s==0&&row[r].firstChild){t=document.getElementPoSi(row[r].firstChild);s=row[r].firstChild.offsetHeight}s/=2;if((u>=(t.top-s))&&(u<(t.top+s))){return q[r]}}return null};var n=function(t){t.style.cursor="move";t.title=lang.drag_and_drop_title;t.onmousedown=function(v){m=false;var u=document.getTarget(v);if(u&&u.className.search(/control/)!=-1){return false}this.className="drag";this.elementPos=document.getElementPoSi(this);this.handlePos=document.getMousePos(v);d=this;b();return false};var r=t.cells[t.cells.length-1].getElementsByTagName("a");if(r&&r.length>0){for(var s=0;s<r.length;s++){if(r[s].href.search(/move_up/)!=-1){r[s].onclick=function(u){t.parentNode.insertBefore(t,q[Math.max(t.rowIndex-2,0)]);m=true;f();l();return false}}else{if(r[s].href.search(/move_down/)!=-1){r[s].onclick=function(u){t.parentNode.insertBefore(t,q[Math.min(t.rowIndex+1,q.length)]);f();m=true;l();return false}}}}}};(function(){for(var r=0;r<q.length;r++){n(q[r])}}())}window.ready.push(function(){new MyLittleAdmin();new DragAndDropTable(document.getElementById("sortable"))});

1020
js/main.js

File diff suppressed because it is too large Load diff

4
js/main.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,9 +1,9 @@
/***********************************************************************
* MyLittleJavaScript *
************************************************************************
* Created by Michael Loesler <http://derletztekick.com> *
* Created by Michael Loesler <https://github.com/loesler> *
* *
* This script is part of my little forum <http://mylittleforum.net> *
* This script is part of my little forum <https://mylittleforum.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@ -19,7 +19,6 @@
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
***********************************************************************/
/***********************************************************************
@ -28,11 +27,10 @@
* file do not have any effect unless it is loaded by the template *
* (themes/[THEME FOLDER]/main.tpl). *
* The minimized version was created with the YUI Compressor *
* <http://developer.yahoo.com/yui/compressor/>. *
***********************************************************************/
/**
* Klasse fuer BB-Code Schaltflaechen
* BB-Code button object
* @param el
*/
function BBCodeButton(el) {
@ -68,7 +66,7 @@ function BBCodeButton(el) {
this.setHTMLElement = function(el) {
htmlEl = el;
htmlEl.onclick = function(e) {
self.insertCode(this);
self.insertCode(this);
return false;
}
};
@ -78,50 +76,42 @@ function BBCodeButton(el) {
};
this.setHTMLElement(el);
}
};
/**
* Sonderbutton - LINK
* Special button for link elements
* @param el
*/
function BBCodeLinkButton(el) {
this.constructor(el);
var link_bb_code = "link";
var regExpURI = new RegExp(/[http|https|ftp|ftps]:\/\/[a-zA-Z0-9-.][a-zA-Z0-9-.]+(S+)?/);
var regExpFID = new RegExp(/[?|&]id=([0-9]+)/);
var forumURI = window.location.hostname + window.location.pathname;
this.insertCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection().trim();
var insert_link = (regExpURI.test( selectionRange ))?window.prompt(lang["bbcode_link_url"], selectionRange):window.prompt(lang["bbcode_link_url"],"http://");
if (!insert_link || insert_link == '' || insert_link == "http://")
return;
if (insert_link.indexOf(forumURI) > 0 && regExpFID.test(insert_link)) {
var msgQuery = regExpFID.exec(insert_link);
link_bb_code = "msg";
insert_link = msgQuery[1];
}
else
link_bb_code = "link";
if (selectionRange == '' || regExpURI.test( selectionRange ))
selectionRange = window.prompt(lang["bbcode_link_text"], "");
if (selectionRange != null) {
if(selectionRange != '')
txtarea.insertTextRange( "["+link_bb_code+"=" + insert_link + "]" + selectionRange + "[/"+link_bb_code+"]" );
else
txtarea.insertTextRange( "["+link_bb_code+"]" + insert_link + "[/"+link_bb_code+"]" );
}
};
}
var buttonGroup = this.getButtonGroup();
window.setTimeout(function(){
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection().trim();
var insert_link = (regExpURI.test( selectionRange ))?window.prompt(lang["bbcode_link_url"], selectionRange):window.prompt(lang["bbcode_link_url"],"https://");
if (!insert_link || insert_link == '' || insert_link == "https://" || insert_link == "http://" || insert_link == "ftp://" || insert_link == "ftps://")
return;
if (selectionRange == '' || regExpURI.test( selectionRange ))
selectionRange = window.prompt(lang["bbcode_link_text"], "");
if (selectionRange != null) {
if(selectionRange != '')
txtarea.insertTextRange( "["+link_bb_code+"=" + insert_link + "]" + selectionRange + "[/"+link_bb_code+"]" );
else
txtarea.insertTextRange( "["+link_bb_code+"]" + insert_link + "[/"+link_bb_code+"]" );
}
}, 150);
};
};
/**
* Sonderbutton mit Promt-Box
* Special button with PROMT option
* @param el
* @param quest
* @param par
@ -132,23 +122,25 @@ function BBCodePromtButton(el, quest, par) {
this.insertCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection().trim();
var buttonGroup = this.getButtonGroup();
var code = this.getCode();
window.setTimeout(function(){
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection().trim();
if (selectionRange == "") {
var p = window.prompt(quest, par);
if (p && p.trim() != "" && p.trim() != par )
txtarea.insertTextRange( "[" + this.getCode() + "]" + p + "[/" + this.getCode() + "]" );
}
else
txtarea.insertTextRange( "[" + this.getCode() + "]" + selectionRange + "[/" + this.getCode() + "]" );
if (selectionRange == "") {
var p = window.prompt(quest, par);
if (p && p.trim() != "" && p.trim() != par )
txtarea.insertTextRange( "[" + code + "]" + p + "[/" + code + "]" );
}
else
txtarea.insertTextRange( "[" + code + "]" + selectionRange + "[/" + code + "]" );
}, 150);
};
}
};
/**
* Sonderbutton - COLOR
* Special Color-Picker button
* @param el
*/
function BBCodeColorChooserButton(el) {
@ -166,32 +158,32 @@ function BBCodeColorChooserButton(el) {
var colorTable = document.createElement("table");
var colorTableBody = document.createElementWithAttributes("tbody", [], colorTable);
var colorTableBody = document.createElementWithAttributes("tbody", {}, colorTable);
var self = this;
var row = document.createElementWithAttributes("tr", [], colorTableBody);
var row = document.createElementWithAttributes("tr", {}, colorTableBody);
for (var i=0; i<colors.length; i++) {
var cell = document.createElementWithAttributes("td", [], row);
var cell = document.createElementWithAttributes("td", {}, row);
cell.style.backgroundColor = colors[i];
cell.style.width = "15px";
cell.style.height = "15px";
cell.style.fontSize = "15px";
var link = document.createElementWithAttributes("a", [["href", "#"],["extension", "="+colors[i]],["onclick", function(e) { self.insertOptionCode(this); return false; }]], cell);
link.style.display = "block";
var link = document.createElementWithAttributes("a", {"href": "#", "extension": "="+colors[i], "onclick": function(e) { self.insertOptionCode(this); return false; } }, cell);
link.classList.add("js-display-block");
link.appendChild( document.createTextNode( String.fromCharCode(160) ) );
if((i+1)%7==0)
row = document.createElementWithAttributes("tr", [], colorTableBody);
row = document.createElementWithAttributes("tr", {}, colorTableBody);
}
this.insertOptionCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
var buttonGroup = this.getButtonGroup();
var txtarea = buttonGroup.getTextArea();
var code = this.getCode();
txtarea.insertTextRange( "[" + code + obj.extension + "]" + txtarea.getSelection() + "[/" + code + "]" );
txtarea.insertTextRange( "[" + code + obj.extension + "]" + txtarea.getSelection() + "[/" + code + "]" );
buttonGroup.getAdditionalOptionsWindow().enableOptionList(false);
}
};
this.insertCode = function(obj) {
if (!this.canInsert())
@ -199,12 +191,12 @@ function BBCodeColorChooserButton(el) {
var buttonGroup = this.getButtonGroup();
var objPos = document.getElementPoSi(obj);
buttonGroup.getAdditionalOptionsWindow().setOptionList(colorTable);
buttonGroup.getAdditionalOptionsWindow().enableOptionList(true, objPos);
buttonGroup.getAdditionalOptionsWindow().enableOptionList(true, objPos);
};
}
};
/**
* Sonderbutton mit zusaetzlichen Optionen
* Special button which provides additional options e.g. font-size [small large]
* @param el
* @param list
* @param quest
@ -219,8 +211,8 @@ function BBCodeOptionButton(el, list, quest, par) {
var self = this;
for (var i=0; i<list.length; i++) {
var obj = list[i];
var listElement = document.createElementWithAttributes("li", [], optionList);
var link = document.createElementWithAttributes("a", [["href", "#"],["attribute", obj.attribute],["onclick", function(e) { self.insertOptionCode(this); return false; }]], listElement);
var listElement = document.createElementWithAttributes("li", {}, optionList);
var link = document.createElementWithAttributes("a", {"href": "#", "attribute": obj.attribute, "onclick": function(e) { self.insertOptionCode(this); return false; } }, listElement);
link.appendChild( document.createTextNode(obj.label) );
optionList.appendChild(listElement);
}
@ -228,40 +220,44 @@ function BBCodeOptionButton(el, list, quest, par) {
this.insertOptionCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection();
var buttonGroup = this.getButtonGroup();
// Ausnahme INLINECODE
var codestart = this.getCode(), codeend = this.getCode();
if (obj.attribute.toLowerCase() == "inlinecode") {
codestart = codeend = obj.attribute;
}
if (obj.attribute.trim() && obj.attribute.toLowerCase() != "inlinecode")
codestart += "=" + obj.attribute;
window.setTimeout(function(){
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection();
if (quest && selectionRange == "") {
var p = window.prompt(quest, par);
if (p && p.trim() != "" && p.trim() != par )
txtarea.insertTextRange( "[" + codestart + "]" + p + "[/" + codeend + "]" );
}
else
txtarea.insertTextRange( "[" + codestart + "]" + selectionRange + "[/" + codeend + "]" );
if (obj.attribute != null && obj.attribute.trim() != "") {
if (obj.attribute.trim().toLowerCase() == "inlinecode")
codestart = codeend = obj.attribute;
else
codestart += "=" + obj.attribute;
}
buttonGroup.getAdditionalOptionsWindow().enableOptionList(false);
}
if (quest && selectionRange == "") {
var p = window.prompt(quest, par);
if (p && p.trim() != "" && p.trim() != par )
txtarea.insertTextRange( "[" + codestart + "]" + p + "[/" + codeend + "]" );
}
else
txtarea.insertTextRange( "[" + codestart + "]" + selectionRange + "[/" + codeend + "]" );
buttonGroup.getAdditionalOptionsWindow().enableOptionList(false);
}, 150);
};
this.insertCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
var buttonGroup = this.getButtonGroup();
var objPos = document.getElementPoSi(obj);
buttonGroup.getAdditionalOptionsWindow().setOptionList(optionList);
buttonGroup.getAdditionalOptionsWindow().enableOptionList(true, objPos);
buttonGroup.getAdditionalOptionsWindow().enableOptionList(true, objPos);
};
}
};
/**
* Sonderbutton - LIST
* Special button to create a LIST
* @param el
*/
function BBCodeListButton(el) {
@ -269,7 +265,7 @@ function BBCodeListButton(el) {
this.insertCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
var buttonGroup = this.getButtonGroup();
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection();
var listStr = "";
@ -282,10 +278,10 @@ function BBCodeListButton(el) {
txtarea.insertTextRange( "\r\n[list]" + listStr + "\r\n[/list]\r\n");
};
}
};
/**
* Sonderbutton - einzelnes Smilies
* Special button for emotional icon
* @param el
*/
function BBCodeSingleSmilieButton(el) {
@ -293,59 +289,51 @@ function BBCodeSingleSmilieButton(el) {
this.insertCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
var buttonGroup = this.getButtonGroup();
var txtarea = buttonGroup.getTextArea();
var selectionRange = txtarea.getSelection();
txtarea.insertTextRange( selectionRange + this.getCode() + " " );
};
}
};
/**
* Sonderbutton - Smilies
* Special button for larger list of emotional icons
* @param el
* @param list
*/
function BBCodeSmilieButton(el, list) {
this.constructor(el, list);
var self = this;
//var smilies = document.createElement("div");
var smilies = document.createElementWithAttributes("div", [["id", "additional-smilies"]], null);
var smilies = document.createElementWithAttributes("ul", {"id": "additional-smilies"}, null);
for (var i=0; i<list.length; i++) {
var link = document.createElementWithAttributes("a", [["href", "#"],["title", list[i].title],["code", list[i].code],["onclick", function(e) { self.insertOptionCode(this); return false; }]], smilies);
link.appendChild( list[i].label );
//if ((i+1)%5==0)
// document.createElementWithAttributes("br", [], smilies);
//else
//smilies.appendChild( document.createTextNode( String.fromCharCode(32) ) );
let item = document.createElementWithAttributes("li",{}, smilies);
let btn = document.createElementWithAttributes("button",{"type": "button", "title": list[i].title, "value": list[i].code, "onclick": function(e) { self.insertButtonCode(this); return false; }}, item);
btn.appendChild( list[i].label);
}
this.insertOptionCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
this.insertButtonCode = function(obj) {
if (!this.canInsert()) return;
var buttonGroup = this.getButtonGroup();
var txtarea = buttonGroup.getTextArea();
var code = obj.code;
txtarea.insertTextRange( txtarea.getSelection() +code + " " );
const val = event.target.closest("button").getAttribute("value");
txtarea.insertTextRange( txtarea.getSelection() + val + " " );
buttonGroup.getAdditionalOptionsWindow().enableOptionList(false);
}
this.insertCode = function(obj) {
if (!this.canInsert())
return;
var buttonGroup = this.getButtonGroup();
//var txtarea = buttonGroup.getTextArea();
//selectionRange = txtarea.getSelection();
var buttonGroup = this.getButtonGroup();
var objPos = document.getElementPoSi(obj);
buttonGroup.getAdditionalOptionsWindow().setOptionList(smilies);
buttonGroup.getAdditionalOptionsWindow().enableOptionList(true, objPos);
};
}
buttonGroup.getAdditionalOptionsWindow().enableOptionList(true, objPos);
};
};
/**
* Sonderbutton mit Zusatzfenster
* Special button to open a pop-up
* @param el
* @param uri
* @param width
@ -366,8 +354,8 @@ function BBCodePopUpButton(el, uri, width, height) {
var win = window.open(uri,"MyLittleForum","height="+height+",width="+width+",left="+left+", top="+top+",scrollbars,resizable");
window.mlfBBCodeButton = this;
win.focus();
}
}
};
};
/* Vererbung */
BBCodeLinkButton.prototype = new BBCodeButton;
@ -380,7 +368,7 @@ BBCodePopUpButton.prototype = new BBCodeButton;
BBCodePromtButton.prototype = new BBCodeButton;
/**
* ButtonGroup, die allte BB-Code-Button verwaltet
* ButtonGroup, which handles the created BB-code buttons
* @param form
*/
function ButtonGroup(f) {
@ -389,7 +377,7 @@ function ButtonGroup(f) {
var textarea = f.elements["text"];
if (!textarea)
textarea = document.createElementWithAttributes("textarea", [["name", "text"], ["id", "text"], ["cols", 80], ["rows", 20]], f);
textarea = document.createElementWithAttributes("textarea", {"name": "text", "id": "text", "cols": 80, "rows": 20}, f);
var hasUserButtons = false;
var buttons = [];
@ -398,8 +386,8 @@ function ButtonGroup(f) {
var self = this;
/**
* Pruefe das Formaular, ob alle notwendigen Felder ausgefuellt sind!
* return isComplete
* Check form
* return complete
*/
f.onsubmit = function(e) {
var error_message = '';
@ -407,7 +395,6 @@ function ButtonGroup(f) {
if (f.elements['name_required'] && f.elements['name'] && f.elements['name'].value.trim() == '')
error_message += "- "+lang["error_no_name"]+"\n";
//if (f.elements['subject_required'] && f.elements['subject'] && f.elements['subject'].value.trim() =='')
if (f.elements['subject'] && f.elements['subject'].value.trim() =='')
error_message += "- "+lang["error_no_subject"]+"\n";
@ -421,58 +408,66 @@ function ButtonGroup(f) {
window.alert(error_message);
return false;
}
if (document.getElementById('throbber-submit'))
document.getElementById('throbber-submit').style.visibility = 'visible';
if (document.getElementById('throbber-submit')) {
document.getElementById('throbber-submit').classList.remove('js-visibility-hidden');
}
return true;
};
/**
* Wandelt die Smilie-Anleitung in klickbare Elemente um
* Transform introduction (for adding emotional icons) into button elements
*/
convertInstructionsToSmilies = function() {
var convertInstructionsToSmilies = function() {
if (!document.getElementById("smiley-bar"))
return;
var buttonBar = document.getElementById("smiley-bar");
if (document.getElementById("smiley-instructions")) {
var el = document.getElementById("smiley-instructions").firstChild;
let elems = document.getElementById("smiley-instructions").querySelectorAll("div");
var obj = null;
var list = [];
while (el != null) {
if (el.nodeName && el.nodeName.toLowerCase() == "dt") {
for (const el of elems) {
const term = el.querySelector("dt");
const desc = el.querySelectorAll("dd");
if (term) {
obj = {
code : el.firstChild.nodeValue,
title : el.title,
classes : el.className,
code : term.textContent,
title : term.getAttribute("title"),
classes : term.getAttribute("class"),
isSmilie: true,
childs : []
};
}
if (obj && desc) {
for (const d of desc) {
obj.label = d.firstChild;
if (obj.classes.search(/default/) != -1)
createSingleButton(obj, buttonBar);
else
list.push(obj);
obj = null;
}
}
else if (obj && el.nodeName && el.nodeName.toLowerCase() == "dd") {
obj.label = el.firstChild;
if (obj.classes.search(/default/) != -1)
createSingleButton(obj, buttonBar);
else
list.push(obj);
obj = null;
}
el = el.nextSibling;
}
if (list && list.length > 0) {
obj = {
code : "",
title : lang["more_smilies_title"],
label : lang["more_smilies_label"],
classes : "more-smilies",
classes : "",
isSmilie: true,
childs : list
};
createSingleButton(obj, buttonBar);
if (obj)
createSingleButton(obj, buttonBar);
}
}
}
/**
* Wandelt die BB-Code-Anleitung in klickbare Elemente um
* Transform introduction (for adding source code) into button elements
*/
var convertInstructionsToButton = function() {
if (!document.getElementById("bbcode-bar"))
@ -480,38 +475,38 @@ function ButtonGroup(f) {
var buttonBar = document.getElementById("bbcode-bar");
if (document.getElementById("bbcode-instructions")) {
var el = document.getElementById("bbcode-instructions").firstChild;
let elems = document.getElementById("bbcode-instructions").querySelectorAll("div");
var obj = null;
while (el != null) {
if (el.nodeName && el.nodeName.toLowerCase() == "dt") {
if (obj)
createSingleButton(obj, buttonBar);
for (const el of elems) {
const term = el.querySelector("dt");
const desc = el.querySelectorAll("dd");
if (term) {
obj = {
code : el.id,
label : el.title,
title : el.firstChild.nodeValue,
classes : el.className,
code : term.getAttribute("id"),
label : term.getAttribute("title"),
title : term.textContent,
classes : term.getAttribute("class"),
childs : []
}
};
}
else if (obj && el.nodeName && el.nodeName.toLowerCase() == "dd") {
var attChild = {
attribute : el.id,
label : el.title
if (obj && desc) {
for (const d of desc) {
var attChild = {
attribute : d.getAttribute("id"),
label : d.getAttribute("title")
}
obj.childs.push(attChild);
}
obj.childs.push( attChild );
}
el = el.nextSibling;
if (obj)
createSingleButton(obj, buttonBar);
}
if (obj)
createSingleButton(obj, buttonBar);
}
};
/**
* Fuegt einen BB-Button dem Dokument hinzu.
* Add a bb code button element to the document
* @param button
* @param isUserButton
*/
@ -536,18 +531,17 @@ function ButtonGroup(f) {
}
/**
* Erzeugt einen einfachen Klick-Button, der ein SPAN-Element enthaelt
* aus einem spezifischen Objekt
* Creates a simple button, which contains a SPAN element for labeling
* @param obj
* @param buttonBar
*/
var createSingleButton = function(obj, buttonBar) {
var par = [["className", obj.classes], ["name", obj.code], ["type", "button"], ["title", obj.title]];
var par = {"className": obj.classes, "name": obj.code, "type": "button", "title": obj.title, "tabIndex": -1};
var id = obj.code.trim() == ""?"bbcodebutton":"bbcodebutton-"+obj.code;
if (obj.isSmilie)
par.push(["isSmilie", obj.isSmilie]);
par["isSmilie"] = obj.isSmilie;
else
par.push(["id", id]);
par["id"] = id;
var b = document.createElementWithAttributes("button", par, buttonBar);
var buttonSpan = document.createElement("span");
@ -560,64 +554,59 @@ function ButtonGroup(f) {
};
/**
* Erzeugt aus einem normalen Klick-Button ein
* BBCodeButton-Objekt (ggf. mit Zusatzoptionen)
* Transform a normal button element to a bb-code button elemement
*
* @param button
* @param list
* @return button
*/
var createBBCodeButton = function(button, list) {
var bbCodeButton = null;
switch(button.name.toLowerCase()) {
case "link":
bbCodeButton = new BBCodeLinkButton( button );
break;
case "img":
if (list && list.length > 1)
bbCodeButton = new BBCodeOptionButton(button, list, lang["bbcode_image_url"], "http://" );
else
bbCodeButton = new BBCodePromtButton( button, lang["bbcode_image_url"], "http://" );
break;
case "color":
bbCodeButton = new BBCodeColorChooserButton( button );
break;
case "list":
bbCodeButton = new BBCodeListButton( button );
break;
case "flash":
bbCodeButton = new BBCodePopUpButton( button, "index.php?mode=insert_flash", settings["flash_popup_width"], settings["flash_popup_height"]);
break;
case "upload":
bbCodeButton = new BBCodePopUpButton( button, "index.php?mode=upload_image", settings["upload_popup_width"], settings["upload_popup_height"]);
break;
case "tex":
bbCodeButton = new BBCodePromtButton( button, lang["bbcode_tex_code"] );
break;
default:
if (button.isSmilie && list && list.length > 1)
bbCodeButton = new BBCodeSmilieButton( button, list );
else if (button.isSmilie)
bbCodeButton = new BBCodeSingleSmilieButton( button );
else if (list && list.length > 1)
bbCodeButton = new BBCodeOptionButton( button, list );
else
bbCodeButton = new BBCodeButton( button );
break;
var bname = button && button.name ? button.name.toLowerCase() : "";
switch(bname) {
case "link":
bbCodeButton = new BBCodeLinkButton( button );
break;
case "img":
if (list && list.length > 1)
bbCodeButton = new BBCodeOptionButton(button, list, lang["bbcode_image_url"], "https://" );
else
bbCodeButton = new BBCodePromtButton( button, lang["bbcode_image_url"], "https://" );
break;
case "color":
bbCodeButton = new BBCodeColorChooserButton( button );
break;
case "list":
bbCodeButton = new BBCodeListButton( button );
break;
case "upload":
bbCodeButton = new BBCodePopUpButton( button, "index.php?mode=upload_image", settings["upload_popup_width"], settings["upload_popup_height"]);
break;
case "tex":
bbCodeButton = new BBCodePromtButton( button, lang["bbcode_tex_code"] );
break;
default:
if (button.isSmilie && list && list.length > 0)
bbCodeButton = new BBCodeSmilieButton( button, list );
else if (button.isSmilie)
bbCodeButton = new BBCodeSingleSmilieButton( button );
else if (list && list.length > 1)
bbCodeButton = new BBCodeOptionButton( button, list );
else
bbCodeButton = new BBCodeButton( button );
break;
}
return bbCodeButton;
}
/**
* Erzeugt ein Fenster, in dem die Zusatzoptionen
* angezeigt werden koennen
};
/**
* Creates a window to show further options of the clicked button
* @return win
*/
var createAdditionalOptionsWindow = function() {
var w = document.createElementWithAttributes("div", [["id", "bbcode-options"]], document.body);
var content = document.createElementWithAttributes("div", [], w);
w.style.display = "none";
w.style.position = "absolute";
var w = document.createElementWithAttributes("div", {"id": "bbcode-options"}, document.body);
var content = document.createElementWithAttributes("div", {}, w);
w.classList.add("js-display-none");
var timeout = null;
w.onmouseover = function(e) {
@ -643,53 +632,53 @@ function ButtonGroup(f) {
else
content.replaceChild(list, content.firstChild);
};
w.enableOptionList = function(enable, pos) {
if (pos) {
this.style.left = pos.left + "px";
this.style.left = pos.left + "px";
this.style.top = pos.top + "px";
}
this.style.display = enable?"":"none";
if (enable)
this.classList.remove("js-display-none");
else
this.classList.add("js-display-none");
};
var oldOnKeyPressFunc = window.document.onmousedown;
window.document.onkeypress = function(e) {
var keyCode = document.getKeyCode(e);
if (keyCode == 27)
self.enableOptionList(false);
window.document.onkeypress = function(e) {
if (e.key == "Esc")
self.enableOptionList(false);
if (typeof oldOnKeyPressFunc == "function")
oldOnKeyPressFunc(e);
}
}
return w;
};
/**
* Sucht nach Button, die der Nutzer
* ins Dokument eingefuegt hat
* Search for added buttons within the document
* @param isSmilie
*/
var initUserBBCodeButtons = function(isSmilie) {
isSmilie = isSmilie || false;
hasUserButtons = false;
var id = isSmilie?"smiley-bar":"bbcode-bar";
var id = isSmilie ? "smiley-bar" : "bbcode-bar";
if (!document.getElementById(id))
return;
var userButtons = document.getElementById(id).getElementsByTagName("button");
if (userButtons && userButtons.length > 0) {
for (var i=0; i<userButtons.length; i++) {
var j = userButtons.length;
for (var i=0; i<j; i++) {
hasUserButtons = true;
userButtons[i].isSmilie = isSmilie;
addButton(createBBCodeButton(userButtons[i], null), true);
}
}
}
};
/**
* Initialisiert die Textarea
* und setzt Funktionen zum Ermitteln
* des selektierten Textes
* Init. text area of the posting form
*/
var initTextArea = function() {
// Sichert den (alten) Text in der Area
@ -698,25 +687,24 @@ function ButtonGroup(f) {
textarea.quote = textarea.value;
textarea.value = "";
}
textarea.getQuote = function() {
return textarea.quote.trim();
}
// Zitieren-Link einfuegen
// insert the quotation-link
if (textarea.getQuote() != "" && document.getElementById("message")) {
var labels = document.getElementById("message").getElementsByTagName("label");
var label = null;
for (var i=0; i<labels.length; i++) {
if (labels[i].className.search(/textarea/) != -1) {
label = labels[i];
break;
}
}
var label = document.querySelector('label[for="text"]');
if (label) {
label.appendChild( document.createTextNode( String.fromCharCode(160) ) );
var quoteLink = document.createElementWithAttributes("a", [["onclick", function(e) {textarea.value = textarea.getQuote() + "\r\n\r\n" + textarea.value; this.style.display = "none"; textarea.focus(); return false;}], ["id", "insert-quote"], ["href", window.location.href], ["title", lang["quote_title"]]], label);
quoteLink.appendChild( document.createTextNode(lang["quote_label"]) );
var quoteButton = document.createElementWithAttributes("button", {"type": "button", "id": "insert-quote", "title": lang["quote_title"], "tabIndex": -1});
quoteButton.onclick = function(e) {
textarea.value = textarea.getQuote() + "\r\n\r\n" + textarea.value;
this.classList.add("js-display-none");
textarea.focus();
return false;
};
quoteButton.appendChild( document.createTextNode(lang["quote_label"]) )
label.parentNode.insertBefore(quoteButton, label.nextSibling);
}
}
@ -756,15 +744,15 @@ function ButtonGroup(f) {
};
/**
* Liefert die Textarea
* Returns the text area of the form
* @return area
*/
this.getTextArea = function() {
return textarea;
};
};
/**
* Liefert das Option-Window
* Returns the property window of the button
* @return win
*/
this.getAdditionalOptionsWindow = function() {
@ -779,20 +767,19 @@ function ButtonGroup(f) {
link.onclick = function(e) {
document.cookie = settings["session_prefix"]+'userdata=; expires=Thu, 01-Jan-70 00:00:01 GMT;';
span.innerHTML = "";
if(f.elements["setcookie"]) f.elements["setcookie"].checked = false;
if(f.elements["setcookie"]) f.elements["setcookie"].checked = false;
return false;
};
};
};
var removeIntroductionElements = function() {
if (document.getElementById("formatting-help")) {
var el = document.getElementById("formatting-help");
el.classList.add('js-display-none');
}
};
/**
* Initialisiert ButtonGroup
*
*/
(function() {
if (document.getElementById("bbcode-instructions"))
document.getElementById("bbcode-instructions").style.display = "none";
if (document.getElementById("smiley-instructions"))
document.getElementById("smiley-instructions").style.display = "none";
additionalOptionsWindow = createAdditionalOptionsWindow();
// Erzeuge Textarea
initTextArea();
@ -802,10 +789,12 @@ function ButtonGroup(f) {
initUserBBCodeButtons(true);
convertInstructionsToSmilies();
initDeleteCookieLink();
// entferne die Introduction-Elemente zur Definition der Button
removeIntroductionElements();
}());
}
window.ready.push(function() {
document.addEventListener("DOMContentLoaded", function(e) {
if (typeof settings == "object" && typeof lang == "object")
new ButtonGroup( document.getElementById("postingform") );
});
});

2
js/posting.min.js vendored

File diff suppressed because one or more lines are too long

1264
lang/arabic.lang Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1267
lang/danish.lang Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1276
lang/swedish.lang Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

407
modules/b8/b8.php Normal file
View file

@ -0,0 +1,407 @@
<?php
/* Copyright (C) 2006-2019 Tobias Leupold <tobias.leupold@gmx.de>
b8 - A statistical ("Bayesian") spam filter written in PHP
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation in version 2.1 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
/**
* The b8 spam filter library
*
* @license LGPL 2.1
* @package b8
* @author Tobias Leupold <tobias.leupold@gmx.de>
* @author Oliver Lillie <ollie@buggedcom.co.uk> (original PHP 5 port)
*/
namespace b8;
spl_autoload_register(
function ($class) {
$parts = explode('\\', $class);
if (count($parts) > 2 && $parts[0] == 'b8') {
require_once __DIR__ . DIRECTORY_SEPARATOR . $parts[1]
. DIRECTORY_SEPARATOR . $parts[2] . '.php';
}
}
);
class b8
{
const DBVERSION = 3;
const SPAM = 'spam';
const HAM = 'ham';
const LEARN = 'learn';
const UNLEARN = 'unlearn';
const CLASSIFIER_TEXT_MISSING = 'CLASSIFIER_TEXT_MISSING';
const TRAINER_TEXT_MISSING = 'TRAINER_TEXT_MISSING';
const TRAINER_CATEGORY_MISSING = 'TRAINER_CATEGORY_MISSING';
const TRAINER_CATEGORY_FAIL = 'TRAINER_CATEGORY_FAIL';
const INTERNALS_TEXTS = 'b8*texts';
const INTERNALS_DBVERSION = 'b8*dbversion';
const KEY_DB_VERSION = 'dbversion';
const KEY_COUNT_HAM = 'count_ham';
const KEY_COUNT_SPAM = 'count_spam';
const KEY_TEXTS_HAM = 'texts_ham';
const KEY_TEXTS_SPAM = 'texts_spam';
private $config = [ 'lexer' => 'standard',
'degenerator' => 'standard',
'storage' => 'dba',
'use_relevant' => 15,
'min_dev' => 0.2,
'rob_s' => 0.3,
'rob_x' => 0.5 ];
private $storage = null;
private $lexer = null;
private $degenerator = null;
private $token_data = null;
/**
* Constructs b8
*
* @access public
* @param array b8's configuration: [ 'lexer' => string,
'degenerator' => string,
'storage' => string,
'use_relevant' => int,
'min_dev' => float,
'rob_s' => float,
'rob_x' => float ]
* @param array The storage backend's config (depending on the backend used)
* @param array The lexer's config (depending on the lexer used)
* @param array The degenerator's config (depending on the degenerator used)
* @return void
*/
function __construct(array $config = [],
array $config_storage = [],
array $config_lexer = [],
array $config_degenerator = [])
{
// Validate config data
foreach ($config as $name => $value) {
switch ($name) {
case 'min_dev':
case 'rob_s':
case 'rob_x':
$this->config[$name] = (float) $value;
break;
case 'use_relevant':
$this->config[$name] = (int) $value;
break;
case 'lexer':
case 'degenerator':
case 'storage':
$this->config[$name] = (string) $value;
break;
default:
throw new \Exception(b8::class . ": Unknown configuration key: \"$name\"");
}
}
// Setup the degenerator class
$class = '\\b8\\degenerator\\' . $this->config['degenerator'];
$this->degenerator = new $class($config_degenerator);
// Setup the lexer class
$class = '\\b8\\lexer\\' . $this->config['lexer'];
$this->lexer = new $class($config_lexer);
// Setup the storage backend
$class = '\\b8\\storage\\' . $this->config['storage'];
$this->storage = new $class($config_storage, $this->degenerator);
}
/**
* Classifies a text
*
* @access public
* @param string The text to classify
* @return mixed float The rating between 0 (ham) and 1 (spam) or an error code
*/
public function classify(string $text = null)
{
// Let's first see if the user called the function correctly
if ($text === null) {
return \b8\b8::CLASSIFIER_TEXT_MISSING;
}
// Get the internal database variables, containing the number of ham and spam texts so the
// spam probability can be calculated in relation to them
$internals = $this->storage->get_internals();
// Calculate the spaminess of all tokens
// Get all tokens we want to rate
$tokens = $this->lexer->get_tokens($text);
// Check if the lexer failed (if so, $tokens will be a lexer error code, if not, $tokens
// will be an array)
if (! is_array($tokens)) {
return $tokens;
}
// Fetch all available data for the token set from the database
$this->token_data = $this->storage->get(array_keys($tokens));
// Calculate the spaminess and importance for each token (or a degenerated form of it)
$word_count = [];
$rating = [];
$importance = [];
foreach ($tokens as $word => $count) {
$word_count[$word] = $count;
// Although we only call this function only here ... let's do the calculation stuff in a
// function to make this a bit less confusing ;-)
$rating[$word] = $this->get_probability($word, $internals);
$importance[$word] = abs(0.5 - $rating[$word]);
}
// Order by importance
arsort($importance);
reset($importance);
// Get the most interesting tokens (use all if we have less than the given number)
$relevant = [];
for ($i = 0; $i < $this->config['use_relevant']; $i++) {
if ($token = key($importance)) {
// Important tokens remain
// If the token's rating is relevant enough, use it
if (abs(0.5 - $rating[$token]) > $this->config['min_dev']) {
// Tokens that appear more than once also count more than once
for ($x = 0, $l = $word_count[$token]; $x < $l; $x++) {
array_push($relevant, $rating[$token]);
}
}
} else {
// We have less words as we want to use, so we already use what we have and can
// break here
break;
}
next($importance);
}
// Calculate the spaminess of the text (thanks to Mr. Robinson ;-)
// We set both haminess and spaminess to 1 for the first multiplying
$haminess = 1;
$spaminess = 1;
// Consider all relevant ratings
foreach ($relevant as $value) {
$haminess *= (1.0 - $value);
$spaminess *= $value;
}
// If no token was good for calculation, we really don't know how to rate this text, so
// we can return 0.5 without further calculations.
if ($haminess == 1 && $spaminess == 1) {
return 0.5;
}
// Calculate the combined rating
// Get the number of relevant ratings
$n = count($relevant);
// The actual haminess and spaminess
$haminess = 1 - pow($haminess, (1 / $n));
$spaminess = 1 - pow($spaminess, (1 / $n));
// Calculate the combined indicator
$probability = ($haminess - $spaminess) / ($haminess + $spaminess);
// We want a value between 0 and 1, not between -1 and +1, so ...
$probability = (1 + $probability) / 2;
// Alea iacta est
return $probability;
}
/**
* Calculate the spaminess of a single token also considering "degenerated" versions
*
* @access private
* @param string The word to rate
* @param array The "internals" array
* @return float The word's rating
*/
private function get_probability(string $word, array $internals)
{
// Let's see what we have!
if (isset($this->token_data['tokens'][$word])) {
// The token is in the database, so we can use it's data as-is and calculate the
// spaminess of this token directly
return $this->calculate_probability($this->token_data['tokens'][$word], $internals);
}
// The token was not found, so do we at least have similar words?
if (isset($this->token_data['degenerates'][$word])) {
// We found similar words, so calculate the spaminess for each one and choose the most
// important one for the further calculation
// The default rating is 0.5 simply saying nothing
$rating = 0.5;
foreach ($this->token_data['degenerates'][$word] as $degenerate => $count) {
// Calculate the rating of the current degenerated token
$rating_tmp = $this->calculate_probability($count, $internals);
// Is it more important than the rating of another degenerated version?
if(abs(0.5 - $rating_tmp) > abs(0.5 - $rating)) {
$rating = $rating_tmp;
}
}
return $rating;
} else {
// The token is really unknown, so choose the default rating for completely unknown
// tokens. This strips down to the robX parameter so we can cheap out the freaky math
// ;-)
return $this->config['rob_x'];
}
}
/**
* Do the actual spaminess calculation of a single token
*
* @access private
* @param array The token's data [ \b8\b8::KEY_COUNT_HAM => int,
\b8\b8::KEY_COUNT_SPAM => int ]
* @param array The "internals" array
* @return float The rating
*/
private function calculate_probability(array $data, array $internals)
{
// Calculate the basic probability as proposed by Mr. Graham
// But: consider the number of ham and spam texts saved instead of the number of entries
// where the token appeared to calculate a relative spaminess because we count tokens
// appearing multiple times not just once but as often as they appear in the learned texts.
$rel_ham = $data[\b8\b8::KEY_COUNT_HAM];
$rel_spam = $data[\b8\b8::KEY_COUNT_SPAM];
if ($internals[\b8\b8::KEY_TEXTS_HAM] > 0) {
$rel_ham = $data[\b8\b8::KEY_COUNT_HAM] / $internals[\b8\b8::KEY_TEXTS_HAM];
}
if ($internals[\b8\b8::KEY_TEXTS_SPAM] > 0) {
$rel_spam = $data[\b8\b8::KEY_COUNT_SPAM] / $internals[\b8\b8::KEY_TEXTS_SPAM];
}
$rating = $rel_spam / ($rel_ham + $rel_spam);
// Calculate the better probability proposed by Mr. Robinson
$all = $data[\b8\b8::KEY_COUNT_HAM] + $data[\b8\b8::KEY_COUNT_SPAM];
return (($this->config['rob_s'] * $this->config['rob_x']) + ($all * $rating))
/ ($this->config['rob_s'] + $all);
}
/**
* Check the validity of the category of a request
*
* @access private
* @param string The category
* @return void
*/
private function check_category(string $category)
{
return $category === \b8\b8::HAM || $category === \b8\b8::SPAM;
}
/**
* Learn a reference text
*
* @access public
* @param string The text to learn
* @param string Either b8::SPAM or b8::HAM
* @return mixed void or an error code
*/
public function learn(string $text = null, string $category = null)
{
// Let's first see if the user called the function correctly
if ($text === null) {
return \b8\b8::TRAINER_TEXT_MISSING;
}
if ($category === null) {
return \b8\b8::TRAINER_CATEGORY_MISSING;
}
return $this->process_text($text, $category, \b8\b8::LEARN);
}
/**
* Unlearn a reference text
*
* @access public
* @param string The text to unlearn
* @param string Either b8::SPAM or b8::HAM
* @return mixed void or an error code
*/
public function unlearn(string $text = null, string $category = null)
{
// Let's first see if the user called the function correctly
if ($text === null) {
return \b8\b8::TRAINER_TEXT_MISSING;
}
if ($category === null) {
return \b8\b8::TRAINER_CATEGORY_MISSING;
}
return $this->process_text($text, $category, \b8\b8::UNLEARN);
}
/**
* Does the actual interaction with the storage backend for learning or unlearning texts
*
* @access private
* @param string The text to process
* @param string Either b8::SPAM or b8::HAM
* @param string Either b8::LEARN or b8::UNLEARN
* @return mixed void or an error code
*/
private function process_text(string $text, string $category, string $action)
{
// Look if the request is okay
if (! $this->check_category($category)) {
return \b8\b8::TRAINER_CATEGORY_FAIL;
}
// Get all tokens from $text
$tokens = $this->lexer->get_tokens($text);
// Check if the lexer failed (if so, $tokens will be a lexer error code, if not, $tokens
// will be an array)
if (! is_array($tokens)) {
return $tokens;
}
// Pass the tokens and what to do with it to the storage backend
return $this->storage->process_text($tokens, $category, $action);
}
}

View file

@ -0,0 +1,176 @@
<?php
/* Copyright (C) 2006-2019 Tobias Leupold <tobias.leupold@gmx.de>
This file is part of the b8 package
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation in version 2.1 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
/**
* A helper class to derive simplified tokens
*
* @license LGPL 2.1
* @package b8
* @author Tobias Leupold <tobias.leupold@gmx.de>
*/
namespace b8\degenerator;
class standard
{
public $config = [ 'multibyte' => true,
'encoding' => 'UTF-8' ];
public $degenerates = [];
/**
* Constructs the degenerator.
*
* @access public
* @param array $config The configuration: [ 'multibyte' => bool,
'encoding' => string ]
* @return void
*/
public function __construct(array $config)
{
// Validate config data
foreach ($config as $name => $value) {
switch($name) {
case 'multibyte':
$this->config[$name] = (bool) $value;
break;
case 'encoding':
$this->config[$name] = (string) $value;
break;
default:
throw new \Exception(standard::class . ": Unknown configuration key: "
. "\"$name\"");
}
}
}
/**
* Generates a list of "degenerated" words for a list of words.
*
* @access public
* @param array $words The words to degenerate
* @return array An array containing an array of degenerated tokens for each token
*/
public function degenerate(array $words)
{
$degenerates = [];
foreach ($words as $word) {
$degenerates[$word] = $this->degenerate_word($word);
}
return $degenerates;
}
/**
* Remove duplicates from a list of degenerates of a word.
*
* @access private
* @param string $word The word
* @param array $list The list to process
* @return array The list without duplicates
*/
private function delete_duplicates(string $word, array $list)
{
$list_processed = [];
// Check each upper/lower version
foreach ($list as $alt_word) {
if ($alt_word != $word) {
array_push($list_processed, $alt_word);
}
}
return $list_processed;
}
/**
* Builds a list of "degenerated" versions of a word.
*
* @access private
* @param string $word The word
* @return array An array of degenerated words
*/
private function degenerate_word(string $word)
{
// Check for any stored words so the process doesn't have to repeat
if (isset($this->degenerates[$word]) === true) {
return $this->degenerates[$word];
}
// Create different versions of upper and lower case
if ($this->config['multibyte'] === false) {
// The standard upper/lower versions
$lower = strtolower($word);
$upper = strtoupper($word);
$first = substr($upper, 0, 1) . substr($lower, 1, strlen($word));
} elseif ($this->config['multibyte'] === true) {
// The multibyte upper/lower versions
$lower = mb_strtolower($word, $this->config['encoding']);
$upper = mb_strtoupper($word, $this->config['encoding']);
$first = mb_substr($upper, 0, 1, $this->config['encoding'])
. mb_substr($lower, 1, mb_strlen($word), $this->config['encoding']);
}
// Add the versions
$upper_lower = [];
array_push($upper_lower, $lower);
array_push($upper_lower, $upper);
array_push($upper_lower, $first);
// Delete duplicate upper/lower versions
$degenerate = $this->delete_duplicates($word, $upper_lower);
// Append the original word
array_push($degenerate, $word);
// Degenerate all versions
foreach ($degenerate as $alt_word) {
// Look for stuff like !!! and ???
if (preg_match('/[!?]$/', $alt_word) > 0) {
// Add versions with different !s and ?s
if (preg_match('/[!?]{2,}$/', $alt_word) > 0) {
$tmp = preg_replace('/([!?])+$/', '$1', $alt_word);
array_push($degenerate, $tmp);
}
$tmp = preg_replace('/([!?])+$/', '', $alt_word);
array_push($degenerate, $tmp);
}
// Look for "..." at the end of the word
$alt_word_int = $alt_word;
while (preg_match('/[\.]$/', $alt_word_int) > 0) {
$alt_word_int = substr($alt_word_int, 0, strlen($alt_word_int) - 1);
array_push($degenerate, $alt_word_int);
}
}
// Some degenerates are the same as the original word. These don't have to be fetched, so we
// create a new array with only new tokens
$degenerate = $this->delete_duplicates($word, $degenerate);
// Store the list of degenerates for the token to prevent unnecessary re-processing
$this->degenerates[$word] = $degenerate;
return $degenerate;
}
}

View file

@ -0,0 +1,267 @@
<?php
/* Copyright (C) 2006-2019 Tobias Leupold <tobias.leupold@gmx.de>
This file is part of the b8 package
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation in version 2.1 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
/**
* A helper class to disassemble a text to tokens
*
* @license LGPL 2.1
* @package b8
* @author Tobias Leupold <tobias.leupold@gmx.de>
* @author Oliver Lillie <ollie@buggedcom.co.uk> (original PHP 5 port)
*/
namespace b8\lexer;
class standard
{
const LEXER_TEXT_NOT_STRING = 'LEXER_TEXT_NOT_STRING';
const LEXER_TEXT_EMPTY = 'LEXER_TEXT_EMPTY';
const LEXER_NO_TOKENS = 'b8*no_tokens';
private $config = [ 'min_size' => 3,
'max_size' => 30,
'get_uris' => true,
'get_html' => true,
'get_bbcode' => false,
'allow_numbers' => false ];
private $tokens = null;
private $processed_text = null;
// The regular expressions we use to split the text to tokens
private $regexp = [ 'raw_split' => '/[\s,\.\/"\:;\|<>\-_\[\]{}\+=\)\(\*\&\^%]+/',
'ip' => '/([A-Za-z0-9\_\-\.]+)/',
'uris' => '/([A-Za-z0-9\_\-]*\.[A-Za-z0-9\_\-\.]+)/',
'html' => '/(<.+?>)/',
'bbcode' => '/(\[.+?\])/',
'tagname' => '/(.+?)\s/',
'numbers' => '/^[0-9]+$/' ];
/**
* Constructs the lexer.
*
* @access public
* @param array $config The configuration: [ 'min_size' => int,
* 'max_size' => int,
* 'get_uris' => bool,
* 'get_html' => bool,
* 'get_bbcode' => bool,
* 'allow_numbers' => bool ]
* @return void
*/
function __construct(array $config)
{
// Validate config data
foreach ($config as $name=>$value) {
switch ($name) {
case 'min_size':
case 'max_size':
$this->config[$name] = (int) $value;
break;
case 'allow_numbers':
case 'get_uris':
case 'get_html':
case 'get_bbcode':
$this->config[$name] = (bool) $value;
break;
default:
throw new \Exception(standard::class . ": Unknown configuration key: "
. "\"$name\"");
}
}
}
/**
* Splits a text to tokens.
*
* @access public
* @param string $text The text to disassemble
* @return mixed Returns a list of tokens or an error code
*/
public function get_tokens(string $text)
{
// Check if we actually have a string ...
if (is_string($text) === false) {
return self::LEXER_TEXT_NOT_STRING;
}
// ... and if it's empty
if (empty($text) === true) {
return self::LEXER_TEXT_EMPTY;
}
// Re-convert the text to the original characters coded in UTF-8, as they have been coded in
// html entities during the post process
$this->processed_text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
// Reset the token list
$this->tokens = array();
if ($this->config['get_uris'] === true) {
// Get URIs
$this->get_uris($this->processed_text);
}
if ($this->config['get_html'] === true) {
// Get HTML
$this->get_markup($this->processed_text, $this->regexp['html']);
}
if ($this->config['get_bbcode'] === true) {
// Get BBCode
$this->get_markup($this->processed_text, $this->regexp['bbcode']);
}
// We always want to do a raw split of the (remaining) text, so:
$this->raw_split($this->processed_text);
// Be sure not to return an empty array
if (count($this->tokens) == 0) {
$this->tokens[self::LEXER_NO_TOKENS] = 1;
}
// Return a list of all found tokens
return $this->tokens;
}
/**
* Validates a token.
*
* @access private
* @param string $token The token string
* @return bool Returns true if the token is valid, otherwise returns false.
*/
private function is_valid(string $token)
{
// Just to be sure that the token's name won't collide with b8's internal variables
if (substr($token, 0, 3) == 'b8*') {
return false;
}
// Validate the size of the token
$len = strlen($token);
if ($len < $this->config['min_size'] || $len > $this->config['max_size']) {
return false;
}
// We may want to exclude pure numbers
if ($this->config['allow_numbers'] === false
&& preg_match($this->regexp['numbers'], $token) > 0) {
return false;
}
// Token is okay
return true;
}
/**
* Checks the validity of a token and adds it to the token list if it's valid.
*
* @access private
* @param string $token
* @param string $word_to_remove Word to remove from the processed string
* @return void
*/
private function add_token(string $token, string $word_to_remove = null)
{
// Check the validity of the token
if (! $this->is_valid($token)) {
return;
}
// Add it to the list or increase it's counter
if (! isset($this->tokens[$token])) {
$this->tokens[$token] = 1;
} else {
$this->tokens[$token] += 1;
}
// If requested, remove the word or it's original version from the text
if ($word_to_remove !== null) {
$this->processed_text = str_replace($word_to_remove, '', $this->processed_text);
}
}
/**
* Gets URIs.
*
* @access private
* @param string $text
* @return void
*/
private function get_uris(string $text)
{
// Find URIs
preg_match_all($this->regexp['uris'], $text, $raw_tokens);
foreach ($raw_tokens[1] as $word) {
// Remove a possible trailing dot
$word = rtrim($word, '.');
// Try to add the found tokens to the list
$this->add_token($word, $word);
// Also process the parts of the found URIs
$this->raw_split($word);
}
}
/**
* Gets HTML or BBCode markup, depending on the regexp used.
*
* @access private
* @param string $text
* @param string $regexp
* @return void
*/
private function get_markup(string $text, string $regexp)
{
// Search for the markup
preg_match_all($regexp, $text, $raw_tokens);
foreach ($raw_tokens[1] as $word) {
$actual_word = $word;
// If the tag has parameters, just use the tag itself
if (strpos($word, ' ') !== false) {
preg_match($this->regexp['tagname'], $word, $match);
$actual_word = $match[1];
$word = "$actual_word..." . substr($word, -1);
}
// Try to add the found tokens to the list
$this->add_token($word, $actual_word);
}
}
/**
* Does a raw split.
*
* @access private
* @param string $text
* @return void
*/
private function raw_split(string $text)
{
foreach (preg_split($this->regexp['raw_split'], $text) as $word) {
// Check the word and add it to the token list if it's valid
$this->add_token($word);
}
}
}

View file

@ -0,0 +1,110 @@
<?php
/* Copyright (C) 2019 Tobias Leupold <tobias.leupold@gmx.de>
This file is part of the b8 package
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation in version 2.1 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
namespace b8\storage;
/**
* A MySQL storage backend
*
* @license LGPL 2.1
* @package b8
* @author Tobias Leupold <tobias.leupold@gmx.de>
*/
class mysql extends storage_base
{
private $mysql = null;
private $table = null;
protected function setup_backend(array $config)
{
if (! isset($config['resource'])
|| get_class($config['resource']) !== 'mysqli') {
throw new \Exception(mysql::class . ": No valid mysqli object passed");
}
$this->mysql = $config['resource'];
if (! isset($config['table'])) {
throw new \Exception(mysql::class . ": No b8 wordlist table name passed");
}
$this->table = $config['table'];
}
protected function fetch_token_data(array $tokens)
{
$data = [];
$escaped = [];
foreach ($tokens as $token) {
$escaped[] = $this->mysql->real_escape_string($token);
}
$result = $this->mysql->query('SELECT token, count_ham, count_spam'
. ' FROM ' . $this->table
. ' WHERE token IN '
. "('" . implode("','", $escaped) . "')");
while ($row = $result->fetch_row()) {
$data[$row[0]] = [ \b8\b8::KEY_COUNT_HAM => $row[1],
\b8\b8::KEY_COUNT_SPAM => $row[2] ];
}
$result->free_result();
return $data;
}
protected function add_token(string $token, array $count)
{
$query = $this->mysql->prepare('INSERT INTO ' . $this->table
. '(token, count_ham, count_spam) VALUES(?, ?, ?)');
$query->bind_param('sii', $token, $count[\b8\b8::KEY_COUNT_HAM],
$count[\b8\b8::KEY_COUNT_SPAM]);
$query->execute();
}
protected function update_token(string $token, array $count)
{
$query = $this->mysql->prepare('UPDATE ' . $this->table
. ' SET count_ham = ?, count_spam = ? WHERE token = ?');
$query->bind_param('iis', $count[\b8\b8::KEY_COUNT_HAM], $count[\b8\b8::KEY_COUNT_SPAM],
$token);
$query->execute();
}
protected function delete_token(string $token)
{
$query = $this->mysql->prepare('DELETE FROM ' . $this->table . ' WHERE token = ?');
$query->bind_param('s', $token);
$query->execute();
}
protected function start_transaction()
{
$this->mysql->begin_transaction();
}
protected function finish_transaction()
{
$this->mysql->commit();
}
}

View file

@ -0,0 +1,316 @@
<?php
/* Copyright (C) 2006-2019 Tobias Leupold <tobias.leupold@gmx.de>
This file is part of the b8 package
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation in version 2.1 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
/**
* Abstract base class for storage backends
*
* @license LGPL 2.1
* @package b8
* @author Tobias Leupold <tobias.leupold@gmx.de>
*/
namespace b8\storage;
abstract class storage_base
{
protected $degenerator = null;
/**
* Sets up the backend
*
* @access public
* @param array The configuration for the respective backend
*/
abstract protected function setup_backend(array $config);
/**
* Does the actual interaction with the database when fetching data
*
* @access protected
* @param array $tokens List of token names to fetch
* @return mixed Returns an array of the returned data in the format array(token => data)
or an empty array if there was no data.
*/
abstract protected function fetch_token_data(array $tokens);
/**
* Stores a new token to the database
*
* @access protected
* @param string $token The token's name
* @param array $count The ham and spam counters [ \b8\b8::KEY_COUNT_HAM => int,
\b8\b8::KEY_COUNT_SPAM => int ]
* @return bool true on success or false on failure
*/
abstract protected function add_token(string $token, array $count);
/**
* Updates an existing token
*
* @access protected
* @param string $token The token's name
* @param array $count The ham and spam counters [ \b8\b8::KEY_COUNT_HAM => int,
\b8\b8::KEY_COUNT_SPAM => int ]
* @return bool true on success or false on failure
*/
abstract protected function update_token(string $token, array $count);
/**
* Removes a token from the database
*
* @access protected
* @param string $token The token's name
* @return bool true on success or false on failure
*/
abstract protected function delete_token(string $token);
/**
* Starts a transaction (if the underlying database supports/needs this)
*
* @access protected
* @return void
*/
abstract protected function start_transaction();
/**
* Finishes a transaction (if the underlying database supports/needs this)
*
* @access protected
* @return void
*/
abstract protected function finish_transaction();
/**
* Passes the degenerator to the instance and calls the backend setup
*
* @access public
* @param array The respective backen's configuration
* @param object The degenerator to use
* @return void
*/
public function __construct(array $config, object $degenerator)
{
$this->degenerator = $degenerator;
$this->setup_backend($config);
$internals = $this->get_internals();
if (! isset($internals[\b8\b8::KEY_DB_VERSION])
|| $internals[\b8\b8::KEY_DB_VERSION] !== \b8\b8::DBVERSION) {
throw new \Exception(storage_base::class . ': The connected database is not a b8 v'
. \b8\b8::DBVERSION . ' database.');
}
}
/**
* Get the database's internal variables.
*
* @access public
* @return array Returns an array of all internals.
*/
public function get_internals()
{
$internals = $this->fetch_token_data([ \b8\b8::INTERNALS_TEXTS,
\b8\b8::INTERNALS_DBVERSION ]);
// Just in case this is called by check_database() and it's not yet clear if we actually
// have a b8 database
$texts_ham = null;
$texts_spam = null;
$dbversion = null;
if(isset($internals[\b8\b8::INTERNALS_TEXTS][\b8\b8::KEY_COUNT_HAM])) {
$texts_ham = (int) $internals[\b8\b8::INTERNALS_TEXTS][\b8\b8::KEY_COUNT_HAM];
}
if(isset($internals[\b8\b8::INTERNALS_TEXTS][\b8\b8::KEY_COUNT_SPAM])) {
$texts_spam = (int) $internals[\b8\b8::INTERNALS_TEXTS][\b8\b8::KEY_COUNT_SPAM];
}
if(isset($internals[\b8\b8::INTERNALS_DBVERSION][\b8\b8::KEY_COUNT_HAM])) {
$dbversion = (int) $internals[\b8\b8::INTERNALS_DBVERSION][\b8\b8::KEY_COUNT_HAM];
}
return [ \b8\b8::KEY_TEXTS_HAM => $texts_ham,
\b8\b8::KEY_TEXTS_SPAM => $texts_spam,
\b8\b8::KEY_DB_VERSION => $dbversion ];
}
/**
* Get all data about a list of tokens from the database.
*
* @access public
* @param array The tokens list
* @return mixed Returns False on failure, otherwise returns array of returned data
in the format [ 'tokens' => [ token => count ],
'degenerates' => [ token => [ degenerate => count ] ] ].
*/
public function get(array $tokens)
{
// First we see what we have in the database
$token_data = $this->fetch_token_data($tokens);
// Check if we have to degenerate some tokens
$missing_tokens = array();
foreach ($tokens as $token) {
if (! isset($token_data[$token])) {
$missing_tokens[] = $token;
}
}
if (count($missing_tokens) > 0) {
// We have to degenerate some tokens
$degenerates_list = [];
// Generate a list of degenerated tokens for the missing tokens ...
$degenerates = $this->degenerator->degenerate($missing_tokens);
// ... and look them up
foreach ($degenerates as $token => $token_degenerates) {
$degenerates_list = array_merge($degenerates_list, $token_degenerates);
}
$token_data = array_merge($token_data, $this->fetch_token_data($degenerates_list));
}
// Here, we have all available data in $token_data.
$return_data_tokens = [];
$return_data_degenerates = [];
foreach ($tokens as $token) {
if (isset($token_data[$token])) {
// The token was found in the database
$return_data_tokens[$token] = $token_data[$token];
} else {
// The token was not found, so we look if we can return data for degenerated tokens
foreach ($this->degenerator->degenerates[$token] as $degenerate) {
if (isset($token_data[$degenerate])) {
// A degenertaed version of the token way found in the database
$return_data_degenerates[$token][$degenerate] = $token_data[$degenerate];
}
}
}
}
// Now, all token data directly found in the database is in $return_data_tokens and all
// data for degenerated versions is in $return_data_degenerates, so
return [ 'tokens' => $return_data_tokens,
'degenerates' => $return_data_degenerates ];
}
/**
* Stores or deletes a list of tokens from the given category.
*
* @access public
* @param array The tokens list
* @param string Either \b8\b8::HAM or \b8\b8::SPAM
* @param string Either \b8\b8::LEARN or \b8\b8::UNLEARN
* @return void
*/
public function process_text(array $tokens, string $category, string $action)
{
// No matter what we do, we first have to check what data we have.
// First get the internals, including the ham texts and spam texts counter
$internals = $this->get_internals();
// Then, fetch all data for all tokens we have
$token_data = $this->fetch_token_data(array_keys($tokens));
$this->start_transaction();
// Process all tokens to learn/unlearn
foreach ($tokens as $token => $count) {
if (isset($token_data[$token])) {
// We already have this token, so update it's data
// Get the existing data
$count_ham = $token_data[$token][\b8\b8::KEY_COUNT_HAM];
$count_spam = $token_data[$token][\b8\b8::KEY_COUNT_SPAM];
// Increase or decrease the right counter
if ($action === \b8\b8::LEARN) {
if ($category === \b8\b8::HAM) {
$count_ham += $count;
} elseif ($category === \b8\b8::SPAM) {
$count_spam += $count;
}
} elseif ($action == \b8\b8::UNLEARN) {
if ($category === \b8\b8::HAM) {
$count_ham -= $count;
} elseif ($category === \b8\b8::SPAM) {
$count_spam -= $count;
}
}
// We don't want to have negative values
if ($count_ham < 0) {
$count_ham = 0;
}
if ($count_spam < 0) {
$count_spam = 0;
}
// Now let's see if we have to update or delete the token
if ($count_ham != 0 or $count_spam != 0) {
$this->update_token($token, [ \b8\b8::KEY_COUNT_HAM => $count_ham,
\b8\b8::KEY_COUNT_SPAM => $count_spam ]);
} else {
$this->delete_token($token);
}
} else {
// We don't have the token. If we unlearn a text, we can't delete it as we don't
// have it anyway, so just do something if we learn a text
if ($action === \b8\b8::LEARN) {
if ($category === \b8\b8::HAM) {
$this->add_token($token, [ \b8\b8::KEY_COUNT_HAM => $count,
\b8\b8::KEY_COUNT_SPAM => 0 ]);
} elseif ($category === \b8\b8::SPAM) {
$this->add_token($token, [ \b8\b8::KEY_COUNT_HAM => 0,
\b8\b8::KEY_COUNT_SPAM => $count ]);
}
}
}
}
// Now, all token have been processed, so let's update the right text
if ($action === \b8\b8::LEARN) {
if ($category === \b8\b8::HAM) {
$internals[\b8\b8::KEY_TEXTS_HAM]++;
} elseif ($category === \b8\b8::SPAM) {
$internals[\b8\b8::KEY_TEXTS_SPAM]++;
}
} elseif ($action === \b8\b8::UNLEARN) {
if ($category === \b8\b8::HAM) {
if ($internals[\b8\b8::KEY_TEXTS_HAM] > 0) {
$internals[\b8\b8::KEY_TEXTS_HAM]--;
}
} elseif ($category === \b8\b8::SPAM) {
if ($internals[\b8\b8::KEY_TEXTS_SPAM] > 0) {
$internals[\b8\b8::KEY_TEXTS_SPAM]--;
}
}
}
$this->update_token(\b8\b8::INTERNALS_TEXTS,
[ \b8\b8::KEY_COUNT_HAM => $internals[\b8\b8::KEY_TEXTS_HAM],
\b8\b8::KEY_COUNT_SPAM => $internals[\b8\b8::KEY_TEXTS_SPAM] ]);
$this->finish_transaction();
}
}

View file

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View file

@ -1,102 +0,0 @@
=== Bad Behavior ===
Tags: comment,trackback,referrer,spam,robot,antispam
Contributors: error, MarkJaquith, Firas, skeltoac
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=error%40ioerror%2eus&item_name=Bad%20Behavior%20%28From%20WordPress%20Page%29&no_shipping=1&cn=Comments%20about%20Bad%20Behavior&tax=0&currency_code=USD&bn=PP%2dDonationsBF&charset=UTF%2d8
Requires at least: 1.5
Tested up to: 2.9
Stable tag: 2.0.36
Welcome to a whole new way of keeping your blog, forum, guestbook, wiki or
content management system free of link spam. Bad Behavior is a PHP-based
solution for blocking link spam and the robots which deliver it.
Bad Behavior complements other link spam solutions by acting as a gatekeeper,
preventing spammers from ever delivering their junk, and in many cases, from
ever reading your site in the first place. This keeps your site's load down,
makes your site logs cleaner, and can help prevent denial of service
conditions caused by spammers.
Bad Behavior also transcends other link spam solutions by working in a
completely different, unique way. Instead of merely looking at the content of
potential spam, Bad Behavior analyzes the delivery method as well as the
software the spammer is using. In this way, Bad Behavior can stop spam attacks
even when nobody has ever seen the particular spam before.
Bad Behavior is designed to work alongside existing spam prevention services
to increase their effectiveness and efficiency. Whenever possible, you should
run it in combination with a more traditional spam prevention service.
Bad Behavior works on, or can be adapted to, virtually any PHP-based Web
software package. Bad Behavior is available natively for WordPress, MediaWiki,
Drupal, ExpressionEngine, and LifeType, and people have successfully made it
work with Movable Type, phpBB, and many other packages.
Installing and configuring Bad Behavior on most platforms is simple and takes
only a few minutes. In most cases, no configuration at all is needed. Simply
turn it on and stop worrying about spam!
The core of Bad Behavior is free software released under the GNU General
Public License. (On some non-free platforms, special license terms exist for
Bad Behavior's platform connector.)
== Installation ==
*Warning*: If you are upgrading from a 1.x.x version of Bad Behavior,
you must remove it from your system entirely, and delete all of its
database tables, before installing Bad Behavior 2.0.x. You do not need
to remove a 2.0.x version of Bad Behavior before upgrading to this
release.
Bad Behavior has been designed to install on each host software in the
manner most appropriate to each platform. It's usually sufficient to
follow the generic instructions for installing any plugin or extension
for your host software.
On MediaWiki, it is necessary to add a second line to LocalSettings.php
when installing the extension. Your LocalSettings.php should include
the following:
` include_once( 'includes/DatabaseFunctions.php' );
include( './extensions/Bad-Behavior/bad-behavior-mediawiki.php' );
For complete documentation and installation instructions, please visit
http://www.bad-behavior.ioerror.us/
== Release Notes ==
= Bad Behavior 2.0 Known Issues =
* Bad Behavior may be unable to protect cached pages on MediaWiki.
* When upgrading from version 2.0.19 or prior on MediaWiki and WordPress,
you must remove the old version of Bad Behavior from your system manually
before manually installing the new version. Other platforms are not
affected by this issue.
* The basic functionality of Bad Behavior on WordPress requires version 1.2
or later. The management page for WordPress, which allows browsing Bad
Behavior's logs, requires version 2.1 or later. Users of older versions should
use phpMyAdmin to browse Bad Behavior's logs, or upgrade WordPress.
* On WordPress when using WordPress Advanced Cache (WP-Cache) or WP-Super
Cache, Bad Behavior requires a patch to WP-Cache or WP-Super Cache in order to
protect Cached pages. Bad Behavior cannot protect Super Cached pages.
Edit the wp-content/plugins/wp-cache/wp-cache-phase1.php or
wp-content/plugins/wp-super-cache/wp-cache-phase1.php file and find the
following two lines at around line 34 (line 56 in WP-Super Cache):
` if (! ($meta = unserialize(@file_get_contents($meta_pathname))) )
return true;`
Immediately after this, insert the following line:
` require_once( ABSPATH . 'wp-content/plugins/Bad-Behavior/bad-behavior-generic.php');`
Then visit your site. Everything should work normally, but spammers will
not be able to access your cached pages either.
* When using Bad Behavior in conjunction with Spam Karma 2, you may see PHP
warnings when Spam Karma 2 displays its internally generated CAPTCHA. This
is a design problem in Spam Karma 2. Contact the author of Spam Karma 2 for
a fix.

View file

@ -1,145 +0,0 @@
<?php
/*
Bad Behavior - detects and blocks unwanted Web accesses
Copyright (C) 2005-2006 Michael Hampton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
As a special exemption, you may link this program with any of the
programs listed below, regardless of the license terms of those
programs, and distribute the resulting program, without including the
source code for such programs: ExpressionEngine
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Please report any problems to badbots AT ioerror DOT us
*/
###############################################################################
###############################################################################
define('BB2_CWD', dirname(__FILE__));
// Settings you can adjust for Bad Behavior.
// Most of these are unused in non-database mode.
$bb2_settings_defaults = array(
'log_table' => 'bad_behavior',
'display_stats' => true,
'strict' => false,
'verbose' => false,
'logging' => true,
'httpbl_key' => '',
'httpbl_threat' => '25',
'httpbl_maxage' => '30',
'offsite_forms' => false,
);
// Bad Behavior callback functions.
// Return current time in the format preferred by your database.
function bb2_db_date() {
return gmdate('Y-m-d H:i:s'); // Example is MySQL format
}
// Return affected rows from most recent query.
function bb2_db_affected_rows() {
return false;
}
// Escape a string for database usage
function bb2_db_escape($string) {
// return mysql_real_escape_string($string);
return $string; // No-op when database not in use.
}
// Return the number of rows in a particular query.
function bb2_db_num_rows($result) {
if ($result !== FALSE)
return count($result);
return 0;
}
// Run a query and return the results, if any.
// Should return FALSE if an error occurred.
// Bad Behavior will use the return value here in other callbacks.
function bb2_db_query($query) {
return FALSE;
}
// Return all rows in a particular query.
// Should contain an array of all rows generated by calling mysql_fetch_assoc()
// or equivalent and appending the result of each call to an array.
function bb2_db_rows($result) {
return $result;
}
// Return emergency contact email address.
function bb2_email() {
// return "example@example.com"; // You need to change this.
return "badbots@ioerror.us"; // You need to change this.
}
// retrieve settings from database
// Settings are hard-coded for non-database use
function bb2_read_settings() {
global $bb2_settings_defaults;
return $bb2_settings_defaults;
}
// write settings to database
function bb2_write_settings($settings) {
return false;
}
// installation
function bb2_install() {
return false;
}
// Screener
// Insert this into the <head> section of your HTML through a template call
// or whatever is appropriate. This is optional we'll fall back to cookies
// if you don't use it.
function bb2_insert_head() {
global $bb2_javascript;
echo $bb2_javascript;
}
// Display stats? This is optional.
function bb2_insert_stats($force = false) {
$settings = bb2_read_settings();
if ($force || $settings['display_stats']) {
$blocked = bb2_db_query("SELECT COUNT(*) FROM " . $settings['log_table'] . " WHERE `key` NOT LIKE '00000000'");
if ($blocked !== FALSE) {
echo sprintf('<p><a href="http://www.bad-behavior.ioerror.us/">%1$s</a> %2$s <strong>%3$s</strong> %4$s</p>', __('Bad Behavior'), __('has blocked'), $blocked[0]["COUNT(*)"], __('access attempts in the last 7 days.'));
}
}
}
// Return the top-level relative path of wherever we are (for cookies)
// You should provide in $url the top-level URL for your site.
function bb2_relative_path() {
//$url = parse_url(get_bloginfo('url'));
//return $url['path'] . '/';
return '/';
}
// Calls inward to Bad Behavor itself.
require_once(BB2_CWD . "/bad-behavior/version.inc.php");
require_once(BB2_CWD . "/bad-behavior/core.inc.php");
bb2_install(); // FIXME: see above
bb2_start(bb2_read_settings());
?>

View file

@ -1,50 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Functions called when a request has been denied
// This part can be gawd-awful slow, doesn't matter :)
require_once(BB2_CORE . "/responses.inc.php");
function bb2_display_denial($settings, $key, $previous_key = false)
{
define('DONOTCACHEPAGE', true); // WP Super Cache
if (!$previous_key) $previous_key = $key;
if ($key == "e87553e1") {
// FIXME: lookup the real key
}
// Create support key
$ip = explode(".", $_SERVER['REMOTE_ADDR']);
$ip_hex = "";
foreach ($ip as $octet) {
$ip_hex .= str_pad(dechex($octet), 2, 0, STR_PAD_LEFT);
}
$support_key = implode("-", str_split("$ip_hex$key", 4));
// Get response data
$response = bb2_get_response($previous_key);
header("HTTP/1.1 " . $response['response'] . " Bad Behavior");
header("Status: " . $response['response'] . " Bad Behavior");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--< html xmlns="http://www.w3.org/1999/xhtml">-->
<head>
<title>HTTP Error <?php echo $response['response']; ?></title>
</head>
<body>
<h1>Error <?php echo $response['response']; ?></h1>
<p>We're sorry, but we could not fulfill your request for
<?php echo htmlspecialchars($_SERVER['REQUEST_URI']) ?> on this server.</p>
<p><?php echo $response['explanation']; ?></p>
<p>Your technical support key is: <strong><?php echo $support_key; ?></strong></p>
<p>You can use this key to <a href="http://www.ioerror.us/bb2-support-key?key=<?php echo $support_key; ?>">fix this problem yourself</a>.</p>
<p>If you are unable to fix the problem yourself, please contact <a href="mailto:<?php echo htmlspecialchars(str_replace("@", "+nospam@nospam.", bb2_email())); ?>"><?php echo htmlspecialchars(str_replace("@", " at ", bb2_email())); ?></a> and be sure to provide the technical support key shown above.</p>
<?php
}
function bb2_log_denial($settings, $package, $key, $previous_key=false)
{
if (!$settings['logging']) return;
bb2_db_query(bb2_insert($settings, $package, $key));
}
?>

View file

@ -1,69 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Quick and dirty check for an IPv6 address
function is_ipv6($address) {
return (strpos($address, ":")) ? TRUE : FALSE;
}
// Look up address on various blackhole lists.
// These should not be used for GET requests under any circumstances!
// FIXME: Note that this code is no longer in use
function bb2_blackhole($package) {
// Can't use IPv6 addresses yet
if (@is_ipv6($package['ip'])) return false;
// Workaround for "MySQL server has gone away"
bb2_db_query("SET @@session.wait_timeout = 90");
// Only conservative lists
$bb2_blackhole_lists = array(
"sbl-xbl.spamhaus.org", // All around nasties
// "dnsbl.sorbs.net", // Old useless data.
// "list.dsbl.org", // Old useless data.
// "dnsbl.ioerror.us", // Bad Behavior Blackhole
);
// Things that shouldn't be blocked, from aggregate lists
$bb2_blackhole_exceptions = array(
"sbl-xbl.spamhaus.org" => array("127.0.0.4"), // CBL is problematic
"dnsbl.sorbs.net" => array("127.0.0.10",), // Dynamic IPs only
"list.dsbl.org" => array(),
"dnsbl.ioerror.us" => array(),
);
// Check the blackhole lists
$ip = $package['ip'];
$find = implode('.', array_reverse(explode('.', $ip)));
foreach ($bb2_blackhole_lists as $dnsbl) {
$result = gethostbynamel($find . "." . $dnsbl . ".");
if (!empty($result)) {
// Got a match and it isn't on the exception list
$result = @array_diff($result, $bb2_blackhole_exceptions[$dnsbl]);
if (!empty($result)) {
return '136673cd';
}
}
}
return false;
}
function bb2_httpbl($settings, $package) {
// Can't use IPv6 addresses yet
if (@is_ipv6($package['ip'])) return false;
if (@!$settings['httpbl_key']) return false;
// Workaround for "MySQL server has gone away"
bb2_db_query("SET @@session.wait_timeout = 90");
$find = implode('.', array_reverse(explode('.', $package['ip'])));
$result = gethostbynamel($settings['httpbl_key'].".${find}.dnsbl.httpbl.org.");
if (!empty($result)) {
$ip = explode('.', $result[0]);
if ($ip[0] == 127 && ($ip[3] & 7) && $ip[2] >= $settings['httpbl_threat'] && $ip[1] <= $settings['httpbl_maxage']) {
return '2b021b1f';
}
}
return false;
}
?>

View file

@ -1,125 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
function bb2_blacklist($package) {
// Blacklisted user agents
// These user agent strings occur at the beginning of the line.
$bb2_spambots_0 = array(
"<sc", // XSS exploit attempts
"8484 Boston Project", // video poker/porn spam
"adwords", // referrer spam
"autoemailspider", // spam harvester
"blogsearchbot-martin", // from honeypot
"CherryPicker", // spam harvester
"core-project/", // FrontPage extension exploits
"Diamond", // delivers spyware/adware
"Digger", // spam harvester
"ecollector", // spam harvester
"EmailCollector", // spam harvester
"Email Siphon", // spam harvester
"EmailSiphon", // spam harvester
"grub crawler", // misc comment/email spam
"HttpProxy", // misc comment/email spam
"Internet Explorer", // XMLRPC exploits seen
"ISC Systems iRc", // spam harvester
"Jakarta Commons", // custommised spambots
"Java 1.", // definitely a spammer
"Java/1.", // definitely a spammer
"libwww-perl", // spambot scripts
"LWP", // spambot scripts
"Microsoft URL", // spam harvester
"Missigua", // spam harvester
"MJ12bot/v1.0.8", // malicious botnet
"Movable Type", // customised spambots
"Mozilla ", // malicious software
"Mozilla/2", // malicious software
"Mozilla/4.0(", // from honeypot
"Mozilla/4.0+(", // suspicious harvester
"MSIE", // malicious software
"NutchCVS", // unidentified robots
"Nutscrape/", // misc comment spam
"OmniExplorer", // spam harvester
"psycheclone", // spam harvester
"PussyCat ", // misc comment spam
"PycURL", // misc comment spam
// "Shockwave Flash", // spam harvester
// WP 2.5 now has Flash; FIXME
"Super Happy Fun ", // spam harvester
"TrackBack/", // trackback spam
"user", // suspicious harvester
"User Agent: ", // spam harvester
"User-Agent: ", // spam harvester
"WebSite-X Suite", // misc comment spam
"Winnie Poh", // Automated Coppermine hacks
"Wordpress", // malicious software
"\"", // malicious software
);
// These user agent strings occur anywhere within the line.
$bb2_spambots = array(
"\r", // A really dumb bot
"; Widows ", // misc comment/email spam
"a href=", // referrer spam
"Bad Behavior Test", // Add this to your user-agent to test BB
"compatible ; MSIE", // misc comment/email spam
"compatible-", // misc comment/email spam
"DTS Agent", // misc comment/email spam
"Email Extractor", // spam harvester
"Gecko/25", // revisit this in 500 years
"grub-client", // search engine ignores robots.txt
"hanzoweb", // very badly behaved crawler
"Indy Library", // misc comment/email spam
"larbin@unspecified", // stealth harvesters
"Murzillo compatible", // comment spam bot
".NET CLR 1)", // free poker, etc.
"POE-Component-Client", // free poker, etc.
"Turing Machine", // www.anonymizer.com abuse
"User-agent: ", // spam harvester/splogger
"WebaltBot", // spam harvester
"WISEbot", // spam harvester
"WISEnutbot", // spam harvester
"Windows NT 4.0;)", // wikispam bot
"Windows NT 5.0;)", // wikispam bot
"Windows NT 5.1;)", // wikispam bot
"Windows XP 5", // spam harvester
"WordPress/4.01", // pingback spam
"\\\\)", // spam harvester
);
// These are regular expression matches.
$bb2_spambots_regex = array(
"/^[A-Z]{10}$/", // misc email spam
// msnbot is using this fake user agent string now
// "/^Mozilla...[05]$/i", // fake user agent/email spam
"/[bcdfghjklmnpqrstvwxz ]{8,}/",
// "/(;\){1,2}$/", // misc spammers/harvesters
// "/MSIE.*Windows XP/", // misc comment spam
);
// Do not edit below this line.
@$ua = $package['headers_mixed']['User-Agent'];
foreach ($bb2_spambots_0 as $spambot) {
$pos = strpos($ua, $spambot);
if ($pos !== FALSE && $pos == 0) {
return "17f4e8c8";
}
}
foreach ($bb2_spambots as $spambot) {
if (strpos($ua, $spambot) !== FALSE) {
return "17f4e8c8";
}
}
foreach ($bb2_spambots_regex as $spambot) {
if (preg_match($spambot, $ua)) {
return "17f4e8c8";
}
}
return FALSE;
}
?>

View file

@ -1,144 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Enforce adherence to protocol version claimed by user-agent.
function bb2_protocol($settings, $package)
{
// Is it claiming to be HTTP/1.0? Then it shouldn't do HTTP/1.1 things
// Always run this test; we should never see Expect:
if (array_key_exists('Expect', $package['headers_mixed']) && stripos($package['headers_mixed']['Expect'], "100-continue") !== FALSE) {
return "a0105122";
}
// Is it claiming to be HTTP/1.1? Then it shouldn't do HTTP/1.0 things
// Blocks some common corporate proxy servers in strict mode
if ($settings['strict'] && !strcmp($package['server_protocol'], "HTTP/1.1")) {
if (array_key_exists('Pragma', $package['headers_mixed']) && strpos($package['headers_mixed']['Pragma'], "no-cache") !== FALSE && !array_key_exists('Cache-Control', $package['headers_mixed'])) {
return "41feed15";
}
}
return false;
}
function bb2_cookies($settings, $package)
{
// Enforce RFC 2965 sec 3.3.5 and 9.1
// Bots wanting new-style cookies should send Cookie2
// FIXME: Amazon Kindle is broken; Amazon has been notified 9/24/08
if (@strpos($package['headers_mixed']['Cookie'], '$Version=0') !== FALSE && !array_key_exists('Cookie2', $package['headers_mixed']) && strpos($package['headers_mixed']['User-Agent'], "Kindle/") === FALSE) {
return '6c502ff1';
}
return false;
}
function bb2_misc_headers($settings, $package)
{
@$ua = $package['headers_mixed']['User-Agent'];
if (!strcmp($package['request_method'], "POST") && empty($ua)) {
return "f9f2b8b9";
}
// Broken spambots send URLs with various invalid characters
// Some broken browsers send the #vector in the referer field :(
// if (strpos($package['request_uri'], "#") !== FALSE || strpos($package['headers_mixed']['Referer'], "#") !== FALSE) {
if (strpos($package['request_uri'], "#") !== FALSE) {
return "dfd9b1ad";
}
// A pretty nasty SQL injection attack on IIS servers
if (strpos($package['request_uri'], ";DECLARE%20@") !== FALSE) {
return "dfd9b1ad";
}
// Range: field exists and begins with 0
// Real user-agents do not start ranges at 0
// NOTE: this blocks the whois.sc bot. No big loss.
// Exceptions: MT (not fixable); LJ (refuses to fix; may be
// blocked again in the future)
if ($settings['strict'] && array_key_exists('Range', $package['headers_mixed']) && strpos($package['headers_mixed']['Range'], "=0-") !== FALSE) {
if (strncmp($ua, "MovableType", 11) && strncmp($ua, "URI::Fetch", 10) && strncmp($ua, "php-openid/", 11)) {
return "7ad04a8a";
}
}
// Content-Range is a response header, not a request header
if (array_key_exists('Content-Range', $package['headers_mixed'])) {
return '7d12528e';
}
// Lowercase via is used by open proxies/referrer spammers
// Exceptions: Clearswift uses lowercase via (refuses to fix;
// may be blocked again in the future)
// Coral CDN uses lowercase via
if (array_key_exists('via', $package['headers']) &&
strpos($package['headers']['via'],'Clearswift') === FALSE &&
strpos($ua,'CoralWebPrx') === FALSE) {
return "9c9e4979";
}
// pinappleproxy is used by referrer spammers
if (array_key_exists('Via', $package['headers_mixed'])) {
if (stripos($package['headers_mixed']['Via'], "pinappleproxy") !== FALSE || stripos($package['headers_mixed']['Via'], "PCNETSERVER") !== FALSE || stripos($package['headers_mixed']['Via'], "Invisiware") !== FALSE) {
return "939a6fbb";
}
}
// TE: if present must have Connection: TE
// RFC 2616 14.39
// Blocks Microsoft ISA Server 2004 in strict mode. Contact Microsoft
// to obtain a hotfix.
if ($settings['strict'] && array_key_exists('Te', $package['headers_mixed'])) {
if (!preg_match('/\bTE\b/', $package['headers_mixed']['Connection'])) {
return "582ec5e4";
}
}
if (array_key_exists('Connection', $package['headers_mixed'])) {
// Connection: keep-alive and close are mutually exclusive
if (preg_match('/\bKeep-Alive\b/i', $package['headers_mixed']['Connection']) && preg_match('/\bClose\b/i', $package['headers_mixed']['Connection'])) {
return "a52f0448";
}
// Close shouldn't appear twice
if (preg_match('/\bclose,\s?close\b/i', $package['headers_mixed']['Connection'])) {
return "a52f0448";
}
// Keey-Alive shouldn't appear twice either
if (preg_match('/\bkeep-alive,\s?keep-alive\b/i', $package['headers_mixed']['Connection'])) {
return "a52f0448";
}
}
// Headers which are not seen from normal user agents; only malicious bots
if (array_key_exists('X-Aaaaaaaaaaaa', $package['headers_mixed']) || array_key_exists('X-Aaaaaaaaaa', $package['headers_mixed'])) {
return "b9cc1d86";
}
// Proxy-Connection does not exist and should never be seen in the wild
if (array_key_exists('Proxy-Connection', $package['headers_mixed'])) {
return "b7830251";
}
if (array_key_exists('Referer', $package['headers_mixed'])) {
// Referer, if it exists, must not be blank
if (empty($package['headers_mixed']['Referer'])) {
return "69920ee5";
}
// Referer, if it exists, must contain a :
// While a relative URL is technically valid in Referer, all known
// legit user-agents send an absolute URL
if (strpos($package['headers_mixed']['Referer'], ":") === FALSE) {
return "45b35e30";
}
}
// "uk" is not a language (ISO 639) nor a country (ISO 3166)
// oops, yes it is :( Please shoot any Ukrainian spammers you see.
# if (preg_match('/\buk\b/', $package['headers_mixed']['Accept-Language'])) {
# return "35ea7ffa";
# }
return false;
}
?>

View file

@ -1,210 +0,0 @@
<?php if (!defined('BB2_CWD')) die("I said no cheating!");
// Bad Behavior entry point is start_bad_behavior().
// If you're reading this, you are probably lost.
// Go read the bad-behavior-generic.php file.
define('BB2_CORE', dirname(__FILE__));
define('BB2_COOKIE', 'bb2_screener_');
require_once(BB2_CORE . "/functions.inc.php");
// Our log table structure
function bb2_table_structure($name)
{
// It's not paranoia if they really are out to get you.
$name_escaped = bb2_db_escape($name);
return "CREATE TABLE IF NOT EXISTS `$name_escaped` (
`id` INT(11) NOT NULL auto_increment,
`ip` TEXT NOT NULL,
`date` DATETIME NOT NULL default '0000-00-00 00:00:00',
`request_method` TEXT NOT NULL,
`request_uri` TEXT NOT NULL,
`server_protocol` TEXT NOT NULL,
`http_headers` TEXT NOT NULL,
`user_agent` TEXT NOT NULL,
`request_entity` TEXT NOT NULL,
`key` TEXT NOT NULL,
INDEX (`ip`(15)),
INDEX (`user_agent`(10)),
PRIMARY KEY (`id`) );"; // TODO: INDEX might need tuning
}
// Insert a new record
function bb2_insert($settings, $package, $key)
{
$ip = bb2_db_escape($package['ip']);
$date = bb2_db_date();
$request_method = bb2_db_escape($package['request_method']);
$request_uri = bb2_db_escape($package['request_uri']);
$server_protocol = bb2_db_escape($package['server_protocol']);
$user_agent = bb2_db_escape($package['user_agent']);
$headers = "$request_method $request_uri $server_protocol\n";
foreach ($package['headers'] as $h => $v) {
$headers .= bb2_db_escape("$h: $v\n");
}
$request_entity = "";
if (!strcasecmp($request_method, "POST")) {
foreach ($package['request_entity'] as $h => $v) {
$request_entity .= bb2_db_escape("$h: $v\n");
}
}
return "INSERT INTO `" . bb2_db_escape($settings['log_table']) . "`
(`ip`, `date`, `request_method`, `request_uri`, `server_protocol`, `http_headers`, `user_agent`, `request_entity`, `key`) VALUES
('$ip', '$date', '$request_method', '$request_uri', '$server_protocol', '$headers', '$user_agent', '$request_entity', '$key')";
}
// Kill 'em all!
function bb2_banned($settings, $package, $key, $previous_key=false)
{
// Some spambots hit too hard. Slow them down a bit.
sleep(2);
require_once(BB2_CORE . "/banned.inc.php");
bb2_display_denial($settings, $key, $previous_key);
bb2_log_denial($settings, $package, $key, $previous_key);
if (is_callable('bb2_banned_callback')) {
bb2_banned_callback($settings, $package, $key);
}
// Penalize the spammers some more
require_once(BB2_CORE . "/housekeeping.inc.php");
bb2_housekeeping($settings, $package);
die();
}
function bb2_approved($settings, $package)
{
// Dirk wanted this
if (is_callable('bb2_approved_callback')) {
bb2_approved_callback($settings, $package);
}
// Decide what to log on approved requests.
if (($settings['verbose'] && $settings['logging']) || empty($package['user_agent'])) {
bb2_db_query(bb2_insert($settings, $package, "00000000"));
}
}
// Check the results of a particular test; see below for usage
// Returns FALSE if test passed (yes this is backwards)
function bb2_test($settings, $package, $result)
{
if ($result !== FALSE)
{
bb2_banned($settings, $package, $result);
return TRUE;
}
return FALSE;
}
// Let God sort 'em out!
function bb2_start($settings)
{
// Gather up all the information we need, first of all.
$headers = bb2_load_headers();
// Postprocess the headers to mixed-case
// FIXME: get the world to stop using PHP as CGI
$headers_mixed = array();
foreach ($headers as $h => $v) {
$headers_mixed[uc_all($h)] = $v;
}
// IPv6 - IPv4 compatibility mode hack
$_SERVER['REMOTE_ADDR'] = preg_replace("/^::ffff:/", "", $_SERVER['REMOTE_ADDR']);
// We use these frequently. Keep a copy close at hand.
$ip = $_SERVER['REMOTE_ADDR'];
$request_method = $_SERVER['REQUEST_METHOD'];
$request_uri = $_SERVER['REQUEST_URI'];
$server_protocol = $_SERVER['SERVER_PROTOCOL'];
@$user_agent = $_SERVER['HTTP_USER_AGENT'];
// Reconstruct the HTTP entity, if present.
$request_entity = array();
if (!strcasecmp($request_method, "POST") || !strcasecmp($request_method, "PUT")) {
foreach ($_POST as $h => $v) {
$request_entity[$h] = $v;
}
}
$package = array('ip' => $ip, 'headers' => $headers, 'headers_mixed' => $headers_mixed, 'request_method' => $request_method, 'request_uri' => $request_uri, 'server_protocol' => $server_protocol, 'request_entity' => $request_entity, 'user_agent' => $user_agent, 'is_browser' => false);
// Please proceed to the security checkpoint and have your
// identification and boarding pass ready.
// First check the whitelist
require_once(BB2_CORE . "/whitelist.inc.php");
if (!bb2_whitelist($package)) {
// Now check the blacklist
require_once(BB2_CORE . "/blacklist.inc.php");
bb2_test($settings, $package, bb2_blacklist($package));
// Check the http:BL
require_once(BB2_CORE . "/blackhole.inc.php");
bb2_test($settings, $package, bb2_httpbl($settings, $package));
// Check for common stuff
require_once(BB2_CORE . "/common_tests.inc.php");
bb2_test($settings, $package, bb2_protocol($settings, $package));
bb2_test($settings, $package, bb2_cookies($settings, $package));
bb2_test($settings, $package, bb2_misc_headers($settings, $package));
// Specific checks
@$ua = $headers_mixed['User-Agent'];
// MSIE checks
if (stripos($ua, "MSIE") !== FALSE) {
$package['is_browser'] = true;
if (stripos($ua, "Opera") !== FALSE) {
require_once(BB2_CORE . "/opera.inc.php");
bb2_test($settings, $package, bb2_opera($package));
} else {
require_once(BB2_CORE . "/msie.inc.php");
bb2_test($settings, $package, bb2_msie($package));
}
} elseif (stripos($ua, "Konqueror") !== FALSE) {
$package['is_browser'] = true;
require_once(BB2_CORE . "/konqueror.inc.php");
bb2_test($settings, $package, bb2_konqueror($package));
} elseif (stripos($ua, "Opera") !== FALSE) {
$package['is_browser'] = true;
require_once(BB2_CORE . "/opera.inc.php");
bb2_test($settings, $package, bb2_opera($package));
} elseif (stripos($ua, "Safari") !== FALSE) {
$package['is_browser'] = true;
require_once(BB2_CORE . "/safari.inc.php");
bb2_test($settings, $package, bb2_safari($package));
} elseif (stripos($ua, "Lynx") !== FALSE) {
$package['is_browser'] = true;
require_once(BB2_CORE . "/lynx.inc.php");
bb2_test($settings, $package, bb2_lynx($package));
} elseif (stripos($ua, "MovableType") !== FALSE) {
require_once(BB2_CORE . "/movabletype.inc.php");
bb2_test($settings, $package, bb2_movabletype($package));
} elseif (stripos($ua, "msnbot") !== FALSE || stripos($ua, "MS Search") !== FALSE) {
require_once(BB2_CORE . "/msnbot.inc.php");
bb2_test($settings, $package, bb2_msnbot($package));
} elseif (stripos($ua, "Googlebot") !== FALSE || stripos($ua, "Mediapartners-Google") !== FALSE || stripos($ua, "Google Wireless") !== FALSE) {
require_once(BB2_CORE . "/google.inc.php");
bb2_test($settings, $package, bb2_google($package));
} elseif (stripos($ua, "Mozilla") !== FALSE && stripos($ua, "Mozilla") == 0) {
$package['is_browser'] = true;
require_once(BB2_CORE . "/mozilla.inc.php");
bb2_test($settings, $package, bb2_mozilla($package));
}
// More intensive screening applies to POST requests
if (!strcasecmp('POST', $package['request_method'])) {
require_once(BB2_CORE . "/post.inc.php");
bb2_test($settings, $package, bb2_post($settings, $package));
}
}
// Last chance screening.
require_once(BB2_CORE . "/screener.inc.php");
bb2_screener($settings, $package);
// And that's about it.
bb2_approved($settings, $package);
return true;
}
?>

View file

@ -1,70 +0,0 @@
<?php if (!defined('BB2_CORE')) die("I said no cheating!");
// Miscellaneous helper functions.
// stripos() needed because stripos is only present on PHP 5
if (!function_exists('stripos')) {
function stripos($haystack,$needle,$offset = 0) {
return(strpos(strtolower($haystack),strtolower($needle),$offset));
}
}
// str_split() needed because str_split is only present on PHP 5
if (!function_exists('str_split')) {
function str_split($string, $split_length=1)
{
if ($split_length < 1) {
return false;
}
for ($pos=0, $chunks = array(); $pos < strlen($string); $pos+=$split_length) {
$chunks[] = substr($string, $pos, $split_length);
}
return $chunks;
}
}
// Convert a string to mixed-case on word boundaries.
function uc_all($string) {
$temp = preg_split('/(\W)/', str_replace("_", "-", $string), -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($temp as $key=>$word) {
$temp[$key] = ucfirst(strtolower($word));
}
return join ('', $temp);
}
// Determine if an IP address resides in a CIDR netblock or netblocks.
function match_cidr($addr, $cidr) {
$output = false;
if (is_array($cidr)) {
foreach ($cidr as $cidrlet) {
if (match_cidr($addr, $cidrlet)) {
$output = true;
}
}
} else {
@list($ip, $mask) = explode('/', $cidr);
if (!$mask) $mask = 32;
$mask = pow(2,32) - pow(2, (32 - $mask));
$output = ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
}
return $output;
}
// Obtain all the HTTP headers.
// NB: on PHP-CGI we have to fake it out a bit, since we can't get the REAL
// headers. Run PHP as Apache 2.0 module if possible for best results.
function bb2_load_headers() {
if (!is_callable('getallheaders')) {
$headers = array();
foreach ($_SERVER as $h => $v)
if (ereg('HTTP_(.+)', $h, $hp))
$headers[str_replace("_", "-", uc_all($hp[1]))] = $v;
} else {
$headers = getallheaders();
}
return $headers;
}
?>

View file

@ -1,13 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be Googlebot
function bb2_google($package)
{
if (match_cidr($package['ip'], "66.249.64.0/19") === FALSE && match_cidr($package['ip'], "64.233.160.0/19") === FALSE && match_cidr($package['ip'], "72.14.192.0/18") === FALSE) {
return "f1182195";
}
return false;
}
?>

View file

@ -1,16 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
function bb2_housekeeping($settings, $package)
{
// FIXME Yes, the interval's hard coded (again) for now.
$query = "DELETE FROM `" . $settings['log_table'] . "` WHERE `date` < DATE_SUB('" . bb2_db_date() . "', INTERVAL 7 DAY)";
bb2_db_query($query);
// Waste a bunch more of the spammer's time, sometimes.
if (rand(1,1000) == 1) {
$query = "OPTIMIZE TABLE `" . $settings['log_table'] . "`";
bb2_db_query($query);
}
}
?>

View file

@ -1 +0,0 @@
Viewing directory contents is not permitted.

View file

@ -1,17 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be Konqueror
function bb2_konqueror($package)
{
// CafeKelsa is a dev project at Yahoo which indexes job listings for
// Yahoo! HotJobs. It identifies as Konqueror so we skip these checks.
if (stripos($package['headers_mixed']['User-Agent'], "YahooSeeker/CafeKelsa") === FALSE || match_cidr($package['ip'], "209.73.160.0/19") === FALSE) {
if (!array_key_exists('Accept', $package['headers_mixed'])) {
return "17566707";
}
}
return false;
}
?>

View file

@ -1,13 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be Lynx
function bb2_lynx($package)
{
if (!array_key_exists('Accept', $package['headers_mixed'])) {
return "17566707";
}
return false;
}
?>

View file

@ -1,14 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
function bb2_movabletype($package)
{
// Is it a trackback?
if (strcasecmp($package['request_method'], "POST")) {
if (strcmp($package['headers_mixed']['Range'], "bytes=0-99999")) {
return "7d12528e";
}
}
return false;
}
?>

View file

@ -1,19 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be Mozilla
function bb2_mozilla($package)
{
// First off, workaround for Google Desktop, until they fix it FIXME
// Google Desktop fixed it, but apparently some old versions are
// still out there. :(
// Always check accept header for Mozilla user agents
if (strpos($package['headers_mixed']['User-Agent'], "Google Desktop") === FALSE && strpos($package['headers_mixed']['User-Agent'], "PLAYSTATION 3") === FALSE) {
if (!array_key_exists('Accept', $package['headers_mixed'])) {
return "17566707";
}
}
return false;
}
?>

View file

@ -1,26 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be MSIE
function bb2_msie($package)
{
if (!array_key_exists('Accept', $package['headers_mixed'])) {
return "17566707";
}
// MSIE does NOT send "Windows ME" or "Windows XP" in the user agent
if (strpos($package['headers_mixed']['User-Agent'], "Windows ME") !== FALSE || strpos($package['headers_mixed']['User-Agent'], "Windows XP") !== FALSE || strpos($package['headers_mixed']['User-Agent'], "Windows 2000") !== FALSE || strpos($package['headers_mixed']['User-Agent'], "Win32") !== FALSE) {
return "a1084bad";
}
// MSIE does NOT send Connection: TE but Akamai does
// Bypass this test when Akamai detected
// The latest version of IE for Windows CE also uses Connection: TE
if (!array_key_exists('Akamai-Origin-Hop', $package['headers_mixed']) && strpos($package['headers_mixed']['User-Agent'], "IEMobile") === FALSE && @preg_match('/\bTE\b/i', $package['headers_mixed']['Connection'])) {
return "2b90f772";
}
return false;
}
?>

View file

@ -1,13 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be msnbot
function bb2_msnbot($package)
{
if (match_cidr($package['ip'], "207.46.0.0/16") === FALSE && match_cidr($package['ip'], "65.52.0.0/14") === FALSE && match_cidr($package['ip'], "207.68.128.0/18") === FALSE && match_cidr($package['ip'], "207.68.192.0/20") === FALSE && match_cidr($package['ip'], "64.4.0.0/18") === FALSE) {
return "e4de0453";
}
return false;
}
?>

View file

@ -1,13 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be Opera
function bb2_opera($package)
{
if (!array_key_exists('Accept', $package['headers_mixed'])) {
return "17566707";
}
return false;
}
?>

View file

@ -1,80 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// All tests which apply specifically to POST requests
function bb2_post($settings, $package)
{
// Check blackhole lists for known spam/malicious activity
// require_once(BB2_CORE . "/blackhole.inc.php");
// bb2_test($settings, $package, bb2_blackhole($package));
// MovableType needs specialized screening
if (stripos($package['headers_mixed']['User-Agent'], "MovableType") !== FALSE) {
if (strcmp($package['headers_mixed']['Range'], "bytes=0-99999")) {
return "7d12528e";
}
}
// Trackbacks need special screening
$request_entity = $package['request_entity'];
if (isset($request_entity['title']) && isset($request_entity['url']) && isset($request_entity['blog_name'])) {
require_once(BB2_CORE . "/trackback.inc.php");
return bb2_trackback($package);
}
// Catch a few completely broken spambots
foreach ($request_entity as $key => $value) {
$pos = strpos($key, " document.write");
if ($pos !== FALSE) {
return "dfd9b1ad";
}
}
// If Referer exists, it should refer to a page on our site
if ($settings['offsite_forms'] && array_key_exists('Referer', $package['headers_mixed']) && stripos($package['headers_mixed']['Referer'], $package['headers_mixed']['Host']) === FALSE) {
return "cd361abb";
}
// Screen by cookie/JavaScript form add
if (isset($_COOKIE[BB2_COOKIE])) {
$screener1 = explode(" ", $_COOKIE[BB2_COOKIE]);
} else {
$screener1 = array(0);
}
if (isset($_POST[BB2_COOKIE])) {
$screener2 = explode(" ", $_POST[BB2_COOKIE]);
} else {
$screener2 = array(0);
}
$screener = max($screener1[0], $screener2[0]);
if ($screener > 0) {
// Posting too fast? 5 sec
// FIXME: even 5 sec is too intrusive
// if ($screener + 5 > time())
// return "408d7e72";
// Posting too slow? 48 hr
if ($screener + 172800 < time())
return "b40c8ddc";
// Screen by IP address
$ip = ip2long($package['ip']);
$ip_screener = ip2long($screener[1]);
// FIXME: This is b0rked, but why?
// if ($ip && $ip_screener && abs($ip_screener - $ip) > 256)
// return "c1fa729b";
if (!empty($package['headers_mixed']['X-Forwarded-For'])) {
$ip = $package['headers_mixed']['X-Forwarded-For'];
}
// Screen for user agent changes
// User connected previously with blank user agent
// $q = bb2_db_query("SELECT `ip` FROM " . $settings['log_table'] . " WHERE (`ip` = '" . $package['ip'] . "' OR `ip` = '" . $screener[1] . "') AND `user_agent` != '" . $package['user_agent'] . "' AND `date` > DATE_SUB('" . bb2_db_date() . "', INTERVAL 5 MINUTE)");
// Damnit, too many ways for this to fail :(
// if ($q !== FALSE && $q != NULL && bb2_db_num_rows($q) > 0)
// return "799165c2";
}
return false;
}
?>

View file

@ -1,49 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Defines the responses which Bad Behavior might return.
function bb2_get_response($key) {
$bb2_responses = array(
'00000000' => array('response' => 200, 'explanation' => '', 'log' => 'Permitted'),
'136673cd' => array('response' => 403, 'explanation' => 'Your Internet Protocol address is listed on a blacklist of addresses involved in malicious or illegal activity. See the listing below for more details on specific blacklists and removal procedures.', 'log' => 'IP address found on external blacklist'),
'17566707' => array('response' => 403, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Required header \'Accept\' missing'),
'17f4e8c8' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'User-Agent was found on blacklist'),
'21f11d3f' => array('response' => 403, 'explanation' => 'An invalid request was received. You claimed to be a mobile Web device, but you do not actually appear to be a mobile Web device.', 'log' => 'User-Agent claimed to be AvantGo, claim appears false'),
'2b021b1f' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'IP address found on http:BL blacklist'),
'2b90f772' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. If you are using the Opera browser, then Opera must appear in your user agent.', 'log' => 'Connection: TE present, not supported by MSIE'),
'35ea7ffa' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Check your browser\'s language and locale settings.', 'log' => 'Invalid language specified'),
'408d7e72' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'POST comes too quickly after GET'),
'41feed15' => array('response' => 400, 'explanation' => 'An invalid request was received. This may be caused by a malfunctioning proxy server. Bypass the proxy server and connect directly, or contact your proxy server administrator.', 'log' => 'Header \'Pragma\' without \'Cache-Control\' prohibited for HTTP/1.1 requests'),
'45b35e30' => array('response' => 400, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Header \'Referer\' is corrupt'),
'57796684' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'Prohibited header \'X-Aaaaaaaaaa\' or \'X-Aaaaaaaaaaaa\' present'),
'582ec5e4' => array('response' => 400, 'explanation' => 'An invalid request was received. If you are using a proxy server, bypass the proxy server or contact your proxy server administrator. This may also be caused by a bug in the Opera web browser.', 'log' => '"Header \'TE\' present but TE not specified in \'Connection\' header'),
'69920ee5' => array('response' => 400, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Header \'Referer\' present but blank'),
'6c502ff1' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'Bot not fully compliant with RFC 2965'),
'799165c2' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'Rotating user-agents detected'),
'7a06532b' => array('response' => 400, 'explanation' => 'An invalid request was received from your browser. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'Required header \'Accept-Encoding\' missing'),
'7ad04a8a' => array('response' => 400, 'explanation' => 'The automated program you are using is not permitted to access this server. Please use a different program or a standard Web browser.', 'log' => 'Prohibited header \'Range\' present'),
'7d12528e' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'Prohibited header \'Range\' or \'Content-Range\' in POST request'),
'939a6fbb' => array('response' => 403, 'explanation' => 'The proxy server you are using is not permitted to access this server. Please bypass the proxy server, or contact your proxy server administrator.', 'log' => 'Banned proxy server in use'),
'9c9e4979' => array('response' => 403, 'explanation' => 'The proxy server you are using is not permitted to access this server. Please bypass the proxy server, or contact your proxy server administrator.', 'log' => 'Prohibited header \'via\' present'),
'a0105122' => array('response' => 417, 'explanation' => 'Expectation failed. Please retry your request.', 'log' => 'Header \'Expect\' prohibited; resend without Expect'),
'a1084bad' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'User-Agent claimed to be MSIE, with invalid Windows version'),
'a52f0448' => array('response' => 400, 'explanation' => 'An invalid request was received. This may be caused by a malfunctioning proxy server or browser privacy software. If you are using a proxy server, bypass the proxy server or contact your proxy server administrator.', 'log' => 'Header \'Connection\' contains invalid values'),
'b40c8ddc' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, close your browser, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'POST more than two days after GET'),
'b7830251' => array('response' => 400, 'explanation' => 'Your proxy server sent an invalid request. Please contact the proxy server administrator to have this problem fixed.', 'log' => 'Prohibited header \'Proxy-Connection\' present'),
'b9cc1d86' => array('response' => 403, 'explanation' => 'The proxy server you are using is not permitted to access this server. Please bypass the proxy server, or contact your proxy server administrator.', 'log' => 'Prohibited header \'X-Aaaaaaaaaa\' or \'X-Aaaaaaaaaaaa\' present'),
'c1fa729b' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'Use of rotating proxy servers detected'),
'cd361abb' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Data may not be posted from offsite forms.', 'log' => 'Referer did not point to a form on this site'),
'd60b87c7' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, please remove any viruses or spyware from your computer.', 'log' => 'Trackback received via proxy server'),
'e3990b47' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, please remove any viruses or spyware from your computer.', 'log' => 'Obviously fake trackback received'),
'dfd9b1ad' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'Request contained a malicious JavaScript or SQL injection attack'),
'e4de0453' => array('response' => 403, 'explanation' => 'An invalid request was received. You claimed to be a major search engine, but you do not appear to actually be a major search engine.', 'log' => 'User-Agent claimed to be msnbot, claim appears to be false'),
'e87553e1' => array('response' => 403, 'explanation' => 'You do not have permission to access this server.', 'log' => 'I know you and I don\'t like you, dirty spammer.'),
'f0dcb3fd' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. Before trying again, run anti-virus and anti-spyware software and remove any viruses and spyware from your computer.', 'log' => 'Web browser attempted to send a trackback'),
'f1182195' => array('response' => 403, 'explanation' => 'An invalid request was received. You claimed to be a major search engine, but you do not appear to actually be a major search engine.', 'log' => 'User-Agent claimed to be Googlebot, claim appears to be false.'),
'f9f2b8b9' => array('response' => 403, 'explanation' => 'You do not have permission to access this server. This may be caused by a malfunctioning proxy server or browser privacy software.', 'log' => 'A User-Agent is required but none was provided.'),
);
if (array_key_exists($key, $bb2_responses)) return $bb2_responses[$key];
return array('00000000');
}
?>

View file

@ -1,13 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Analyze user agents claiming to be Safari
function bb2_safari($package)
{
if (!array_key_exists('Accept', $package['headers_mixed'])) {
return "17566707";
}
return false;
}
?>

View file

@ -1,63 +0,0 @@
<?php if (!defined('BB2_CWD')) die("I said no cheating!");
// Bad Behavior browser screener
function bb2_screener_cookie($settings, $package, $cookie_name, $cookie_value)
{
// FIXME: Set the real cookie
setcookie($cookie_name, $cookie_value, 0, bb2_relative_path());
}
function bb2_screener_javascript($settings, $package, $cookie_name, $cookie_value)
{
global $bb2_javascript;
// FIXME: do something
$bb2_javascript = "<script type=\"text/javascript\">
<!--
function bb2_addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
bb2_addLoadEvent(function() {
for ( i=0; i < document.forms.length; i++ ) {
if (document.forms[i].method == 'post') {
var myElement = document.createElement('input');
myElement.setAttribute('type', 'hidden');
myElement.name = '$cookie_name';
myElement.value = '$cookie_value';
document.forms[i].appendChild(myElement);
}
}
});
// --></script>
";
}
function bb2_screener($settings, $package)
{
$cookie_name = BB2_COOKIE;
// Set up a simple cookie
$screener = array(time(), $package['ip']);
if (isset($package['headers_mixed']['X-Forwarded-For'])) {
array_push($screener, $package['headers_mixed']['X-Forwarded-For']);
}
if (isset($package['headers_mixed']['Client-Ip'])) {
array_push($screener, $package['headers_mixed']['Client-Ip']);
}
$cookie_value = implode(" ", $screener);
bb2_screener_cookie($settings, $package, BB2_COOKIE, $cookie_value);
bb2_screener_javascript($settings, $package, BB2_COOKIE, $cookie_value);
}
?>

View file

@ -1,28 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
// Specialized screening for trackbacks
function bb2_trackback($package)
{
// Web browsers don't send trackbacks
if ($package['is_browser']) {
return 'f0dcb3fd';
}
// Proxy servers don't send trackbacks either
if (array_key_exists('Via', $package['headers_mixed']) || array_key_exists('Max-Forwards', $package['headers_mixed']) || array_key_exists('X-Forwarded-For', $package['headers_mixed']) || array_key_exists('Client-Ip', $package['headers_mixed'])) {
return 'd60b87c7';
}
// Fake WordPress trackbacks
// Real ones do not contain Accept:, and have a charset defined
// Real WP trackbacks may contain Accept: depending on the HTTP
// transport being used by the sending host
if (strpos($package['headers_mixed']['User-Agent'], "WordPress/") !== FALSE) {
if (strpos($package['headers_mixed']['Content-Type'], "charset=") === FALSE) {
return 'e3990b47';
}
}
return false;
}
?>

View file

@ -1,3 +0,0 @@
<?php if (!defined('BB2_CWD')) die("I said no cheating!");
define('BB2_VERSION', "2.0.36");
?>

View file

@ -1,83 +0,0 @@
<?php if (!defined('BB2_CORE')) die('I said no cheating!');
function bb2_whitelist($package)
{
// DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
// Inappropriate whitelisting WILL expose you to spam, or cause Bad
// Behavior to stop functioning entirely! DO NOT WHITELIST unless you
// are 100% CERTAIN that you should.
// IP address ranges use the CIDR format.
// Includes four examples of whitelisting by IP address and netblock.
$bb2_whitelist_ip_ranges = array(
"64.191.203.34", // Digg whitelisted as of 2.0.12
"208.67.217.130", // Digg whitelisted as of 2.0.12
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
// "127.0.0.1",
);
// DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
// Inappropriate whitelisting WILL expose you to spam, or cause Bad
// Behavior to stop functioning entirely! DO NOT WHITELIST unless you
// are 100% CERTAIN that you should.
// You should not whitelist search engines by user agent. Use the IP
// netblock for the search engine instead. See http://whois.arin.net/
// to locate the netblocks for an IP.
// User agents are matched by exact match only.
// Includes one example of whitelisting by user agent.
// All are commented out.
$bb2_whitelist_user_agents = array(
// "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) It's me, let me in",
);
// DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
// Inappropriate whitelisting WILL expose you to spam, or cause Bad
// Behavior to stop functioning entirely! DO NOT WHITELIST unless you
// are 100% CERTAIN that you should.
// URLs are matched from the first / after the server name up to,
// but not including, the ? (if any).
// Includes two examples of whitelisting by URL.
$bb2_whitelist_urls = array(
// "/example.php",
// "/openid/server",
);
// DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER!
// Do not edit below this line
if (!empty($bb2_whitelist_ip_ranges)) {
foreach ($bb2_whitelist_ip_ranges as $range) {
if (match_cidr($package['ip'], $range)) return true;
}
}
if (!empty($bb2_whitelist_user_agents)) {
foreach ($bb2_whitelist_user_agents as $user_agent) {
if (!strcmp($package['headers_mixed']['User-Agent'], $user_agent)) return true;
}
}
if (!empty($bb2_whitelist_urls)) {
if (strpos($package['request_uri'], "?") === FALSE) {
$request_uri = $package['request_uri'];
} else {
$request_uri = substr($package['request_uri'], 0, strpos($settings['request_uri'], "?"));
}
foreach ($bb2_whitelist_urls as $url) {
if (!strcmp($request_uri, $url)) return true;
}
}
return false;
}
?>

View file

@ -1 +0,0 @@
Viewing directory contents is not permitted.

View file

@ -19,126 +19,110 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
class Captcha
{
function check_captcha($code,$entered_code)
{
if(strtolower($entered_code) == strtolower($code)) return true;
else return false;
}
class Captcha {
function check_captcha($code, $entered_code) {
if (strtolower($entered_code) == strtolower($code)) return true;
else return false;
}
function generate_code($letters='abcdefhjkmnpqrstuvwxyz234568')
{
mt_srand((double)microtime()*1000000);
$code='';
for($i=0;$i<5;$i++)
{
$code.=substr($letters,mt_rand(0,strlen($letters)-1),1);
}
return $code;
}
function generate_code($letters = 'abcdefhjkmnpqrstuvwxyz234568') {
mt_srand((double)microtime()*1000000);
$code = '';
for ($i = 0; $i < 5; $i++) {
$code .= substr($letters, mt_rand(0, strlen($letters) -1), 1);
}
return $code;
}
function generate_image($code,$backgrounds_folder='',$fonts_folder='')
{
$font_size = 23;
$font_pos_x = 10;
$font_pos_y = 30;
function generate_image($code, $backgrounds_folder = '', $fonts_folder = '') {
$font_size = 23;
$font_pos_x = 10;
$font_pos_y = 30;
// get background images:
if($backgrounds_folder!='')
{
$handle=opendir($backgrounds_folder);
while ($file = readdir($handle))
{
if(preg_match('/\.png$/i', $file) || preg_match('/\.gif$/i', $file) || preg_match('/\.jpg$/i', $file)) $backgrounds[] = $file;
}
closedir($handle);
}
// get background images:
if ($backgrounds_folder != '') {
$handle = opendir($backgrounds_folder);
while ($file = readdir($handle)) {
if (preg_match('/\.png$/i', $file) || preg_match('/\.gif$/i', $file) || preg_match('/\.jpg$/i', $file)) $backgrounds[] = $file;
}
closedir($handle);
}
// get fonts:
if($fonts_folder!='')
{
$handle=opendir($fonts_folder);
while($file = readdir($handle))
{
if(preg_match('/\.ttf$/i', $file)) $fonts[] = $file;
}
closedir($handle);
}
// get fonts:
if ($fonts_folder != '') {
$handle = opendir($fonts_folder);
while ($file = readdir($handle)) {
if (preg_match('/\.ttf$/i', $file)) $fonts[] = $file;
}
closedir($handle);
}
// split code into chars:
$code_length = strlen($code);
for($i=0;$i<$code_length;$i++)
{
$code_chars_array[] = substr($code,$i,1);
}
// split code into chars:
$code_length = strlen($code);
for ($i = 0; $i < $code_length; $i++) {
$code_chars_array[] = substr($code, $i, 1);
}
// if background images are available, craete image from one of them:
if(isset($backgrounds))
{
$bg = $backgrounds[mt_rand(0,count($backgrounds)-1)];
if(preg_match('/\.png$/i', $bg)) $im = ImageCreateFromPNG($backgrounds_folder.$bg);
elseif(preg_match('/\.gif$/i', $bg)) $im = ImageCreateFromGIF($backgrounds_folder.$bg);
else $im = ImageCreateFromJPEG($backgrounds_folder.$bg);
if(function_exists('imagerotate') && mt_rand(0,1)==1) $im = imagerotate($im, 180, 0);
}
// if not, create an empty image:
else
{
$im = ImageCreate(180, 40);
$background_color = ImageColorAllocate ($im, 234, 234, 234);
}
// if background images are available, craete image from one of them:
if (isset($backgrounds)) {
$bg = $backgrounds[mt_rand(0,count($backgrounds)-1)];
if (preg_match('/\.png$/i', $bg)) $im = ImageCreateFromPNG($backgrounds_folder.$bg);
else if (preg_match('/\.gif$/i', $bg)) $im = ImageCreateFromGIF($backgrounds_folder.$bg);
else $im = ImageCreateFromJPEG($backgrounds_folder.$bg);
if (function_exists('imageflip') && mt_rand(0, 5) % 2 == 0) {
$flipConsts = [IMG_FLIP_HORIZONTAL, IMG_FLIP_VERTICAL, IMG_FLIP_BOTH];
$flipper = mt_rand(0, 2);
imageflip($im, $flipConsts[$flipper]);
}
} else {
// if not, create an empty image:
$im = ImageCreate(180, 40);
$background_color = ImageColorAllocate ($im, 234, 234, 234);
}
// set text color:
$text_color = ImageColorAllocate ($im, 0, 0, 0);
// set text color:
$text_color = ImageColorAllocate ($im, 0, 0, 0);
// use fonts, if available:
if(isset($fonts))
{
foreach($code_chars_array as $char)
{
$angle = intval(rand((30 * -1), 30));
ImageTTFText($im, $font_size, $angle, $font_pos_x, $font_pos_y, $text_color, $fonts_folder.$fonts[mt_rand(0,count($fonts)-1)],$char);
$font_pos_x=$font_pos_x+($font_size+13);
}
}
// if not, use internal font:
else
{
ImageString($im, 5, 30, 10, $code, $text_color);
}
header("Expires: Expires: Sat, 20 Oct 2007 00:00:00 GMT");
header("Cache-Control: max-age=0");
header("Content-type: image/png");
ImagePNG($im);
exit();
}
// use fonts, if available:
if (isset($fonts)) {
foreach ($code_chars_array as $char) {
$angle = intval(rand((30 * -1), 30));
ImageTTFText($im, $font_size, $angle, $font_pos_x, $font_pos_y, $text_color, $fonts_folder.$fonts[mt_rand(0, count($fonts) -1)], $char);
$font_pos_x = $font_pos_x + ($font_size + 13);
}
} else {
// if not, use internal font:
ImageString($im, 5, 30, 10, $code, $text_color);
}
header("Expires: Expires: Sat, 20 Oct 2007 00:00:00 GMT");
header("Cache-Control: max-age=0");
header("Content-type: image/png");
ImagePNG($im);
exit();
}
function generate_dummy_image()
{
$im = @ImageCreate(180, 40);
$background_color = ImageColorAllocate ($im, 234, 234, 234);
$text_color = ImageColorAllocate ($im, 0, 0, 0);
#ImageString($im, 3, 7, 4, 'CAPTCHA not available', $text_color);
header("Expires: Expires: Sat, 20 Oct 2007 00:00:00 GMT");
header("Cache-Control: max-age=0");
header("Content-type: image/png");
ImagePNG($im);
}
function generate_dummy_image() {
$im = @ImageCreate(180, 40);
$background_color = ImageColorAllocate ($im, 234, 234, 234);
$text_color = ImageColorAllocate ($im, 0, 0, 0);
//ImageString($im, 3, 7, 4, 'CAPTCHA not available', $text_color);
header("Expires: Expires: Sat, 20 Oct 2007 00:00:00 GMT");
header("Cache-Control: max-age=0");
header("Content-type: image/png");
ImagePNG($im);
}
// for math CAPTCHA:
function generate_math_captcha($number1from=1,$number1to=10,$number2from=0,$number2to=10)
{
$number[0] = rand($number1from,$number1to);
$number[1] = rand($number2from,$number2to);
$number[2] = $number[0] + $number[1];
return $number;
}
// for math CAPTCHA:
function generate_math_captcha($number1from = 1, $number1to = 10, $number2from = 0, $number2to = 10) {
$number[0] = rand($number1from, $number1to);
$number[1] = rand($number2from, $number2to);
$number[2] = $number[0] + $number[1];
return $number;
}
function check_math_captcha($result, $entered_result)
{
if(intval($result) == intval($entered_result)) return true;
else return false;
}
}
function check_math_captcha($result, $entered_result) {
if (intval($result) == intval($entered_result)) return true;
else return false;
}
}
?>

View file

@ -1,14 +1,12 @@
<?php
ini_set('error_reporting','E_ALL');
// ini_set('error_reporting', 'E_ALL');
session_set_cookie_params(['samesite' => 'strict']);
session_start();
require('captcha.php');
$captcha = new Captcha();
if(isset($_SESSION['captcha_session']))
{
$captcha->generate_image($_SESSION['captcha_session'],'backgrounds/','fonts/');
}
else
{
$captcha->generate_dummy_image();
}
if (isset($_SESSION['captcha_session'])) {
$captcha->generate_image($_SESSION['captcha_session'], 'backgrounds/', 'fonts/');
} else {
$captcha->generate_dummy_image();
}
?>

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
<?php
/*************************************************************************************
* html4strict.php
* html5.php
* ---------------
* Author: Nigel McNie (nigel@geshi.org)
* Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
* Release Version: 1.0.8.6
* Release Version: 1.0.9.0
* Date Started: 2004/07/10
*
* HTML 4.01 strict language file for GeSHi.
* HTML 5 language file for GeSHi.
*
* CHANGES
* -------
@ -50,7 +50,7 @@
************************************************************************************/
$language_data = array (
'LANG_NAME' => 'HTML',
'LANG_NAME' => 'HTML5',
'COMMENT_SINGLE' => array(),
'COMMENT_MULTI' => array(),
'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
@ -58,60 +58,64 @@ $language_data = array (
'ESCAPE_CHAR' => '',
'KEYWORDS' => array(
2 => array(
'a', 'abbr', 'acronym', 'address', 'applet',
'a', 'abbr', 'address', 'article', 'area', 'aside', 'audio',
'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
'base', 'bdo', 'blockquote', 'body', 'br', 'button', 'b',
'caption', 'center', 'cite', 'code', 'colgroup', 'col',
'caption', 'cite', 'code', 'colgroup', 'col', 'canvas', 'command', 'datalist', 'details',
'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
'dd', 'del', 'dfn', 'div', 'dl', 'dt',
'em',
'em', 'embed',
'fieldset', 'font', 'form', 'frame', 'frameset',
'fieldset', 'form', 'figcaption', 'figure', 'footer',
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'header', 'hgroup',
'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
'kbd',
'kbd', 'keygen',
'label', 'legend', 'link', 'li',
'map', 'meta',
'map', 'meta', 'mark', 'meter',
'noframes', 'noscript',
'noscript', 'nav',
'object', 'ol', 'optgroup', 'option',
'object', 'ol', 'optgroup', 'option', 'output',
'param', 'pre', 'p',
'param', 'pre', 'p', 'progress',
'q',
'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
'rp', 'rt', 'ruby',
'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
'samp', 'script', 'select', 'small', 'span', 'strong', 'style', 'sub', 'sup', 's', 'section', 'source', 'summary',
'ul', 'u',
'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'time',
'var',
'ul',
'var', 'video',
'wbr',
),
3 => array(
'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis', 'autocomplete', 'autofocus',
'background', 'bgcolor', 'border',
'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords', 'contenteditable', 'contextmenu',
'data', 'datetime', 'declare', 'defer', 'dir', 'disabled', 'draggable', 'dropzone',
'enctype',
'face', 'for', 'frame', 'frameborder',
'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
'face', 'for', 'frame', 'frameborder', 'form', 'formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget',
'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv', 'hidden',
'id', 'ismap',
'label', 'lang', 'language', 'link', 'longdesc',
'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
'name', 'nohref', 'noresize', 'noshade', 'nowrap',
'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
'profile', 'prompt',
'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple', 'min', 'max',
'name', 'nohref', 'noresize', 'noshade', 'nowrap', 'novalidate',
'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onselect', 'onsubmit', 'onunload', 'onafterprint', 'onbeforeprint', 'onbeforeonload', 'onerror', 'onhaschange', 'onmessage', 'onoffline', 'ononline', 'onpagehide', 'onpageshow', 'onpopstate', 'onredo', 'onresize', 'onstorage', 'onundo', 'oncontextmenu', 'onformchange', 'onforminput', 'oninput', 'oninvalid', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onmousewheel', 'onscroll', 'oncanplay', 'oncanplaythrough', 'ondurationchange', 'onemptied', 'onended', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onreadystatechange', 'onseeked', 'onseeking', 'onstalled', 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting',
'profile', 'prompt', 'pattern', 'placeholder',
'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules', 'required',
'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary', 'spellcheck', 'step',
'tabindex', 'target', 'text', 'title', 'type',
'usemap',
'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
@ -151,6 +155,7 @@ $language_data = array (
0 => 'color: #66cc66;'
),
'SCRIPT' => array(
-2 => 'color: #404040;', // CDATA
-1 => 'color: #808080; font-style: italic;', // comments
0 => 'color: #00bbdd;',
1 => 'color: #ddbb00;',
@ -170,6 +175,9 @@ $language_data = array (
),
'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
'SCRIPT_DELIMITERS' => array(
-2 => array(
'<![CDATA[' => ']]>'
),
-1 => array(
'<!--' => '-->'
),
@ -184,6 +192,7 @@ $language_data = array (
)
),
'HIGHLIGHT_STRICT_BLOCK' => array(
-2 => false,
-1 => false,
0 => false,
1 => false,
@ -199,5 +208,3 @@ $language_data = array (
)
)
);
?>

View file

@ -4,13 +4,15 @@
* --------------
* Author: Ben Keen (ben.keen@gmail.com)
* Copyright: (c) 2004 Ben Keen (ben.keen@gmail.com), Nigel McNie (http://qbnz.com/highlighter)
* Release Version: 1.0.8.6
* Release Version: 1.0.9.0
* Date Started: 2004/06/20
*
* JavaScript language file for GeSHi.
*
* CHANGES
* -------
* 2012/06/27 (1.0.8.11)
* - Reordered Keyword Groups to reflect syntactical meaning of keywords
* 2008/05/23 (1.0.7.22)
* - Added description of extra language features (SF#1970248)
* 2004/11/27 (1.0.1)
@ -45,30 +47,47 @@ $language_data = array (
'LANG_NAME' => 'Javascript',
'COMMENT_SINGLE' => array(1 => '//'),
'COMMENT_MULTI' => array('/*' => '*/'),
//Regular Expressions
'COMMENT_REGEXP' => array(2 => "/(?<=[\\s^])s\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])m?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\,\\;\\)])/iU"),
'COMMENT_REGEXP' => array(
//Regular Expressions
2 => "/(?<=[\\s^])(s|tr|y)\\/(?!\*)(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])*(?<!\s)\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?!\*)(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU"
),
'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
'QUOTEMARKS' => array("'", '"'),
'ESCAPE_CHAR' => '\\',
'KEYWORDS' => array(
1 => array(
'as', 'break', 'case', 'catch', 'continue', 'decodeURI', 'delete', 'do',
'else', 'encodeURI', 'eval', 'finally', 'for', 'if', 'in', 'is', 'item',
'instanceof', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'void',
'while', 'write', 'with'
//reserved/keywords; also some non-reserved keywords
'break','case','catch','const','continue',
'default','delete','do',
'else',
'finally','for','function',
'get','goto',
'if','in','instanceof',
'new',
'prototype',
'return',
'set','static','switch',
'this','throw','try','typeof',
'var','void'
),
2 => array(
'class', 'const', 'default', 'debugger', 'export', 'extends', 'false',
'function', 'import', 'namespace', 'new', 'null', 'package', 'private',
'protected', 'public', 'super', 'true', 'use', 'var'
//reserved/non-keywords; metaconstants
'false','null','true','undefined','NaN','Infinity'
),
3 => array(
// common functions for Window object
'alert', 'back', 'blur', 'close', 'confirm', 'focus', 'forward', 'home',
'name', 'navigate', 'onblur', 'onerror', 'onfocus', 'onload', 'onmove',
'onresize', 'onunload', 'open', 'print', 'prompt', 'scroll', 'status',
'stop',
)
//magic properties/functions
'__proto__','__defineGetter__','__defineSetter__','hasOwnProperty','hasProperty'
),
4 => array(
//type constructors
'Object', 'Function', 'Date', 'Math', 'String', 'Number', 'Boolean', 'Array'
),
5 => array(
//reserved, but invalid in language
'abstract','boolean','byte','char','class','debugger','double','enum','export','extends',
'final','float','implements','import','int','interface','long','native',
'short','super','synchronized','throws','transient','volatile'
),
),
'SYMBOLS' => array(
'(', ')', '[', ']', '{', '}',
@ -79,15 +98,18 @@ $language_data = array (
),
'CASE_SENSITIVE' => array(
GESHI_COMMENTS => false,
1 => false,
2 => false,
3 => false
1 => true,
2 => true,
3 => true,
4 => true,
5 => true
),
'STYLES' => array(
'KEYWORDS' => array(
1 => 'color: #000066; font-weight: bold;',
2 => 'color: #003366; font-weight: bold;',
3 => 'color: #000066;'
3 => 'color: #000066;',
5 => 'color: #FF0000;'
),
'COMMENTS' => array(
1 => 'color: #006600; font-style: italic;',
@ -124,8 +146,10 @@ $language_data = array (
'URLS' => array(
1 => '',
2 => '',
3 => ''
),
3 => '',
4 => '',
5 => ''
),
'OOLANG' => true,
'OBJECT_SPLITTERS' => array(
1 => '.'
@ -146,5 +170,3 @@ $language_data = array (
1 => true
)
);
?>

View file

@ -4,7 +4,7 @@
* --------
* Author: Andreas Gohr (andi@splitbrain.org), Ben Keen (ben.keen@gmail.com)
* Copyright: (c) 2004 Andreas Gohr, Ben Keen (http://www.benjaminkeen.org/), Nigel McNie (http://qbnz.com/highlighter/)
* Release Version: 1.0.8.6
* Release Version: 1.0.9.0
* Date Started: 2004/08/20
*
* Perl language file for GeSHi.
@ -209,5 +209,3 @@ $language_data = array (
)
)
);
?>

View file

@ -4,7 +4,7 @@
* --------
* Author: Nigel McNie (nigel@geshi.org)
* Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
* Release Version: 1.0.8.6
* Release Version: 1.0.9.0
* Date Started: 2004/06/20
*
* PHP language file for GeSHi.
@ -90,14 +90,15 @@ $language_data = array(
'as','break','case','continue','default','do','else','elseif',
'endfor','endforeach','endif','endswitch','endwhile','for',
'foreach','if','include','include_once','require','require_once',
'return','switch','throw','while',
'return','switch','throw','while', 'yield',
'echo','print'
),
2 => array(
'&amp;new','&lt;/script&gt;','&lt;?php','&lt;script language',
'class','const','declare','extends','function','global','interface',
'namespace','new','private','protected','public','self','use','var'
'abstract','class','const','declare','extends','function','global',
'implements', 'interface','namespace','new','private','protected',
'public','self','trait','use','var'
),
3 => array(
'abs','acos','acosh','addcslashes','addslashes','aggregate',
@ -1061,7 +1062,7 @@ $language_data = array(
),
'REGEXPS' => array(
//Variables
0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
0 => "[\\$]+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"
),
'STRICT_MODE_APPLIES' => GESHI_MAYBE,
'SCRIPT_DELIMITERS' => array(
@ -1083,22 +1084,24 @@ $language_data = array(
"(?>'(?>[^'\\\\]|\\\\'|\\\\\\\|\\\\)*')|".
"(?>\"(?>[^\"\\\\]|\\\\\"|\\\\\\\\|\\\\)*\")|".
"(?>\\/\\*(?>[^\\*]|(?!\\*\\/)\\*)*\\*\\/)|".
"\\/\\/(?>.*?$)|".
"\\/\\/(?>.*?(?:\\?>|$))|".
"#(?>.*?(?:\\?>|$))|".
"\\/(?=[^*\\/])|".
"<(?!<<)|".
"<<<(?P<phpdoc>\w+)\s.*?\s\k<phpdoc>".
")*(?P<end>\\?>|\Z)/sm",
")*?(?P<end>\\?>|\Z)/sm",
5 => "/(?P<start><%)(?:".
"(?>[^\"'%\\/<]+)|".
"%(?!>)|".
"(?>'(?>[^'\\\\]|\\\\'|\\\\\\\|\\\\)*')|".
"(?>\"(?>[^\\\"\\\\]|\\\\\"|\\\\\\\\|\\\\)*\")|".
"(?>\\/\\*(?>[^\\*]|(?!\\*\\/)\\*)*\\*\\/)|".
"\\/\\/(?>.*?$)|".
"\\/\\/(?>.*?(?:%>|$))|".
"#(?>.*?(?:%>|$))|".
"\\/(?=[^*\\/])|".
"<(?!<<)|".
"<<<(?P<phpdoc>\w+)\s.*?\s\k<phpdoc>".
")*(?P<end>%>)/sm",
")*?(?P<end>%>|\Z)/sm",
),
'HIGHLIGHT_STRICT_BLOCK' => array(
0 => true,
@ -1110,5 +1113,3 @@ $language_data = array(
),
'TAB_WIDTH' => 4
);
?>

View file

@ -3,14 +3,18 @@
* sql.php
* -------
* Author: Nigel McNie (nigel@geshi.org)
* Contributors:
* - Jürgen Thomas (Juergen.Thomas@vs-polis.de)
* Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
* Release Version: 1.0.8.6
* Release Version: 1.0.9.0
* Date Started: 2004/06/04
*
* SQL language file for GeSHi.
*
* CHANGES
* -------
* 2010/07/19 (1.0.8.9)
* - Added many more keywords
* 2008/05/23 (1.0.7.22)
* - Added additional symbols for highlighting
* 2004/11/27 (1.0.3)
@ -58,30 +62,51 @@ $language_data = array (
'ESCAPE_CHAR' => '\\',
'KEYWORDS' => array(
1 => array(
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC',
'AUTO_INCREMENT', 'BETWEEN', 'BINARY', 'BOOLEAN',
'BOTH', 'BY', 'CHANGE', 'CHECK', 'COLUMN', 'COLUMNS',
'CREATE', 'CROSS', 'DATA', 'DATABASE', 'DATABASES',
'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE',
'DISTINCT', 'DROP', 'ENCLOSED', 'ESCAPED', 'EXISTS',
'EXPLAIN', 'FIELD', 'FIELDS', 'FLUSH', 'FOR',
'FOREIGN', 'FROM', 'FULL', 'FUNCTION', 'GRANT',
'GROUP', 'HAVING', 'IDENTIFIED', 'IF', 'IGNORE',
'IN', 'INDEX', 'INFILE', 'INNER', 'INSERT', 'INTO',
'IS', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LANGUAGE',
'LEADING', 'LEFT', 'LIKE', 'LIMIT', 'LINES', 'LOAD',
'LOCAL', 'LOCK', 'LOW_PRIORITY', 'MODIFY', 'NATURAL',
'NEXTVAL', 'NOT', 'NULL', 'ON', 'OPTIMIZE', 'OPTION',
'OPTIONALLY', 'OR', 'ORDER', 'OUTER', 'OUTFILE',
'PRIMARY', 'PROCEDURAL', 'PROCEEDURE', 'READ',
'REFERENCES', 'REGEXP', 'RENAME', 'REPLACE',
'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SELECT',
'SET', 'SETVAL', 'SHOW', 'SONAME', 'STATUS',
'STRAIGHT_JOIN', 'TABLE', 'TABLES', 'TEMINATED',
'TEMPORARY', 'TO', 'TRAILING', 'TRIGGER', 'TRUNCATE',
'TRUSTED', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED',
'UPDATE', 'USE', 'USING', 'VALUES', 'VARIABLES',
'VIEW', 'WHERE', 'WITH', 'WRITE', 'XOR', 'ZEROFILL'
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'AUTO_INCREMENT',
'BEFORE', 'BEGIN', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOOLEAN', 'BOTH', 'BY',
'CALL', 'CASE', 'CAST', 'CEIL', 'CEILING', 'CHANGE', 'CHAR', 'CHAR_LENGTH', 'CHARACTER',
'CHARACTER_LENGTH', 'CHECK', 'CLOB', 'COALESCE', 'COLLATE', 'COLUMN', 'COLUMNS',
'CONNECT', 'CONSTRAINT', 'CONVERT', 'COUNT', 'CREATE', 'CROSS', 'CURRENT',
'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER',
'DATA', 'DATABASE', 'DATABASES', 'DATE', 'DAY', 'DEC', 'DECIMAL', 'DECLARE',
'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DISTINCT', 'DOUBLE',
'DOMAIN', 'DROP',
'ELSE', 'ELSEIF', 'ENCLOSED', 'END', 'ESCAPED', 'EXCEPT', 'EXEC', 'EXECUTE', 'EXISTS',
'EXP', 'EXPLAIN', 'EXTRACT',
'FALSE', 'FIELD', 'FIELDS', 'FILTER', 'FIRST', 'FLOAT', 'FLOOR', 'FLUSH', 'FOR',
'FOREIGN', 'FROM', 'FULL', 'FUNCTION',
'GET', 'GROUP', 'GROUPING', 'GO', 'GOTO', 'GRANT', 'GRANTED',
'HAVING', 'HOUR',
'IDENTIFIED', 'IDENTITY', 'IF', 'IGNORE', 'IN', 'INCREMENT', 'INDEX', 'INFILE', 'INNER',
'INOUT', 'INPUT', 'INSERT', 'INT', 'INTEGER', 'INTERSECT', 'INTERSECTION', 'INTERVAL',
'INTO', 'IS',
'JOIN',
'KEY', 'KEYS', 'KILL',
'LANGUAGE', 'LARGE', 'LAST', 'LEADING', 'LEFT', 'LENGTH', 'LIKE', 'LIMIT', 'LINES', 'LOAD',
'LOCAL', 'LOCK', 'LOW_PRIORITY', 'LOWER',
'MATCH', 'MAX', 'MERGE', 'MIN', 'MINUTE', 'MOD', 'MODIFIES', 'MODIFY', 'MONTH',
'NATIONAL', 'NATURAL', 'NCHAR', 'NEW', 'NEXT', 'NEXTVAL', 'NONE', 'NOT',
'NULL', 'NULLABLE', 'NULLIF', 'NULLS', 'NUMBER', 'NUMERIC',
'OF', 'OLD', 'ON', 'ONLY', 'OPEN', 'OPTIMIZE', 'OPTION',
'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'OVER',
'POSITION', 'POWER', 'PRECISION', 'PREPARE', 'PRIMARY', 'PROCEDURAL', 'PROCEDURE',
'READ', 'REAL', 'REF', 'REFERENCES', 'REFERENCING', 'REGEXP', 'RENAME', 'REPLACE',
'RESULT', 'RETURN', 'RETURNS', 'REVOKE', 'RIGHT', 'RLIKE', 'ROLLBACK', 'ROW',
'ROW_NUMBER', 'ROWS', 'RESTRICT', 'ROLE', 'ROUTINE', 'ROW_COUNT',
'SAVEPOINT', 'SEARCH', 'SECOND', 'SECTION', 'SELECT', 'SELF', 'SEQUENCE',
'SESSION', 'SET', 'SETVAL', 'SHOW', 'SIMILAR', 'SIZE', 'SMALLINT', 'SOME',
'SONAME', 'SOURCE', 'SPACE', 'SQL', 'SQRT', 'START', 'STATUS',
'STRAIGHT_JOIN', 'STRUCTURE', 'STYLE', 'SUBSTRING', 'SUM',
'TABLE', 'TABLE_NAME', 'TABLES', 'TERMINATED', 'TEMPORARY', 'THEN', 'TIME',
'TIMESTAMP', 'TO', 'TRAILING', 'TRANSACTION', 'TRIGGER', 'TRIM', 'TRUE', 'TRUNCATE',
'TRUSTED', 'TYPE',
'UNDER', 'UNION', 'UNIQUE', 'UNKNOWN', 'UNLOCK', 'UNSIGNED',
'UPDATE', 'UPPER', 'USE', 'USER', 'USING',
'VALUE', 'VALUES', 'VARCHAR', 'VARIABLES', 'VARYING', 'VIEW',
'WHEN', 'WHERE', 'WITH', 'WITHIN', 'WITHOUT', 'WORK', 'WRITE',
'XOR',
'YEAR',
'ZEROFILL'
)
),
'SYMBOLS' => array(
@ -134,7 +159,10 @@ $language_data = array (
'SCRIPT_DELIMITERS' => array(
),
'HIGHLIGHT_STRICT_BLOCK' => array(
),
'PARSER_CONTROL' => array(
'KEYWORDS' => array( //'
'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\.\|\#|^&])"
)
)
);
?>

View file

@ -4,7 +4,7 @@
* -------
* Author: Nigel McNie (nigel@geshi.org)
* Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
* Release Version: 1.0.8.6
* Release Version: 1.0.9.0
* Date Started: 2004/09/01
*
* XML language file for GeSHi. Based on the idea/file by Christian Weiske
@ -153,5 +153,3 @@ $language_data = array (
)
)
);
?>

Some files were not shown because too many files have changed in this diff Show more