1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-09-14 01:52:06 +02:00

Compare commits

...

234 Commits

Author SHA1 Message Date
Marc Alexander
b59bfadec7 Merge pull request #6840 from battye/ticket/17034
[ticket/17034] Fix minimum posts rank validation
2025-07-21 21:32:36 +02:00
Marc Alexander
f6269dde2d Merge pull request #6791 from IdfbAn/ticket/17110
[ticket/17110] Change "slanderous" to "libellous" in T&C
2025-07-21 21:25:05 +02:00
battye
1633288447 [ticket/17034] Fix min posts rank validation
PHPBB-17034
2025-07-20 04:41:27 +00:00
Marc Alexander
081f2391cb Merge pull request #6836 from rxu/ticket/17533
[ticket/17533] Fix reverting migrations logic
2025-07-07 17:35:37 +02:00
rxu
0b242b9608 [ticket/17533] Fix reverting migrations logic
Basically, prefer revert_data() if exists.

PHPBB-17533
2025-07-07 11:02:30 +07:00
Marc Alexander
3b03f3a8f9 Merge pull request #6833 from iMattPro/ticket/17519
[ticket/17519] Revert cron url escape back to html_attr
2025-06-17 19:42:42 +02:00
Matt Friedman
e47ba9e81d [ticket/17519] Fix tests
PHPBB-17519
2025-06-17 09:19:40 -07:00
Matt Friedman
8d016bafa2 [ticket/17519] Revert cron url escape back to html_attr
PHPBB-17519
2025-06-17 07:59:04 -07:00
Marc Alexander
35221f8ba5 Merge pull request #6826 from danieltj27/ticket/17522
[ticket/17522] Add event to member list to modify template vars
2025-06-17 14:04:28 +02:00
Marc Alexander
9219c03b36 Merge pull request #6831 from rxu/ticket/17527
[ticket/17527] Add Twig extensions existence check while registering
2025-06-17 11:30:52 +02:00
Daniel James
72c3745868 [ticket/17522] Change event name and update var type
PHPBB-17522
2025-06-17 07:18:41 +01:00
rxu
579b4a8287 [ticket/17527] Add Twig extensions existence check while registering
PHPBB-17527
2025-06-16 22:25:59 +07:00
Marc Alexander
2f43c1facd [ticket/17399] Fix docblock and use space-ship operator
PHPBB-17399
2025-06-16 10:34:38 +02:00
Marc Alexander
d4a3311b76 Merge pull request #6829 from battye/ticket/17399
[ticket/17399] Fix selected language bug in installer
2025-06-15 09:08:49 +02:00
battye
8411da1819 [ticket/17399] Fix selected language in installer
This fixes a bug where a user could have other languages in the installer
but the language dropdown did not match the language shown.

PHPBB-17399
2025-06-14 14:35:18 +00:00
Marc Alexander
8f8a93fa71 Merge pull request #6818 from rxu/ticket/17515
[ticket/17515] Add template event before PM text - 3.3.x
2025-06-14 08:51:41 +02:00
Marc Alexander
c726382d84 Merge pull request #6824 from iMattPro/ticket/17519
[ticket/17519] Correctly encode cron task urls
2025-06-13 20:41:22 +02:00
Marc Alexander
5deeea025f [ticket/17519] Add unit tests for task wrapper
PHPBB-17519
2025-06-12 21:00:24 +02:00
Daniel James
b6c42b3768 [ticket/17522] Switch array syntax to short code
PHPBB-17522
2025-06-06 11:50:49 +01:00
Daniel James
da2733a7d8 [ticket/17522] Change since from beta to release candidate
PHPBB-17522
2025-06-06 11:03:10 +01:00
Daniel James
b8204d24f9 [ticket/17522] Add event to member list to modify template vars
PHPBB-17522
2025-06-05 22:18:51 +01:00
Matt Friedman
6947dc8c92 [ticket/17519] Correctly encode cron task urls
PHPBB-17519
2025-06-03 04:21:24 +00:00
rxu
ddc7f1df34 [ticket/17515] Add template event before PM text
PHPBB-17515
2025-05-22 13:29:47 +07:00
Marc Alexander
478d119d42 Merge pull request #6814 from iMattPro/ticket/17510
[ticket/17510] Fix Code Sniffer deprecations
2025-05-19 17:53:18 +02:00
Marc Alexander
b3478d83d1 Merge pull request #6811 from rxu/ticket/17506
[ticket/17506] Ensure superglobal variables are arrays before applying addition - 3.3.x
2025-05-19 17:44:47 +02:00
Matt Friedman
7268859226 [ticket/17510] Fix Code Sniffer deprecations
PHPBB-17510
2025-05-13 18:03:10 -07:00
rxu
10947f3d49 [ticket/17506] Ensure superglobal variables are arrays before applying addition
PHPBB-17506
2025-05-09 16:58:36 +07:00
Marc Alexander
04f2141a7d Merge pull request #6799 from rxu/ticket/17491
[ticket/17491] Fix caching search results - 3.3.x
2025-05-07 20:15:53 +02:00
rxu
3d76a8bd09 [ticket/17491] Fix rows duplication in search results
PHPBB-17491
2025-05-07 00:31:21 +07:00
rxu
1c399dcab7 [ticket/17491] Consistently apply array_unique to search results
PHPBB-17491
2025-05-06 00:11:45 +07:00
rxu
e91c7d42a9 [ticket/17491] Add test
PHPBB-17491
2025-05-05 23:46:09 +07:00
Marc Alexander
1b2ac50cfd Merge pull request #6810 from rxu/ticket/17504
[ticket/17504] Fix tests failure caused by ondrej/php PPA repo label changed
2025-04-28 21:17:23 +02:00
rxu
779bec5fcf [ticket/17504] Run apt-get update on runner lever rather than in bash scripts
PHPBB-17504
2025-04-28 23:28:05 +07:00
rxu
f512af1823 [ticket/17504] Fix tests
Fix the following apt-get update issue with ondrej/php PPA repo:
Repository 'https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble InRelease'
changed its 'Label' value from '***** The main PPA for supported PHP versions
with many PECL extensions *****' to 'PPA for PHP'

Alternative fix might be: sudo apt update && sudo apt full-upgrade -y

PHPBB-17504
2025-04-28 21:17:57 +07:00
Marc Alexander
59e8875fa8 Merge pull request #6807 from rxu/ticket/16941
[ticket/16941] Add sphinx tests to 3.3.x
2025-04-26 08:34:09 +02:00
rxu
1ae9a49811 [ticket/16941] Remove ending slash from binlog_path
PHPBB3-14401
2025-04-25 21:28:36 +07:00
rxu
80a08d9c54 [ticket/16941] Add sphinx tests to 3.3.x
Also adjust Sphinx keywords splitting to be consistent with other search
backends when it comes to handling hyphen (like ignoring hyphen when it hasn't
NOT meaning and ignoring hyphen wrapped with "plus" signs)

PHPBB3-16941
2025-04-24 23:17:26 +07:00
Marc Alexander
4140d50f6a Merge pull request #6804 from rxu/ticket/17498
[ticket/17498] Move to Ubuntu 22.04 runner images for SQLite and MSSQL tests - 3.3.x
2025-04-15 22:00:00 +02:00
rxu
dd53db1625 [ticket/17498] Move to Ubuntu 22.04 runner images for SQLite and MSSQL tests
PHPBB-17498
2025-04-16 00:48:48 +07:00
Marc Alexander
e5f599c43b Merge pull request #6797 from LukeWCS/ticket/17492
[ticket/17492] Unintuitive checkbox status inverted for forum/topic subscriptions
2025-04-14 20:49:26 +02:00
LukeWCS
705b5ca572 [ticket/17492] Unintuitive checkbox status inverted for forum subscriptions
PHPBB-17492
2025-04-13 12:58:09 +02:00
rxu
8d0d6c012c [ticket/17491] Fix caching search results
PHPBB-17491
2025-04-12 14:35:40 +07:00
LukeWCS
8c5e22f4d5 [ticket/17492] Update viewtopic_topic_tools.html
Changed compact but icon-specific code to neutral code for easier changing.

PHPBB-17492
2025-04-12 09:17:39 +02:00
LukeWCS
cac3d81e73 [ticket/17492] Unintuitive checkbox status inverted for topic subscriptions
PHPBB-17492
2025-04-12 09:17:24 +02:00
Marc Alexander
40608777f0 Merge pull request #6789 from rxu/ticket/17475
[ticket/17475] Fix MSSQL arithmetic overflow error on counting attachments size
2025-04-03 19:39:24 +02:00
Marc Alexander
84a835a995 Merge pull request #6792 from rxu/ticket/17486
[ticket/17486] Fix SQL error on phpBB v.3.0 to v.3.3 upgrade
2025-04-03 19:35:16 +02:00
Marc Alexander
b8ea36a70f Merge branch 'prep-release-3.3.15' into 3.3.x 2025-04-02 16:50:53 +02:00
rxu
98a8999283 [ticket/17486] Fix SQL error on phpBB v.3.0 to v.3.3 upgrade
Ensure v310/bot_update runs after v310/avatars migration which changes
user_avatar_type column type from tinyint(2) to varchar(255).

PHPBB-17486
2025-04-01 10:46:29 +07:00
IdfbAn
fabef37d71 [ticket/17110] Change "slanderous" to "libellous" in T&C
Slander is spoken and libel is written, so "libellous" is more accurate here.

PHPBB-17110
2025-03-31 20:36:21 +04:00
Marc Alexander
b92ca5d1f8 [prep-release-3.3.15] Update changelog for 3.3.15 2025-03-23 20:20:03 +01:00
Marc Alexander
fb46aa38b8 [prep-release-3.3.15] Add migration for 3.3.15 2025-03-23 19:41:47 +01:00
Marc Alexander
51465670f6 [prep-release-3.3.15] Update version numbers to 3.3.15 2025-03-23 19:39:07 +01:00
rxu
14a6322b4f [ticket/17475] Fix MSSQL arithmetic overflow error on counting attachments size
PHPBB-17475
2025-03-10 21:24:15 +07:00
Marc Alexander
cfa3a21e20 Merge pull request #73 from phpbb/ticket/security-283
[ticket/security-283] Use jQuery to generate HTML for page from page data
2025-03-08 11:23:40 +01:00
Marc Alexander
64dd8b668e Merge branch 'prep-release-3.3.15' into 3.3.x 2025-03-08 09:07:41 +01:00
Marc Alexander
57abba6be0 Merge pull request #6788 from rxu/ticket/17480-2
[ticket/17480] Properly catch RuntimeException if no http handler is available
2025-03-08 09:00:35 +01:00
rxu
0826a41da8 [ticket/17480] Adjust message wording
PHPBB-17480
2025-03-08 11:05:39 +07:00
rxu
1ea59731f0 [ticket/17480] Use phpBB error message text instead of thrown by GuzzleHTTP
PHPBB-17480
2025-03-05 10:18:23 +07:00
rxu
9bdb88879d [ticket/17480] Properly catch RuntimeException if no http handler is available
PHPBB-17480
2025-03-04 13:03:18 +07:00
Marc Alexander
430200cbf6 Merge branch 'prep-release-3.3.15' into 3.3.x 2025-03-03 21:55:21 +01:00
Marc Alexander
d8aa6873b2 Merge pull request #6786 from rxu/ticket/17480
[ticket/17480] Fix PHP fatal error in version check failure
2025-03-03 21:53:51 +01:00
rxu
d9136469ea [ticket/17480] Catch runtime_exception instead of exception_interface
Catch runtime_exception instead of exception_interface
for extensions version check failures.

PHPBB-17480
2025-03-04 01:06:46 +07:00
rxu
7fd634b420 [ticket/17480] Fix PHP fatal error in version check failure
PHPBB-17480
2025-03-03 23:33:58 +07:00
Marc Alexander
bb3d41e193 [3.3.x] Update version numbers to 3.3.16-dev 2025-03-02 17:11:26 +01:00
Marc Alexander
94fde8fa23 Merge branch 'prep-release-3.3.15' into 3.3.x 2025-03-02 17:09:49 +01:00
Marc Alexander
66650cb0e2 [prep-release-3.3.15] Update changelog for 3.3.15-RC1 2025-03-01 21:55:15 +01:00
Marc Alexander
d9e4ce6dde [prep-release-3.3.15] Add migration for 3.3.15-RC1 2025-03-01 21:45:21 +01:00
Marc Alexander
24fc7d5388 [prep-release-3.3.15] Update version numbers to 3.3.15 2025-03-01 21:41:36 +01:00
Marc Alexander
ae40c6365e [prep-release-3.3.15] Update version numbers to 3.3.15-RC1 2025-03-01 21:41:28 +01:00
Marc Alexander
63c110b511 Merge pull request #6785 from marc1706/ticket/17478
[ticket/17478] Add security policy file
2025-03-01 18:12:17 +01:00
Marc Alexander
be67bfbe63 [ticket/17478] Remove versions and reword reporting section
[skip ci]

PHPBB-17478
2025-03-01 17:04:16 +01:00
Marc Alexander
cedbbb0c76 [ticket/17478] Add security policy file
PHPBB-17478
2025-03-01 16:45:36 +01:00
Marc Alexander
a5bf1ff165 Merge pull request #6758 from battye/ticket/17381
[ticket/17381] Topic view count validation
2025-03-01 15:55:40 +01:00
Marc Alexander
08fd9caa11 Merge pull request #6772 from rxu/ticket/17227
[ticket/17227] Fix rows duplication in memberlist
2025-03-01 15:47:55 +01:00
Marc Alexander
746133d005 Merge pull request #6783 from rxu/ticket/17461
[ticket/17461] Add core events to acp_main
2025-03-01 10:23:35 +01:00
Marc Alexander
17480d7d07 [ticket/security-283] Unify behavior between adm and prosilver, clean up
SECURITY-283
2025-03-01 09:22:23 +01:00
Marc Alexander
c3bb5e1bec [ticket/security-283] Ensure text is properly handled for responsiveness
SECURITY-283
2025-02-28 20:33:41 +01:00
battye
29730e49ce [ticket/17381] Add migration for topic_views to ULINT
PHPBB-17381
2025-02-28 03:22:08 +00:00
rxu
8adc853dea [ticket/17461] Add core events to acp_main
PHPBB-17461
2025-02-22 13:28:43 +07:00
Marc Alexander
a223da37fb Merge pull request #6782 from rxu/ticket/17470
[ticket/17470] Fix feed functional tests for master
2025-02-19 17:15:15 +01:00
Marc Alexander
7181c4d591 Merge pull request #6781 from cabot/fix_forumlist_feed_link
[ticket/17471] Fix feed link href for feed icon
2025-02-19 17:11:39 +01:00
rxu
2fa5da1454 [ticket/17470] Fix feed functional tests for master
Symfony DomCrawler component validates form values and throws
InvalidArgumentException for impossible values set.

PHPBB-17470
2025-02-19 21:45:47 +07:00
cabot
77f83306b5 [ticket/17471] Fix feed link href for feed icon
PHPBB-17471
2025-02-18 17:33:30 +01:00
Marc Alexander
4f5ace858d Merge pull request #6780 from Neo-CTC/ticket/17470
[ticket/17470] Feed enable config not enforced
2025-02-16 18:00:31 +01:00
Marc Alexander
f42c4be939 [ticket/17470] Check feed enabled in each handler and add tests
PHPBB-17470
2025-02-16 12:00:36 +01:00
Neo-CTC
bfdf172992 [ticket/17470] Feed enable config not enforced
The 'feed_enable' config is never checked before generating the feeds. The
effective result is that feeds are always enabled, regardless of the setting.

PHPBB-17470
2025-02-16 00:09:45 -06:00
Marc Alexander
6b5bb4d51f Merge pull request #6741 from phpbbtr/patch-5
[ticket/17417] Day selection not visible when no results
2025-02-11 21:28:00 +01:00
phpBB TR
736ef320ed [ticket/17417] Show display options even without search results
PHPBB-17417
2025-02-11 20:59:28 +01:00
Marc Alexander
bf29596bad Merge pull request #6775 from rxu/ticket/17467
[ticket/17467] Provide TLS v.1.3 support for SMTP connections
2025-02-10 20:01:24 +01:00
Marc Alexander
120ae90636 Merge pull request #6777 from rxu/ticket/17468
[ticket/17468] Send reset password link to email only
2025-02-06 20:29:00 +01:00
Marc Alexander
b157e1b0d2 Merge pull request #6771 from Neo-CTC/ticket/17463
[ticket/17463] Remove extraneous '&' from search page urls
2025-02-04 20:33:30 +01:00
rxu
cd47344ee2 [ticket/17468] Send reset password link to email only
PHPBB-17468
2025-02-02 19:46:49 +07:00
rxu
a86f368f3d [ticket/17467] Provide TLS v.1.3 support for SMTP connections
PHPBB-17467
2025-02-02 10:42:29 +07:00
rxu
f9def4a725 [ticket/17227] Fix rows duplication in memberlist
PHPBB-17227
2025-01-23 11:15:47 +07:00
NeoDev
3d6e63154f [ticket/17463] Remove extraneous '&' from search page urls
Normally $u_show_results always starts with '&' as it is appended to the
$u_sort_param variable. Which is fine if $u_sort_param is always populated,
which it is, except when searching for new or unread posts. This fix adds a
check for when $u_sort_param is empty and adds '&' as needed.

PHPBB-17463
2025-01-22 19:31:25 -06:00
Marc Alexander
2f08d8eb72 Merge pull request #6763 from rxu/ticket/17455
[ticket/17455] Fix PHP warning on MySQLi connection failure
2025-01-06 10:57:16 +01:00
rxu
059e82de8f [ticket/17455] Remove outdated mysqli_connect_error function existence check
PHPBB-17455
2025-01-02 20:15:55 +07:00
Marc Alexander
c06bec87dc Merge pull request #6746 from TheBrainOne/ticket/17429
[ticket/17429] Added trigger for event "group_add_user_before"
2024-12-31 15:44:18 +01:00
rxu
7540720c79 [ticket/17455] Fix PHP warning on MySQLi connection failure
PHPBB-17455
2024-12-16 20:04:33 +07:00
Marc Alexander
e73ba63590 Merge pull request #6754 from rxu/ticket/17443
[ticket/17443] Fix various Guzzle client issues for version checks
2024-12-08 17:23:34 +01:00
Marc Alexander
1255febe6b Merge pull request #6756 from kaileymsnay/ticket/17446
[ticket/17446] Add acp_account_activation_edit_add event
2024-12-08 13:02:37 +01:00
Marc Alexander
911f8a5fb7 Merge pull request #6749 from rxu/ticket/17433
[ticket/17433] Clarify wording for use system cron ACP setting
2024-12-02 17:24:37 +01:00
Kailey M Snay
a4879e9249 [ticket/17446] Fix typo
PHPBB-17446
2024-11-29 23:57:35 -05:00
Kailey M Snay
922fde6d53 [ticket/17446] Add $phpbb_dispatcher and docblock updates
PHPBB-17446
2024-11-29 23:02:40 -05:00
Kailey M Snay
332ecb3d9c [ticket/17446] Use array shorthand
PHPBB-17446
2024-11-29 17:03:32 -05:00
Kailey M Snay
8978594d6d [ticket/17446] Add acp_account_activation_edit_add event
Event added for additional account activation methods.

PHPBB-17446
2024-11-29 15:45:42 -05:00
rxu
13945f56a9 [ticket/17443] Use default */* accept header (like curl etc)
PHPBB-17443
2024-11-25 16:06:44 +07:00
rxu
253579761d [ticket/17443] Fix HTTP 403 response to Guzzle client requests for some hosts
PHPBB-17443
2024-11-25 13:30:33 +07:00
rxu
7baba29d9d [ticket/17443] Increase Guzzle client request timeout for version checks
PHPBB-17443
2024-11-25 12:39:53 +07:00
rxu
32a1d82969 [ticket/17433] Specify "operating" system term
PHPBB-17433
2024-11-25 10:04:10 +07:00
rxu
5dc93ea51e [ticket/17433] Clarify wording for use system cron ACP setting
PHPBB-17433
2024-11-25 10:03:55 +07:00
Marc Alexander
0e8f4f89d8 Merge pull request #6751 from rxu/ticket/17436
[ticket/17436] Fix phpBB 2.0 converter PHP fatal error
2024-11-24 20:20:47 +01:00
Marc Alexander
4a98024474 Merge pull request #6747 from kaileymsnay/ticket/17431
[ticket/17431] Add more vars to memberlist event
2024-11-24 20:18:18 +01:00
Marc Alexander
5538b9a37b [ticket/17429] Add add_id_ary to event and fix since version
PHPBB-17429
2024-11-24 20:15:18 +01:00
Alexey Dolzhenko
5d0b1661f2 [ticket/17429] Adding event before users have been added to a group
PHPBB-17429
2024-11-24 20:12:26 +01:00
Marc Alexander
c7e68fb572 Merge pull request #6744 from rxu/ticket/17422
[ticket/17422] Fix search results sorting - 3.3.x
2024-11-24 20:00:39 +01:00
rxu
150bd59c82 [ticket/17436] Fix phpBB 2.0 converter PHP fatal error
PHPBB-17436
2024-11-21 22:46:31 +07:00
Marc Alexander
5c7cbbc6a8 Merge branch 'prep-release-3.3.14' into 3.3.x 2024-11-20 20:03:39 +01:00
Marc Alexander
72ae28d583 [prep-release-3.3.14] Update changelog for 3.3.14 2024-11-18 21:34:22 +01:00
Marc Alexander
ff08756ea0 [prep-release-3.3.14] Add migration for 3.3.14 2024-11-18 21:23:18 +01:00
Marc Alexander
1f48926b1d [prep-release-3.3.14] Update version numbers to 3.3.14 2024-11-18 21:19:37 +01:00
kaileymsnay
b40cdb757f [ticket/17431] Add more vars to memberlist event
PHPBB3-17431
2024-11-11 14:13:29 -05:00
Marc Alexander
65e457d3d2 Merge branch 'prep-release-3.3.14' into 3.3.x 2024-11-10 10:46:19 +01:00
Marc Alexander
bf83c73a60 Merge pull request #6743 from marc1706/ticket/17421
[ticket/17421] Rename extensions section to "not installed"
2024-11-10 10:31:53 +01:00
rxu
4194cb2228 [ticket/17422] Adjust tests code
PHPBB-17422
2024-10-31 14:55:35 +07:00
rxu
7086fa746f [ticket/17422] Fix tests
PHPBB-17422
2024-10-31 09:41:15 +07:00
rxu
eeede1ab6c [ticket/17422] Add author_id search tests
PHPBB-17422
2024-10-31 01:34:24 +07:00
rxu
be52902541 [ticket/17422] Fix author_id search results sorting
PHPBB-17422
2024-10-30 23:56:05 +07:00
Marc Alexander
c252fb9bfb [ticket/17421] Rename extensions section to "not installed"
PHPBB-17421
2024-10-28 20:20:36 +01:00
Marc Alexander
725cbd31c8 [3.3.x] Update versions to 3.3.15-dev 2024-10-22 20:43:13 +02:00
Marc Alexander
cefce7df54 Merge branch 'prep-release-3.3.14' into 3.3.x 2024-10-22 20:41:29 +02:00
Marc Alexander
c992272036 [prep-release-3.3.14] Update changelog for 3.3.14-RC1 2024-10-21 20:15:47 +02:00
Marc Alexander
7c090c6e2a [prep-release-3.3.14] Add migration for 3.3.14-RC1 2024-10-21 19:39:11 +02:00
Marc Alexander
4c419c5acd [prep-release-3.3.14] Update version numbers to 3.3.14 2024-10-21 19:36:43 +02:00
Marc Alexander
eaa0c779a6 [prep-release-3.3.14] Update version numbers to 3.3.14-RC1 2024-10-21 19:36:42 +02:00
Marc Alexander
3c7bf782a7 Merge pull request #6738 from rxu/ticket/17388
[ticket/17388] Add core events to bump_topic_allowed()
2024-10-20 17:31:29 +02:00
Marc Alexander
aa21aff080 Merge pull request #6736 from rxu/ticket/17411
[ticket/17411] Add core event to search.php
2024-10-20 17:29:33 +02:00
rxu
443d82d082 [ticket/17388] Add core events to bump_topic_allowed()
PHPBB-16852
PHPBB-17388
2024-10-20 20:05:55 +07:00
Marc Alexander
5abc36f651 Merge pull request #6734 from marc1706/ticket/17410
[ticket/17410] Only fall back acp main page when in ACP with test permission
2024-10-19 21:06:24 +02:00
Marc Alexander
f971d7ffcb Merge pull request #6722 from rxu/ticket/17402
[ticket/17402] Add CLI reparser option to force reparsing BBCode - 3.3.x
2024-10-19 17:14:58 +02:00
rxu
ed145b8317 [ticket/17411] Fix docblock typo
PHPBB-17411
2024-10-18 23:28:56 +07:00
Marc Alexander
26e49d4b15 Merge pull request #6732 from marc1706/ticket/17398
[ticket/17398] Add referer to delete cookies route to ensure proper URLs
2024-10-17 22:38:33 +02:00
rxu
43ff56a7a7 [ticket/17411] Add core event to search.php
PHPBB-17411
2024-10-17 11:01:43 +07:00
rxu
6c35cea146 [ticket/17402] Adjust description
PHPBB-17402
2024-10-17 00:31:42 +07:00
Marc Alexander
62f9f53f46 Merge pull request #6699 from danieltj27/ticket/17376
[ticket/17376] Add aria label to quote reference link
2024-10-16 19:18:30 +02:00
Marc Alexander
4a039d853f [ticket/17376] Update default formatting test
PHPBB-17376
2024-10-11 20:13:22 +02:00
Marc Alexander
b1282fcbc7 [ticket/17410] Only fall back acp main page when in ACP with test permission
PHPBB-17410
2024-10-10 21:38:19 +02:00
Marc Alexander
58d87c7c06 Merge pull request #6719 from ClutchEngineering/ticket-17397
[ticket/17397] Add core.viewforum_modify_sql event
2024-10-09 21:31:20 +02:00
Marc Alexander
fd58e4f338 [ticket/17398] Use referer for web paths in ajax requests
PHPBB-17398
2024-10-09 20:16:30 +02:00
Jeff Verkoeyen
8129208e56 [ticket/17397] Add core.viewforum_modify_sql event
PHPBB-17397
2024-10-06 18:58:26 +00:00
Marc Alexander
ecceeab709 [ticket/17398] Add referer to delete cookies route to ensure proper URLs
PHPBB-17398
2024-10-06 14:57:17 +02:00
rxu
660f3d2b86 [ticket/17402] Adjust precaution text
PHPBB-17402
2024-10-04 22:53:32 +07:00
Marc Alexander
ae1d830e84 Merge pull request #6729 from rxu/ticket/17391
[ticket/17391] Fix PHP warning on creating group with the name already in use
2024-10-03 13:43:04 +02:00
Marc Alexander
688c7cad49 Merge pull request #6731 from marc1706/ticket/17407
[ticket/17407] Combine create and update step and use replace edit-mode
2024-10-03 11:33:36 +02:00
Marc Alexander
44f04a91f3 [ticket/17407] Combine create and update step and use replace edit-mode
[skip ci] Since this change won't run until merged.

PHPBB-17407
2024-10-03 11:29:51 +02:00
Marc Alexander
db7b4c999d Merge pull request #6730 from marc1706/ticket/17407
[ticket/17407] Update comment in merge check if possible
2024-10-03 10:20:18 +02:00
Marc Alexander
1b0c9b22e0 [ticket/17407] Update comment in merge check if possible
PHPBB-17407
2024-10-03 09:32:43 +02:00
rxu
4217dc46ca [ticket/17391] Add simple functional test
PHPBB-17391
2024-10-03 13:24:52 +07:00
rxu
46ea7a8ffd [ticket/17391] Fix PHP warning on creating group with the name already in use
PHPBB-17391
2024-10-03 12:37:30 +07:00
Marc Alexander
f80b41aa77 Merge pull request #6704 from danieltj27/ticket/17382
[ticket/17382] Update the find a member FAQ text to fix grammar
2024-09-30 21:05:09 +02:00
Daniel James
501ecf5dec [ticket/17382] Update FAQ string with new suggestion
PHPBB-17382
2024-09-29 23:38:09 +01:00
Marc Alexander
13b267ca6f Merge pull request #6715 from marc1706/ticket/17385
[ticket/17385] Backport file_downloader with guzzle for versioncheck with redirect support
2024-09-29 19:57:33 +02:00
Marc Alexander
6db142b8ef Merge pull request #6705 from rxu/ticket/17383
[ticket/17383] Fix HELO/EHLO error in email messenger on PHP8
2024-09-29 19:29:37 +02:00
rxu
4ba4b94fe0 [ticket/17402] Add precaution
PHPBB-17402
2024-09-29 16:42:28 +07:00
Marc Alexander
7c95839951 Merge pull request #6725 from iMattPro/ticket/17404
[ticket/17404] Update workflow test badges
2024-09-29 11:26:09 +02:00
Marc Alexander
cd619d350b Merge pull request #6727 from marc1706/ticket/17396
[ticket/17396] Use GitHub App to merge to master
2024-09-29 11:13:59 +02:00
Marc Alexander
fe4d8bfa7e [ticket/17396] Use GitHub App to merge to master
[skip actions] Due to no code changes that run in PRs.

PHPBB-17396
2024-09-29 11:09:46 +02:00
Marc Alexander
283b4f8171 Merge pull request #6726 from rxu/ticket/17405
[ticket/17405] Fix getting UTC date/time information logic
2024-09-29 09:38:13 +02:00
rxu
990cbe093b [ticket/17405] Fix getting UTC date/time information logic
PHPBB-17405
2024-09-29 01:57:53 +07:00
Matt Friedman
80957d12eb [ticket/17404] Update workflow test badges
PHPBB-17404

Signed-off-by: Matt Friedman <maf675@gmail.com>
2024-09-28 09:26:04 -07:00
Marc Alexander
d8dc1204c2 Merge pull request #6723 from marc1706/ticket/17394
[ticket/17394] Merge local 3.3.x and not remote into master
2024-09-28 16:52:12 +01:00
Marc Alexander
d5e94f1d97 [ticket/17394] Merge local 3.3.x and not remote into master
PHPBB-17394
2024-09-28 16:14:22 +01:00
Marc Alexander
9ace4dc585 [ticket/17385] Change default value in docblock
PHPBB-17385
2024-09-28 16:01:02 +01:00
rxu
2ac9c0ae7c [ticket/17402] Add CLI reparser option to force reparsing BBCode
PHPBB-17402
2024-09-28 21:47:09 +07:00
Marc Alexander
914383a581 Merge pull request #6714 from danieltj27/ticket/17390
[ticket/17390] Fix unset template variable for topic approval in mcp
2024-09-25 16:12:07 +01:00
Marc Alexander
45a43e85d8 Merge pull request #6720 from marc1706/ticket/17396
[ticket/17396] Fetch full history and branch 3.3.x if merging to master
2024-09-25 16:14:45 +02:00
Marc Alexander
08d184b0fa [ticket/17396] Try running other-tests on ubuntu-20.04
PHPBB-17396
2024-09-25 14:34:54 +01:00
Marc Alexander
d6a17c1fe7 [ticket/17396] Fetch full history and branch 3.3.x if merging to master
PHPBB-17396
2024-09-19 20:48:21 +02:00
Marc Alexander
ba03a05d27 Merge pull request #6718 from marc1706/ticket/17396
[ticket/17396] Only try pushing if merge was successful
2024-09-18 22:31:45 +02:00
Marc Alexander
17d066a980 [ticket/17396] Only try pushing if merge was successful
PHPBB-17396
2024-09-18 20:41:03 +02:00
Marc Alexander
b574a0294c Merge pull request #6717 from marc1706/ticket/17396
[ticket/17396] Add workflow for merging 3.3.x into master
2024-09-18 20:29:43 +02:00
Marc Alexander
4fb06b00b7 [ticket/17396] Adjust merge code
PHPBB-17396
2024-09-17 22:10:28 +02:00
Marc Alexander
3d70d87b57 [ticket/17396] Split merge check to master to separate yml file
PHPBB-17396
2024-09-17 21:46:03 +02:00
Marc Alexander
f55d747bb4 [ticket/17396] Add workflow for merging 3.3.x into master
PHPBB-17396
2024-09-17 20:38:14 +02:00
Marc Alexander
c5f13dd327 Merge pull request #6716 from marc1706/ticket/17394
[ticket/17394] Check mergeability of 3.3.x PRs
2024-09-17 20:26:46 +02:00
Marc Alexander
e406308244 [ticket/17394] Specify pull_request_target types
PHPBB-17394
2024-09-16 21:38:39 +02:00
Marc Alexander
15556319d9 [ticket/17394] Try using pull_request_target event
PHPBB-17394
2024-09-16 20:13:16 +02:00
Marc Alexander
7a21119d17 [ticket/17394] Check mergeability of 3.3.x PRs
PHPBB-17394
2024-09-15 20:34:25 +02:00
Marc Alexander
5a09105c3c [ticket/17385] Backport tests for updated file downloader to 3.3.x
PHPBB-17385
2024-09-10 22:04:55 +02:00
Marc Alexander
48c2ca9dfe [ticket/12479] Add missing file fixture
PHPBB-12479
2024-09-10 22:01:29 +02:00
Marc Alexander
d6ed21f3f2 [ticket/12479] Use separate mock in "remote" file test
PHPBB-12479
2024-09-10 22:01:14 +02:00
Marc Alexander
929013388f [ticket/12479] Fix use statements in file_downloader
PHPBB-12479
2024-09-10 22:00:58 +02:00
Marc Alexander
d844f82f56 [ticket/12479] Remove dns check from test as we don't test against host anymore
PHPBB-12479
2024-09-10 22:00:43 +02:00
Marc Alexander
f7d16fc626 [ticket/12479] Convert file_downloader to use guzzle instead of fsockopen
PHPBB-12479
2024-09-10 22:00:07 +02:00
Marc Alexander
9eb30b5d8e Merge pull request #6712 from rxu/ticket/17387
[ticket/17387] Fix PHP warnings in search results
2024-09-09 21:04:04 +02:00
rxu
544e0900e6 [ticket/17387] Add more unicode tests
PHPBB-17387
2024-09-03 00:16:05 +07:00
rxu
c26ded6025 [ticket/17387] Fix handling unicode strings
PHPBB-17387
2024-09-02 23:24:24 +07:00
Daniel James
1c73b7ab19 [ticket/17390] Fix unset template variable for topic approval in mcp
Fixes a bug that was introduced in 558b8ae whereby a template
variable was added to wrap around the approve / disapprove UI
however that variable was not set in mcp_queue so the check
failed every time meaning you couldn't approve from the MCP.

PHPBB-17390
2024-09-02 17:13:49 +01:00
Ruben Calvo
472b36877c [ticket/17387] Add test for when words are separated by a non-space character
PHPBB-17387
2024-09-02 14:38:50 +02:00
rxu
66b6a5e1f3 [ticket/17387] Make regex match unicode characters
PHPBB-17387
2024-09-02 17:46:16 +07:00
rxu
8acba2db02 [ticket/17387] Return entire post text for zero or negative length value
In according to 'Default number of returned characters' setting ACP explanation
`A value of 0 will return the entire post`. Do the same for negative values too

PHPBB-17387
2024-09-02 16:37:15 +07:00
Marc Alexander
bf4e26a0b8 Merge pull request #6713 from rxu/ticket/17386-master
[ticket/17386] Unify user based permissions test for 3.3.x and master branches
2024-09-01 20:05:41 +02:00
rxu
7c4b6cde8b [ticket/17386] Fix user based permissions test
PHPBB-17386
2024-09-02 00:19:20 +07:00
Marc Alexander
7f08efb04c Merge pull request #6709 from rxu/ticket/17386
[ticket/17386] Fix resulting permission for user-based tracing
2024-09-01 16:51:05 +02:00
Marc Alexander
6ca926c146 Merge pull request #6665 from rxu/ticket/17359
[ticket/17359] Distinct disabled and available extensions list
2024-09-01 16:44:43 +02:00
rxu
a7b673a1b6 [ticket/17387] Fix PHP warnings in search results
PHPBB-17387
2024-08-31 23:23:10 +07:00
rxu
03f315f7b7 [ticket/17386] Add test
PHPBB-17386
2024-08-31 22:15:03 +07:00
rxu
76752800c2 [ticket/17386] Fix resulting permission for user-based tracing
PHPBB-17386
2024-08-31 22:14:52 +07:00
Marc Alexander
23f872d138 Merge pull request #6710 from marc1706/ticket/17384
[ticket/17384] Stop overriding error handler in test case
2024-08-31 15:30:38 +02:00
Marc Alexander
92730af7a4 [ticket/17384] Stop overriding error handler in test case
PHPBB-17384
2024-08-31 08:59:57 +02:00
Marc Alexander
80f4c07bc5 Merge pull request #6695 from battye/ticket/17181
[ticket/17181] Remove unused PM report code
2024-08-30 11:42:02 +02:00
Marc Alexander
dc0561c8bf Merge pull request #6706 from rxu/ticket/17384
[ticket/17384] Handle E_USER_ERROR for PHP 8.4 tests - 3.3.x
2024-08-30 11:12:40 +02:00
Marc Alexander
9c9dcb1e35 Merge branch 'prep-release-3.3.13' into 3.3.x 2024-08-29 20:34:46 +02:00
Marc Alexander
b083e223e2 [prep-release-3.3.13] Update changelog for 3.3.13 2024-08-28 20:18:39 +02:00
Marc Alexander
88243d296c [prep-release-3.3.13] Add migration for 3.3.13 2024-08-28 20:12:25 +02:00
Marc Alexander
53c60419b4 [prep-release-3.3.13] Update version numbers to 3.3.13 2024-08-28 20:09:41 +02:00
rxu
45515b7072 [ticket/17384] Handle E_USER_ERROR for PHP 8.4 tests
PHPBB-17384
2024-08-18 18:15:52 +07:00
rxu
cc4579ee04 [ticket/17383] Validate php_uname() output too
PHPBB-17383
2024-08-16 00:30:40 +07:00
rxu
6d0a965db2 [ticket/17383] Fix HELO/EHLO error in email messenger on PHP8
PHPBB-17383
2024-08-15 23:49:50 +07:00
rxu
629a909b65 [ticket/17359] Adjust template event target phpBB version
PHPBB-17359
2024-08-13 15:33:18 +07:00
Daniel James
331bea8b22 [ticket/17382] Undo rename of install folder to check front-end changes!
PHPBB-17382
2024-08-12 21:21:14 +01:00
Daniel James
9b4743c028 [ticket/17382] Update the find a member FAQ text to fix grammar
Updated the text of an answer on the FAQ page that explained how
to search for members on the forum. Originally the text read as
`Visit to the “Members” page` which is grammatically incorrect,
specifically `visit to the`.

PHPBB-17382
2024-08-12 21:17:52 +01:00
Daniel James
6623e7fe1d [ticket/17376] Update quote template and change icon to FA arrow
PHPBB-17376
2024-08-07 11:40:12 +01:00
Marc Alexander
9d64579dea Merge branch 'prep-release-3.3.13' into 3.3.x 2024-08-06 22:11:16 +02:00
Marc Alexander
092f583422 Merge pull request #6700 from marc1706/ticket/17377
[ticket/17377] Use specific mssql docker images to have uniform builds
2024-08-06 22:10:49 +02:00
Marc Alexander
8b7f215309 [ticket/17377] Use specific mssql docker images to have uniform builds
PHPBB-17377
2024-08-06 21:08:10 +02:00
Marc Alexander
31f0e7b882 [3.3.x] Update versions to 3.3.14-dev 2024-08-05 20:30:55 +02:00
Marc Alexander
ee3b351419 Merge branch 'prep-release-3.3.13' into 3.3.x 2024-08-05 20:29:22 +02:00
Daniel James
99861a8c10 [ticket/17376] Add aria label to quote reference link
Adds an aria label attribute to the quoted post reference link so
that screen readers can inform the user of what the link is used
for. Before this change the link was too vague and would not have
been well described to users of its purpose if they couldn't see it.

PHPBB-17376
2024-08-04 15:09:34 +01:00
battye
8104facb30 [ticket/17181] Remove unused PM report code
PHPBB-17181
2024-07-22 02:41:20 +00:00
rxu
e53db0775a [ticket/17359] Get rid of template code duplication
PHPBB-17359
2024-07-01 00:54:20 +07:00
rxu
8aef7b5659 [ticket/17359] Fix template events
PHPBB-17359
2024-06-30 20:35:58 +07:00
rxu
9e11624693 [ticket/17359] Fix tests
PHPBB-17359
2024-06-30 19:59:45 +07:00
rxu
e6bdecbfee [ticket/17359] Distinct disabled and available extensions list
PHPBB-17359
2024-06-30 19:07:41 +07:00
106 changed files with 2186 additions and 358 deletions

View File

@@ -10,5 +10,4 @@
#
set -e
sudo apt-get update
sudo apt-get install -y parallel libimage-exiftool-perl

143
.github/setup-sphinx.sh vendored Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/bash
#
# This file is part of the phpBB Forum Software package.
#
# @copyright (c) phpBB Limited <https://www.phpbb.com>
# @license GNU General Public License, version 2 (GPL-2.0)
#
# For full copyright and license information, please see
# the docs/CREDITS.txt file.
#
set -e
set -x
sudo apt-get install -q -y sphinxsearch
DIR=$(dirname "$0")
SPHINX_DAEMON_HOST="localhost"
SPHINX_DAEMON_PORT="9312"
SPHINX_CONF="$DIR/sphinx.conf"
SPHINX_DATA_DIR="/var/run/sphinxsearch"
SPHINX_LOG="$SPHINX_DATA_DIR/log/searchd.log"
SPHINX_QUERY_LOG="$SPHINX_DATA_DIR/log/sphinx-query.log"
ID="gokw5rvjvvxp8kgj" # Randomly generated via phpBB unique_id()
PHPBB_TEST_DBHOST="0.0.0.0"
PHPBB_TEST_DBNAME="phpbb_tests"
PHPBB_TEST_DBUSER="root"
PHPBB_TEST_DBPASSWD=""
sudo service sphinxsearch stop
sudo mkdir -p "$SPHINX_DATA_DIR/log"
sudo chown "sphinxsearch" "$SPHINX_DATA_DIR/log"
# Generate configuration file for Sphinx
echo "
source source_phpbb_${ID}_main
{
type = mysql # mysql or pgsql
sql_host = $PHPBB_TEST_DBHOST
sql_user = $PHPBB_TEST_DBUSER
sql_pass = $PHPBB_TEST_DBPASSWD
sql_db = $PHPBB_TEST_DBNAME
sql_port =
sql_query_pre = SET NAMES 'utf8'
sql_query_pre = UPDATE phpbb_sphinx SET max_doc_id = (SELECT MAX(post_id) FROM phpbb_posts) WHERE counter_id = 1
sql_query_range = SELECT MIN(post_id), MAX(post_id) FROM phpbb_posts
sql_range_step = 5000
sql_query = SELECT \
p.post_id AS id, \
p.forum_id, \
p.topic_id, \
p.poster_id, \
p.post_visibility, \
CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \
p.post_time, \
p.post_subject, \
p.post_subject as title, \
p.post_text as data, \
t.topic_last_post_time, \
0 as deleted \
FROM phpbb_posts p, phpbb_topics t \
WHERE \
p.topic_id = t.topic_id \
AND p.post_id >= \$start AND p.post_id <= \$end
sql_query_post =
sql_query_post_index = UPDATE phpbb_sphinx SET max_doc_id = \$maxid WHERE counter_id = 1
sql_attr_uint = forum_id
sql_attr_uint = topic_id
sql_attr_uint = poster_id
sql_attr_uint = post_visibility
sql_attr_bool = topic_first_post
sql_attr_bool = deleted
sql_attr_timestamp = post_time
sql_attr_timestamp = topic_last_post_time
sql_attr_string = post_subject
}
source source_phpbb_${ID}_delta : source_phpbb_${ID}_main
{
sql_query_pre = SET NAMES 'utf8'
sql_query_range =
sql_range_step =
sql_query = SELECT \
p.post_id AS id, \
p.forum_id, \
p.topic_id, \
p.poster_id, \
p.post_visibility, \
CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \
p.post_time, \
p.post_subject, \
p.post_subject as title, \
p.post_text as data, \
t.topic_last_post_time, \
0 as deleted \
FROM phpbb_posts p, phpbb_topics t \
WHERE \
p.topic_id = t.topic_id \
AND p.post_id >= ( SELECT max_doc_id FROM phpbb_sphinx WHERE counter_id=1 )
sql_query_post_index =
}
index index_phpbb_${ID}_main
{
path = $SPHINX_DATA_DIR/index_phpbb_${ID}_main
source = source_phpbb_${ID}_main
docinfo = extern
morphology = none
stopwords =
wordforms =
exceptions =
min_word_len = 2
charset_table = U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z, A..Z->a..z, a..z, U+0149, U+017F, U+0138, U+00DF, U+00FF, U+00C0..U+00D6->U+00E0..U+00F6, U+00E0..U+00F6, U+00D8..U+00DE->U+00F8..U+00FE, U+00F8..U+00FE, U+0100->U+0101, U+0101, U+0102->U+0103, U+0103, U+0104->U+0105, U+0105, U+0106->U+0107, U+0107, U+0108->U+0109, U+0109, U+010A->U+010B, U+010B, U+010C->U+010D, U+010D, U+010E->U+010F, U+010F, U+0110->U+0111, U+0111, U+0112->U+0113, U+0113, U+0114->U+0115, U+0115, U+0116->U+0117, U+0117, U+0118->U+0119, U+0119, U+011A->U+011B, U+011B, U+011C->U+011D, U+011D, U+011E->U+011F, U+011F, U+0130->U+0131, U+0131, U+0132->U+0133, U+0133, U+0134->U+0135, U+0135, U+0136->U+0137, U+0137, U+0139->U+013A, U+013A, U+013B->U+013C, U+013C, U+013D->U+013E, U+013E, U+013F->U+0140, U+0140, U+0141->U+0142, U+0142, U+0143->U+0144, U+0144, U+0145->U+0146, U+0146, U+0147->U+0148, U+0148, U+014A->U+014B, U+014B, U+014C->U+014D, U+014D, U+014E->U+014F, U+014F, U+0150->U+0151, U+0151, U+0152->U+0153, U+0153, U+0154->U+0155, U+0155, U+0156->U+0157, U+0157, U+0158->U+0159, U+0159, U+015A->U+015B, U+015B, U+015C->U+015D, U+015D, U+015E->U+015F, U+015F, U+0160->U+0161, U+0161, U+0162->U+0163, U+0163, U+0164->U+0165, U+0165, U+0166->U+0167, U+0167, U+0168->U+0169, U+0169, U+016A->U+016B, U+016B, U+016C->U+016D, U+016D, U+016E->U+016F, U+016F, U+0170->U+0171, U+0171, U+0172->U+0173, U+0173, U+0174->U+0175, U+0175, U+0176->U+0177, U+0177, U+0178->U+00FF, U+00FF, U+0179->U+017A, U+017A, U+017B->U+017C, U+017C, U+017D->U+017E, U+017E, U+0410..U+042F->U+0430..U+044F, U+0430..U+044F, U+4E00..U+9FFF
ignore_chars = U+0027, U+002C
min_prefix_len = 3
min_infix_len = 0
html_strip = 1
index_exact_words = 0
blend_chars = U+23, U+24, U+25, U+26, U+40
}
index index_phpbb_${ID}_delta : index_phpbb_${ID}_main
{
path = $SPHINX_DATA_DIR/index_phpbb_${ID}_delta
source = source_phpbb_${ID}_delta
}
indexer
{
mem_limit = 512M
}
searchd
{
listen = $SPHINX_DAEMON_PORT
log = $SPHINX_LOG
query_log = $SPHINX_QUERY_LOG
read_timeout = 5
max_children = 30
pid_file = $SPHINX_DATA_DIR/searchd.pid
binlog_path = $SPHINX_DATA_DIR
}
" > $SPHINX_CONF
sudo mv "$SPHINX_CONF" "/etc/sphinxsearch/sphinx.conf"
sudo sed -i "s/START=no/START=yes/g" "/etc/default/sphinxsearch"
sudo chmod 777 "/var/run/sphinxsearch"

View File

@@ -10,5 +10,4 @@
#
set -e
sudo apt-get update
sudo apt-get install -y expect-dev

View File

@@ -11,7 +11,6 @@
set -e
set -x
sudo apt-get update
sudo apt-get install -y nginx coreutils
sudo service nginx stop

View File

@@ -0,0 +1,70 @@
name: Check merge to master
on:
pull_request_target:
types: [ opened, synchronize, reopened ]
branches:
- 3.3.x
jobs:
merge-check:
if: github.event_name == 'pull_request_target' && github.event.pull_request.base.ref == '3.3.x'
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # Ensure full history is fetched
- name: Set up Git user
run: |
git config --global user.name "github-actions"
git config --global user.email "github-actions@github.com"
- name: Fetch all branches
run: git fetch origin
- name: Simulate merging PR into 3.3.x
id: simulate_merge
run: |
git checkout 3.3.x
git fetch origin pull/${{ github.event.pull_request.number }}/head
git merge --no-ff FETCH_HEAD || exit 1
- name: Attempt to merge updated 3.3.x into master
id: merge_master
run: |
git checkout master
if git merge --no-ff 3.3.x --no-commit; then
echo "mergeable=true" >> $GITHUB_OUTPUT
else
echo "mergeable=false" >> $GITHUB_OUTPUT
git merge --abort
fi
- name: Find Comment
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: The attempt to merge branch `3.3.x` into `master` has completed
- name: Post comment on PR
if: always() # Ensure this step always runs, regardless of merge result
uses: peter-evans/create-or-update-comment@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.fc.outputs.comment-id }}
edit-mode: replace
body: |
The attempt to merge branch `3.3.x` into `master` has completed after considering the changes in this PR.
- Merge result: ${{ steps.merge_master.outputs.mergeable == 'true' && 'Success ✅' || 'Conflict ❌' }}
${{ steps.merge_master.outputs.mergeable == 'true' && 'This PR is ready to be merged.' || 'A separate PR will be needed to merge `3.3.x` into `master`.' }}
- name: Mark job as succeeded
if: always()
run: echo "Merge check completed. Ignoring the result to avoid failed status."

View File

@@ -0,0 +1,60 @@
name: Merge 3.3.x into master
on:
push:
branches:
- 3.3.x
jobs:
merge-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.MERGE_MASTER_APP_ID }}
private-key: ${{ secrets.MERGE_MASTER_SECRET }}
- name: Checkout the repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for proper merging
ref: 3.3.x # Checkout the 3.3.x branch
token: ${{ steps.app-token.outputs.token }}
- name: Fetch the latest commit information
id: get-commit-info
run: |
# Get the latest commit SHA and its author details
COMMIT_SHA=$(git rev-parse HEAD)
COMMIT_AUTHOR_NAME=$(git log -1 --pretty=format:'%an' $COMMIT_SHA)
COMMIT_AUTHOR_EMAIL=$(git log -1 --pretty=format:'%ae' $COMMIT_SHA)
# Save them as output for later steps
echo "commit_sha=$COMMIT_SHA" >> $GITHUB_ENV
echo "commit_author_name=$COMMIT_AUTHOR_NAME" >> $GITHUB_ENV
echo "commit_author_email=$COMMIT_AUTHOR_EMAIL" >> $GITHUB_ENV
- name: Set up Git with the pull request author's info
run: |
git config --global user.name "${{ env.commit_author_name }}"
git config --global user.email "${{ env.commit_author_email }}"
- name: Fetch all branches
run: git fetch --all
- name: Merge 3.3.x into master
run: |
git checkout master
if git merge --no-ff 3.3.x; then
echo "merge_failed=false" >> $GITHUB_ENV
else
echo "merge_failed=true" >> $GITHUB_ENV
fi
- name: Push changes to master if merge was successful
if: env.merge_failed == 'false'
run: git push origin master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -28,6 +28,10 @@ jobs:
name: PHP ${{ matrix.php }} - ${{ matrix.db }}
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
with:
@@ -158,6 +162,10 @@ jobs:
- 6379:6379
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
@@ -211,6 +219,10 @@ jobs:
run: |
.github/setup-ldap.sh
- name: Setup SPHINX
run: |
.github/setup-sphinx.sh
- name: Lint tests
if: ${{ matrix.SLOWTESTS != 1 && steps.database-type.outputs.db == 'mysql' }}
run: phpBB/vendor/bin/phpunit tests/lint_test.php
@@ -295,6 +307,10 @@ jobs:
- 6379:6379
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
@@ -358,17 +374,17 @@ jobs:
- php: '7.2'
db: "sqlite3"
- php: '7.2'
db: "mcr.microsoft.com/mssql/server:2017-latest"
db_alias: 'MSSQL 2017'
- php: '7.2'
db: "mcr.microsoft.com/mssql/server:2019-latest"
db: "mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04"
db_alias: 'MSSQL 2019'
- php: '7.2'
db: "mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04"
db_alias: 'MSSQL 2022'
name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }}
services:
mssql:
image: ${{ matrix.db != 'mcr.microsoft.com/mssql/server:2017-latest' && matrix.db != 'mcr.microsoft.com/mssql/server:2019-latest' && 'mcr.microsoft.com/mssql/server:2017-latest' || matrix.db }}
image: ${{ matrix.db != 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' && matrix.db != 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' && 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' || matrix.db }}
env:
SA_PASSWORD: "Pssw0rd_12"
ACCEPT_EULA: "y"
@@ -393,6 +409,10 @@ jobs:
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
@@ -400,7 +420,7 @@ jobs:
env:
MATRIX_DB: ${{ matrix.db }}
run: |
if [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2017-latest' ] || [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2019-latest' ]
if [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' ] || [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' ]
then
db='mssql'
else

View File

@@ -42,8 +42,8 @@ We have unit and functional tests in order to prevent regressions. You can view
Branch | Description | GitHub Actions |
------- | ----------- | -------------- |
**master** | Latest development version | ![Tests](https://github.com/phpbb/phpbb/workflows/Tests/badge.svg?branch=master) |
**3.3.x** | Development of version 3.3.x | ![Tests](https://github.com/phpbb/phpbb/workflows/Tests/badge.svg?branch=3.3.x) |
**master** | Latest development version | ![Tests](https://github.com/phpbb/phpbb/actions/workflows/tests.yml/badge.svg?branch=master) |
**3.3.x** | Development of version 3.3.x | ![Tests](https://github.com/phpbb/phpbb/actions/workflows/tests.yml/badge.svg?branch=3.3.x) |
## 📜 License

13
SECURITY.md Normal file
View File

@@ -0,0 +1,13 @@
# Security Policy
## Reporting a Vulnerability
Please do not post potential security vulnerabilities publicly. Instead, report them to the phpBB team.
We take security very seriously and will respond to reports about potential security vulnerabilities as quickly as possible.
There are multiple ways a potential security vulnerability can be reported:
- HackerOne: [phpBB | Vulnerability Disclosure Program | HackerOne](https://hackerone.com/phpbb)
- Create a report in the security tracker: [Security Tracker](https://www.phpbb.com/security/)
- Send an email: [security@phpbb.com](mailto:security@phpbb.com)
Please provide as much detail as possible when reporting a vulnerability. You can expect to receive an update on your report within a few days. If the vulnerability is accepted, we will work on a fix and keep you informed of the progress. If the vulnerability is declined, we will provide an explanation.

View File

@@ -2,9 +2,9 @@
<project name="phpBB" description="The phpBB forum software" default="all" basedir="../">
<!-- a few settings for the build -->
<property name="newversion" value="3.3.13-RC1" />
<property name="prevversion" value="3.3.12" />
<property name="olderversions" value="3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.7, 3.2.8, 3.2.9, 3.2.10, 3.2.11, 3.3.0, 3.3.1, 3.3.2, 3.3.3, 3.3.4, 3.3.5, 3.3.6, 3.3.7, 3.3.8, 3.3.9, 3.3.10, 3.3.11" />
<property name="newversion" value="3.3.16-dev" />
<property name="prevversion" value="3.3.15" />
<property name="olderversions" value="3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.7, 3.2.8, 3.2.9, 3.2.10, 3.2.11, 3.3.0, 3.3.1, 3.3.2, 3.3.3, 3.3.4, 3.3.5, 3.3.6, 3.3.7, 3.3.8, 3.3.9, 3.3.10, 3.3.11, 3.3.12, 3.3.13, 3.3.14" />
<!-- no configuration should be needed beyond this point -->
<property name="oldversions" value="${olderversions}, ${prevversion}" />

View File

@@ -11,6 +11,8 @@
*
*/
namespace phpbb\Sniffs\Commenting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@@ -21,7 +23,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* @package code_sniffer
* @author Manuel Pichler <mapi@phpundercontrol.org>
*/
class phpbb_Sniffs_Commenting_FileCommentSniff implements Sniff
class FileCommentSniff implements Sniff
{
/**
* Returns an array of tokens this test wants to listen for.

View File

@@ -11,6 +11,8 @@
*
*/
namespace phpbb\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@@ -18,7 +20,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* Checks that the opening brace of a control structures is on the line after.
* From Generic_Sniffs_Functions_OpeningFunctionBraceBsdAllmanSniff
*/
class phpbb_Sniffs_ControlStructures_OpeningBraceBsdAllmanSniff implements Sniff
class OpeningBraceBsdAllmanSniff implements Sniff
{
/**
* Registers the tokens that this sniff wants to listen for.

View File

@@ -10,6 +10,7 @@
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@@ -18,7 +19,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* Checks that there is exactly one space between the keyword and the opening
* parenthesis of a control structures.
*/
class phpbb_Sniffs_ControlStructures_OpeningParenthesisSniff implements Sniff
class OpeningParenthesisSniff implements Sniff
{
/**
* Registers the tokens that this sniff wants to listen for.

View File

@@ -11,6 +11,8 @@
*
*/
namespace phpbb\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@@ -18,7 +20,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* Checks that the visibility qualifiers are placed after the static keyword
* according to the coding guidelines
*/
class phpbb_Sniffs_ControlStructures_StaticKeywordSniff implements Sniff
class StaticKeywordSniff implements Sniff
{
/**
* Registers the tokens that this sniff wants to listen for.

View File

@@ -11,13 +11,15 @@
*
*/
namespace phpbb\Sniffs\Namespaces;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Checks that each use statement is used.
*/
class phpbb_Sniffs_Namespaces_UnusedUseSniff implements Sniff
class UnusedUseSniff implements Sniff
{
const FIND = [
T_NS_SEPARATOR,

View File

@@ -17,9 +17,6 @@
<!-- There MUST not be more than one statement per line. -->
<rule ref="Generic.Formatting.DisallowMultipleStatements" />
<!-- Call-time pass-by-reference MUST not be used. -->
<rule ref="Generic.Functions.CallTimePassByReference.NotAllowed" />
<!-- Filenames MUST be lowercase. -->
<rule ref="Generic.Files.LowercasedFilename" />

View File

@@ -42,59 +42,52 @@
</tr>
</thead>
<tbody>
<!-- IF .enabled -->
<tr>
<td class="row3" colspan="4"><strong>{L_EXTENSIONS_ENABLED}</strong><!-- EVENT acp_ext_list_enabled_title_after --></td>
</tr>
<!-- BEGIN enabled -->
<tr class="ext_enabled row-highlight">
<td><strong title="{enabled.NAME}">{enabled.META_DISPLAY_NAME}</strong><!-- EVENT acp_ext_list_enabled_name_after --></td>
<td style="text-align: center;">
<!-- IF enabled.S_VERSIONCHECK -->
<strong class="<!-- IF enabled.S_UP_TO_DATE -->current-ext<!-- ELSE -->outdated-ext<!-- ENDIF -->">{enabled.META_VERSION}</strong>
<!-- IF not enabled.S_UP_TO_DATE --><i class="fa fa-exclamation-circle outdated-ext" aria-hidden="true"></i><!-- ENDIF -->
<!-- ELSE -->
{enabled.META_VERSION}
<!-- ENDIF -->
</td>
<td style="text-align: center;"><a href="{enabled.U_DETAILS}">{L_DETAILS}</a></td>
<td style="text-align: center;">
<!-- BEGIN actions -->
<a href="{enabled.actions.U_ACTION}"<!-- IF enabled.actions.L_ACTION_EXPLAIN --> title="{enabled.actions.L_ACTION_EXPLAIN}"<!-- ENDIF -->>{enabled.actions.L_ACTION}</a>
<!-- IF not enabled.actions.S_LAST_ROW -->&nbsp;|&nbsp;<!-- ENDIF -->
<!-- END actions -->
</td>
</tr>
<!-- END enabled -->
<!-- ENDIF -->
<!-- IF .disabled -->
<tr>
<td class="row3" colspan="4"><strong>{L_EXTENSIONS_DISABLED}</strong><!-- EVENT acp_ext_list_disabled_title_after --></td>
</tr>
<!-- BEGIN disabled -->
<tr class="ext_disabled row-highlight">
<td><strong title="{disabled.NAME}">{disabled.META_DISPLAY_NAME}</strong><!-- EVENT acp_ext_list_disabled_name_after --></td>
<td style="text-align: center;">
<!-- IF disabled.S_VERSIONCHECK -->
<strong class="<!-- IF disabled.S_UP_TO_DATE -->current-ext<!-- ELSE -->outdated-ext<!-- ENDIF -->">{disabled.META_VERSION}</strong>
<!-- IF not disabled.S_UP_TO_DATE --><i class="fa fa-exclamation-circle outdated-ext" aria-hidden="true"></i><!-- ENDIF -->
<!-- ELSE -->
{disabled.META_VERSION}
<!-- ENDIF -->
</td>
<td style="text-align: center;">
<!-- IF disabled.U_DETAILS --><a href="{disabled.U_DETAILS}">{L_DETAILS}</a><!-- ENDIF -->
</td>
<td style="text-align: center;">
<!-- BEGIN actions -->
<a href="{disabled.actions.U_ACTION}"<!-- IF disabled.actions.L_ACTION_EXPLAIN --> title="{disabled.actions.L_ACTION_EXPLAIN}"<!-- ENDIF -->>{disabled.actions.L_ACTION}</a>
<!-- IF not disabled.actions.S_LAST_ROW -->&nbsp;|&nbsp;<!-- ENDIF -->
<!-- END actions -->
</td>
</tr>
<!-- END disabled -->
<!-- ENDIF -->
{% for list in ['enabled', 'disabled', 'not_installed'] %}
{% set blockname = attribute(loops, list) %}
{% if blockname|length %}
<tr>
<td class="row3" colspan="4"><strong>{{ lang('EXTENSIONS_' ~ list|upper) }}</strong>
{% if list == 'enabled' %}
{% EVENT acp_ext_list_enabled_title_after %}
{% elseif list == 'disabled' %}
{% EVENT acp_ext_list_disabled_title_after %}
{% elseif list == 'not_installed' %}
{% EVENT acp_ext_list_not_installed_title_after %}
{% endif %}
</td>
</tr>
{% for data in blockname %}
<tr class="ext_{{ list }} row-highlight">
<td><strong title="{{ data.NAME }}">{{ data.META_DISPLAY_NAME }}</strong>
{% if list == 'enabled' %}
{% EVENT acp_ext_list_enabled_name_after %}
{% elseif list == 'disabled' %}
{% EVENT acp_ext_list_disabled_name_after %}
{% elseif list == 'not_installed' %}
{% EVENT acp_ext_list_not_installed_name_after %}
{% endif %}
</td>
<td style="text-align: center;">
{% if data.S_VERSIONCHECK %}
<strong class="{% if data.S_UP_TO_DATE %}current-ext{% else %}outdated-ext{% endif %}">{{ data.META_VERSION }}</strong>
{% if not data.S_UP_TO_DATE %}<i class="fa fa-exclamation-circle outdated-ext" aria-hidden="true"></i>{% endif %}
{% else %}
{{ data.META_VERSION }}
{% endif %}
</td>
<td style="text-align: center;">
{% if data.U_DETAILS %}<a href="{{ data.U_DETAILS }}">{{ lang ('DETAILS') }}</a>{% endif %}
</td>
<td style="text-align: center;">
{% for actions in data.actions %}
<a href="{{ actions.U_ACTION }}"{% if actions.L_ACTION_EXPLAIN %} title="{{ actions.L_ACTION_EXPLAIN }}"{% endif %}>{{ actions.L_ACTION }}</a>
{% if not actions.S_LAST_ROW %}&nbsp;|&nbsp;{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
{% endif %}
{% endfor %}
</tbody>
</table>

View File

@@ -44,7 +44,7 @@
<div id="posts"<!-- IF S_SPECIAL_RANK --> style="display: none;"<!-- ENDIF -->>
<dl>
<dt><label for="min_posts">{L_RANK_MINIMUM}{L_COLON}</label></dt>
<dd><input name="min_posts" type="number" id="min_posts" min="0" max="9999999999" value="{MIN_POSTS}" /></dd>
<dd><input name="min_posts" type="number" id="min_posts" min="0" max="16777215" value="{MIN_POSTS}" /></dd>
</dl>
</div>

View File

@@ -5,7 +5,7 @@
/**
* Parse document block
*/
function parse_document(container)
function parse_document(container)
{
var test = document.createElement('div'),
oldBrowser = (typeof test.style.borderRadius == 'undefined');
@@ -90,7 +90,7 @@ function parse_document(container)
}
});
}
headersLength = headers.length;
// Add header text to each cell as <dfn>
@@ -121,8 +121,8 @@ function parse_document(container)
}
if ((text.length && text !== '-') || cell.children().length) {
if (headers[column] != '') {
cell.prepend('<dfn style="display: none;">' + headers[column] + '</dfn>');
if (headers[column].length) {
cell.prepend($("<dfn>").css('display', 'none').text(headers[column]));
}
}
else {
@@ -143,7 +143,7 @@ function parse_document(container)
*/
container.find('table.responsive > tbody').each(function() {
var items = $(this).children('tr');
if (items.length == 0)
if (!items.length)
{
$(this).parent('table:first').addClass('responsive-hide');
}
@@ -157,7 +157,7 @@ function parse_document(container)
if ($this.html() == '&nbsp;') {
$this.addClass('responsive-hide');
}
});
/**
@@ -184,7 +184,7 @@ function parse_document(container)
var width = $body.width(),
height = $this.height();
if (arguments.length == 0 && (!responsive || width <= lastWidth) && height <= maxHeight) {
if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) {
return;
}

View File

@@ -235,14 +235,20 @@ function submitPermissions() {
if ($alertBoxLink) {
// Remove forum_id[] from URL
$alertBoxLink.attr('href', $alertBoxLink.attr('href').replace(/(&forum_id\[\]=[0-9]+)/g, ''));
var previousPageForm = '<form action="' + $alertBoxLink.attr('href') + '" method="post">';
$.each(forumIds, function (key, value) {
previousPageForm += '<input type="text" name="forum_id[]" value="' + value + '" />';
const $previousPageForm = $('<form>').attr({
action: $alertBoxLink.attr('href'),
method: 'post'
});
$.each(forumIds, function (key, value) {
$previousPageForm.append($('<input>').attr({
type: 'text',
name: 'forum_id[]',
value: value
}));
});
previousPageForm += '</form>';
$alertBoxLink.on('click', function (e) {
var $previousPageForm = $(previousPageForm);
$('body').append($previousPageForm);
e.preventDefault();
$previousPageForm.submit();
@@ -257,12 +263,19 @@ function submitPermissions() {
setTimeout(function () {
// Create forum to submit using POST. This will prevent
// exceeding the maximum length of URLs
var form = '<form action="' + res.REFRESH_DATA.url.replace(/(&forum_id\[\]=[0-9]+)/g, '') + '" method="post">';
$.each(forumIds, function (key, value) {
form += '<input type="text" name="forum_id[]" value="' + value + '" />';
const $form = $('<form>').attr({
action: res.REFRESH_DATA.url.replace(/(&forum_id\[\]=[0-9]+)/g, ''),
method: 'post'
});
form += '</form>';
$form = $(form);
$.each(forumIds, function (key, value) {
$form.append($('<input>').attr({
type: 'text',
name: 'forum_id[]',
value: value
}));
});
$('body').append($form);
// Hide the alert even if we refresh the page, in case the user

View File

@@ -19,7 +19,7 @@
<form method="post" action="#" id="language_selector">
<fieldset class="nobg">
<label for="language">{L_SELECT_LANG}{L_COLON}</label>
<select id="language" name="language">
<select id="language" name="language">
<!-- BEGIN language_select_item -->
<option value="{language_select_item.VALUE}"<!-- IF language_select_item.SELECTED --> selected="selected"<!-- ENDIF -->>{language_select_item.NAME}</option>
<!-- END language_select_item -->

16
phpBB/composer.lock generated
View File

@@ -4702,16 +4702,16 @@
},
{
"name": "squizlabs/php_codesniffer",
"version": "3.10.1",
"version": "3.13.0",
"source": {
"type": "git",
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
"reference": "8f90f7a53ce271935282967f53d0894f8f1ff877"
"reference": "65ff2489553b83b4597e89c3b8b721487011d186"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/8f90f7a53ce271935282967f53d0894f8f1ff877",
"reference": "8f90f7a53ce271935282967f53d0894f8f1ff877",
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/65ff2489553b83b4597e89c3b8b721487011d186",
"reference": "65ff2489553b83b4597e89c3b8b721487011d186",
"shasum": ""
},
"require": {
@@ -4776,9 +4776,13 @@
{
"url": "https://opencollective.com/php_codesniffer",
"type": "open_collective"
},
{
"url": "https://thanks.dev/u/gh/phpcsstandards",
"type": "thanks_dev"
}
],
"time": "2024-05-22T21:24:41+00:00"
"time": "2025-05-11T03:36:00+00:00"
},
{
"name": "symfony/browser-kit",
@@ -5106,5 +5110,5 @@
"platform-overrides": {
"php": "7.2"
},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.2.0"
}

View File

@@ -50,6 +50,11 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ul>
<li><a href="#v3315rc1">Changes since 3.3.15-RC1</a></li>
<li><a href="#v3314">Changes since 3.3.14</a></li>
<li><a href="#v3314rc1">Changes since 3.3.14-RC1</a></li>
<li><a href="#v3313">Changes since 3.3.13</a></li>
<li><a href="#v3313rc1">Changes since 3.3.13-RC1</a></li>
<li><a href="#v3312">Changes since 3.3.12</a></li>
<li><a href="#v3312rc1">Changes since 3.3.12-RC1</a></li>
<li><a href="#v3311">Changes since 3.3.11</a></li>
@@ -170,6 +175,84 @@
<div class="inner">
<div class="content">
<a name="v3315rc1"></a><h3>Changes since 3.3.15-RC1</h3>
<h4>Bug</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17480">PHPBB-17480</a>] - PHP fatal error in version check failure</li>
</ul>
<h4>Security Issue</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/SECURITY-283">SECURITY-283</a>] - Use jQuery to generate HTML from page data</li>
</ul>
<a name="v3314"></a><h3>Changes since 3.3.14</h3>
<h4>Bug</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17227">PHPBB-17227</a>] - Member list sorting bug - repeating users on several pages</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17381">PHPBB-17381</a>] - 'topic_views' column overflow blocks access to the topic</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17417">PHPBB-17417</a>] - Day selection not visible when no results</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17422">PHPBB-17422</a>] - Ascending posts pagination</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17436">PHPBB-17436</a>] - PHP fatal error while converting from phpBB 2.0 with Attachment MOD</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17455">PHPBB-17455</a>] - PHP warning on MySQLi connection failure</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17463">PHPBB-17463</a>] - Extra &amp; in unread posts search pagination </li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17468">PHPBB-17468</a>] - Reset password feature is not restricted to email</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17470">PHPBB-17470</a>] - Enable feeds setting not enforced</li>
</ul>
<h4>Improvement</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17429">PHPBB-17429</a>] - Adding event before users have been added to a group</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17431">PHPBB-17431</a>] - Add more vars to memberlist event</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17433">PHPBB-17433</a>] - Unclear instructions in ACP, Server settings</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17443">PHPBB-17443</a>] - Various Guzzle client issues for version checks</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17446">PHPBB-17446</a>] - Add acp_account_activation_edit_add event</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17461">PHPBB-17461</a>] - Add php events for ACP main actions</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17467">PHPBB-17467</a>] - Add TLS v.1.3 support to email messenger connection</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17471">PHPBB-17471</a>] - Forum feed link in forumlist_body does not return the correct URL</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17478">PHPBB-17478</a>] - Add security policy to repository</li>
</ul>
<a name="v3314rc1"></a><h3>Changes since 3.3.14-RC1</h3>
<h4>Improvement</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17421">PHPBB-17421</a>] - Rename section for not installed extensions to not installed</li>
</ul>
<a name="v3313"></a><h3>Changes since 3.3.13</h3>
<h4>Bug</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17181">PHPBB-17181</a>] - If statement to highlight Reported PMS on the view message page doesn't work.</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17383">PHPBB-17383</a>] - HELO/EHLO error while using gethostbyaddr()</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17384">PHPBB-17384</a>] - Passing E_USER_ERROR to trigger_error() is deprecated in PHP 8.4</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17385">PHPBB-17385</a>] - Version check without SSL flag for CDB extensions fails</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17386">PHPBB-17386</a>] - Incorrect trace result while tracing user-based permissions</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17387">PHPBB-17387</a>] - PHP warnings in search results</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17390">PHPBB-17390</a>] - Missing buttons for approval of new messages</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17391">PHPBB-17391</a>] - PHP warnings on attempt to create user group having name already in use</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17398">PHPBB-17398</a>] - Ajax error on deleting cookies</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17405">PHPBB-17405</a>] - Function phpbb_gmgetdate() returns incorrect result for edge cases</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17410">PHPBB-17410</a>] - UCP tabs do not work when testing out another user's permissions</li>
</ul>
<h4>Improvement</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-16852">PHPBB-16852</a>] - Addition of a new PHP event concerning bump topics</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17359">PHPBB-17359</a>] - Distinct disabled and not installed extensions in the list</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17376">PHPBB-17376</a>] - Link reference to quote post is a poor accessibility experience</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17382">PHPBB-17382</a>] - Incorrect grammar on FAQ page regarding searching for members</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17388">PHPBB-17388</a>] - Add php event to bump_topic_allowed function</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17394">PHPBB-17394</a>] - Check mergeability of PR on GitHub Actions</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17396">PHPBB-17396</a>] - Automatically handle merges of 3.3.x into master</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17397">PHPBB-17397</a>] - Add event for forum_data query in viewforum</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17402">PHPBB-17402</a>] - Add possibility to force reparsing BBCode via CLI</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17407">PHPBB-17407</a>] - Limit mergeability check to single comment</li>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17411">PHPBB-17411</a>] - Add core event to search.php</li>
</ul>
<a name="v3313rc1"></a><h3>Changes since 3.3.13-RC1</h3>
<h4>Bug</h4>
<ul>
<li>[<a href="https://tracker.phpbb.com/browse/PHPBB-17377">PHPBB-17377</a>] - MSSQL builds on GitHub actions broken</li>
</ul>
<a name="v3312"></a><h3>Changes since 3.3.12</h3>
<h4>Bug</h4>
<ul>

View File

@@ -94,6 +94,20 @@ acp_ext_list_enabled_title_after
* Since: 3.1.11-RC1
* Purpose: Add text after enabled extensions section title.
acp_ext_list_not_installed_name_after
===
* Location: adm/style/acp_ext_list.html
* Since: 3.3.14-RC1
* Changed: 3.3.14 Renamed from acp_ext_list_available_name_after
* Purpose: Add content after the name of not installed extensions in the list
acp_ext_list_not_installed_title_after
===
* Location: adm/style/acp_ext_list.html
* Since: 3.3.14-RC1
* Changed: 3.3.14 Renamed from acp_ext_list_available_title_after
* Purpose: Add text after not installed extensions section title.
acp_forums_custom_settings
===
* Location: adm/style/acp_forums.html
@@ -2792,6 +2806,13 @@ ucp_pm_viewmessage_custom_fields_before
* Purpose: Add data before the custom fields on the user profile when viewing
a private message
ucp_pm_viewmessage_message_content_before
===
* Locations:
+ styles/prosilver/template/ucp_pm_viewmessage.html
* Since: 3.3.16-RC1
* Purpose: Add content before the private message text
ucp_pm_viewmessage_options_before
===
* Locations:

View File

@@ -1077,7 +1077,7 @@ class acp_attachments
$attachments_per_page = (int) $config['topics_per_page'];
// Get total number or orphans older than 3 hours
$sql = 'SELECT COUNT(attach_id) as num_files, SUM(filesize) as total_size
$sql = 'SELECT COUNT(attach_id) as num_files, SUM(' . $this->db->cast_expr_to_bigint('filesize') . ') as total_size
FROM ' . ATTACHMENTS_TABLE . '
WHERE is_orphan = 1
AND filetime < ' . (time() - 3*60*60);

View File

@@ -386,7 +386,7 @@ class acp_board
'vars' => array(
'legend1' => 'ACP_SERVER_SETTINGS',
'gzip_compress' => array('lang' => 'ENABLE_GZIP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'use_system_cron' => array('lang' => 'USE_SYSTEM_CRON', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'use_system_cron' => array('lang' => 'USE_SYSTEM_CRON', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
'legend2' => 'PATH_SETTINGS',
'enable_mod_rewrite' => array('lang' => 'MOD_REWRITE_ENABLE', 'validate' => 'bool', 'type' => 'custom', 'method' => 'enable_mod_rewrite', 'explain' => true),
@@ -921,7 +921,7 @@ class acp_board
*/
function select_acc_activation($selected_value, $value)
{
global $user, $config;
global $user, $config, $phpbb_dispatcher;
$act_ary = array(
'ACC_DISABLE' => array(true, USER_ACTIVATION_DISABLE),
@@ -931,6 +931,18 @@ class acp_board
);
$act_options = '';
/**
* Event to add and/or modify account activation configurations
*
* @event core.acp_account_activation_edit_add
* @var array act_ary Array of account activation methods
* @var string act_options Options available in the activation method
* @since 3.3.15-RC1
*/
$vars = ['act_ary', 'act_options'];
extract($phpbb_dispatcher->trigger_event('core.acp_account_activation_edit_add', compact($vars)));
foreach ($act_ary as $key => $data)
{
list($available, $value) = $data;

View File

@@ -12,6 +12,7 @@
*/
use phpbb\exception\exception_interface;
use phpbb\exception\runtime_exception;
use phpbb\exception\version_check_exception;
/**
@@ -344,7 +345,7 @@ class acp_extensions
$this->template->assign_block_vars('updates_available', $updates_available);
}
catch (exception_interface $e)
catch (runtime_exception $e)
{
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
@@ -423,7 +424,7 @@ class acp_extensions
$enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
$enabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name'));
}
catch (exception_interface $e)
catch (runtime_exception $e)
{
// Ignore exceptions due to the version check
}
@@ -433,7 +434,7 @@ class acp_extensions
$enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
}
}
catch (exception_interface $e)
catch (runtime_exception $e)
{
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
$this->template->assign_block_vars('disabled', array(
@@ -501,7 +502,7 @@ class acp_extensions
{
$disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
}
catch (exception_interface $e)
catch (runtime_exception $e)
{
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
$this->template->assign_block_vars('disabled', array(
@@ -572,10 +573,10 @@ class acp_extensions
{
$available_extension_meta_data[$name]['S_VERSIONCHECK'] = false;
}
catch (exception_interface $e)
catch (runtime_exception $e)
{
$message = call_user_func_array(array($this->user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
$this->template->assign_block_vars('disabled', array(
$this->template->assign_block_vars('not_installed', array(
'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $message),
'S_VERSIONCHECK' => false,
));
@@ -589,9 +590,9 @@ class acp_extensions
$block_vars['NAME'] = $name;
$block_vars['U_DETAILS'] = $this->u_action . '&amp;action=details&amp;ext_name=' . urlencode($name);
$this->template->assign_block_vars('disabled', $block_vars);
$this->template->assign_block_vars('not_installed', $block_vars);
$this->output_actions('disabled', array(
$this->output_actions('not_installed', array(
'ENABLE' => $this->u_action . '&amp;action=enable_pre&amp;ext_name=' . urlencode($name),
));
}

View File

@@ -2071,7 +2071,7 @@ class acp_forums
$config->set('num_files', (int) $row['stat'], false);
$sql = 'SELECT SUM(filesize) as stat
$sql = 'SELECT SUM(' . $db->cast_expr_to_bigint('filesize') . ') as stat
FROM ' . ATTACHMENTS_TABLE;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);

View File

@@ -396,7 +396,7 @@ class acp_groups
$allow_desc_urls = $request->variable('desc_parse_urls', false);
$allow_desc_smilies = $request->variable('desc_parse_smilies', false);
$submit_ary = array(
$submit_ary = [
'colour' => $request->variable('group_colour', ''),
'rank' => $request->variable('group_rank', 0),
'receive_pm' => isset($_REQUEST['group_receive_pm']) ? 1 : 0,
@@ -406,7 +406,13 @@ class acp_groups
'max_recipients' => $request->variable('group_max_recipients', 0),
'founder_manage' => 0,
'skip_auth' => $request->variable('group_skip_auth', 0),
);
// Initialize avatar data
'avatar' => $avatar_data['avatar'] ?? '',
'avatar_type' => $avatar_data['avatar_type'] ?? '',
'avatar_height' => $avatar_data['avatar_height'] ?? 0,
'avatar_width' => $avatar_data['avatar_width'] ?? 0,
];
if ($user->data['user_type'] == USER_FOUNDER)
{

View File

@@ -100,6 +100,20 @@ class acp_main
default:
$confirm = true;
$confirm_lang = 'CONFIRM_OPERATION';
/**
* Event to add confirm box for custom ACP quick actions
*
* @event core.acp_main_add_actions_confirm
* @var string id The module ID
* @var string mode The module mode
* @var string action Custom action type name
* @var boolean confirm Do we display the confirm box to run the custom action
* @var string confirm_lang Lang var name to display in confirm box
* @since 3.3.15-RC1
*/
$vars = ['id', 'mode', 'action', 'confirm', 'confirm_lang'];
extract($phpbb_dispatcher->trigger_event('core.acp_main_add_actions_confirm', compact($vars)));
}
if ($confirm)
@@ -168,7 +182,7 @@ class acp_main
$config->set('num_files', (int) $db->sql_fetchfield('stat'), false);
$db->sql_freeresult($result);
$sql = 'SELECT SUM(filesize) as stat
$sql = 'SELECT SUM(' . $db->cast_expr_to_bigint('filesize') . ') as stat
FROM ' . ATTACHMENTS_TABLE . '
WHERE is_orphan = 0';
$result = $db->sql_query($sql);
@@ -423,6 +437,19 @@ class acp_main
trigger_error('PURGE_SESSIONS_SUCCESS');
}
break;
default:
/**
* Event to add custom ACP quick actions
*
* @event core.acp_main_add_actions
* @var string id The module ID
* @var string mode The module mode
* @var string action Custom action type name
* @since 3.3.15-RC1
*/
$vars = ['id', 'mode', 'action'];
extract($phpbb_dispatcher->trigger_event('core.acp_main_add_actions', compact($vars)));
}
}
}
@@ -458,7 +485,7 @@ class acp_main
'UPGRADE_INSTRUCTIONS' => !empty($upgrades_available) ? $user->lang('UPGRADE_INSTRUCTIONS', $upgrades_available['current'], $upgrades_available['announcement']) : false,
));
}
catch (\RuntimeException $e)
catch (\phpbb\exception\runtime_exception $e)
{
$message = call_user_func_array(array($user, 'lang'), array_merge(array($e->getMessage()), $e->get_parameters()));
$template->assign_vars(array(

View File

@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
@define('PHPBB_VERSION', '3.3.13-RC1');
@define('PHPBB_VERSION', '3.3.16-dev');
// QA-related
// define('PHPBB_QA', 1);

View File

@@ -107,9 +107,17 @@ function phpbb_gmgetdate($time = false)
}
// getdate() interprets timestamps in local time.
// What follows uses the fact that getdate() and
// date('Z') balance each other out.
return getdate($time - date('Z'));
// So use UTC timezone temporarily to get UTC date info array.
$current_timezone = date_default_timezone_get();
// Set UTC timezone and get respective date info
date_default_timezone_set('UTC');
$date_info = getdate($time);
// Restore timezone back
date_default_timezone_set($current_timezone);
return $date_info;
}
/**

View File

@@ -289,7 +289,27 @@ function make_jumpbox($action, $forum_id = false, $select_all = false, $acl_list
*/
function bump_topic_allowed($forum_id, $topic_bumped, $last_post_time, $topic_poster, $last_topic_poster)
{
global $config, $auth, $user;
global $config, $auth, $user, $phpbb_dispatcher;
/**
* Event to run code before the topic bump checks
*
* @event core.bump_topic_allowed_before
* @var int forum_id ID of the forum
* @var int topic_bumped Flag indicating if the topic was already bumped (0/1)
* @var int last_post_time The time of the topic last post
* @var int topic_poster User ID of the topic author
* @var int last_topic_poster User ID of the topic last post author
* @since 3.3.14-RC1
*/
$vars = [
'forum_id',
'topic_bumped',
'last_post_time',
'topic_poster',
'last_topic_poster',
];
extract($phpbb_dispatcher->trigger_event('core.bump_topic_allowed_before', compact($vars)));
// Check permission and make sure the last post was not already bumped
if (!$auth->acl_get('f_bump', $forum_id) || $topic_bumped)
@@ -312,6 +332,28 @@ function bump_topic_allowed($forum_id, $topic_bumped, $last_post_time, $topic_po
return false;
}
/**
* Event to run code after the topic bump checks
*
* @event core.bump_topic_allowed_after
* @var int forum_id ID of the forum
* @var int topic_bumped Flag indicating if the topic was already bumped (0/1)
* @var int last_post_time The time of the topic last post
* @var int topic_poster User ID of the topic author
* @var int last_topic_poster User ID of the topic last post author
* @var int bump_time Bump time range
* @since 3.3.14-RC1
*/
$vars = [
'forum_id',
'topic_bumped',
'last_post_time',
'topic_poster',
'last_topic_poster',
'bump_time',
];
extract($phpbb_dispatcher->trigger_event('core.bump_topic_allowed_after', compact($vars)));
// A bump time of 0 will completely disable the bump feature... not intended but might be useful.
return $bump_time;
}
@@ -329,14 +371,14 @@ function get_context(string $text, array $words, int $length = 400): string
{
if ($length <= 0)
{
return '...';
return $text;
}
// we need to turn the entities back into their original form, to not cut the message in between them
$text = html_entity_decode($text);
// We need to turn the entities back into their original form, to not cut the message in between them
$text = htmlspecialchars_decode($text);
// Replace all spaces/invisible characters with single spaces
$text = preg_replace("/\s+/u", ' ', $text);
$text = preg_replace("/[\p{Z}\h\v]+/u", ' ', $text);
$text_length = utf8_strlen($text);
@@ -351,7 +393,6 @@ function get_context(string $text, array $words, int $length = 400): string
$word_indexes[$pos] = $word;
}
}
if (!empty($word_indexes))
{
ksort($word_indexes);
@@ -400,23 +441,21 @@ function get_context(string $text, array $words, int $length = 400): string
$fragment_end = $end - $start + 1;
// Find the first valid alphanumeric character in the fragment to don't cut words
if ($start > 0)
if ($start > 0 && preg_match('/[^\p{L}\p{N}][\p{L}\p{N}]/u', $fragment, $matches, PREG_OFFSET_CAPTURE))
{
preg_match('/[^a-zA-Z0-9][a-zA-Z0-9]/u', $fragment, $matches, PREG_OFFSET_CAPTURE);
$fragment_start = (int) $matches[0][1] + 1; // first valid alphanumeric character
$fragment_start = utf8_strlen(substr($fragment, 0, (int) $matches[0][1])) + 1;
}
// Find the last valid alphanumeric character in the fragment to don't cut words
if ($end < $text_length - 1)
if ($end < $text_length - 1 && preg_match_all('/[\p{L}\p{N}][^\p{L}\p{N}]/u', $fragment, $matches, PREG_OFFSET_CAPTURE))
{
preg_match_all('/[a-zA-Z0-9][^a-zA-Z0-9]/u', $fragment, $matches, PREG_OFFSET_CAPTURE);
$fragment_end = end($matches[0])[1]; // last valid alphanumeric character
$fragment_end = utf8_strlen(substr($fragment, 0, end($matches[0])[1]));
}
$output[] = utf8_substr($fragment, $fragment_start, $fragment_end - $fragment_start + 1);
}
return ($fragments[0][0] !== 0 ? '... ' : '') . htmlentities(implode(' ... ', $output)) . ($end < $text_length - 1 ? ' ...' : '');
return ($fragments[0][0] !== 0 ? '... ' : '') . utf8_htmlspecialchars(implode(' ... ', $output)) . ($end < $text_length - 1 ? ' ...' : '');
}
/**

View File

@@ -1998,7 +1998,7 @@ function update_dynamic_config()
$config->set('num_files', (int) $db->sql_fetchfield('stat'), false);
$db->sql_freeresult($result);
$sql = 'SELECT SUM(filesize) as stat
$sql = 'SELECT SUM(' . $db->cast_expr_to_bigint('filesize') . ') as stat
FROM ' . ATTACHMENTS_TABLE . '
WHERE is_orphan = 0';
$result = $db->sql_query($sql);

View File

@@ -1418,22 +1418,22 @@ class smtp_class
global $user;
// Here we try to determine the *real* hostname (reverse DNS entry preferrably)
$local_host = $user->host;
if (function_exists('php_uname'))
if (function_exists('php_uname') && !empty($local_host = php_uname('n')))
{
$local_host = php_uname('n');
// Able to resolve name to IP
if (($addr = @gethostbyname($local_host)) !== $local_host)
{
// Able to resolve IP back to name
if (($name = @gethostbyaddr($addr)) !== $addr)
if (!empty($name = @gethostbyaddr($addr)) && $name !== $addr)
{
$local_host = $name;
}
}
}
else
{
$local_host = $user->host;
}
// If we are authenticating through pop-before-smtp, we
// have to login ones before we get authenticated
@@ -1615,12 +1615,10 @@ class smtp_class
$result = false;
$stream_meta = stream_get_meta_data($this->socket);
if (socket_set_blocking($this->socket, 1))
if (stream_set_blocking($this->socket, 1))
{
// https://secure.php.net/manual/en/function.stream-socket-enable-crypto.php#119122
$crypto = (phpbb_version_compare(PHP_VERSION, '5.6.7', '<')) ? STREAM_CRYPTO_METHOD_TLS_CLIENT : STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
$result = stream_socket_enable_crypto($this->socket, true, $crypto);
socket_set_blocking($this->socket, (int) $stream_meta['blocked']);
$result = stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
stream_set_blocking($this->socket, (int) $stream_meta['blocked']);
}
return $result;

View File

@@ -502,8 +502,8 @@ class p_master
$id = $this->p_class . '_' . $id;
}
// Fallback to acp main page for special restore permission mode
if ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm'))
// Fallback to acp main page for special test permission mode
if ($this->p_class === 'acp' && $user->data['user_perm_from'] && $auth->acl_get('a_switchperm'))
{
$id = '';
$mode = '';

View File

@@ -2759,6 +2759,28 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false,
return 'GROUP_USERS_EXIST';
}
/**
* Event before users are added to a group
*
* @event core.group_add_user_before
* @var int group_id ID of the group to which users are added
* @var string group_name Name of the group
* @var array user_id_ary IDs of the users to be added
* @var array username_ary Names of the users to be added
* @var int pending Pending setting, 1 if user(s) added are pending
* @var array add_id_ary IDs of the users to be added who are not members yet
* @since 3.3.15-RC1
*/
$vars = array(
'group_id',
'group_name',
'user_id_ary',
'username_ary',
'pending',
'add_id_ary',
);
extract($phpbb_dispatcher->trigger_event('core.group_add_user_before', compact($vars)));
$db->sql_transaction('begin');
// Insert the new users

View File

@@ -284,6 +284,7 @@ class mcp_queue
$post_data = array(
'S_MCP_QUEUE' => true,
'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;p=$post_id"),
'S_CAN_APPROVE' => $auth->acl_get('m_approve', $post_info['forum_id']),
'S_CAN_DELETE_POST' => $auth->acl_get('m_delete', $post_info['forum_id']),
'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']),
'S_POST_REPORTED' => $post_info['post_reported'],

View File

@@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
$convertor_data = array(
'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.3',
'phpbb_version' => '3.3.13',
'phpbb_version' => '3.3.15',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,

View File

@@ -1418,9 +1418,9 @@ function phpbb_attachment_extension_group_name()
$result = $db->sql_query($sql);
$extension_groups_updated = array();
while ($lang_dir = $db->sql_fetchfield('lang_dir'))
while ($row = $db->sql_fetchrow($result))
{
$lang_dir = basename($lang_dir);
$lang_dir = basename($row['lang_dir']);
$lang_file = $phpbb_root_path . 'language/' . $lang_dir . '/acp/attachments.' . $phpEx;
if (!file_exists($lang_file))

View File

@@ -23,7 +23,7 @@ if (php_sapi_name() !== 'cli')
define('IN_PHPBB', true);
define('IN_INSTALL', true);
define('PHPBB_ENVIRONMENT', 'production');
define('PHPBB_VERSION', '3.3.13-RC1');
define('PHPBB_VERSION', '3.3.15');
$phpbb_root_path = __DIR__ . '/../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);

View File

@@ -316,7 +316,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('update_hashes_lock
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.13-RC1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.16-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');

View File

@@ -493,8 +493,8 @@ $lang = array_merge($lang, array(
'SMILIES_PATH_EXPLAIN' => 'Path under your phpBB root directory, e.g. <samp>images/smilies</samp>.',
'UPLOAD_ICONS_PATH' => 'Extension group icons storage path',
'UPLOAD_ICONS_PATH_EXPLAIN' => 'Path under your phpBB root directory, e.g. <samp>images/upload_icons</samp>.',
'USE_SYSTEM_CRON' => 'Run periodic tasks from system cron',
'USE_SYSTEM_CRON_EXPLAIN' => 'When off, phpBB will arrange for periodic tasks to be run automatically. When on, phpBB will not schedule any periodic tasks by itself; a system administrator must arrange for <code>bin/phpbbcli.php cron:run</code> to be run by the system cron facility at regular intervals (e.g. every 5 minutes).',
'USE_SYSTEM_CRON' => 'Run periodic tasks from operating system cron',
'USE_SYSTEM_CRON_EXPLAIN' => 'When disabled, phpBB will arrange for periodic tasks to be run automatically. When enabled, phpBB will not schedule any periodic tasks by itself; a system administrator must arrange for <code>bin/phpbbcli.php cron:run</code> to be run by the operating system cron facility at regular intervals (e.g. every 5 minutes).',
));
// Security Settings

View File

@@ -47,8 +47,9 @@ $lang = array_merge($lang, array(
'DETAILS' => 'Details',
'EXTENSIONS_DISABLED' => 'Disabled Extensions',
'EXTENSIONS_ENABLED' => 'Enabled Extensions',
'EXTENSIONS_NOT_INSTALLED' => 'Not installed Extensions',
'EXTENSIONS_DISABLED' => 'Disabled Extensions',
'EXTENSIONS_ENABLED' => 'Enabled Extensions',
'EXTENSION_DELETE_DATA' => 'Delete data',
'EXTENSION_DISABLE' => 'Disable',

View File

@@ -75,6 +75,7 @@ $lang = array_merge($lang, array(
'CLI_DESCRIPTION_REPARSER_REPARSE' => 'Reparses stored text with the current text_formatter services.',
'CLI_DESCRIPTION_REPARSER_REPARSE_ARG_1' => 'Type of text to reparse. Leave blank to reparse everything.',
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_DRY_RUN' => 'Do not save any changes; just print what would happen',
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_FORCE_BBCODE' => 'Re-parse all BBCodes without exception. Note that any previously disabled BBCodes will be reprocessed, enabled, and fully rendered.',
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RANGE_MIN' => 'Lowest record ID to process',
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RANGE_MAX' => 'Highest record ID to process',
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RANGE_SIZE' => 'Approximate number of records to process at a time',

View File

@@ -357,6 +357,7 @@ $lang = array_merge($lang, array(
'HIDE_ME' => 'Hide my online status this session',
'HOURS' => 'Hours',
'HOME' => 'Home',
'HTTP_HANDLER_NOT_FOUND' => 'The operation could not be completed because the cURL PHP extension and allow_url_fopen PHP ini setting have been disabled and no other HTTP handler could be found.',
'ICQ' => 'ICQ',
'IF' => 'If',

View File

@@ -158,7 +158,7 @@ $lang = array_merge($lang, array(
'HELP_FAQ_SEARCH_BLANK_QUESTION' => 'Why does my search return a blank page!?',
'HELP_FAQ_SEARCH_FORUM_ANSWER' => 'Enter a search term in the search box located on the index, forum or topic pages. Advanced search can be accessed by clicking the “Advance Search” link which is available on all pages on the forum. How to access the search may depend on the style used.',
'HELP_FAQ_SEARCH_FORUM_QUESTION' => 'How can I search a forum or forums?',
'HELP_FAQ_SEARCH_MEMBERS_ANSWER' => 'Visit to the “Members” page and click the “Find a member” link.',
'HELP_FAQ_SEARCH_MEMBERS_ANSWER' => 'Visit the memberlist and click the “Find a member” link.',
'HELP_FAQ_SEARCH_MEMBERS_QUESTION' => 'How do I search for members?',
'HELP_FAQ_SEARCH_NO_RESULT_ANSWER' => 'Your search was probably too vague and included many common terms which are not indexed by phpBB. Be more specific and use the options available within Advanced search.',
'HELP_FAQ_SEARCH_NO_RESULT_QUESTION' => 'Why does my search return no results?',

View File

@@ -42,7 +42,7 @@ $lang = array_merge($lang, array(
<br><br>
Our forums are powered by phpBB (hereinafter “they”, “them”, “their”, “phpBB software”, “www.phpbb.com”, “phpBB Limited”, “phpBB Teams”) which is a bulletin board solution released under the “<a href="http://opensource.org/licenses/gpl-2.0.php">GNU General Public License v2</a>” (hereinafter “GPL”) and can be downloaded from <a href="https://www.phpbb.com/">www.phpbb.com</a>. The phpBB software only facilitates internet based discussions; phpBB Limited is not responsible for what we allow and/or disallow as permissible content and/or conduct. For further information about phpBB, please see: <a href="https://www.phpbb.com/">https://www.phpbb.com/</a>.
<br><br>
You agree not to post any abusive, obscene, vulgar, slanderous, hateful, threatening, sexually-orientated or any other material that may violate any laws be it of your country, the country where “%1$s” is hosted or International Law. Doing so may lead to you being immediately and permanently banned, with notification of your Internet Service Provider if deemed required by us. The IP address of all posts are recorded to aid in enforcing these conditions. You agree that “%1$s” have the right to remove, edit, move or close any topic at any time should we see fit. As a user you agree to any information you have entered to being stored in a database. While this information will not be disclosed to any third party without your consent, neither “%1$s” nor phpBB shall be held responsible for any hacking attempt that may lead to the data being compromised.
You agree not to post any abusive, obscene, vulgar, libellous, hateful, threatening, sexually-orientated or any other material that may violate any laws be it of your country, the country where “%1$s” is hosted or International Law. Doing so may lead to you being immediately and permanently banned, with notification of your Internet Service Provider if deemed required by us. The IP address of all posts are recorded to aid in enforcing these conditions. You agree that “%1$s” have the right to remove, edit, move or close any topic at any time should we see fit. As a user you agree to any information you have entered to being stored in a database. While this information will not be disclosed to any third party without your consent, neither “%1$s” nor phpBB shall be held responsible for any hacking attempt that may lead to the data being compromised.
',
'PRIVACY_POLICY' => 'This policy explains in detail how “%1$s” along with its affiliated companies (hereinafter “we”, “us”, “our”, “%1$s”, “%2$s”) and phpBB (hereinafter “they”, “them”, “their”, “phpBB software”, “www.phpbb.com”, “phpBB Limited”, “phpBB Teams”) use any information collected during any session of usage by you (hereinafter “your information”).

View File

@@ -112,6 +112,7 @@ $lang = array_merge($lang, array(
'VIEW_INFO' => 'Post details',
'VIEW_NEXT_TOPIC' => 'Next topic',
'VIEW_PREVIOUS_TOPIC' => 'Previous topic',
'VIEW_QUOTED_POST' => 'View quoted post',
'VIEW_RESULTS' => 'View results',
'VIEW_TOPIC_POSTS' => array(
1 => '%d post',

View File

@@ -816,11 +816,26 @@ switch ($mode)
* Modify user's template vars before we display the profile
*
* @event core.memberlist_modify_view_profile_template_vars
* @var array template_ary Array with user's template vars
* @var array template_ary Array with user's template vars
* @var int user_id The user ID
* @var bool user_notes_enabled Is the mcp user notes module enabled?
* @var bool warn_user_enabled Is the mcp warnings module enabled?
* @var bool friends_enabled Is the ucp friends module enabled?
* @var bool foes_enabled Is the ucp foes module enabled?
* @var bool friend Is the user friend?
* @var bool foe Is the user foe?
* @since 3.2.6-RC1
* @changed 3.3.15-RC1 Added vars user_id, user_notes_enabled, warn_user_enabled, friend, friends_enabled, foe, foes_enabled
*/
$vars = array(
'template_ary',
'user_id',
'user_notes_enabled',
'warn_user_enabled',
'friend',
'friends_enabled',
'foe',
'foes_enabled',
);
extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_view_profile_template_vars', compact($vars)));
@@ -1375,10 +1390,10 @@ switch ($mode)
$order_by .= $sort_key_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC');
// Unfortunately we must do this here for sorting by rank, else the sort order is applied wrongly
if ($sort_key == 'm')
// For sorting by non-unique columns (rank, posts) add unique sort key to avoid duplicated rows in results
if ($sort_key == 'm' || $sort_key == 'd')
{
$order_by .= ', u.user_posts DESC';
$order_by .= ', u.user_id ASC';
}
/**
@@ -1797,6 +1812,18 @@ switch ($mode)
$memberrow = array_merge($memberrow, $cp_row['row']);
}
/**
* Modify the memberrow data before template variables are assigned.
*
* @event core.memberlist_modify_memberrow
* @var int user_id The current user ID.
* @var array row Array of raw user data.
* @var array memberrow Array of member template variables.
* @since 3.3.16-RC1
*/
$vars = ['user_id', 'row', 'memberrow'];
extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_memberrow', compact($vars)));
$template->assign_block_vars('memberrow', $memberrow);
if (isset($cp_row['blockrow']) && count($cp_row['blockrow']))

View File

@@ -776,7 +776,7 @@ class auth
$sql_group = ($group_id !== false) ? ((!is_array($group_id)) ? 'group_id = ' . (int) $group_id : $db->sql_in_set('group_id', array_map('intval', $group_id))) : '';
$sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? 'AND a.forum_id = ' . (int) $forum_id : 'AND ' . $db->sql_in_set('a.forum_id', array_map('intval', $forum_id))) : '';
$sql_is_local = $forum_id !== false ? 'AND ao.is_local <> 0' : '';
$sql_is_local = !empty($forum_id) ? 'AND ao.is_local <> 0' : '';
$sql_opts = '';
$hold_ary = $sql_ary = array();

View File

@@ -92,6 +92,12 @@ class reparse extends \phpbb\console\command\command
InputOption::VALUE_NONE,
$this->user->lang('CLI_DESCRIPTION_REPARSER_REPARSE_OPT_DRY_RUN')
)
->addOption(
'force-bbcode-reparsing',
null,
InputOption::VALUE_NONE,
$this->user->lang('CLI_DESCRIPTION_REPARSER_REPARSE_OPT_FORCE_BBCODE')
)
->addOption(
'resume',
null,
@@ -222,13 +228,15 @@ class reparse extends \phpbb\console\command\command
// Start from $max and decrement $current by $size until we reach $min
$current = $max;
$force_bbcode_reparsing = (bool) $this->get_option('force-bbcode-reparsing');
while ($current >= $min)
{
$start = max($min, $current + 1 - $size);
$end = max($min, $current);
$progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', $reparser->get_name(), $start, $end));
$reparser->reparse_range($start, $end);
$reparser->reparse_range($start, $end, $force_bbcode_reparsing);
$current = $start - 1;
$progress->setProgress($max + 1 - $start);

View File

@@ -59,14 +59,17 @@ class mysqli extends \phpbb\db\driver\mysql_base
}
}
$this->db_connect_id = mysqli_init();
if (!@mysqli_real_connect($this->db_connect_id, $this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket, MYSQLI_CLIENT_FOUND_ROWS))
if (!$this->db_connect_id = mysqli_init())
{
$this->db_connect_id = '';
$this->connect_error = 'Failed to initialize MySQLi object.';
}
else if (!@mysqli_real_connect($this->db_connect_id, $this->server, $this->user, $sqlpassword, $this->dbname, $port, $socket, MYSQLI_CLIENT_FOUND_ROWS))
{
$this->connect_error = 'Failed to establish a connection to the MySQL database engine. Please ensure MySQL server is running and the database configuration parameters are correct.';
}
if ($this->db_connect_id && $this->dbname != '')
if (!$this->connect_error && $this->db_connect_id && $this->dbname != '')
{
// Disable loading local files on client side
@mysqli_options($this->db_connect_id, MYSQLI_OPT_LOCAL_INFILE, false);
@@ -357,15 +360,8 @@ class mysqli extends \phpbb\db\driver\mysql_base
if ($this->db_connect_id)
{
$error = [
'message' => $this->db_connect_id->error,
'code' => $this->db_connect_id->errno,
];
}
else if (function_exists('mysqli_connect_error'))
{
$error = [
'message' => $this->db_connect_id->connect_error,
'code' => $this->db_connect_id->connect_errno,
'message' => $this->db_connect_id->connect_error ?: $this->db_connect_id->error,
'code' => $this->db_connect_id->connect_errno ?: $this->db_connect_id->errno,
];
}
else

View File

@@ -17,7 +17,10 @@ class bot_update extends \phpbb\db\migration\migration
{
static public function depends_on()
{
return array('\phpbb\db\migration\data\v310\rc6');
return array(
'\phpbb\db\migration\data\v310\rc6',
'\phpbb\db\migration\data\v310\avatars',
);
}
public function update_data()

View File

@@ -0,0 +1,47 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\db\migration\data\v33x;
class topic_views_update extends \phpbb\db\migration\migration
{
public static function depends_on()
{
return [
'\phpbb\db\migration\data\v33x\v3314',
];
}
public function update_schema(): array
{
// This extends the topic view count field so we can support much larger values.
return [
'change_columns' => [
$this->table_prefix . 'topics' => [
'topic_views' => ['ULINT', 0],
],
]
];
}
public function revert_schema(): array
{
return [
'change_columns' => [
$this->table_prefix . 'topics' => [
'topic_views' => ['UINT', 0],
],
]
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\db\migration\data\v33x;
class v3313 extends \phpbb\db\migration\migration
{
public function effectively_installed()
{
return version_compare($this->config['version'], '3.3.13', '>=');
}
public static function depends_on()
{
return [
'\phpbb\db\migration\data\v33x\v3313rc1',
];
}
public function update_data()
{
return [
['config.update', ['version', '3.3.13']],
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\db\migration\data\v33x;
class v3314 extends \phpbb\db\migration\migration
{
public function effectively_installed()
{
return version_compare($this->config['version'], '3.3.14', '>=');
}
public static function depends_on()
{
return [
'\phpbb\db\migration\data\v33x\v3314rc1',
];
}
public function update_data()
{
return [
['config.update', ['version', '3.3.14']],
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\db\migration\data\v33x;
class v3314rc1 extends \phpbb\db\migration\migration
{
public function effectively_installed()
{
return version_compare($this->config['version'], '3.3.14-RC1', '>=');
}
public static function depends_on()
{
return [
'\phpbb\db\migration\data\v33x\v3313',
];
}
public function update_data()
{
return [
['config.update', ['version', '3.3.14-RC1']],
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\db\migration\data\v33x;
class v3315 extends \phpbb\db\migration\migration
{
public function effectively_installed()
{
return version_compare($this->config['version'], '3.3.15', '>=');
}
public static function depends_on()
{
return [
'\phpbb\db\migration\data\v33x\v3315rc1',
];
}
public function update_data()
{
return [
['config.update', ['version', '3.3.15']],
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\db\migration\data\v33x;
class v3315rc1 extends \phpbb\db\migration\migration
{
public function effectively_installed()
{
return version_compare($this->config['version'], '3.3.15-RC1', '>=');
}
public static function depends_on()
{
return [
'\phpbb\db\migration\data\v33x\topic_views_update',
];
}
public function update_data()
{
return [
['config.update', ['version', '3.3.15-RC1']],
];
}
}

View File

@@ -551,7 +551,7 @@ class migrator
$state['migration_data_state']['_total_time'] : 0.0;
$elapsed_time = microtime(true);
$steps = array_merge($this->helper->reverse_update_data($migration->update_data()), $migration->revert_data());
$steps = $migration->revert_data() ?: $this->helper->reverse_update_data($migration->update_data());
$result = $this->process_data_step($steps, $state['migration_data_state']);
$elapsed_time = microtime(true) - $elapsed_time;

View File

@@ -134,6 +134,8 @@ class feed
*/
public function forums()
{
$this->check_enabled();
if (!$this->config['feed_overall_forums'])
{
$this->send_unavailable();
@@ -151,6 +153,8 @@ class feed
*/
public function news()
{
$this->check_enabled();
// Get at least one news forum
$sql = 'SELECT forum_id
FROM ' . FORUMS_TABLE . '
@@ -176,6 +180,8 @@ class feed
*/
public function topics()
{
$this->check_enabled();
if (!$this->config['feed_topics_new'])
{
$this->send_unavailable();
@@ -193,6 +199,8 @@ class feed
*/
public function topics_new()
{
$this->check_enabled();
return $this->topics();
}
@@ -205,6 +213,8 @@ class feed
*/
public function topics_active()
{
$this->check_enabled();
if (!$this->config['feed_topics_active'])
{
$this->send_unavailable();
@@ -224,6 +234,8 @@ class feed
*/
public function forum($forum_id)
{
$this->check_enabled();
if (!$this->config['feed_forum'])
{
$this->send_unavailable();
@@ -243,6 +255,8 @@ class feed
*/
public function topic($topic_id)
{
$this->check_enabled();
if (!$this->config['feed_topic'])
{
$this->send_unavailable();
@@ -260,6 +274,8 @@ class feed
*/
public function overall()
{
$this->check_enabled();
if (!$this->config['feed_overall'])
{
$this->send_unavailable();
@@ -407,6 +423,22 @@ class feed
return $response;
}
/**
* Check if feeds are enabled in the configuration.
*
* @throws http_exception If feeds are disabled.
*
* @return void
*/
protected function check_enabled()
{
// Feeds are disabled, no need to continue
if (!$this->config['feed_enable'])
{
throw new http_exception(404, 'NO_FEED_ENABLED');
}
}
/**
* Throw and exception saying that the feed isn't available
*

View File

@@ -13,91 +13,127 @@
namespace phpbb;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use phpbb\exception\runtime_exception;
class file_downloader
{
const OK = 200;
const NOT_FOUND = 404;
const REQUEST_TIMEOUT = 408;
/** @var string Error string */
protected $error_string = '';
/** @var int Error number */
protected $error_number = 0;
/**
* Create new guzzle client
*
* @param string $host
* @param int $port
* @param int $timeout
*
* @return Client
*/
protected function create_client(string $host, int $port = 443, int $timeout = 6): Client
{
// Only set URL scheme if not specified in URL
$url_parts = parse_url($host);
if (!isset($url_parts['scheme']))
{
$host = (($port === 443) ? 'https://' : 'http://') . $host;
}
// Initialize Guzzle client
return new Client([
'base_uri' => $host,
'timeout' => $timeout,
'headers' => [
'user-agent' => 'phpBB/' . PHPBB_VERSION,
'accept' => '*/*',
],
]);
}
/**
* Retrieve contents from remotely stored file
*
* @param string $host File host
* @param string $directory Directory file is in
* @param string $filename Filename of file to retrieve
* @param int $port Port to connect to; default: 80
* @param int $timeout Connection timeout in seconds; default: 6
* @param string $host File host
* @param string $directory Directory file is in
* @param string $filename Filename of file to retrieve
* @param int $port Port to connect to; default: 443
* @param int $timeout Connection timeout in seconds; default: 6
*
* @return mixed File data as string if file can be read and there is no
* timeout, false if there were errors or the connection timed out
* @return false|string File data as string if file can be read and there is no
* timeout, false if there were errors or the connection timed out
*
* @throws \phpbb\exception\runtime_exception If data can't be retrieved and no error
* message is returned
* @throws runtime_exception If data can't be retrieved and no error
* message is returned
*/
public function get($host, $directory, $filename, $port = 80, $timeout = 6)
public function get(string $host, string $directory, string $filename, int $port = 443, int $timeout = 6)
{
try
{
// Initialize Guzzle client
$client = $this->create_client($host, $port, $timeout);
}
catch (\RuntimeException $exception)
{
throw new runtime_exception('HTTP_HANDLER_NOT_FOUND');
}
// Set default values for error variables
$this->error_number = 0;
$this->error_string = '';
if (function_exists('fsockopen') &&
$socket = @fsockopen(($port == 443 ? 'ssl://' : '') . $host, $port, $this->error_number, $this->error_string, $timeout)
)
try
{
@fputs($socket, "GET $directory/$filename HTTP/1.0\r\n");
@fputs($socket, "HOST: $host\r\n");
@fputs($socket, "Connection: close\r\n\r\n");
$response = $client->request('GET', "$directory/$filename");
$timer_stop = time() + $timeout;
stream_set_timeout($socket, $timeout);
$file_info = '';
$get_info = false;
while (!@feof($socket))
// Check if the response status code is 200 (OK)
if ($response->getStatusCode() == self::OK)
{
if ($get_info)
{
$file_info .= @fread($socket, 1024);
}
else
{
$line = @fgets($socket, 1024);
if ($line == "\r\n")
{
$get_info = true;
}
else if (stripos($line, '404 not found') !== false)
{
throw new \phpbb\exception\runtime_exception('FILE_NOT_FOUND', array($filename));
}
}
$stream_meta_data = stream_get_meta_data($socket);
if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop)
{
throw new \phpbb\exception\runtime_exception('FSOCK_TIMEOUT');
}
}
@fclose($socket);
}
else
{
if ($this->error_string)
{
$this->error_string = utf8_convert_message($this->error_string);
return false;
return $response->getBody()->getContents();
}
else
{
throw new \phpbb\exception\runtime_exception('FSOCK_DISABLED');
$this->error_number = $response->getStatusCode();
throw new runtime_exception('FILE_NOT_FOUND', [$filename]);
}
}
catch (RequestException $exception)
{
if ($exception->hasResponse())
{
$this->error_number = $exception->getResponse()->getStatusCode();
return $file_info;
if ($this->error_number == self::NOT_FOUND)
{
throw new runtime_exception('FILE_NOT_FOUND', [$filename]);
}
}
else
{
$this->error_number = self::REQUEST_TIMEOUT;
throw new runtime_exception('FSOCK_TIMEOUT');
}
$this->error_string = utf8_convert_message($exception->getMessage());
return false;
}
catch (runtime_exception $exception)
{
// Rethrow runtime_exceptions, only handle unknown cases below
throw $exception;
}
catch (\Throwable $exception)
{
$this->error_string = utf8_convert_message($exception->getMessage());
throw new runtime_exception('FSOCK_DISABLED');
}
}
/**
@@ -105,7 +141,7 @@ class file_downloader
*
* @return string Error string
*/
public function get_error_string()
public function get_error_string(): string
{
return $this->error_string;
}
@@ -115,7 +151,7 @@ class file_downloader
*
* @return int Error number
*/
public function get_error_number()
public function get_error_number(): int
{
return $this->error_number;
}

View File

@@ -339,6 +339,14 @@ class helper
protected function render_language_select($selected_language = null)
{
$langs = $this->lang_helper->get_available_languages();
// The first language will be selected by default. Unless a user has consciously included
// other languages in the installation process, it will be British English anyway.
if ($selected_language === null && count($langs))
{
$selected_language = $langs[0]['iso'];
}
foreach ($langs as $lang)
{
$this->template->assign_block_vars('language_select_item', array(

View File

@@ -67,6 +67,20 @@ class language_file_helper
);
}
usort($available_languages, [$this, 'sort_by_local_name']);
return $available_languages;
}
/**
* Sorts the languages by their name instead of iso code
*
* @param mixed $a First language data
* @param mixed $b Second language data
* @return int
*/
private static function sort_by_local_name($a, $b): int
{
return $a['local_name'] <=> $b['local_name'];
}
}

View File

@@ -223,13 +223,13 @@ class path_helper
*
* The referer must be specified as a parameter in the query.
*/
if ($this->request->is_ajax() && $this->symfony_request->get('_referer'))
if ($this->request->is_ajax() && $this->request->header('Referer'))
{
// We need to escape $absolute_board_url because it can be partially concatenated to the result.
$absolute_board_url = $this->request->escape($this->symfony_request->getSchemeAndHttpHost() . $this->symfony_request->getBasePath(), true);
$referer_web_root_path = $this->get_web_root_path_from_ajax_referer(
$this->symfony_request->get('_referer'),
$this->request->header('Referer'),
$absolute_board_url
);
return $this->web_root_path = $referer_web_root_path;

View File

@@ -70,12 +70,12 @@ class request implements \phpbb\request\request_interface
foreach ($this->super_globals as $const => $super_global)
{
$this->input[$const] = isset($GLOBALS[$super_global]) ? $GLOBALS[$super_global] : array();
$this->input[$const] = isset($GLOBALS[$super_global]) ? (array) $GLOBALS[$super_global] : array();
}
// simulate request_order = GP
$this->original_request = $this->input[\phpbb\request\request_interface::REQUEST];
$this->input[\phpbb\request\request_interface::REQUEST] = $this->input[\phpbb\request\request_interface::POST] + $this->input[\phpbb\request\request_interface::GET];
$this->original_request = (array) $this->input[\phpbb\request\request_interface::REQUEST];
$this->input[\phpbb\request\request_interface::REQUEST] = (array) $this->input[\phpbb\request\request_interface::POST] + (array) $this->input[\phpbb\request\request_interface::GET];
if ($disable_super_globals)
{

View File

@@ -76,17 +76,16 @@ class base
}
}
// change the start to the actual end of the current request if the sort direction differs
// from the dirction in the cache and reverse the ids later
// If the sort direction differs from the direction in the cache, then recalculate array keys
if ($reverse_ids)
{
$start = $result_count - $start - $per_page;
// the user requested a page past the last index
if ($start < 0)
{
return SEARCH_RESULT_NOT_IN_CACHE;
}
$keys = array_keys($stored_ids);
array_walk($keys, function (&$value, $key) use ($result_count)
{
$value = ($value >= 0) ? $result_count - $value - 1 : $value;
}
);
$stored_ids = array_combine($keys, $stored_ids);
}
for ($i = $start, $n = $start + $per_page; ($i < $n) && ($i < $result_count); $i++)
@@ -102,11 +101,6 @@ class base
}
unset($stored_ids);
if ($reverse_ids)
{
$id_ary = array_reverse($id_ary);
}
if (!$complete)
{
return SEARCH_RESULT_INCOMPLETE;
@@ -142,6 +136,8 @@ class base
}
$store_ids = array_slice($id_ary, 0, $length);
$id_range = range($start, $start + $length - 1);
$store_ids = array_combine($id_range, $store_ids);
// create a new resultset if there is none for this search_key yet
// or add the ids to the existing resultset
@@ -176,29 +172,26 @@ class base
$db->sql_query($sql);
$store = array(-1 => $result_count, -2 => $sort_dir);
$id_range = range($start, $start + $length - 1);
}
else
{
// we use one set of results for both sort directions so we have to calculate the indizes
// for the reversed array and we also have to reverse the ids themselves
// for the reversed array
if ($store[-2] != $sort_dir)
{
$store_ids = array_reverse($store_ids);
$id_range = range($store[-1] - $start - $length, $store[-1] - $start - 1);
}
else
{
$id_range = range($start, $start + $length - 1);
$keys = array_keys($store_ids);
array_walk($keys, function (&$value, $key) use ($store) {
$value = $store[-1] - $value - 1;
});
$store_ids = array_combine($keys, $store_ids);
}
}
$store_ids = array_combine($id_range, $store_ids);
// append the ids
if (is_array($store_ids))
{
$store += $store_ids;
ksort($store);
// if the cache is too big
if (count($store) - 2 > 20 * $config['search_block_size'])

View File

@@ -609,7 +609,6 @@ class fulltext_mysql extends \phpbb\search\base
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
// if the total result count is not cached yet, retrieve it from the db
if (!$result_count && count($id_ary))
{
@@ -635,10 +634,10 @@ class fulltext_mysql extends \phpbb\search\base
$id_ary[] = (int) $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
$this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir);
$id_ary = array_slice($id_ary, 0, (int) $per_page);
@@ -833,6 +832,8 @@ class fulltext_mysql extends \phpbb\search\base
// Build the query for really selecting the post_ids
if ($type == 'posts')
{
// For sorting by non-unique columns, add unique sort key to avoid duplicated rows in results
$sql_sort .= ', p.post_id' . (($sort_dir == 'a') ? ' ASC' : ' DESC');
$sql = "SELECT $sql_select
FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t ' : ' ') . "
WHERE $sql_author
@@ -896,10 +897,10 @@ class fulltext_mysql extends \phpbb\search\base
$id_ary[] = (int) $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
if (count($id_ary))
{
$this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir);

View File

@@ -1012,6 +1012,8 @@ class fulltext_native extends \phpbb\search\base
$this->db->sql_freeresult($result);
}
$id_ary = array_unique($id_ary);
// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
$this->save_ids($search_key, $this->search_query, $author_ary, $total_results, $id_ary, $start, $sort_dir);
$id_ary = array_slice($id_ary, 0, (int) $per_page);
@@ -1249,6 +1251,8 @@ class fulltext_native extends \phpbb\search\base
// Build the query for really selecting the post_ids
if ($type == 'posts')
{
// For sorting by non-unique columns, add unique sort key to avoid duplicated rows in results
$sql_sort .= ', p.post_id' . (($sort_dir == 'a') ? ' ASC' : ' DESC');
$sql = "SELECT $select
FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t' : '') . "
WHERE $sql_author
@@ -1313,6 +1317,8 @@ class fulltext_native extends \phpbb\search\base
$this->db->sql_freeresult($result);
}
$id_ary = array_unique($id_ary);
if (count($id_ary))
{
$this->save_ids($search_key, '', $author_ary, $total_results, $id_ary, $start, $sort_dir);

View File

@@ -545,8 +545,6 @@ class fulltext_postgres extends \phpbb\search\base
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
// if the total result count is not cached yet, retrieve it from the db
if (!$result_count)
{
@@ -576,10 +574,10 @@ class fulltext_postgres extends \phpbb\search\base
$id_ary[] = $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
// store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page
$this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir);
$id_ary = array_slice($id_ary, 0, (int) $per_page);
@@ -766,6 +764,8 @@ class fulltext_postgres extends \phpbb\search\base
// Build the query for really selecting the post_ids
if ($type == 'posts')
{
// For sorting by non-unique columns, add unique sort key to avoid duplicated rows in results
$sql_sort .= ', p.post_id' . (($sort_dir == 'a') ? ' ASC' : ' DESC');
$sql = "SELECT p.post_id
FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t ' : ' ') . "
WHERE $sql_author
@@ -858,10 +858,10 @@ class fulltext_postgres extends \phpbb\search\base
$id_ary[] = (int) $row[$field];
}
$this->db->sql_freeresult($result);
$id_ary = array_unique($id_ary);
}
$id_ary = array_unique($id_ary);
if (count($id_ary))
{
$this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir);

View File

@@ -356,7 +356,7 @@ class fulltext_sphinx
array('read_timeout', '5'),
array('max_children', '30'),
array('pid_file', $this->config['fulltext_sphinx_data_path'] . 'searchd.pid'),
array('binlog_path', $this->config['fulltext_sphinx_data_path']),
array('binlog_path', rtrim($this->config['fulltext_sphinx_data_path'], '/\\')), // Trim trailing slash
),
);
@@ -455,9 +455,47 @@ class fulltext_sphinx
$this->sphinx->SetMatchMode(SPH_MATCH_ANY);
}
if (strlen($keywords) > 0)
// Split words
$split_keywords = preg_replace('#([^\p{L}\p{N}\'*"()])#u', '$1$1', str_replace('\'\'', '\' \'', trim($keywords)));
$matches = array();
preg_match_all('#(?:[^\p{L}\p{N}*"()]|^)([+\-|]?(?:[\p{L}\p{N}*"()]+\'?)*[\p{L}\p{N}*"()])(?:[^\p{L}\p{N}*"()]|$)#u', $split_keywords, $matches);
$this->split_words = $matches[1];
if ($terms == 'any')
{
$this->search_query = str_replace('"', '&quot;', $keywords);
$this->search_query = '';
foreach ($this->split_words as $word)
{
if ((strpos($word, '+') === 0) || (strpos($word, '-') === 0) || (strpos($word, '|') === 0))
{
$word = substr($word, 1);
}
$this->search_query .= $word . ' ';
}
}
else
{
$this->search_query = '';
foreach ($this->split_words as $word)
{
if ((strpos($word, '+') === 0) || (strpos($word, '-') === 0))
{
$this->search_query .= $word . ' ';
}
else if (strpos($word, '|') === 0)
{
$this->search_query .= substr($word, 1) . ' ';
}
else
{
$this->search_query .= '+' . $word . ' ';
}
}
}
if ($this->search_query)
{
$this->search_query = str_replace('"', '&quot;', $this->search_query);
return true;
}

View File

@@ -99,7 +99,10 @@ class twig extends \phpbb\template\base
foreach ($extensions as $extension)
{
$this->twig->addExtension($extension);
if (!$this->twig->hasExtension(get_class($extension)))
{
$this->twig->addExtension($extension);
}
}
// Add admin namespace

View File

@@ -216,11 +216,11 @@ abstract class base implements reparser_interface
/**
* {@inheritdoc}
*/
public function reparse_range($min_id, $max_id)
public function reparse_range($min_id, $max_id, bool $force_bbcode_reparsing = false)
{
foreach ($this->get_records_by_range($min_id, $max_id) as $record)
{
$this->reparse_record($record);
$this->reparse_record($record, $force_bbcode_reparsing);
}
}
@@ -228,16 +228,17 @@ abstract class base implements reparser_interface
* Reparse given record
*
* @param array $record Associative array containing the record's data
* @param bool $force_bbcode_reparsing Flag indicating if BBCode should be reparsed unconditionally
*/
protected function reparse_record(array $record)
protected function reparse_record(array $record, bool $force_bbcode_reparsing = false)
{
// Guess magic URL state based on actual record content before adding fields
$record['enable_magic_url'] = $this->guess_magic_url($record);
$record = $this->add_missing_fields($record);
$flags = ($record['enable_bbcode']) ? OPTION_FLAG_BBCODE : 0;
$flags |= ($record['enable_smilies']) ? OPTION_FLAG_SMILIES : 0;
$flags |= ($record['enable_magic_url']) ? OPTION_FLAG_LINKS : 0;
$flags = ($record['enable_bbcode'] || $force_bbcode_reparsing) ? OPTION_FLAG_BBCODE : 0;
$flags |= ($record['enable_smilies'] || $force_bbcode_reparsing) ? OPTION_FLAG_SMILIES : 0;
$flags |= ($record['enable_magic_url'] || $force_bbcode_reparsing) ? OPTION_FLAG_LINKS : 0;
$unparsed = array_merge(
$record,
generate_text_for_edit($record['text'], $record['bbcode_uid'], $flags)
@@ -252,13 +253,13 @@ abstract class base implements reparser_interface
$unparsed['bbcode_uid'],
$bitfield,
$flags,
$unparsed['enable_bbcode'],
$unparsed['enable_magic_url'],
$unparsed['enable_smilies'],
$unparsed['enable_img_bbcode'],
$unparsed['enable_bbcode'] || $force_bbcode_reparsing,
$unparsed['enable_magic_url'] || $force_bbcode_reparsing,
$unparsed['enable_smilies'] || $force_bbcode_reparsing,
$unparsed['enable_img_bbcode'] || $force_bbcode_reparsing,
$unparsed['enable_flash_bbcode'],
$unparsed['enable_quote_bbcode'],
$unparsed['enable_url_bbcode'],
$unparsed['enable_quote_bbcode'] || $force_bbcode_reparsing,
$unparsed['enable_url_bbcode'] || $force_bbcode_reparsing,
'text_reparser.' . $this->get_name()
);

View File

@@ -41,6 +41,7 @@ interface reparser_interface
*
* @param integer $min_id Lower bound
* @param integer $max_id Upper bound
* @param bool $force_bbcode_reparsing Flag indicating if BBCode should be reparsed unconditionally
*/
public function reparse_range($min_id, $max_id);
public function reparse_range($min_id, $max_id, bool $force_bbcode_reparsing = false);
}

View File

@@ -272,7 +272,7 @@ class reset_password
], false)
]);
$messenger->send($user_row['user_notify_type']);
$messenger->send(NOTIFY_EMAIL);
return $this->helper->message($message);
}

View File

@@ -381,7 +381,7 @@ class version_helper
}
else if ($info === false || $force_update)
{
$info = $this->file_downloader->get($this->host, $this->path, $this->file, $this->use_ssl ? 443 : 80);
$info = $this->file_downloader->get($this->host, $this->path, $this->file, $this->use_ssl ? 443 : 80, 30);
$error_string = $this->file_downloader->get_error_string();
if (!empty($error_string))

View File

@@ -90,8 +90,21 @@ switch ($search_id)
break;
}
$search_auth_check_override = false;
/**
* This event allows you to override search auth checks
*
* @event core.search_auth_check_override
* @var bool search_auth_check_override Whether or not the search auth check overridden
* @since 3.3.14-RC1
*/
$vars = [
'search_auth_check_override',
];
extract($phpbb_dispatcher->trigger_event('core.search_auth_check_override', compact($vars)));
// Is user able to search? Has search been disabled?
if (!$auth->acl_get('u_search') || !$auth->acl_getf_global('f_search') || !$config['load_search'])
if (!$search_auth_check_override && (!$auth->acl_get('u_search') || !$auth->acl_getf_global('f_search') || !$config['load_search']))
{
$template->assign_var('S_NO_SEARCH', true);
trigger_error('NO_SEARCH');
@@ -684,10 +697,10 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$hilit = str_replace(' ', '|', $hilit);
$u_hilit = urlencode(html_entity_decode(str_replace('|', ' ', $hilit), ENT_COMPAT));
$u_show_results = '&amp;sr=' . $show_results;
$u_show_results = 'sr=' . $show_results;
$u_search_forum = implode('&amp;fid%5B%5D=', $search_forum);
$u_search = append_sid("{$phpbb_root_path}search.$phpEx", $u_sort_param . $u_show_results);
$u_search = append_sid("{$phpbb_root_path}search.$phpEx", (($u_sort_param) ? $u_sort_param . '&amp;' : '') . $u_show_results);
$u_search .= ($search_id) ? '&amp;search_id=' . $search_id : '';
$u_search .= ($u_hilit) ? '&amp;keywords=' . urlencode(html_entity_decode($keywords, ENT_COMPAT)) : '';
$u_search .= ($search_terms != 'all') ? '&amp;terms=' . $search_terms : '';

View File

@@ -21,8 +21,8 @@
# General Information about this style
name = prosilver
copyright = © phpBB Limited, 2007
style_version = 3.3.13
phpbb_version = 3.3.13
style_version = 3.3.15
phpbb_version = 3.3.15
# Defining a different template bitfield
# template_bitfield = //g=

View File

@@ -38,11 +38,11 @@
<xsl:value-of select="$L_COLON"/>
<xsl:if test="@post_url">
<xsl:text> </xsl:text>
<a href="{@post_url}" data-post-id="{@post_id}" onclick="if(document.getElementById(hash.substr(1)))href=hash">&#8593;</a>
<a href="{@post_url}" aria-label="{L_VIEW_QUOTED_POST}" data-post-id="{@post_id}" onclick="if(document.getElementById(hash.substr(1)))href=hash"><i class="icon fa-arrow-circle-up fa-fw" aria-hidden="true"></i></a>
</xsl:if>
<xsl:if test="@msg_url">
<xsl:text> </xsl:text>
<a href="{@msg_url}" data-msg-id="{@msg_id}">&#8593;</a>
<a href="{@msg_url}" aria-label="{L_VIEW_QUOTED_POST}" data-msg-id="{@msg_id}"><i class="icon fa-arrow-circle-up fa-fw" aria-hidden="true"></i></a>
</xsl:if>
<xsl:if test="@date">
<span class="responsive-hide"><xsl:value-of select="@date"/></span>

View File

@@ -650,7 +650,7 @@ function parseDocument($container) {
html = $children.html();
}
$block.append((first ? '' : '<br />') + html);
$block.append((first ? '' : '<br>') + html);
first = false;
});
@@ -670,7 +670,7 @@ function parseDocument($container) {
// Find all headers, get contents
$list.prev('.topiclist').find('li.header dd').not('.mark').each(function() {
headers.push($(this).text());
headers.push($("<div>").text($(this).text()).html());
headersLength++;
});
@@ -707,7 +707,7 @@ function parseDocument($container) {
html = headers[i] + ': <strong>' + html + '</strong>';
}
$block.append((first ? '' : '<br />') + html);
$block.append((first ? '' : '<br>') + html);
first = false;
});
@@ -773,7 +773,9 @@ function parseDocument($container) {
}
if ((text.length && text !== '-') || cell.children().length) {
cell.prepend('<dfn style="display: none;">' + headers[column] + '</dfn>');
if (headers[column].length) {
cell.prepend($("<dfn>").css('display', 'none').text(headers[column]));
}
} else {
cell.addClass('empty');
}

View File

@@ -37,7 +37,7 @@
<div class="list-inner">
<!-- IF S_ENABLE_FEEDS and forumrow.S_FEED_ENABLED -->
<!--
<a class="feed-icon-forum" title="{L_FEED} - {forumrow.FORUM_NAME}" href="{U_FEED}?f={forumrow.FORUM_ID}">
<a class="feed-icon-forum" title="{L_FEED} - {forumrow.FORUM_NAME}" href="{{ path('phpbb_feed_forum', { forum_id : forumrow.FORUM_ID } ) }}">
<i class="icon fa-rss-square fa-fw icon-orange" aria-hidden="true"></i><span class="sr-only">{L_FEED} - {forumrow.FORUM_NAME}</span>
</a>
-->

View File

@@ -22,13 +22,13 @@
{% endapply %}
<!-- EVENT overall_footer_breadcrumb_append -->
</li>
<!-- IF U_WATCH_FORUM_LINK and not S_IS_BOT -->
{% if U_WATCH_FORUM_LINK && !S_IS_BOT %}
<li data-last-responsive="true">
<a href="{U_WATCH_FORUM_LINK}" title="{S_WATCH_FORUM_TITLE}" data-ajax="toggle_link" data-toggle-class="icon <!-- IF S_WATCHING_FORUM -->fa-check-square-o<!-- ELSE -->fa-square-o<!-- ENDIF --> fa-fw" data-toggle-text="{S_WATCH_FORUM_TOGGLE}" data-toggle-url="{U_WATCH_FORUM_TOGGLE}">
<i class="icon <!-- IF S_WATCHING_FORUM -->fa-square-o<!-- ELSE -->fa-check-square-o<!-- ENDIF --> fa-fw" aria-hidden="true"></i><span>{S_WATCH_FORUM_TITLE}</span>
<a href="{{ U_WATCH_FORUM_LINK }}" title="{{ S_WATCH_FORUM_TITLE }}" data-ajax="toggle_link" data-toggle-class="icon {{ !S_WATCHING_FORUM ? 'fa-check-square-o' : 'fa-square-o' }} fa-fw" data-toggle-text="{{ S_WATCH_FORUM_TOGGLE }}" data-toggle-url="{{ U_WATCH_FORUM_TOGGLE }}">
<i class="icon {{ S_WATCHING_FORUM ? 'fa-check-square-o' : 'fa-square-o' }} fa-fw" aria-hidden="true"></i><span>{{ S_WATCH_FORUM_TITLE }}</span>
</a>
</li>
<!-- ENDIF -->
{% endif %}
<!-- EVENT overall_footer_timezone_before -->
<li class="rightside">{S_TIMEZONE}</li>

View File

@@ -226,7 +226,7 @@
<!-- ENDIF -->
<div class="action-bar bottom">
<!-- IF .searchresults and (S_SELECT_SORT_DAYS or S_SELECT_SORT_KEY) -->
<!-- IF S_SELECT_SORT_DAYS or S_SELECT_SORT_KEY -->
<form method="post" action="{S_SEARCH_ACTION}">
<!-- INCLUDE display_options.html -->
</form>

View File

@@ -22,7 +22,7 @@
<!-- ENDIF -->
<div id="post-{MESSAGE_ID}" class="post pm has-profile<!-- IF S_POST_UNAPPROVED or S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF S_ONLINE --> online<!-- ENDIF -->">
<div id="post-{MESSAGE_ID}" class="post pm has-profile<!-- IF S_ONLINE --> online<!-- ENDIF -->">
<div class="inner">
<dl class="postprofile" id="profile{MESSAGE_ID}">
@@ -130,6 +130,7 @@
<!-- IF S_BCC_RECIPIENT --><br /><strong>{L_BCC}{L_COLON}</strong> <!-- BEGIN bcc_recipient --><!-- IF bcc_recipient.NAME_FULL -->{bcc_recipient.NAME_FULL}<!-- ELSE --><a href="{bcc_recipient.U_VIEW}"<!-- IF bcc_recipient.COLOUR --> style="color:{bcc_recipient.COLOUR};"<!-- ENDIF -->><strong>{bcc_recipient.NAME}</strong></a><!-- ENDIF -->&nbsp;<!-- END bcc_recipient --><!-- ENDIF -->
</p>
{% EVENT ucp_pm_viewmessage_message_content_before %}
<div class="content">{MESSAGE}</div>

View File

@@ -8,13 +8,13 @@
<div class="pointer"><div class="pointer-inner"></div></div>
<ul class="dropdown-contents">
<!-- EVENT viewtopic_topic_tools_before -->
<!-- IF U_WATCH_TOPIC -->
{% if U_WATCH_TOPIC %}
<li>
<a href="{U_WATCH_TOPIC}" class="watch-topic-link" title="{S_WATCH_TOPIC_TITLE}" data-ajax="toggle_link" data-toggle-class="icon <!-- IF S_WATCHING_TOPIC -->fa-check-square-o<!-- ELSE -->fa-square-o<!-- ENDIF --> fa-fw" data-toggle-text="{S_WATCH_TOPIC_TOGGLE}" data-toggle-url="{U_WATCH_TOPIC_TOGGLE}" data-update-all=".watch-topic-link">
<i class="icon <!-- IF S_WATCHING_TOPIC -->fa-square-o<!-- ELSE -->fa-check-square-o<!-- ENDIF --> fa-fw" aria-hidden="true"></i><span>{S_WATCH_TOPIC_TITLE}</span>
<a href="{{ U_WATCH_TOPIC }}" class="watch-topic-link" title="{{ S_WATCH_TOPIC_TITLE }}" data-ajax="toggle_link" data-toggle-class="icon {{ !S_WATCHING_TOPIC ? 'fa-check-square-o' : 'fa-square-o' }} fa-fw" data-toggle-text="{{ S_WATCH_TOPIC_TOGGLE }}" data-toggle-url="{{ U_WATCH_TOPIC_TOGGLE }}" data-update-all=".watch-topic-link">
<i class="icon {{ S_WATCHING_TOPIC ? 'fa-check-square-o' : 'fa-square-o' }} fa-fw" aria-hidden="true"></i><span>{{ S_WATCH_TOPIC_TITLE }}</span>
</a>
</li>
<!-- ENDIF -->
{% endif %}
<!-- IF U_BOOKMARK_TOPIC -->
<li>
<a href="{U_BOOKMARK_TOPIC}" class="bookmark-link" title="{L_BOOKMARK_TOPIC}" data-ajax="alt_text" data-alt-text="{S_BOOKMARK_TOGGLE}" data-update-all=".bookmark-link">

View File

@@ -47,27 +47,45 @@ if (!$forum_id)
trigger_error('NO_FORUM');
}
$sql_from = FORUMS_TABLE . ' f';
$sql_ary = [
'SELECT' => 'f.*',
'FROM' => [
FORUMS_TABLE => 'f',
],
'WHERE' => 'f.forum_id = ' . $forum_id,
];
$lastread_select = '';
// Grab appropriate forum data
if ($config['load_db_lastread'] && $user->data['is_registered'])
{
$sql_from .= ' LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft ON (ft.user_id = ' . $user->data['user_id'] . '
AND ft.forum_id = f.forum_id)';
$lastread_select .= ', ft.mark_time';
$sql_ary['LEFT_JOIN'][] = [
'FROM' => [FORUMS_TRACK_TABLE => 'ft'],
'ON' => 'ft.user_id = ' . $user->data['user_id'] . ' AND ft.forum_id = f.forum_id',
];
$sql_ary['SELECT'] .= ', ft.mark_time';
}
if ($user->data['is_registered'])
{
$sql_from .= ' LEFT JOIN ' . FORUMS_WATCH_TABLE . ' fw ON (fw.forum_id = f.forum_id AND fw.user_id = ' . $user->data['user_id'] . ')';
$lastread_select .= ', fw.notify_status';
$sql_ary['LEFT_JOIN'][] = [
'FROM' => [FORUMS_WATCH_TABLE => 'fw'],
'ON' => 'fw.forum_id = f.forum_id AND fw.user_id = ' . $user->data['user_id'],
];
$sql_ary['SELECT'] .= ', fw.notify_status';
}
$sql = "SELECT f.* $lastread_select
FROM $sql_from
WHERE f.forum_id = $forum_id";
$result = $db->sql_query($sql);
/**
* You can use this event to modify the sql that selects the forum on the viewforum page.
*
* @event core.viewforum_modify_sql
* @var array sql_ary The SQL array to get the data for a forum
* @since 3.3.14-RC1
*/
$vars = ['sql_ary'];
extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_sql', compact($vars)));
$result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
$forum_data = $db->sql_fetchrow($result);
$db->sql_freeresult($result);

142
tests/cron/wrapper_test.php Normal file
View File

@@ -0,0 +1,142 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
require_once __DIR__ . '/../template/template_test_case.php';
class phpbb_cron_wrapper_test extends phpbb_template_template_test_case
{
private $task;
private $routing_helper;
private $wrapper;
protected function setUp(): void
{
global $phpbb_root_path;
// Test the engine can be used
$this->setup_engine([], $phpbb_root_path . 'styles/all/template');
$this->template->clear_cache();
global $phpbb_filesystem;
$phpbb_filesystem = new \phpbb\filesystem\filesystem();
$this->task = $this->createMock(\phpbb\cron\task\task::class);
$this->routing_helper = $this->createMock(\phpbb\routing\helper::class);
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
'/phpbb/',
'php',
$this->template
);
}
public function test_generate_template_pagination()
{
$this->task = $this->createMock(\phpbb\cron\task\parametrized::class);
$this->task->expects($this->any())
->method('get_parameters')
->willReturn(['f' => '5']);
$this->task->expects($this->any())
->method('get_name')
->willReturn('test_task');
$this->routing_helper = $this->createMock(\phpbb\routing\helper::class);
$this->routing_helper->expects($this->any())
->method('route')
->with('phpbb_cron_run', ['cron_type' => 'test_task', 'f' => '5'])
->willReturn('app.php/cron/foo?f=5');
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
'/phpbb/',
'php',
$this->template
);
$this->assertEquals('<img class="sr-only" aria-hidden="true" src="app.php&#x2F;cron&#x2F;foo&#x3F;f&#x3D;5" width="1" height="1" alt="">', str_replace(["\n", "\t"], '', $this->wrapper->get_html_tag()));
}
public function test_is_parametrized_false()
{
$this->assertFalse($this->wrapper->is_parametrized());
}
public function test_is_ready()
{
$this->task->method('is_runnable')->willReturn(true);
$this->task->method('should_run')->willReturn(true);
$this->assertTrue($this->wrapper->is_ready());
}
public function test_get_url_non_parametrized()
{
$this->task->method('get_name')->willReturn('test_task');
$this->routing_helper->expects($this->once())
->method('route')
->with('phpbb_cron_run', ['cron_type' => 'test_task'])
->willReturn('/cron/url');
$this->assertEquals('/cron/url', $this->wrapper->get_url());
}
public function test_get_html_tag()
{
$this->template = $this->createMock(\phpbb\template\template::class);
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
'/phpbb/',
'php',
$this->template
);
$this->template->expects($this->once())
->method('set_filenames');
$this->template->expects($this->once())
->method('assign_var');
$this->template->expects($this->once())
->method('assign_display')
->willReturn('<img src="cron">');
$this->assertEquals('<img src="cron">', $this->wrapper->get_html_tag());
}
public function test_call_forwards_to_task()
{
$this->task = $this->getMockBuilder(\phpbb\cron\task\task::class)
->disableOriginalConstructor()
->setMethods(['get_name', 'run', 'is_runnable', 'should_run', 'some_method'])
->getMock();
$this->routing_helper = $this->createMock(\phpbb\routing\helper::class);
$this->wrapper = new \phpbb\cron\task\wrapper(
$this->task,
$this->routing_helper,
'/phpbb/',
'php',
$this->template
);
$this->task->expects($this->once())
->method('some_method')
->with('arg1', 'arg2')
->willReturn('result');
$result = $this->wrapper->some_method('arg1', 'arg2');
$this->assertEquals('result', $result);
}
}

View File

@@ -123,4 +123,20 @@ class phpbb_functional_acp_groups_test extends phpbb_functional_common_groups_te
$this->assertEquals((bool) $tick_teampage, (bool) ($this->form_data['group_teampage'] ?? false));
}
}
public function test_acp_groups_create_existing_name()
{
$this->group_manage_login();
$crawler = self::request('GET', 'adm/index.php?i=groups&mode=manage&sid=' . $this->sid);
$form = $crawler->selectButton($this->lang('SUBMIT'))->form([
'group_name' => 'Guests', // 'Guests' is the group name already in use for predefined Guests group
]);
$crawler = self::submit($form);
$form = $crawler->selectButton($this->lang('SUBMIT'))->form();
$crawler = self::submit($form); // Just submit the form with selected group name
$this->assertStringContainsString($this->lang('GROUP_NAME_TAKEN'), $crawler->text());
}
}

View File

@@ -149,4 +149,26 @@ class phpbb_functional_acp_permissions_test extends phpbb_functional_test_case
$this->assertContainsLang('ACL_M_EDIT', $page_text);
$this->assertContainsLang('ACL_M_MOVE', $page_text);
}
public function test_tracing_user_based_permissions()
{
$this->create_user('newlyregistereduser');
// Open user-based permissions masks page
$crawler = self::request('GET', "adm/index.php?i=acp_permissions&icat=16&mode=view_user_global&sid=" . $this->sid);
// Select newlyregistereduser
$form = $crawler->filter('#add_user')->form(['username' => ['newlyregistereduser']]);
$crawler = self::submit($form);
// Test 1st "Yes" permission tracing result match
$trace_link_yes = $crawler->filter('td.yes')->eq(0)->siblings()->filter('th > a.trace')->link();
$crawler_trace_yes = self::$client->click($trace_link_yes);
$this->assertEquals(1, $crawler_trace_yes->filter('tr.row2 > td.yes')->count());
// Test 1st "Never" permission tracing result match
$trace_link_never = $crawler->filter('td.never')->eq(0)->siblings()->filter('th > a.trace')->link();
$crawler_trace_never = self::$client->click($trace_link_never);
$this->assertEquals(1, $crawler_trace_never->filter('tr.row2 > td.never')->count());
}
}

View File

@@ -84,7 +84,8 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
$crawler = self::request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid);
$this->assertCount(1, $crawler->filter('.ext_enabled'));
$this->assertCount(7, $crawler->filter('.ext_disabled'));
$this->assertCount(3, $crawler->filter('.ext_disabled'));
$this->assertCount(4, $crawler->filter('.ext_not_installed'));
$this->assertStringContainsString('phpBB Foo Extension', $crawler->filter('.ext_enabled')->eq(0)->text());
$this->assertContainsLang('EXTENSION_DISABLE', $crawler->filter('.ext_enabled')->eq(0)->text());
@@ -98,9 +99,9 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case
$this->assertStringContainsString('The “vendor/test3” extension is not valid.', $crawler->filter('.ext_disabled')->eq(1)->text());
$this->assertStringContainsString('phpBB Bar Extension', $crawler->filter('.ext_disabled')->eq(3)->text());
$this->assertContainsLang('DETAILS', $crawler->filter('.ext_disabled')->eq(3)->text());
$this->assertContainsLang('EXTENSION_ENABLE', $crawler->filter('.ext_disabled')->eq(3)->text());
$this->assertStringContainsString('phpBB Bar Extension', $crawler->filter('.ext_not_installed')->eq(0)->text());
$this->assertContainsLang('DETAILS', $crawler->filter('.ext_not_installed')->eq(0)->text());
$this->assertContainsLang('EXTENSION_ENABLE', $crawler->filter('.ext_not_installed')->eq(0)->text());
// Check that invalid extensions are not listed.
$this->assertStringNotContainsString('phpBB BarFoo Extension', $crawler->filter('.table1')->text());

View File

@@ -261,6 +261,29 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
$this->data['topics']['Feeds #exclude - Topic #1'] = (int) $post['topic_id'];
}
public function test_feeds_disabled()
{
$this->login();
$this->admin_login();
// Disable feeds in ACP
$crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=acp_board&mode=feed");
$form = $crawler->selectButton('Submit')->form();
$crawler = self::submit($form, ['config[feed_enable]' => 0]);
self::assertContainsLang('CONFIG_UPDATED', $crawler->filter('.successbox')->text());
// Assert that feeds aren't available
$crawler = self::request('GET', 'app.php/feed/overall', array(), false);
self::assert_response_status_code(404);
$this->assertContainsLang('NO_FEED_ENABLED', $crawler->text());
// Enable feeds again in ACP
$crawler = self::request('GET', "adm/index.php?sid={$this->sid}&i=acp_board&mode=feed");
$form = $crawler->selectButton('Submit')->form();
$crawler = self::submit($form, ['config[feed_enable]' => 1]);
self::assertContainsLang('CONFIG_UPDATED', $crawler->filter('.successbox')->text());
}
public function test_feeds_exclude()
{
$this->load_ids(array(

View File

@@ -49,6 +49,30 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
$this->assertStringContainsString("Search found $topics_found match", $crawler->filter('.searchresults-title')->text(), $this->search_backend);
}
protected function assert_search_posts_by_author_id($author_id, $posts_found, $sort_key = '', $sort_dir = '')
{
// Test obtaining data from cache if sorting direction is set
if (!$sort_dir)
{
$this->purge_cache();
}
$crawler = self::request('GET', 'search.php?author_id=' . $author_id . ($sort_key ? "&sk=$sort_key" : '') . ($sort_dir ? "&sk=$sort_dir" : ''));
$this->assertEquals($posts_found, $crawler->filter('.postbody')->count(), $this->search_backend);
$this->assertStringContainsString("Search found $posts_found match", $crawler->filter('.searchresults-title')->text(), $this->search_backend);
}
protected function assert_search_topics_by_author_id($author_id, $topics_found, $sort_key = '', $sort_dir = '')
{
// Test obtaining data from cache if sorting direction is set
if (!$sort_dir)
{
$this->purge_cache();
}
$crawler = self::request('GET', 'search.php?sr=topics&author_id=' . $author_id . ($sort_key ? "&sk=$sort_key" : '') . ($sort_dir ? "&sk=$sort_dir" : ''));
$this->assertEquals($topics_found, $crawler->filter('.row')->count(), $this->search_backend);
$this->assertStringContainsString("Search found $topics_found match", $crawler->filter('.searchresults-title')->text(), $this->search_backend);
}
protected function assert_search_in_topic($topic_id, $keywords, $posts_found, $sort_key = '')
{
$this->purge_cache();
@@ -93,10 +117,14 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
$this->add_lang('common');
// Create a new standard user if needed, topic and post to test searh for author
if (!$this->user_exists('searchforauthoruser'))
if (!$searchforauthoruser_id = $this->user_exists('searchforauthoruser'))
{
$searchforauthoruser_id = $this->create_user('searchforauthoruser');
}
else
{
$searchforauthoruser_id = key($searchforauthoruser_id);
}
$this->remove_user_group('NEWLY_REGISTERED', ['searchforauthoruser']);
$this->set_flood_interval(0);
$this->login('searchforauthoruser');
@@ -122,8 +150,19 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
if ($values["config[search_type]"] != $this->search_backend)
{
$values["config[search_type]"] = $this->search_backend;
if (strpos($this->search_backend, 'fulltext_sphinx'))
{
// Set board Sphinx id in according to respective setup-sphinx.sh $ID value
$sql = 'UPDATE ' . CONFIG_TABLE . "
SET config_value = '" . $this->db->sql_escape('gokw5rvjvvxp8kgj') . "'
WHERE config_name = '" . $this->db->sql_escape('fulltext_sphinx_id') . "'";
$this->db->sql_query($sql);
}
$form->setValues($values);
$crawler = self::submit($form);
$this->purge_cache();
$form = $crawler->selectButton($this->lang('YES'))->form();
$values = $form->getValues();
@@ -161,6 +200,11 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
$this->assert_search_posts_by_author('searchforauthoruser', 2, $sort_key);
$this->assert_search_topics_by_author('searchforauthoruser', 1, $sort_key);
$this->assert_search_posts_by_author_id($searchforauthoruser_id, 2, $sort_key);
$this->assert_search_topics_by_author_id($searchforauthoruser_id, 1, $sort_key);
$this->assert_search_posts_by_author_id($searchforauthoruser_id, 2, $sort_key, 'a'); //search asc order
$this->assert_search_topics_by_author_id($searchforauthoruser_id, 1, $sort_key, 'a'); // search asc order
}
$this->assert_search_not_found('loremipsumdedo');
@@ -177,6 +221,159 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
$this->delete_topic($topic_multiple_results_count2['topic_id']);
}
public function test_caching_search_results()
{
global $phpbb_root_path;
// Sphinx search doesn't use phpBB search results caching
if (strpos($this->search_backend, 'fulltext_sphinx'))
{
$this->markTestSkipped("Sphinx search doesn't use phpBB search results caching");
}
$this->purge_cache();
$this->login();
$this->admin_login();
$crawler = self::request('GET', 'search.php?author_id=2&sr=posts');
$posts_found_text = $crawler->filter('.searchresults-title')->text();
// Get total user's post count
preg_match('!(\d+)!', $posts_found_text, $matches);
$posts_count = (int) $matches[1];
$this->assertStringContainsString("Search found $posts_count matches", $posts_found_text, $this->search_backend);
// Set this value to cache less results than total count
$sql = 'UPDATE ' . CONFIG_TABLE . '
SET config_value = ' . floor($posts_count / 3) . "
WHERE config_name = '" . $this->db->sql_escape('search_block_size') . "'";
$this->db->sql_query($sql);
// Temporarily set posts_per_page to the value allowing to get several pages (4+)
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post');
$form = $crawler->selectButton('Submit')->form();
$values = $form->getValues();
$current_posts_per_page = $values['config[posts_per_page]'];
$values['config[posts_per_page]'] = floor($posts_count / 10);
$form->setValues($values);
$crawler = self::submit($form);
$this->assertEquals(1, $crawler->filter('.successbox')->count(), $this->search_backend);
// Now actually test caching search results
$this->purge_cache();
// Default sort direction is 'd' (descending), browse the 1st page
$crawler = self::request('GET', 'search.php?author_id=2&sr=posts');
$pagination = $crawler->filter('.pagination')->eq(0);
$posts_found_text = $pagination->text();
$this->assertStringContainsString("Search found $posts_count matches", $posts_found_text, $this->search_backend);
// Filter all search result page links on the 1st page
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
// Get last page number
$last_page = (int) $pagination->last()->text();
// Browse the last search page
$crawler = self::$client->click($pagination->selectLink($last_page)->link());
$pagination = $crawler->filter('.pagination')->eq(0);
// Filter all search result page links on the last page
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
// Now change sort direction to ascending
$form = $crawler->selectButton('sort')->form();
$values = $form->getValues();
$values['sd'] = 'a';
$form->setValues($values);
$crawler = self::submit($form);
$pagination = $crawler->filter('.pagination')->eq(0);
// Filter all search result page links on the 1st page with new sort direction
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
// Browse the rest of search results pages with new sort direction
$pages = range(2, $last_page);
foreach ($pages as $page_number)
{
$crawler = self::$client->click($pagination->selectLink($page_number)->link());
$pagination = $crawler->filter('.pagination')->eq(0);
$pagination = $pagination->filter('li > a')->reduce(
function ($node, $i)
{
return ($node->attr('class') == 'button');
}
);
}
// Get search results cache varname
$finder = new \Symfony\Component\Finder\Finder();
$finder
->name('data_search_results_*.php')
->files()
->in($phpbb_root_path . 'cache/' . PHPBB_ENVIRONMENT);
$iterator = $finder->getIterator();
$iterator->rewind();
$cache_filename = $iterator->current();
$cache_varname = substr($cache_filename->getBasename('.php'), 4);
// Get cached post ids data
$cache = $this->get_cache_driver();
$post_ids_cached = $cache->get($cache_varname);
$cached_results_count = count($post_ids_cached) - 2; // Don't count '-1' and '-2' indexes
$post_ids_cached_backup = $post_ids_cached;
// Cached data still should have initial 'd' sort direction
$this->assertTrue($post_ids_cached[-2] === 'd', $this->search_backend);
// Cached search results count should be equal to displayed on search results page
$this->assertEquals($posts_count, $post_ids_cached[-1], $this->search_backend);
// Actual cached data array count should be equal to displayed on search results page too
$this->assertEquals($posts_count, $cached_results_count, $this->search_backend);
// Cached data array shouldn't change after removing duplicates. That is, it shouldn't have any duplicates.
unset($post_ids_cached[-2], $post_ids_cached[-1]);
unset($post_ids_cached_backup[-2], $post_ids_cached_backup[-1]);
$post_ids_cached = array_unique($post_ids_cached);
$this->assertEquals($post_ids_cached_backup, $post_ids_cached, $this->search_backend);
// Restore this value to default
$sql = 'UPDATE ' . CONFIG_TABLE . "
SET config_value = 250
WHERE config_name = '" . $this->db->sql_escape('search_block_size') . "'";
$this->db->sql_query($sql);
// Restore posts_per_page value
$crawler = self::request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=post');
$form = $crawler->selectButton('Submit')->form();
$values = $form->getValues();
$values['config[posts_per_page]'] = $current_posts_per_page;
$form->setValues($values);
$crawler = self::submit($form);
$this->assertEquals(1, $crawler->filter('.successbox')->count(), $this->search_backend);
}
protected function create_search_index($backend = null)
{
$this->add_lang('acp/search');
@@ -211,7 +408,12 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
// Ensure search index has been actually created
$crawler = self::request('GET', 'adm/index.php?i=acp_search&mode=index&sid=' . $this->sid);
$posts_indexed = (int) $crawler->filter('#acp_search_index_' . $search_type . ' td')->eq(1)->text();
$posts_indexed = (int) $crawler->filter('#acp_search_index_' . $search_type . ' td')->reduce(
function ($node, $i) {
// Find the value of total posts indexed
return (strpos($node->text(), $this->lang('FULLTEXT_MYSQL_TOTAL_POSTS')) !== false || strpos($node->text(), $this->lang('TOTAL_WORDS')) !== false);
})
->nextAll()->eq(0)->text();
$this->assertTrue($posts_indexed > 0);
}
@@ -248,7 +450,12 @@ abstract class phpbb_functional_search_base extends phpbb_functional_test_case
// Ensure search index has been actually removed
$crawler = self::request('GET', 'adm/index.php?i=acp_search&mode=index&sid=' . $this->sid);
$posts_indexed = (int) $crawler->filter('#acp_search_index_' . $this->search_backend . ' td')->eq(1)->text();
$posts_indexed = (int) $crawler->filter('#acp_search_index_' . $this->search_backend . ' td')->reduce(
function ($node, $i) {
// Find the value of total posts indexed
return (strpos($node->text(), $this->lang('FULLTEXT_MYSQL_TOTAL_POSTS')) !== false || strpos($node->text(), $this->lang('TOTAL_WORDS')) !== false);
})
->nextAll()->eq(0)->text();
$this->assertEquals(0, $posts_indexed);
}
}

View File

@@ -20,8 +20,31 @@ class phpbb_functional_search_sphinx_test extends phpbb_functional_search_base
{
protected $search_backend = '\phpbb\search\fulltext_sphinx';
protected function create_search_index($backend = null)
{
parent::create_search_index($backend);
$this->purge_cache();
if (!$backend || $this->search_backend == $backend)
{
$output = $retval = null;
// After creating phpBB search index, build Sphinx index
exec('sudo -S service sphinxsearch stop', $output, $retval); // Attempt to stop sphinxsearch service in case it's running
exec('sudo -S indexer --all', $output, $retval); // Run sphinxsearch indexer
exec('sudo -S service sphinxsearch start', $output, $retval); // Attempt to start sphinxsearch service again
}
}
public function test_search_backend()
{
$this->markTestIncomplete('Sphinx Tests are not supported');
if ($this->db->sql_layer != 'mysqli') // Sphinx test runs on MySQL/MariaDB only so far
{
$this->markTestIncomplete('Sphinx Tests are not supported');
}
else
{
parent::test_search_backend();
}
}
}

View File

@@ -28,7 +28,7 @@ class phpbb_functional_switch_permissions_test extends phpbb_functional_test_cas
$this->add_lang(['common', 'ucp']);
}
public function test_switch_permissions()
public function test_switch_permissions_acp()
{
$user_id = $this->create_user(self::TEST_USER);
@@ -67,4 +67,53 @@ class phpbb_functional_switch_permissions_test extends phpbb_functional_test_cas
$crawler->text()
);
}
/**
* @depends test_switch_permissions_acp
*/
public function test_switch_permissions_ucp()
{
$db = $this->get_db();
$sql = 'SELECT user_id
FROM ' . USERS_TABLE . "
WHERE username = '" . self::TEST_USER . "'";
$result = $db->sql_query($sql);
$user_id = $db->sql_fetchfield('user_id');
$db->sql_freeresult($result);
// Open memberlist profile page for user
$crawler = self::request('GET', "memberlist.php?mode=viewprofile&u={$user_id}&sid={$this->sid}");
// Use permissions
$link = $crawler->selectLink($this->lang('USE_PERMISSIONS'))->link();
$crawler = self::$client->click($link);
// Check that we switched permissions to test user
$this->assertStringContainsString(
str_replace('<br />', '<br>', $this->lang('PERMISSIONS_TRANSFERRED', self::TEST_USER)),
$crawler->html()
);
// Check that UCP pages don't get forced to UCP main with restore permission info
$this->add_lang(['memberlist', 'ucp']);
$crawler = self::request('GET', "ucp.php?i=ucp_profile&mode=profile_info&sid={$this->sid}");
$this->assertStringContainsString(
$this->lang('EDIT_PROFILE'),
$crawler->text()
);
// Check that restore permissions link exists
$crawler = self::$client->request('GET', 'index.php?sid=' . $this->sid);
$this->assertStringContainsString(
$this->lang('RESTORE_PERMISSIONS'),
$crawler->text()
);
// Check that restore permissions works
$crawler = self::$client->request('GET', 'ucp.php?mode=restore_perm&sid=' . $this->sid);
$this->assertStringContainsString(
$this->lang('PERMISSIONS_RESTORED'),
$crawler->text()
);
}
}

View File

@@ -601,7 +601,16 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_
// Assert new topic title is indexed as well
$this->add_lang('search');
self::request('GET', "search.php?keywords=bang&sid={$this->sid}");
$this->assertStringContainsString(sprintf($this->lang['FOUND_SEARCH_MATCHES'][1], 1), self::get_content());
// Sphinx search doesn't apply to unapproved or softdeleted posts
if (strpos($this->get_search_type(), 'fulltext_sphinx'))
{
$this->assertStringContainsString(sprintf($this->lang['FOUND_SEARCH_MATCHES'][2], 0), self::get_content());
}
else
{
$this->assertStringContainsString(sprintf($this->lang['FOUND_SEARCH_MATCHES'][1], 1), self::get_content());
}
}
public function test_move_topic_back()

View File

@@ -81,13 +81,13 @@ class phpbb_functions_content_get_context_test extends TestCase
'text' => 'This is a sample text.',
'words' => ['sample'],
'length' => 0,
'expected' => '...',
'expected' => 'This is a sample text.',
],
'negative length' => [
'text' => 'This is a sample text.',
'words' => ['sample'],
'length' => -10,
'expected' => '...',
'expected' => 'This is a sample text.',
],
'ellipses_beginning' => [
'text' => 'foo foo foo foo foo foo foo foo bar',
@@ -112,12 +112,120 @@ class phpbb_functions_content_get_context_test extends TestCase
'words' => ['word1', 'word2'],
'length' => 10,
'expected' => 'word1 ... word2',
],
];
}
/**
* Data provider for unicode get_context test cases.
*
* @return array
*/
public function data_get_context_unicode(): array
{
return [
'text contains words and length greater than text' => [
'text' => 'Это пример текста, содержащего разнообразные слова, включая пример, текст и слова.',
'words' => ['пример', 'слова'],
'length' => 100,
'expected' => 'Это пример текста, содержащего разнообразные слова, включая пример, текст и слова.',
],
'text contains words and length less than text' => [
'text' => 'Это пример текста, содержащего разнообразные слова, включая шаблон, текст и слова.',
'words' => ['пример', 'слова'],
'length' => 50,
'expected' => 'Это пример текста, содержащего разнообразные слова ...',
],
'text does not contain words' => [
'text' => 'Это пример текста, содержащего разнообразные слова, но ни одно из них не совпадает с искомыми.',
'words' => ['nonexistent'],
'length' => 50,
'expected' => 'Это пример текста, содержащего разнообразные слова ...',
],
'desired length equal to text length' => [
'text' => 'Текст точной длины.',
'words' => ['Текст', 'точной'],
'length' => 19,
'expected' => 'Текст точной длины.',
],
'text with html entities' => [
'text' => 'Это пример текста, содержащего &amp; и &lt; и &gt; лексемы.',
'words' => ['пример', 'содержащего'],
'length' => 40,
'expected' => 'Это пример текста, содержащего &amp; и &lt; и ...',
],
'text with html entities and contains last word' => [
'text' => 'Это пример текста, содержащего &amp; и &lt; и &gt; лексемы.',
'words' => ['пример', 'лексемы'],
'length' => 40,
'expected' => 'Это пример текста ... и &lt; и &gt; лексемы.',
],
'text with multiple spaces and special characters' => [
'text' => 'Это пример текста, содержащего разнообразные слова.',
'words' => ['пример', 'разнообразные'],
'length' => 50,
'expected' => 'Это пример текста, содержащего разнообразные слова.',
],
'empty text' => [
'text' => '',
'words' => ['пример', 'слова'],
'length' => 50,
'expected' => '',
],
'empty words array' => [
'text' => 'Это пример текста, содержащего разнообразные слова.',
'words' => [],
'length' => 50,
'expected' => 'Это пример текста, содержащего разнообразные слова.',
],
'zero length' => [
'text' => 'Это пример текста.',
'words' => ['пример'],
'length' => 0,
'expected' => 'Это пример текста.',
],
'negative length' => [
'text' => 'Это пример текста.',
'words' => ['sample'],
'length' => -10,
'expected' => 'Это пример текста.',
],
'ellipses_beginning' => [
'text' => 'раз раз раз раз раз раз раз раз два',
'words' => ['два'],
'length' => 10,
'expected' => '... раз раз два',
],
'ellipsis_end' => [
'text' => 'два раз раз раз раз раз раз раз раз',
'words' => ['два'],
'length' => 10,
'expected' => 'два раз раз ...',
],
'ellipsis_middle' => [
'text' => 'раз слово1 раз раз раз раз раз раз раз раз раз слово2 раз',
'words' => ['слово1', 'слово2'],
'length' => 15,
'expected' => '... слово1 ... слово2 ...',
],
'ellipsis_middle2' => [
'text' => 'слово1 foo foo foo foo foo foo foo foo foo слово2',
'words' => ['слово1', 'слово2'],
'length' => 10,
'expected' => 'слово1 ... слово2',
],
'fruits_spanish' => [
'text' => 'Manzana,plátano,naranja,fresa,mango,uva,piña,pera,kiwi,cereza,sandía,melón,papaya,arándano,durazno',
'words' => ['piña'],
'length' => 20,
'expected' => '... uva,piña,pera ...',
]
];
}
/**
* @dataProvider data_get_context
* @dataProvider data_get_context_unicode
*/
public function test_get_context($text, $words, $length, $expected)
{

View File

@@ -470,9 +470,6 @@ class phpbb_path_helper_test extends phpbb_test_case
->setConstructorArgs([new phpbb_mock_request()])
->setMethods(['get', 'getSchemeAndHttpHost', 'getBasePath', 'getPathInfo'])
->getMock();
$symfony_request->method('get')
->with('_referer')
->willReturn('http://www.phpbb.com/community/route1/route2/');
$symfony_request->method('getSchemeAndHttpHost')
->willReturn('http://www.phpbb.com');
$symfony_request->method('getBasePath')
@@ -486,6 +483,9 @@ class phpbb_path_helper_test extends phpbb_test_case
->willReturn(true);
$request->method('escape')
->willReturnArgument(0);
$request->method('header')
->with('Referer')
->willReturn('http://www.phpbb.com/community/route1/route2/');
$path_helper = new \phpbb\path_helper(
$symfony_request,

View File

@@ -15,7 +15,7 @@ require_once __DIR__ . '/template_test_case.php';
class phpbb_template_extension_test extends phpbb_template_template_test_case
{
protected function setup_engine(array $new_config = array())
protected function setup_engine(array $new_config = array(), string $template_path = '')
{
global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx;

View File

@@ -21,7 +21,7 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te
/** @var string */
protected $parent_template_path;
protected function setup_engine(array $new_config = array())
protected function setup_engine(array $new_config = array(), string $template_path = '')
{
global $phpbb_root_path, $phpEx, $user;

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