From fd22d99e69c8d87292b03fbb254ed87113abbc8c Mon Sep 17 00:00:00 2001 From: Neo <321592+Neo-Desktop@users.noreply.github.com> Date: Fri, 19 Dec 2025 16:10:42 -0800 Subject: [PATCH] Version 4.7.8 --- Credits.txt | 13 +- admin/install/eula.txt | 2 +- applications/blog/api/GraphQL/Mutation.php | 41 + .../api/GraphQL/Mutations/CreateEntry.php | 95 + .../blog/api/GraphQL/Mutations/ReplyEntry.php | 108 + .../blog/api/GraphQL/Queries/Blog.php | 69 + .../blog/api/GraphQL/Queries/Blogs.php | 64 + .../blog/api/GraphQL/Queries/Entries.php | 143 + .../blog/api/GraphQL/Queries/Entry.php | 77 + applications/blog/api/GraphQL/Query.php | 42 + .../blog/api/GraphQL/TypeRegistry.php | 76 + .../blog/api/GraphQL/Types/BlogType.php | 58 + .../blog/api/GraphQL/Types/CommentType.php | 75 + .../blog/api/GraphQL/Types/EntryType.php | 58 + applications/blog/api/blogs.php | 5 +- applications/blog/api/categories.php | 3 +- applications/blog/api/entries.php | 1 + applications/blog/api/entrycategories.php | 8 + applications/blog/data/acpmenu.json | 12 +- applications/blog/data/javascript.xml | 9 +- applications/blog/data/lang.xml | 2 +- applications/blog/data/theme.xml | 80 +- applications/blog/data/versions.json | 16 +- applications/blog/setup/upg_107602/data.json | 23 + applications/blog/setup/upg_107620/data.json | 23 + .../blog/setup/upg_107620/javascript.json | 14 + applications/blog/setup/upg_107621/data.json | 23 + applications/blog/setup/upg_107622/data.json | 23 + applications/blog/setup/upg_107623/data.json | 23 + applications/blog/setup/upg_107624/data.json | 23 + applications/blog/setup/upg_107625/data.json | 23 + applications/blog/setup/upg_107626/data.json | 23 + applications/blog/setup/upg_107627/data.json | 23 + applications/blog/setup/upg_107628/data.json | 23 + applications/blog/setup/upg_107640/data.json | 23 + applications/blog/setup/upg_107640/theme.json | 24 + applications/blog/setup/upg_107641/data.json | 23 + applications/blog/setup/upg_107642/data.json | 23 + applications/blog/setup/upg_107643/data.json | 23 + applications/blog/sources/Blog/Blog.php | 2 +- applications/blog/sources/Entry/Comment.php | 5 - applications/blog/sources/Entry/Entry.php | 15 +- .../calendar/api/GraphQL/Mutation.php | 40 + .../api/GraphQL/Mutations/CreateEvent.php | 99 + .../calendar/api/GraphQL/Queries/Calendar.php | 69 + .../api/GraphQL/Queries/Calendars.php | 64 + .../calendar/api/GraphQL/Queries/Event.php | 77 + .../calendar/api/GraphQL/Queries/Events.php | 127 + applications/calendar/api/GraphQL/Query.php | 42 + .../calendar/api/GraphQL/TypeRegistry.php | 72 + .../api/GraphQL/Types/CalendarType.php | 59 + .../api/GraphQL/Types/CommentType.php | 75 + .../calendar/api/GraphQL/Types/EventType.php | 96 + applications/calendar/api/events.php | 1 + applications/calendar/data/javascript.xml | 120 +- applications/calendar/data/lang.xml | 3 +- applications/calendar/data/schema.json | 124 +- applications/calendar/data/theme.xml | 142 +- applications/calendar/data/versions.json | 16 +- .../calendar/modules/front/calendar/event.php | 12 + .../calendar/modules/front/calendar/view.php | 14 +- .../calendar/setup/upg_105013/queries.json | 4 +- .../calendar/setup/upg_107602/data.json | 23 + .../calendar/setup/upg_107620/data.json | 23 + .../calendar/setup/upg_107620/javascript.json | 14 + .../calendar/setup/upg_107620/lang.json | 14 + .../calendar/setup/upg_107620/theme.json | 20 + .../calendar/setup/upg_107621/data.json | 23 + .../calendar/setup/upg_107622/data.json | 23 + .../calendar/setup/upg_107623/data.json | 23 + .../calendar/setup/upg_107624/data.json | 23 + .../calendar/setup/upg_107625/data.json | 23 + .../calendar/setup/upg_107626/data.json | 23 + .../calendar/setup/upg_107627/data.json | 23 + .../calendar/setup/upg_107628/data.json | 23 + .../calendar/setup/upg_107640/data.json | 23 + .../calendar/setup/upg_107640/javascript.json | 14 + .../calendar/setup/upg_107640/queries.json | 20 + .../calendar/setup/upg_107640/theme.json | 27 + .../calendar/setup/upg_107641/data.json | 23 + .../calendar/setup/upg_107642/data.json | 23 + .../calendar/setup/upg_107643/data.json | 23 + .../calendar/sources/Calendar/Calendar.php | 2 +- applications/calendar/sources/Date/Date.php | 8 +- .../calendar/sources/Event/Comment.php | 5 - applications/calendar/sources/Event/Event.php | 31 +- .../calendar/sources/Event/Review.php | 5 - applications/cms/Application.php | 3 +- applications/cms/api/records.php | 1 + applications/cms/data/cms_theme.xml | 38 +- applications/cms/data/databaseschema.json | 16 + applications/cms/data/javascript.xml | 43 +- applications/cms/data/lang.xml | 5 +- applications/cms/data/schema.json | 24 + applications/cms/data/theme.xml | 4 +- applications/cms/data/versions.json | 16 +- .../cms/extensions/core/Sitemap/Databases.php | 6 +- .../cms/extensions/core/Sitemap/Pages.php | 11 +- .../cms/modules/admin/pages/pages.php | 25 +- .../cms/modules/front/database/category.php | 5 + .../cms/modules/front/database/record.php | 17 +- .../cms/modules/front/pages/builder.php | 4 + applications/cms/setup/upg_106100/upgrade.php | 30 +- applications/cms/setup/upg_107602/data.json | 23 + applications/cms/setup/upg_107620/data.json | 23 + .../cms/setup/upg_107620/javascript.json | 14 + applications/cms/setup/upg_107620/lang.json | 16 + .../cms/setup/upg_107620/queries.json | 38 + applications/cms/setup/upg_107620/upgrade.php | 73 + applications/cms/setup/upg_107621/data.json | 23 + applications/cms/setup/upg_107622/data.json | 23 + applications/cms/setup/upg_107623/data.json | 23 + applications/cms/setup/upg_107624/data.json | 23 + applications/cms/setup/upg_107625/data.json | 23 + applications/cms/setup/upg_107626/data.json | 23 + applications/cms/setup/upg_107627/data.json | 23 + applications/cms/setup/upg_107628/data.json | 23 + applications/cms/setup/upg_107640/data.json | 23 + applications/cms/setup/upg_107640/theme.json | 20 + applications/cms/setup/upg_107641/data.json | 23 + applications/cms/setup/upg_107642/data.json | 23 + applications/cms/setup/upg_107643/data.json | 23 + .../cms/sources/Categories/Categories.php | 3 + .../cms/sources/Databases/Databases.php | 2 +- applications/cms/sources/Fields/Fields.php | 8 +- applications/cms/sources/Pages/Page.php | 15 + applications/cms/sources/Records/Comment.php | 5 - applications/cms/sources/Records/Records.php | 44 +- applications/cms/sources/Records/Review.php | 5 - applications/convert/data/javascript.xml | 5 +- applications/convert/data/lang.xml | 2 +- applications/convert/data/versions.json | 16 +- .../convert/setup/upg_107602/data.json | 23 + .../convert/setup/upg_107620/data.json | 23 + .../convert/setup/upg_107620/javascript.json | 14 + .../convert/setup/upg_107621/data.json | 23 + .../convert/setup/upg_107622/data.json | 23 + .../convert/setup/upg_107623/data.json | 23 + .../convert/setup/upg_107624/data.json | 23 + .../convert/setup/upg_107625/data.json | 23 + .../convert/setup/upg_107626/data.json | 23 + .../convert/setup/upg_107627/data.json | 23 + .../convert/setup/upg_107628/data.json | 23 + .../convert/setup/upg_107640/data.json | 23 + .../convert/setup/upg_107641/data.json | 23 + .../convert/setup/upg_107642/data.json | 23 + .../convert/setup/upg_107643/data.json | 23 + applications/convert/sources/Library/Core.php | 18 +- .../convert/sources/Library/Downloads.php | 8 +- .../Mutations/ChangeNotificationSetting.php | 4 +- .../GraphQL/Mutations/DeleteAttachment.php | 8 +- .../core/api/GraphQL/Mutations/Follow.php | 49 +- .../core/api/GraphQL/Mutations/IgnoreUser.php | 12 +- .../Mutations/MarkNotificationRead.php | 4 +- .../Messenger/AddConversationUser.php | 6 +- .../Mutations/Messenger/LeaveConversation.php | 4 +- .../Messenger/RemoveConversationUser.php | 4 +- .../core/api/GraphQL/Mutations/Unfollow.php | 4 +- .../GraphQL/Mutations/UploadAttachment.php | 13 +- .../core/api/GraphQL/Queries/ActiveUsers.php | 2 +- .../core/api/GraphQL/Queries/Club.php | 2 +- .../core/api/GraphQL/Queries/Clubs.php | 96 + .../core/api/GraphQL/Queries/Content.php | 2 +- .../core/api/GraphQL/Queries/Group.php | 11 +- .../core/api/GraphQL/Queries/Language.php | 2 +- .../api/GraphQL/Queries/LoginHandlers.php | 2 +- applications/core/api/GraphQL/Queries/Me.php | 2 +- .../core/api/GraphQL/Queries/Member.php | 2 +- .../core/api/GraphQL/Queries/Members.php | 95 + .../GraphQL/Queries/MessengerConversation.php | 2 +- .../Queries/MessengerConversations.php | 2 +- .../api/GraphQL/Queries/MessengerFolders.php | 2 +- .../api/GraphQL/Queries/NotificationTypes.php | 2 +- .../core/api/GraphQL/Queries/OurPicks.php | 2 +- .../GraphQL/Queries/PopularContributors.php | 2 +- .../core/api/GraphQL/Queries/Search.php | 2 +- .../core/api/GraphQL/Queries/Settings.php | 2 +- .../core/api/GraphQL/Queries/Stats.php | 2 +- .../core/api/GraphQL/Queries/Stream.php | 2 +- .../core/api/GraphQL/Queries/Streams.php | 2 +- applications/core/api/GraphQL/Query.php | 4 +- .../core/api/GraphQL/TypeRegistry.php | 118 +- .../core/api/GraphQL/Types/ClubType.php | 14 +- .../GraphQL/Types/ContentSearchResultType.php | 2 +- .../core/api/GraphQL/Types/MemberType.php | 9 +- .../core/api/GraphQL/Types/StatsType.php | 8 +- applications/core/api/members.php | 14 +- applications/core/data/acpsearch.json | 10 +- applications/core/data/build.xml | 4 +- applications/core/data/emails.xml | 42 +- applications/core/data/extensions.json | 591 +-- applications/core/data/javascript.xml | 947 ++-- applications/core/data/lang.xml | 44 +- applications/core/data/requirements.json | 2 +- applications/core/data/schema.json | 68 + applications/core/data/settings.json | 5 + applications/core/data/theme.xml | 960 ++-- applications/core/data/versions.json | 16 +- .../AchievementAction/ContentPromotion.php | 15 +- .../core/CommunityEnhancements/Zapier.php | 5 +- .../core/GroupForm/GroupSettings.php | 2 +- .../core/extensions/core/GroupForm/Social.php | 6 +- .../BasicInformation.php | 2 +- .../extensions/core/OutputPlugins/GraphQl.php | 2 +- .../extensions/core/ProfileSteps/Core.php | 2 +- .../core/extensions/core/Sitemap/Clubs.php | 247 + .../core/extensions/core/Sitemap/Content.php | 8 +- .../interface/ckeditor/ckeditor/CHANGES.md | 4509 +++++++++-------- .../interface/ckeditor/ckeditor/LICENSE.md | 2872 +++++------ .../interface/ckeditor/ckeditor/SECURITY.md | 20 +- .../ckeditor/ckeditor/build-config.js | 2 +- .../interface/ckeditor/ckeditor/ckeditor.js | 1783 +++---- .../interface/ckeditor/ckeditor/contents.css | 416 +- .../ckeditor/lang/_translationstatus.txt | 126 +- .../interface/ckeditor/ckeditor/lang/af.js | 2 +- .../interface/ckeditor/ckeditor/lang/ar.js | 2 +- .../interface/ckeditor/ckeditor/lang/az.js | 2 +- .../interface/ckeditor/ckeditor/lang/bg.js | 2 +- .../interface/ckeditor/ckeditor/lang/bn.js | 2 +- .../interface/ckeditor/ckeditor/lang/bs.js | 2 +- .../interface/ckeditor/ckeditor/lang/ca.js | 2 +- .../interface/ckeditor/ckeditor/lang/cs.js | 2 +- .../interface/ckeditor/ckeditor/lang/cy.js | 2 +- .../interface/ckeditor/ckeditor/lang/da.js | 2 +- .../interface/ckeditor/ckeditor/lang/de-ch.js | 2 +- .../interface/ckeditor/ckeditor/lang/de.js | 2 +- .../interface/ckeditor/ckeditor/lang/el.js | 2 +- .../interface/ckeditor/ckeditor/lang/en-au.js | 4 +- .../interface/ckeditor/ckeditor/lang/en-ca.js | 2 +- .../interface/ckeditor/ckeditor/lang/en-gb.js | 2 +- .../interface/ckeditor/ckeditor/lang/en.js | 2 +- .../interface/ckeditor/ckeditor/lang/eo.js | 2 +- .../interface/ckeditor/ckeditor/lang/es-mx.js | 2 +- .../interface/ckeditor/ckeditor/lang/es.js | 2 +- .../interface/ckeditor/ckeditor/lang/et.js | 2 +- .../interface/ckeditor/ckeditor/lang/eu.js | 2 +- .../interface/ckeditor/ckeditor/lang/fa.js | 2 +- .../interface/ckeditor/ckeditor/lang/fi.js | 2 +- .../interface/ckeditor/ckeditor/lang/fo.js | 2 +- .../interface/ckeditor/ckeditor/lang/fr-ca.js | 2 +- .../interface/ckeditor/ckeditor/lang/fr.js | 2 +- .../interface/ckeditor/ckeditor/lang/gl.js | 2 +- .../interface/ckeditor/ckeditor/lang/gu.js | 2 +- .../interface/ckeditor/ckeditor/lang/he.js | 2 +- .../interface/ckeditor/ckeditor/lang/hi.js | 2 +- .../interface/ckeditor/ckeditor/lang/hr.js | 2 +- .../interface/ckeditor/ckeditor/lang/hu.js | 2 +- .../interface/ckeditor/ckeditor/lang/id.js | 2 +- .../interface/ckeditor/ckeditor/lang/is.js | 2 +- .../interface/ckeditor/ckeditor/lang/it.js | 4 +- .../interface/ckeditor/ckeditor/lang/ja.js | 2 +- .../interface/ckeditor/ckeditor/lang/ka.js | 2 +- .../interface/ckeditor/ckeditor/lang/km.js | 2 +- .../interface/ckeditor/ckeditor/lang/ko.js | 2 +- .../interface/ckeditor/ckeditor/lang/ku.js | 2 +- .../interface/ckeditor/ckeditor/lang/lt.js | 2 +- .../interface/ckeditor/ckeditor/lang/lv.js | 2 +- .../interface/ckeditor/ckeditor/lang/mk.js | 2 +- .../interface/ckeditor/ckeditor/lang/mn.js | 2 +- .../interface/ckeditor/ckeditor/lang/ms.js | 2 +- .../interface/ckeditor/ckeditor/lang/nb.js | 2 +- .../interface/ckeditor/ckeditor/lang/nl.js | 2 +- .../interface/ckeditor/ckeditor/lang/no.js | 2 +- .../interface/ckeditor/ckeditor/lang/oc.js | 2 +- .../interface/ckeditor/ckeditor/lang/pl.js | 2 +- .../interface/ckeditor/ckeditor/lang/pt-br.js | 4 +- .../interface/ckeditor/ckeditor/lang/pt.js | 2 +- .../interface/ckeditor/ckeditor/lang/ro.js | 2 +- .../interface/ckeditor/ckeditor/lang/ru.js | 2 +- .../interface/ckeditor/ckeditor/lang/si.js | 2 +- .../interface/ckeditor/ckeditor/lang/sk.js | 2 +- .../interface/ckeditor/ckeditor/lang/sl.js | 2 +- .../interface/ckeditor/ckeditor/lang/sq.js | 2 +- .../ckeditor/ckeditor/lang/sr-latn.js | 4 +- .../interface/ckeditor/ckeditor/lang/sr.js | 4 +- .../interface/ckeditor/ckeditor/lang/sv.js | 2 +- .../interface/ckeditor/ckeditor/lang/th.js | 2 +- .../interface/ckeditor/ckeditor/lang/tr.js | 2 +- .../interface/ckeditor/ckeditor/lang/tt.js | 2 +- .../interface/ckeditor/ckeditor/lang/ug.js | 2 +- .../interface/ckeditor/ckeditor/lang/uk.js | 4 +- .../interface/ckeditor/ckeditor/lang/vi.js | 2 +- .../interface/ckeditor/ckeditor/lang/zh-cn.js | 2 +- .../interface/ckeditor/ckeditor/lang/zh.js | 2 +- .../colordialog/dialogs/colordialog.css | 40 +- .../ckeditor/plugins/dialog/styles/dialog.css | 36 +- .../ckeditor/ckeditor/plugins/icons.png | Bin 7086 -> 6115 bytes .../ckeditor/ckeditor/plugins/icons_hidpi.png | Bin 20982 -> 18537 bytes .../ckeditor/plugins/ipsautosave/plugin.js | 7 +- .../ckeditor/plugins/ipsquote/plugin.js | 18 +- .../ckeditor/ckeditor/skins/ips/dialog.css | 8 +- .../ckeditor/ckeditor/skins/ips/dialog_ie.css | 8 +- .../ckeditor/skins/ips/dialog_ie7.css | 8 +- .../ckeditor/skins/ips/dialog_ie8.css | 8 +- .../ckeditor/skins/ips/dialog_iequirks.css | 8 +- .../ckeditor/ckeditor/skins/ips/editor.css | 10 +- .../ckeditor/skins/ips/editor_gecko.css | 10 +- .../ckeditor/ckeditor/skins/ips/editor_ie.css | 10 +- .../ckeditor/skins/ips/editor_ie7.css | 10 +- .../ckeditor/skins/ips/editor_ie8.css | 10 +- .../ckeditor/skins/ips/editor_iequirks.css | 10 +- .../ckeditor/ckeditor/skins/ips/icons.png | Bin 7086 -> 6115 bytes .../ckeditor/skins/ips/icons_hidpi.png | Bin 20982 -> 18537 bytes .../ckeditor/skins/ips/images/arrow.png | Bin 191 -> 178 bytes .../ckeditor/skins/ips/images/close.png | Bin 468 -> 328 bytes .../ckeditor/skins/ips/images/hidpi/close.png | Bin 1271 -> 893 bytes .../skins/ips/images/hidpi/lock-open.png | Bin 1329 -> 821 bytes .../ckeditor/skins/ips/images/hidpi/lock.png | Bin 1299 -> 986 bytes .../skins/ips/images/hidpi/refresh.png | Bin 1842 -> 1157 bytes .../ckeditor/skins/ips/images/lock-open.png | Bin 349 -> 256 bytes .../ckeditor/skins/ips/images/lock.png | Bin 475 -> 382 bytes .../ckeditor/skins/ips/images/refresh.png | Bin 422 -> 318 bytes .../ckeditor/skins/ips/images/spinner.gif | Bin 2984 -> 2528 bytes .../ckeditor/ckeditor/skins/ips/readme.md | 102 +- .../ckeditor/ckeditor/skins/moono/dialog.css | 8 +- .../ckeditor/skins/moono/dialog_ie.css | 8 +- .../ckeditor/skins/moono/dialog_ie7.css | 8 +- .../ckeditor/skins/moono/dialog_ie8.css | 8 +- .../ckeditor/skins/moono/dialog_iequirks.css | 8 +- .../ckeditor/ckeditor/skins/moono/editor.css | 10 +- .../ckeditor/skins/moono/editor_gecko.css | 10 +- .../ckeditor/skins/moono/editor_ie.css | 10 +- .../ckeditor/skins/moono/editor_ie7.css | 10 +- .../ckeditor/skins/moono/editor_ie8.css | 10 +- .../ckeditor/skins/moono/editor_iequirks.css | 10 +- .../ckeditor/ckeditor/skins/moono/icons.png | Bin 9404 -> 8713 bytes .../ckeditor/skins/moono/icons_hidpi.png | Bin 28220 -> 26259 bytes .../ckeditor/ckeditor/skins/moono/readme.md | 98 +- .../interface/ckeditor/ckeditor/styles.js | 274 +- applications/core/interface/email/clock.png | Bin 4214 -> 214 bytes applications/core/interface/email/comment.png | Bin 195 -> 174 bytes .../core/interface/email/comment_alt.png | Bin 4173 -> 187 bytes .../core/interface/email/deviantart.png | Bin 204 -> 199 bytes applications/core/interface/email/discord.png | Bin 546 -> 379 bytes .../core/interface/email/download.png | Bin 213 -> 190 bytes applications/core/interface/email/etsy.png | Bin 278 -> 252 bytes .../core/interface/email/facebook.png | Bin 201 -> 186 bytes applications/core/interface/email/flickr.png | Bin 230 -> 222 bytes .../core/interface/email/foursquare.png | Bin 243 -> 223 bytes applications/core/interface/email/github.png | Bin 340 -> 321 bytes .../core/interface/email/linkedin.png | Bin 223 -> 210 bytes .../core/interface/email/rating_off.png | Bin 453 -> 339 bytes applications/core/interface/email/slack.png | Bin 314 -> 284 bytes applications/core/interface/email/spacer.png | Bin 95 -> 95 bytes applications/core/interface/email/tada.png | Bin 10826 -> 8235 bytes applications/core/interface/email/trophy.png | Bin 9365 -> 5666 bytes applications/core/interface/email/tumblr.png | Bin 187 -> 181 bytes applications/core/interface/email/twitch.png | Bin 465 -> 330 bytes applications/core/interface/email/twitter.png | Bin 258 -> 244 bytes applications/core/interface/email/vk.png | Bin 225 -> 216 bytes applications/core/interface/email/xing.png | Bin 285 -> 266 bytes applications/core/interface/email/youtube.png | Bin 354 -> 335 bytes .../core/interface/logos/login/Apple.png | Bin 2746 -> 558 bytes .../core/interface/logos/login/Microsoft.png | Bin 170 -> 165 bytes .../modules/admin/applications/apiLogs.php | 4 +- .../admin/applications/applications.php | 2 +- .../modules/admin/applications/developer.php | 42 +- .../core/modules/admin/clubs/clubs.php | 2 +- .../modules/admin/languages/languages.php | 8 +- .../core/modules/admin/members/members.php | 15 +- .../core/modules/admin/overview/onboard.php | 153 +- .../core/modules/admin/settings/dataLayer.php | 6 +- .../core/modules/admin/settings/mfa.php | 18 + .../core/modules/admin/staff/admin.php | 22 +- .../core/modules/admin/stats/moderators.php | 2 +- .../core/modules/admin/support/support.php | 29 +- .../core/modules/front/clubs/page.php | 9 +- .../core/modules/front/clubs/view.php | 3 +- .../core/modules/front/members/profile.php | 3 +- .../core/modules/front/search/search.php | 12 +- .../core/modules/front/system/ajax.php | 17 +- .../core/modules/front/system/attachments.php | 82 + .../modules/front/system/notifications.php | 5 +- .../core/modules/front/system/poll.php | 1 + .../core/modules/front/system/settings.php | 9 +- .../core/modules/front/system/widgets.php | 4 + .../modules/setup/upgrade/applications.php | 6 + .../core/setup/upg_107500/upgrade.php | 41 - applications/core/setup/upg_107602/data.json | 23 + applications/core/setup/upg_107602/lang.json | 15 + applications/core/setup/upg_107602/theme.json | 19 + applications/core/setup/upg_107620/data.json | 23 + .../core/setup/upg_107620/javascript.json | 23 + applications/core/setup/upg_107620/lang.json | 49 + .../core/setup/upg_107620/queries.json | 82 + .../core/setup/upg_107620/settings.json | 7 + applications/core/setup/upg_107620/theme.json | 36 + applications/core/setup/upg_107621/data.json | 23 + applications/core/setup/upg_107621/lang.json | 15 + applications/core/setup/upg_107622/data.json | 23 + applications/core/setup/upg_107622/lang.json | 15 + applications/core/setup/upg_107623/data.json | 23 + .../core/setup/upg_107623/javascript.json | 15 + applications/core/setup/upg_107623/lang.json | 15 + applications/core/setup/upg_107623/theme.json | 19 + applications/core/setup/upg_107624/data.json | 23 + applications/core/setup/upg_107624/lang.json | 15 + applications/core/setup/upg_107625/data.json | 23 + applications/core/setup/upg_107625/lang.json | 15 + applications/core/setup/upg_107626/data.json | 23 + applications/core/setup/upg_107626/lang.json | 15 + applications/core/setup/upg_107627/data.json | 23 + applications/core/setup/upg_107627/lang.json | 15 + applications/core/setup/upg_107628/data.json | 23 + applications/core/setup/upg_107628/lang.json | 15 + .../setup/upg_107640/acpSearchKeywords.json | 9 + applications/core/setup/upg_107640/data.json | 23 + .../core/setup/upg_107640/emailTemplates.json | 9 + .../core/setup/upg_107640/javascript.json | 16 + applications/core/setup/upg_107640/lang.json | 23 + .../core/setup/upg_107640/queries.json | 20 + applications/core/setup/upg_107640/theme.json | 59 + .../core/setup/upg_107640/upgrade.php | 63 + applications/core/setup/upg_107641/data.json | 23 + .../core/setup/upg_107641/javascript.json | 14 + applications/core/setup/upg_107641/lang.json | 15 + applications/core/setup/upg_107641/theme.json | 19 + applications/core/setup/upg_107642/data.json | 23 + applications/core/setup/upg_107642/lang.json | 15 + applications/core/setup/upg_107643/data.json | 23 + applications/core/setup/upg_107643/lang.json | 15 + .../core/sources/DataLayer/DataLayer.php | 8 +- applications/core/sources/Followed/Follow.php | 43 + .../core/sources/Profanity/Profanity.php | 27 +- .../core/sources/ShareLinks/Service.php | 2 +- applications/core/sources/Stream/Stream.php | 25 +- .../core/sources/Warnings/Warning.php | 51 + applications/core/widgets/activeUsers.php | 5 +- applications/downloads/Application.php | 10 + applications/downloads/api/files.php | 3 +- applications/downloads/data/acpsearch.json | 23 +- applications/downloads/data/build.xml | 11 +- applications/downloads/data/javascript.xml | 19 +- applications/downloads/data/lang.xml | 10 +- applications/downloads/data/schema.json | 53 + applications/downloads/data/settings.json | 16 +- applications/downloads/data/theme.xml | 585 ++- applications/downloads/data/versions.json | 16 +- .../modules/admin/downloads/settings.php | 18 +- .../modules/front/downloads/browse.php | 20 + .../modules/front/downloads/pending.php | 23 +- .../downloads/setup/upg_107602/data.json | 23 + .../downloads/setup/upg_107620/data.json | 23 + .../setup/upg_107620/javascript.json | 14 + .../downloads/setup/upg_107620/queries.json | 20 + .../downloads/setup/upg_107621/data.json | 23 + .../downloads/setup/upg_107622/data.json | 23 + .../downloads/setup/upg_107623/data.json | 23 + .../downloads/setup/upg_107624/data.json | 23 + .../downloads/setup/upg_107625/data.json | 23 + .../downloads/setup/upg_107626/data.json | 23 + .../downloads/setup/upg_107627/data.json | 23 + .../downloads/setup/upg_107628/data.json | 23 + .../setup/upg_107640/acpSearchKeywords.json | 7 + .../downloads/setup/upg_107640/data.json | 23 + .../downloads/setup/upg_107640/lang.json | 21 + .../downloads/setup/upg_107640/queries.json | 48 + .../downloads/setup/upg_107640/settings.json | 12 + .../downloads/setup/upg_107640/theme.json | 33 + .../downloads/setup/upg_107641/data.json | 23 + .../downloads/setup/upg_107642/data.json | 23 + .../downloads/setup/upg_107643/data.json | 23 + .../downloads/sources/Category/Category.php | 39 +- .../downloads/sources/Field/Field.php | 4 +- .../downloads/sources/File/Comment.php | 5 - applications/downloads/sources/File/File.php | 25 +- .../downloads/sources/File/PendingVersion.php | 24 + .../downloads/sources/File/Review.php | 5 - .../api/GraphQL/Mutations/CreateTopic.php | 12 +- .../api/GraphQL/Mutations/MarkForumRead.php | 2 +- .../api/GraphQL/Mutations/MarkTopicRead.php | 2 +- .../api/GraphQL/Mutations/MarkTopicSolved.php | 2 +- .../api/GraphQL/Mutations/PostReaction.php | 6 +- .../api/GraphQL/Mutations/ReplyTopic.php | 8 +- .../api/GraphQL/Mutations/ReportPost.php | 4 +- .../GraphQL/Mutations/RevokePostReport.php | 4 +- .../api/GraphQL/Mutations/SetBestAnswer.php | 2 +- .../api/GraphQL/Mutations/VoteAnswer.php | 2 +- .../api/GraphQL/Mutations/VoteInPoll.php | 2 +- .../api/GraphQL/Mutations/VoteQuestion.php | 2 +- .../forums/api/GraphQL/Queries/Forum.php | 2 +- .../forums/api/GraphQL/Queries/Forums.php | 2 +- .../forums/api/GraphQL/Queries/Post.php | 2 +- .../forums/api/GraphQL/Queries/Topic.php | 6 +- .../forums/api/GraphQL/Queries/Topics.php | 4 +- .../forums/api/GraphQL/TypeRegistry.php | 43 +- .../forums/api/GraphQL/Types/PostType.php | 3 - applications/forums/api/topics.php | 1 + applications/forums/data/javascript.xml | 23 +- applications/forums/data/lang.xml | 2 +- applications/forums/data/theme.xml | 711 ++- applications/forums/data/versions.json | 16 +- .../forums/modules/admin/stats/solved.php | 2 + .../forums/modules/front/forums/topic.php | 30 +- .../forums/setup/upg_107602/data.json | 23 + .../forums/setup/upg_107620/data.json | 23 + .../forums/setup/upg_107620/javascript.json | 14 + .../forums/setup/upg_107620/theme.json | 19 + .../forums/setup/upg_107621/data.json | 23 + .../forums/setup/upg_107622/data.json | 23 + .../forums/setup/upg_107623/data.json | 23 + .../forums/setup/upg_107624/data.json | 23 + .../forums/setup/upg_107625/data.json | 23 + .../forums/setup/upg_107626/data.json | 23 + .../forums/setup/upg_107627/data.json | 23 + .../forums/setup/upg_107628/data.json | 23 + .../forums/setup/upg_107640/data.json | 23 + .../forums/setup/upg_107640/javascript.json | 14 + .../forums/setup/upg_107640/theme.json | 31 + .../forums/setup/upg_107641/data.json | 23 + .../forums/setup/upg_107642/data.json | 23 + .../forums/setup/upg_107643/data.json | 23 + applications/forums/sources/Forum/Forum.php | 20 +- .../forums/sources/Topic/LiveTopic.php | 52 + applications/forums/sources/Topic/Post.php | 5 - applications/forums/sources/Topic/Topic.php | 31 +- .../forums/tasks/solvedNotifications.php | 8 +- applications/gallery/api/GraphQL/Mutation.php | 39 + .../gallery/api/GraphQL/Queries/Image.php | 8 +- .../gallery/api/GraphQL/TypeRegistry.php | 49 +- .../gallery/api/GraphQL/Types/ImageType.php | 7 - applications/gallery/api/images.php | 1 + applications/gallery/data/build.xml | 1 + applications/gallery/data/extensions.json | 75 +- applications/gallery/data/javascript.xml | 1070 +--- applications/gallery/data/lang.xml | 25 +- applications/gallery/data/schema.json | 61 +- applications/gallery/data/settings.json | 5 + applications/gallery/data/theme.xml | 3387 +++++++------ applications/gallery/data/versions.json | 16 +- .../extensions/core/ContentRouter/gallery.php | 4 +- .../extensions/core/Profile/gallery.php | 6 +- .../extensions/core/Profile/galleryImages.php | 67 + .../extensions/core/Sitemap/Images.php | 6 +- .../extensions/core/Sitemap/Videos.php | 6 +- .../modules/admin/gallery/settings.php | 6 +- .../gallery/modules/front/gallery/browse.php | 26 +- .../gallery/modules/front/gallery/submit.php | 33 +- .../gallery/modules/front/gallery/view.php | 66 +- .../gallery/setup/upg_107602/data.json | 23 + .../gallery/setup/upg_107620/data.json | 23 + .../gallery/setup/upg_107620/javascript.json | 25 + .../gallery/setup/upg_107620/lang.json | 37 + .../gallery/setup/upg_107620/queries.json | 38 + .../gallery/setup/upg_107620/settings.json | 7 + .../gallery/setup/upg_107620/theme.json | 65 + .../gallery/setup/upg_107621/data.json | 23 + .../gallery/setup/upg_107622/data.json | 23 + .../gallery/setup/upg_107623/data.json | 23 + .../gallery/setup/upg_107623/theme.json | 20 + .../gallery/setup/upg_107624/data.json | 23 + .../gallery/setup/upg_107624/queries.json | 18 + .../gallery/setup/upg_107624/theme.json | 26 + .../gallery/setup/upg_107625/data.json | 23 + .../gallery/setup/upg_107626/data.json | 23 + .../gallery/setup/upg_107626/theme.json | 20 + .../gallery/setup/upg_107627/data.json | 23 + .../gallery/setup/upg_107628/data.json | 23 + .../gallery/setup/upg_107640/data.json | 23 + .../gallery/setup/upg_107640/queries.json | 40 + .../gallery/setup/upg_107640/theme.json | 35 + .../gallery/setup/upg_107641/data.json | 23 + .../gallery/setup/upg_107642/data.json | 23 + .../gallery/setup/upg_107643/data.json | 23 + applications/gallery/sources/Album/Album.php | 104 +- applications/gallery/sources/Album/Item.php | 20 + .../gallery/sources/Category/Category.php | 43 +- .../gallery/sources/Image/Comment.php | 5 - applications/gallery/sources/Image/Image.php | 95 +- applications/gallery/sources/Image/Review.php | 5 - applications/gallery/widgets/imageFeed.php | 1 + applications/nexus/data/javascript.xml | 75 +- applications/nexus/data/lang.xml | 4 +- applications/nexus/data/theme.xml | 17 +- applications/nexus/data/versions.json | 16 +- .../nexus/modules/admin/store/packages.php | 2 +- .../admin/subscriptions/subscriptions.php | 2 - applications/nexus/setup/upg_107602/data.json | 23 + applications/nexus/setup/upg_107602/lang.json | 15 + applications/nexus/setup/upg_107620/data.json | 23 + .../nexus/setup/upg_107620/javascript.json | 14 + applications/nexus/setup/upg_107620/lang.json | 18 + .../nexus/setup/upg_107620/theme.json | 23 + applications/nexus/setup/upg_107621/data.json | 23 + applications/nexus/setup/upg_107621/lang.json | 15 + applications/nexus/setup/upg_107622/data.json | 23 + applications/nexus/setup/upg_107622/lang.json | 15 + applications/nexus/setup/upg_107623/data.json | 23 + applications/nexus/setup/upg_107623/lang.json | 15 + applications/nexus/setup/upg_107624/data.json | 23 + applications/nexus/setup/upg_107624/lang.json | 15 + applications/nexus/setup/upg_107625/data.json | 23 + applications/nexus/setup/upg_107625/lang.json | 15 + applications/nexus/setup/upg_107626/data.json | 23 + applications/nexus/setup/upg_107626/lang.json | 15 + applications/nexus/setup/upg_107627/data.json | 23 + applications/nexus/setup/upg_107627/lang.json | 15 + applications/nexus/setup/upg_107628/data.json | 23 + applications/nexus/setup/upg_107628/lang.json | 15 + applications/nexus/setup/upg_107640/data.json | 23 + applications/nexus/setup/upg_107640/lang.json | 15 + .../nexus/setup/upg_107640/theme.json | 20 + applications/nexus/setup/upg_107641/data.json | 23 + applications/nexus/setup/upg_107641/lang.json | 15 + applications/nexus/setup/upg_107642/data.json | 23 + applications/nexus/setup/upg_107642/lang.json | 15 + applications/nexus/setup/upg_107643/data.json | 23 + applications/nexus/setup/upg_107643/lang.json | 15 + .../Gateway/PayPal/BillingAgreement.php | 2 +- .../nexus/sources/Gateway/Stripe/Stripe.php | 6 +- .../nexus/sources/Invoice/Invoice.php | 10 +- .../nexus/sources/Package/Package.php | 14 +- applications/nexus/sources/Tax/Tax.php | 28 +- .../nexus/sources/Transaction/Transaction.php | 5 +- docs.html | 11 - init.php | 3 + .../HTMLPurifier/HTMLPurifier.includes.php | 3 +- .../3rd_party/HTMLPurifier/HTMLPurifier.php | 6 +- .../HTMLPurifier.safe-includes.php | 1 + .../AttrDef/HTML/ContentEditable.php | 16 + .../HTMLPurifier/AttrTransform/NameSync.php | 5 + .../HTMLPurifier/AttrTransform/SafeParam.php | 5 + .../HTMLPurifier/HTMLPurifier/AttrTypes.php | 1 + .../HTMLPurifier/ChildDef/List.php | 2 + .../HTMLPurifier/HTMLPurifier/Config.php | 2 +- .../HTMLPurifier/HTMLPurifier/ElementDef.php | 2 +- .../HTMLPurifier/HTMLPurifier/Encoder.php | 8 +- .../HTMLModule/CommonAttributes.php | 1 + .../Injector/RemoveSpansWithoutAttributes.php | 15 +- .../HTMLPurifier/HTMLPurifier/Length.php | 2 +- .../HTMLPurifier/HTMLPurifier/Lexer.php | 9 +- .../HTMLPurifier/HTMLPurifier/Lexer/PH5P.php | 2 +- .../HTMLPurifier/PropertyListIterator.php | 1 + .../HTMLPurifier/HTMLPurifier/StringHash.php | 1 + .../HTMLPurifier/URIFilter/HostBlacklist.php | 2 +- .../HTMLPurifier/URIFilter/Munge.php | 10 +- system/Api/GraphQL/AppQueries.php | 2 +- system/Api/GraphQL/Fields/CoverPhotoField.php | 2 +- system/Api/GraphQL/Fields/TagsEditField.php | 2 +- system/Api/GraphQL/GraphQL.php | 6 +- system/Api/GraphQL/Queries/ModuleAccess.php | 5 +- system/Api/GraphQL/TypeRegistry.php | 52 +- system/Api/GraphQL/Types/MutationType.php | 5 +- system/Api/OAuthClient.php | 38 +- system/Application/Application.php | 12 +- system/Content/Api/GraphQL/ItemMutator.php | 13 + system/Content/Api/ItemController.php | 8 + system/Content/ClubContainer.php | 13 +- system/Content/Content.php | 10 +- system/Content/Controller.php | 79 +- system/Content/Item.php | 121 +- system/Content/Search/Mysql/Query.php | 20 +- system/Content/ShareServices/Pinterest.php | 2 +- system/Content/Solvable.php | 6 + system/DateTime/DateTime.php | 27 +- system/Developer/Developer.php | 3 + system/Dispatcher/GraphQL.php | 41 +- system/File/Amazon.php | 33 +- system/File/File.php | 6 +- system/File/FileSystem.php | 24 +- system/File/Iterator.php | 2 +- system/Helpers/Form/CheckboxSet.php | 3 +- system/Helpers/Form/Date.php | 24 +- system/Helpers/Form/DateRange.php | 7 +- system/Helpers/Form/Poll.php | 8 +- system/Helpers/Form/Upload.php | 48 +- system/Helpers/Table/Content.php | 24 + system/Helpers/Table/Table.php | 16 + system/Image/Image.php | 7 +- system/Image/Imagemagick.php | 29 - system/Lang/Lang.php | 4 +- system/MFA/SecurityQuestions/Handler.php | 15 +- system/Member/Club/Club.php | 33 +- system/Member/Club/Page.php | 10 + system/Member/Group.php | 1 + system/Member/Member.php | 14 +- system/Node/Api/NodeController.php | 21 + system/Node/Model.php | 14 +- system/Notification/Notification.php | 15 +- system/Output/Output.php | 32 +- system/Plugin/Plugin.php | 17 +- system/Poll/Poll.php | 25 +- system/Request/Request.php | 12 +- system/Session/Front.php | 2 +- system/Sitemap/Sitemap.php | 3 +- system/Text/Parser.php | 2 +- system/Theme/Compile/ThemeHook.php | 53 + system/Theme/Theme.php | 2 +- 688 files changed, 19814 insertions(+), 10890 deletions(-) create mode 100644 applications/blog/api/GraphQL/Mutation.php create mode 100644 applications/blog/api/GraphQL/Mutations/CreateEntry.php create mode 100644 applications/blog/api/GraphQL/Mutations/ReplyEntry.php create mode 100644 applications/blog/api/GraphQL/Queries/Blog.php create mode 100644 applications/blog/api/GraphQL/Queries/Blogs.php create mode 100644 applications/blog/api/GraphQL/Queries/Entries.php create mode 100644 applications/blog/api/GraphQL/Queries/Entry.php create mode 100644 applications/blog/api/GraphQL/Query.php create mode 100644 applications/blog/api/GraphQL/TypeRegistry.php create mode 100644 applications/blog/api/GraphQL/Types/BlogType.php create mode 100644 applications/blog/api/GraphQL/Types/CommentType.php create mode 100644 applications/blog/api/GraphQL/Types/EntryType.php create mode 100644 applications/blog/setup/upg_107602/data.json create mode 100644 applications/blog/setup/upg_107620/data.json create mode 100644 applications/blog/setup/upg_107620/javascript.json create mode 100644 applications/blog/setup/upg_107621/data.json create mode 100644 applications/blog/setup/upg_107622/data.json create mode 100644 applications/blog/setup/upg_107623/data.json create mode 100644 applications/blog/setup/upg_107624/data.json create mode 100644 applications/blog/setup/upg_107625/data.json create mode 100644 applications/blog/setup/upg_107626/data.json create mode 100644 applications/blog/setup/upg_107627/data.json create mode 100644 applications/blog/setup/upg_107628/data.json create mode 100644 applications/blog/setup/upg_107640/data.json create mode 100644 applications/blog/setup/upg_107640/theme.json create mode 100644 applications/blog/setup/upg_107641/data.json create mode 100644 applications/blog/setup/upg_107642/data.json create mode 100644 applications/blog/setup/upg_107643/data.json create mode 100644 applications/calendar/api/GraphQL/Mutation.php create mode 100644 applications/calendar/api/GraphQL/Mutations/CreateEvent.php create mode 100644 applications/calendar/api/GraphQL/Queries/Calendar.php create mode 100644 applications/calendar/api/GraphQL/Queries/Calendars.php create mode 100644 applications/calendar/api/GraphQL/Queries/Event.php create mode 100644 applications/calendar/api/GraphQL/Queries/Events.php create mode 100644 applications/calendar/api/GraphQL/Query.php create mode 100644 applications/calendar/api/GraphQL/TypeRegistry.php create mode 100644 applications/calendar/api/GraphQL/Types/CalendarType.php create mode 100644 applications/calendar/api/GraphQL/Types/CommentType.php create mode 100644 applications/calendar/api/GraphQL/Types/EventType.php create mode 100644 applications/calendar/setup/upg_107602/data.json create mode 100644 applications/calendar/setup/upg_107620/data.json create mode 100644 applications/calendar/setup/upg_107620/javascript.json create mode 100644 applications/calendar/setup/upg_107620/lang.json create mode 100644 applications/calendar/setup/upg_107620/theme.json create mode 100644 applications/calendar/setup/upg_107621/data.json create mode 100644 applications/calendar/setup/upg_107622/data.json create mode 100644 applications/calendar/setup/upg_107623/data.json create mode 100644 applications/calendar/setup/upg_107624/data.json create mode 100644 applications/calendar/setup/upg_107625/data.json create mode 100644 applications/calendar/setup/upg_107626/data.json create mode 100644 applications/calendar/setup/upg_107627/data.json create mode 100644 applications/calendar/setup/upg_107628/data.json create mode 100644 applications/calendar/setup/upg_107640/data.json create mode 100644 applications/calendar/setup/upg_107640/javascript.json create mode 100644 applications/calendar/setup/upg_107640/queries.json create mode 100644 applications/calendar/setup/upg_107640/theme.json create mode 100644 applications/calendar/setup/upg_107641/data.json create mode 100644 applications/calendar/setup/upg_107642/data.json create mode 100644 applications/calendar/setup/upg_107643/data.json create mode 100644 applications/cms/setup/upg_107602/data.json create mode 100644 applications/cms/setup/upg_107620/data.json create mode 100644 applications/cms/setup/upg_107620/javascript.json create mode 100644 applications/cms/setup/upg_107620/lang.json create mode 100644 applications/cms/setup/upg_107620/queries.json create mode 100644 applications/cms/setup/upg_107620/upgrade.php create mode 100644 applications/cms/setup/upg_107621/data.json create mode 100644 applications/cms/setup/upg_107622/data.json create mode 100644 applications/cms/setup/upg_107623/data.json create mode 100644 applications/cms/setup/upg_107624/data.json create mode 100644 applications/cms/setup/upg_107625/data.json create mode 100644 applications/cms/setup/upg_107626/data.json create mode 100644 applications/cms/setup/upg_107627/data.json create mode 100644 applications/cms/setup/upg_107628/data.json create mode 100644 applications/cms/setup/upg_107640/data.json create mode 100644 applications/cms/setup/upg_107640/theme.json create mode 100644 applications/cms/setup/upg_107641/data.json create mode 100644 applications/cms/setup/upg_107642/data.json create mode 100644 applications/cms/setup/upg_107643/data.json create mode 100644 applications/convert/setup/upg_107602/data.json create mode 100644 applications/convert/setup/upg_107620/data.json create mode 100644 applications/convert/setup/upg_107620/javascript.json create mode 100644 applications/convert/setup/upg_107621/data.json create mode 100644 applications/convert/setup/upg_107622/data.json create mode 100644 applications/convert/setup/upg_107623/data.json create mode 100644 applications/convert/setup/upg_107624/data.json create mode 100644 applications/convert/setup/upg_107625/data.json create mode 100644 applications/convert/setup/upg_107626/data.json create mode 100644 applications/convert/setup/upg_107627/data.json create mode 100644 applications/convert/setup/upg_107628/data.json create mode 100644 applications/convert/setup/upg_107640/data.json create mode 100644 applications/convert/setup/upg_107641/data.json create mode 100644 applications/convert/setup/upg_107642/data.json create mode 100644 applications/convert/setup/upg_107643/data.json create mode 100644 applications/core/api/GraphQL/Queries/Clubs.php create mode 100644 applications/core/api/GraphQL/Queries/Members.php create mode 100644 applications/core/extensions/core/Sitemap/Clubs.php delete mode 100644 applications/core/setup/upg_107500/upgrade.php create mode 100644 applications/core/setup/upg_107602/data.json create mode 100644 applications/core/setup/upg_107602/lang.json create mode 100644 applications/core/setup/upg_107602/theme.json create mode 100644 applications/core/setup/upg_107620/data.json create mode 100644 applications/core/setup/upg_107620/javascript.json create mode 100644 applications/core/setup/upg_107620/lang.json create mode 100644 applications/core/setup/upg_107620/queries.json create mode 100644 applications/core/setup/upg_107620/settings.json create mode 100644 applications/core/setup/upg_107620/theme.json create mode 100644 applications/core/setup/upg_107621/data.json create mode 100644 applications/core/setup/upg_107621/lang.json create mode 100644 applications/core/setup/upg_107622/data.json create mode 100644 applications/core/setup/upg_107622/lang.json create mode 100644 applications/core/setup/upg_107623/data.json create mode 100644 applications/core/setup/upg_107623/javascript.json create mode 100644 applications/core/setup/upg_107623/lang.json create mode 100644 applications/core/setup/upg_107623/theme.json create mode 100644 applications/core/setup/upg_107624/data.json create mode 100644 applications/core/setup/upg_107624/lang.json create mode 100644 applications/core/setup/upg_107625/data.json create mode 100644 applications/core/setup/upg_107625/lang.json create mode 100644 applications/core/setup/upg_107626/data.json create mode 100644 applications/core/setup/upg_107626/lang.json create mode 100644 applications/core/setup/upg_107627/data.json create mode 100644 applications/core/setup/upg_107627/lang.json create mode 100644 applications/core/setup/upg_107628/data.json create mode 100644 applications/core/setup/upg_107628/lang.json create mode 100644 applications/core/setup/upg_107640/acpSearchKeywords.json create mode 100644 applications/core/setup/upg_107640/data.json create mode 100644 applications/core/setup/upg_107640/emailTemplates.json create mode 100644 applications/core/setup/upg_107640/javascript.json create mode 100644 applications/core/setup/upg_107640/lang.json create mode 100644 applications/core/setup/upg_107640/queries.json create mode 100644 applications/core/setup/upg_107640/theme.json create mode 100644 applications/core/setup/upg_107640/upgrade.php create mode 100644 applications/core/setup/upg_107641/data.json create mode 100644 applications/core/setup/upg_107641/javascript.json create mode 100644 applications/core/setup/upg_107641/lang.json create mode 100644 applications/core/setup/upg_107641/theme.json create mode 100644 applications/core/setup/upg_107642/data.json create mode 100644 applications/core/setup/upg_107642/lang.json create mode 100644 applications/core/setup/upg_107643/data.json create mode 100644 applications/core/setup/upg_107643/lang.json create mode 100644 applications/downloads/setup/upg_107602/data.json create mode 100644 applications/downloads/setup/upg_107620/data.json create mode 100644 applications/downloads/setup/upg_107620/javascript.json create mode 100644 applications/downloads/setup/upg_107620/queries.json create mode 100644 applications/downloads/setup/upg_107621/data.json create mode 100644 applications/downloads/setup/upg_107622/data.json create mode 100644 applications/downloads/setup/upg_107623/data.json create mode 100644 applications/downloads/setup/upg_107624/data.json create mode 100644 applications/downloads/setup/upg_107625/data.json create mode 100644 applications/downloads/setup/upg_107626/data.json create mode 100644 applications/downloads/setup/upg_107627/data.json create mode 100644 applications/downloads/setup/upg_107628/data.json create mode 100644 applications/downloads/setup/upg_107640/acpSearchKeywords.json create mode 100644 applications/downloads/setup/upg_107640/data.json create mode 100644 applications/downloads/setup/upg_107640/lang.json create mode 100644 applications/downloads/setup/upg_107640/queries.json create mode 100644 applications/downloads/setup/upg_107640/settings.json create mode 100644 applications/downloads/setup/upg_107640/theme.json create mode 100644 applications/downloads/setup/upg_107641/data.json create mode 100644 applications/downloads/setup/upg_107642/data.json create mode 100644 applications/downloads/setup/upg_107643/data.json create mode 100644 applications/forums/setup/upg_107602/data.json create mode 100644 applications/forums/setup/upg_107620/data.json create mode 100644 applications/forums/setup/upg_107620/javascript.json create mode 100644 applications/forums/setup/upg_107620/theme.json create mode 100644 applications/forums/setup/upg_107621/data.json create mode 100644 applications/forums/setup/upg_107622/data.json create mode 100644 applications/forums/setup/upg_107623/data.json create mode 100644 applications/forums/setup/upg_107624/data.json create mode 100644 applications/forums/setup/upg_107625/data.json create mode 100644 applications/forums/setup/upg_107626/data.json create mode 100644 applications/forums/setup/upg_107627/data.json create mode 100644 applications/forums/setup/upg_107628/data.json create mode 100644 applications/forums/setup/upg_107640/data.json create mode 100644 applications/forums/setup/upg_107640/javascript.json create mode 100644 applications/forums/setup/upg_107640/theme.json create mode 100644 applications/forums/setup/upg_107641/data.json create mode 100644 applications/forums/setup/upg_107642/data.json create mode 100644 applications/forums/setup/upg_107643/data.json create mode 100644 applications/forums/sources/Topic/LiveTopic.php create mode 100644 applications/gallery/api/GraphQL/Mutation.php create mode 100644 applications/gallery/extensions/core/Profile/galleryImages.php create mode 100644 applications/gallery/setup/upg_107602/data.json create mode 100644 applications/gallery/setup/upg_107620/data.json create mode 100644 applications/gallery/setup/upg_107620/javascript.json create mode 100644 applications/gallery/setup/upg_107620/lang.json create mode 100644 applications/gallery/setup/upg_107620/queries.json create mode 100644 applications/gallery/setup/upg_107620/settings.json create mode 100644 applications/gallery/setup/upg_107620/theme.json create mode 100644 applications/gallery/setup/upg_107621/data.json create mode 100644 applications/gallery/setup/upg_107622/data.json create mode 100644 applications/gallery/setup/upg_107623/data.json create mode 100644 applications/gallery/setup/upg_107623/theme.json create mode 100644 applications/gallery/setup/upg_107624/data.json create mode 100644 applications/gallery/setup/upg_107624/queries.json create mode 100644 applications/gallery/setup/upg_107624/theme.json create mode 100644 applications/gallery/setup/upg_107625/data.json create mode 100644 applications/gallery/setup/upg_107626/data.json create mode 100644 applications/gallery/setup/upg_107626/theme.json create mode 100644 applications/gallery/setup/upg_107627/data.json create mode 100644 applications/gallery/setup/upg_107628/data.json create mode 100644 applications/gallery/setup/upg_107640/data.json create mode 100644 applications/gallery/setup/upg_107640/queries.json create mode 100644 applications/gallery/setup/upg_107640/theme.json create mode 100644 applications/gallery/setup/upg_107641/data.json create mode 100644 applications/gallery/setup/upg_107642/data.json create mode 100644 applications/gallery/setup/upg_107643/data.json create mode 100644 applications/nexus/setup/upg_107602/data.json create mode 100644 applications/nexus/setup/upg_107602/lang.json create mode 100644 applications/nexus/setup/upg_107620/data.json create mode 100644 applications/nexus/setup/upg_107620/javascript.json create mode 100644 applications/nexus/setup/upg_107620/lang.json create mode 100644 applications/nexus/setup/upg_107620/theme.json create mode 100644 applications/nexus/setup/upg_107621/data.json create mode 100644 applications/nexus/setup/upg_107621/lang.json create mode 100644 applications/nexus/setup/upg_107622/data.json create mode 100644 applications/nexus/setup/upg_107622/lang.json create mode 100644 applications/nexus/setup/upg_107623/data.json create mode 100644 applications/nexus/setup/upg_107623/lang.json create mode 100644 applications/nexus/setup/upg_107624/data.json create mode 100644 applications/nexus/setup/upg_107624/lang.json create mode 100644 applications/nexus/setup/upg_107625/data.json create mode 100644 applications/nexus/setup/upg_107625/lang.json create mode 100644 applications/nexus/setup/upg_107626/data.json create mode 100644 applications/nexus/setup/upg_107626/lang.json create mode 100644 applications/nexus/setup/upg_107627/data.json create mode 100644 applications/nexus/setup/upg_107627/lang.json create mode 100644 applications/nexus/setup/upg_107628/data.json create mode 100644 applications/nexus/setup/upg_107628/lang.json create mode 100644 applications/nexus/setup/upg_107640/data.json create mode 100644 applications/nexus/setup/upg_107640/lang.json create mode 100644 applications/nexus/setup/upg_107640/theme.json create mode 100644 applications/nexus/setup/upg_107641/data.json create mode 100644 applications/nexus/setup/upg_107641/lang.json create mode 100644 applications/nexus/setup/upg_107642/data.json create mode 100644 applications/nexus/setup/upg_107642/lang.json create mode 100644 applications/nexus/setup/upg_107643/data.json create mode 100644 applications/nexus/setup/upg_107643/lang.json delete mode 100644 docs.html create mode 100644 system/3rd_party/HTMLPurifier/HTMLPurifier/AttrDef/HTML/ContentEditable.php create mode 100644 system/Theme/Compile/ThemeHook.php diff --git a/Credits.txt b/Credits.txt index a17b8690..4e2d146b 100644 --- a/Credits.txt +++ b/Credits.txt @@ -29,7 +29,7 @@ Clipboard CKEditor Description: Provides the editor functionality for submitting content. Location: In development: applications/core/dev/ckeditor (custom build with additional plugins) - Included version: 4.19.1 + Included version: 4.20.1 Website: http://ckeditor.com License: http://www.gnu.org/copyleft/lesser.html @@ -110,7 +110,7 @@ Howler HTMLPurifier Description: Validates and cleans submitted HTML for content Location: system/3rd_party/HTMLPurifier - Included version: 4.14.0 + Included version: 4.15.0 Website: http://htmlpurifier.org License: http://www.gnu.org/copyleft/lesser.html @@ -211,13 +211,6 @@ JShrink Website: https://github.com/tedious/JShrink License: https://github.com/tedious/JShrink/blob/master/LICENSE -jsTimezoneDetect - Description: Provides timezone detection - Location: dev/js/library/jstz - Included version: 1.0.6 - Website: https://bitbucket.org/pellepim/jstimezonedetect - License: http://www.opensource.org/licenses/mit-license.php - JwtFramework Description: Provides JWT signing & encryption support Location: system/3rd_party/JwtFramework @@ -336,7 +329,7 @@ success.mp3 Notification Sound by RCP Tones Twemoji Description: Emoji images Location: Served from CDN - Included version: 2.3 + Included version: 14.0.2 Website: http://twitter.github.io/twemoji/ License: https://github.com/twitter/twemoji/blob/gh-pages/LICENSE diff --git a/admin/install/eula.txt b/admin/install/eula.txt index 1600a87c..57e13bc0 100644 --- a/admin/install/eula.txt +++ b/admin/install/eula.txt @@ -1,5 +1,5 @@ =============================[NOTE]============================= - IPS 4.7.6 (107601) + IPS 4.7.8 (107643) =============================[NOTE]============================= Invision Community End User License Agreement diff --git a/applications/blog/api/GraphQL/Mutation.php b/applications/blog/api/GraphQL/Mutation.php new file mode 100644 index 00000000..6ec65b95 --- /dev/null +++ b/applications/blog/api/GraphQL/Mutation.php @@ -0,0 +1,41 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 22 Oct 2022 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\Types; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Blog mutationss GraphQL API + */ +abstract class _Mutation +{ + /** + * Get the supported query types in this app + * + * @return array + */ + public static function mutations(): array + { + $return = [ + 'createEntry' => new \IPS\blog\api\GraphQL\Mutations\CreateEntry(), + 'replyEntry' => new \IPS\blog\api\GraphQL\Mutations\ReplyEntry(), + ]; + return $return; + } +} diff --git a/applications/blog/api/GraphQL/Mutations/CreateEntry.php b/applications/blog/api/GraphQL/Mutations/CreateEntry.php new file mode 100644 index 00000000..124e6c0c --- /dev/null +++ b/applications/blog/api/GraphQL/Mutations/CreateEntry.php @@ -0,0 +1,95 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 22 oct 2022 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Mutations; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Create blog entry mutation for GraphQL API + */ +class _CreateEntry extends \IPS\Content\Api\GraphQL\ItemMutator +{ + /** + * Class + */ + protected $class = \IPS\blog\Entry::class; + + /* + * @brief Query description + */ + public static $description = "Create a new blog entry"; + + /* + * Mutation arguments + */ + public function args(): array + { + return [ + 'blog' => TypeRegistry::nonNull( TypeRegistry::id() ) + ]; + } + + /** + * Return the mutation return type + */ + public function type() + { + return \IPS\blog\api\GraphQL\TypeRegistry::entry(); + } + + /** + * Resolves this mutation + * + * @param mixed Value passed into this resolver + * @param array Arguments + * @param array Context values + * @return \IPS\blog\Blog + */ + public function resolve($val, $args, $context, $info) + { + /* Get blog */ + try + { + $blog = \IPS\blog\Blog::loadAndCheckPerms( $args['blogID'] ); + } + catch ( \OutOfRangeException $e ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_BLOG', '1B300/1_graphql', 400 ); + } + + /* Check permission */ + if ( !$blog->can( 'add', \IPS\Member::loggedIn() ) ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_PERMISSION', '1B300/A_graphql', 403 ); + } + + /* Check we have a title and a post */ + if ( !$args['title'] ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_TITLE', '1B300/4_graphql', 400 ); + } + if ( !$args['content'] ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_POST', '1B300/5_grapqhl', 400 ); + } + + + return $this->_create( $args, $blog, $args['postKey'] ?? NULL ); + } +} diff --git a/applications/blog/api/GraphQL/Mutations/ReplyEntry.php b/applications/blog/api/GraphQL/Mutations/ReplyEntry.php new file mode 100644 index 00000000..0c18fce1 --- /dev/null +++ b/applications/blog/api/GraphQL/Mutations/ReplyEntry.php @@ -0,0 +1,108 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 10 May 2017 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Mutations; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Reply to entry mutation for GraphQL API + */ +class _ReplyEntry extends \IPS\Content\Api\GraphQL\CommentMutator +{ + /** + * Class + */ + protected $class = \IPS\blog\Entry\Comment::class; + + /* + * @brief Query description + */ + public static $description = "Create a new comment"; + + /* + * Mutation arguments + */ + public function args(): array + { + return [ + 'entryID' => TypeRegistry::nonNull( TypeRegistry::id() ), + 'content' => TypeRegistry::nonNull( TypeRegistry::string() ), + 'replyingTo' => TypeRegistry::id(), + 'postKey' => TypeRegistry::string() + ]; + } + + /** + * Return the mutation return type + */ + public function type() + { + return \IPS\blog\api\GraphQL\TypeRegistry::comment(); + } + + /** + * Resolves this mutation + * + * @param mixed Value passed into this resolver + * @param array Arguments + * @param array Context values + * @return \IPS\blog\Entry + */ + public function resolve($val, $args, $context, $info) + { + /* Get topic */ + try + { + $entry = \IPS\blog\Entry::loadAndCheckPerms( $args['entryID'] ); + } + catch ( \OutOfRangeException $e ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_TOPIC', '1F295/1_graphql', 403 ); + } + + /* Get author */ + if ( !$entry->canComment( \IPS\Member::loggedIn() ) ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_PERMISSION', '2F294/A_graphql', 403 ); + } + + /* Check we have a post */ + if ( !$args['content'] ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_POST', '1F295/3_graphql', 403 ); + } + + $originalPost = NULL; + + if( isset( $args['replyingTo'] ) ) + { + try + { + $originalPost = \IPS\blog\Entry\Comment::loadAndCheckPerms( $args['replyingTo'] ); + } + catch ( \OutOfRangeException $e ) + { + // Just ignore it + } + } + + /* Do it */ + return $this->_createComment( $args, $entry, $args['postKey'] ?? NULL, $originalPost ); + } +} diff --git a/applications/blog/api/GraphQL/Queries/Blog.php b/applications/blog/api/GraphQL/Queries/Blog.php new file mode 100644 index 00000000..2796f952 --- /dev/null +++ b/applications/blog/api/GraphQL/Queries/Blog.php @@ -0,0 +1,69 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 10 May 2017 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Queries; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Blog query for GraphQL API + */ +class _Blog +{ + /* + * @brief Query description + */ + public static $description = "Returns a Blog"; + + /* + * Query arguments + */ + public function args(): array + { + return array( + 'id' => TypeRegistry::nonNull( TypeRegistry::id() ), + ); + } + + /** + * Return the query return type + */ + public function type() + { + return \IPS\blog\api\GraphQL\TypeRegistry::blog(); + } + + /** + * Resolves this query + * + * @param mixed Value passed into this resolver + * @param array Arguments + * @param array Context values + * @return \IPS\blog\Blog + */ + public function resolve($val, $args, $context, $info) + { + $blog = \IPS\blog\Blog::load( $args['id'] ); + + if( !$blog->can( 'view', $context['member'] ) ) + { + throw new \OutOfRangeException; + } + return $blog; + } +} diff --git a/applications/blog/api/GraphQL/Queries/Blogs.php b/applications/blog/api/GraphQL/Queries/Blogs.php new file mode 100644 index 00000000..beb39345 --- /dev/null +++ b/applications/blog/api/GraphQL/Queries/Blogs.php @@ -0,0 +1,64 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 22 Oct 2022 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Queries; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Blogs query for GraphQL API + */ +class _Blogs +{ + /* + * @brief Query description + */ + public static $description = "Returns a list of blogs"; + + /* + * Query arguments + */ + public function args(): array + { + return array( + 'id' => TypeRegistry::id() + ); + } + + /** + * Return the query return type + */ + public function type() + { + return TypeRegistry::listOf( \IPS\blog\api\GraphQL\TypeRegistry::blog() ); + } + + /** + * Resolves this query + * + * @param mixed Value passed into this resolver + * @param array Arguments + * @param array Context values + * @return array + */ + public function resolve($val, $args, $context, $info) + { + \IPS\blog\Blog::loadIntoMemory('view', $context['member']); + return \IPS\blog\Blog::roots(); + } +} diff --git a/applications/blog/api/GraphQL/Queries/Entries.php b/applications/blog/api/GraphQL/Queries/Entries.php new file mode 100644 index 00000000..c25e697f --- /dev/null +++ b/applications/blog/api/GraphQL/Queries/Entries.php @@ -0,0 +1,143 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 10 May 2017 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Queries; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Topics query for GraphQL API + */ +class _Entries +{ + /* + * @brief Query description + */ + public static $description = "Returns a list of blog entries"; + + /* + * Query arguments + */ + public function args(): array + { + return array( + 'blogs' => TypeRegistry::listOf( TypeRegistry::int() ), + 'offset' => [ + 'type' => TypeRegistry::int(), + 'defaultValue' => 0 + ], + 'limit' => [ + 'type' => TypeRegistry::int(), + 'defaultValue' => 25 + ], + 'orderBy' => [ + 'type' => TypeRegistry::eNum([ + 'name' => 'blog_order_by', + 'description' => 'Fields on which event can be sorted', + 'values' => \IPS\blog\api\GraphQL\Types\EntryType::getOrderByOptions() + ]), + 'defaultValue' => NULL // will use default sort option + ], + 'orderDir' => [ + 'type' => TypeRegistry::eNum([ + 'name' => 'entries_order_dir', + 'description' => 'Directions in which items can be sorted', + 'values' => [ 'ASC', 'DESC' ] + ]), + 'defaultValue' => 'DESC' + ], + 'honorPinned' => [ + 'type' => TypeRegistry::boolean(), + 'defaultValue' => true + ] + ); + } + + /** + * Return the query return type + */ + public function type() + { + return TypeRegistry::listOf( \IPS\blog\api\GraphQL\TypeRegistry::entry() ); + } + + /** + * Resolves this query + * + * @param mixed Value passed into this resolver + * @param array Arguments + * @param array Context values + * @return \IPS\blog\Entry + */ + public function resolve($val, $args, $context, $info) + { + \IPS\blog\Blog::loadIntoMemory('view', \IPS\Member::loggedIn() ); + + $blogIds = []; + + /* Are we filtering by blogs? */ + if( isset( $args['blogs'] ) && \count( $args['blogs'] ) ) + { + foreach( $args['blogs'] as $id ) + { + $blog = \IPS\blog\Blog::loadAndCheckPerms( $id ); + $blogIds[] = $blog->id; + } + + if( \count( $blogIds ) ) + { + $where['container'][] = array( \IPS\Db::i()->in( 'blog_blogs.blog_id', array_filter( $blogIds ) ) ); + } + } + + /* Get sorting */ + try + { + if( $args['orderBy'] === NULL ) + { + $orderBy = 'last_post'; + } + else + { + $orderBy = \IPS\blog\Entry::$databaseColumnMap[ $args['orderBy'] ]; + } + + if( $args['orderBy'] === 'last_comment' ) + { + $orderBy = \is_array( $orderBy ) ? array_pop( $orderBy ) : $orderBy; + } + } + catch (\Exception $e) + { + $orderBy = 'last_post'; + } + + $sortBy = \IPS\blog\Entry::$databaseTable . '.' . \IPS\blog\Entry::$databasePrefix . "{$orderBy} {$args['orderDir']}"; + $offset = max( $args['offset'], 0 ); + $limit = min( $args['limit'], 50 ); + + /* Figure out pinned status */ + if ( $args['honorPinned'] ) + { + $column = \IPS\blog\Entry::$databaseTable . '.' . \IPS\blog\Entry::$databasePrefix . \IPS\blog\Entry::$databaseColumnMap['pinned']; + $sortBy = "{$column} DESC, {$sortBy}"; + } + + return \IPS\blog\Entry::getItemsWithPermission( $where, $sortBy, array( $offset, $limit ), 'read' ); + } +} diff --git a/applications/blog/api/GraphQL/Queries/Entry.php b/applications/blog/api/GraphQL/Queries/Entry.php new file mode 100644 index 00000000..e8b3c14e --- /dev/null +++ b/applications/blog/api/GraphQL/Queries/Entry.php @@ -0,0 +1,77 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 22 Oct 2022 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Queries; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Entry query for GraphQL API + */ +class _Entry +{ + /* + * @brief Query description + */ + public static $description = "Returns a Blog Entry"; + + /* + * Query arguments + */ + public function args(): array + { + return array( + 'id' => TypeRegistry::nonNull( TypeRegistry::id() ) + ); + } + + /** + * Return the query return type + */ + public function type() + { + return \IPS\blog\api\GraphQL\TypeRegistry::entry(); + } + + /** + * Resolves this query + * + * @param mixed Value passed into this resolver + * @param array Arguments + * @param array Context values + * @return \IPS\blog\Entry + */ + public function resolve($val, $args, $context, $info) + { + try + { + $entry = \IPS\blog\Entry::loadAndCheckPerms( $args['id'] ); + } + catch ( \OutOfRangeException $e ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_TOPIC', '2B300/A_graphql', 400 ); + } + + if( !$entry->can('read') ) + { + throw new \IPS\Api\GraphQL\SafeException( 'NO_PERMISSION', '2B300/9_graphql', 403 ); + } + + return $entry; + } +} diff --git a/applications/blog/api/GraphQL/Query.php b/applications/blog/api/GraphQL/Query.php new file mode 100644 index 00000000..6be90797 --- /dev/null +++ b/applications/blog/api/GraphQL/Query.php @@ -0,0 +1,42 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 22 Oct 2022 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\Types; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Blog queries for GraphQL API + */ +abstract class _Query +{ + /** + * Get the supported query types in this app + * + * @return array + */ + public static function queries(): array + { + return [ + 'blogs' => new \IPS\blog\api\GraphQL\Queries\Blogs(), + 'blog' => new \IPS\blog\api\GraphQL\Queries\Blog(), + 'entries' => new \IPS\blog\api\GraphQL\Queries\Entries(), + 'entry' => new \IPS\blog\api\GraphQL\Queries\Entry(), + ]; + } +} diff --git a/applications/blog/api/GraphQL/TypeRegistry.php b/applications/blog/api/GraphQL/TypeRegistry.php new file mode 100644 index 00000000..d05de774 --- /dev/null +++ b/applications/blog/api/GraphQL/TypeRegistry.php @@ -0,0 +1,76 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 22 Oct 2022 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\Types; +use IPS\blog\api\GraphQL\Types\_BlogType; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + + +class _TypeRegistry +{ + /** + * The blog type instance + * @var \IPS\blog\api\GraphQL\Types\BlogType + */ + protected static $blog; + + /** + * The blog entry type instance + * @var \IPS\blog\api\GraphQL\Types\EntryType + */ + protected static $entry; + + /** + * The entry comment instance + * @var \IPS\blog\api\GraphQL\Types\CommentType + */ + protected static $comment; + + /** + * Constructor + */ + public function __construct() + { + // Defined to suppress static warnings + } + + /** + * @return BlogType + */ + public static function blog(): \IPS\blog\api\GraphQL\Types\BlogType + { + return self::$blog ?: (self::$blog = new \IPS\blog\api\GraphQL\Types\BlogType()); + } + + /** + * @return EntryType + */ + public static function entry(): \IPS\blog\api\GraphQL\Types\EntryType + { + return self::$entry ?: (self::$entry = new \IPS\blog\api\GraphQL\Types\EntryType()); + } + + /** + * @return CommentType + */ + public static function comment(): \IPS\blog\api\GraphQL\Types\CommentType + { + return self::$comment ?: (self::$comment = new \IPS\blog\api\GraphQL\Types\CommentType()); + } +} \ No newline at end of file diff --git a/applications/blog/api/GraphQL/Types/BlogType.php b/applications/blog/api/GraphQL/Types/BlogType.php new file mode 100644 index 00000000..720f184d --- /dev/null +++ b/applications/blog/api/GraphQL/Types/BlogType.php @@ -0,0 +1,58 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 22 Oct 2022 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Types; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * BlogType for GraphQL API + */ +class _BlogType extends \IPS\Node\Api\GraphQL\NodeType +{ + /* + * @brief The item classname we use for this type + */ + protected static $nodeClass = \IPS\blog\Blog::class; + + /* + * @brief GraphQL type name + */ + protected static $typeName = 'blog_Blog'; + + /* + * @brief GraphQL type description + */ + protected static $typeDescription = 'A blog'; + + /* + * @brief Follow data passed in to FollowType resolver + */ + protected static $followData = array('app' => 'blog', 'area' => 'blog'); + + + /** + * Get the item type that goes with this node type + * + * @return ObjectType + */ + public static function getItemType() + { + return \IPS\blog\api\GraphQL\TypeRegistry::entry(); + } +} diff --git a/applications/blog/api/GraphQL/Types/CommentType.php b/applications/blog/api/GraphQL/Types/CommentType.php new file mode 100644 index 00000000..7a1b19d4 --- /dev/null +++ b/applications/blog/api/GraphQL/Types/CommentType.php @@ -0,0 +1,75 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 10 May 2017 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Types; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * PostType for GraphQL API + */ +class _CommentType extends \IPS\Content\Api\GraphQL\CommentType +{ + /* + * @brief The item classname we use for this type + */ + protected static $commentClass = \IPS\blog\Entry\Comment::class; + + /* + * @brief GraphQL type name + */ + protected static $typeName = 'blog_Comment'; + + /* + * @brief GraphQL type description + */ + protected static $typeDescription = 'A blog comment'; + + /** + * Get the item type that goes with this item type + * + * @return ObjectType + */ + public static function getItemType() + { + return \IPS\blog\api\GraphQL\TypeRegistry::comment(); + } + + /** + * Return the fields available in this type + * + * @return array + */ + public function fields() + { + $defaultFields = parent::fields(); + $postFields = array( + 'entry' => [ + 'type' => \IPS\blog\api\GraphQL\TypeRegistry::entry(), + 'resolve' => function ($comment) { + return $comment->item(); + } + ], + ); + + // Remove duplicated fields + unset( $defaultFields['item'] ); + + return array_merge( $defaultFields, $postFields ); + } +} diff --git a/applications/blog/api/GraphQL/Types/EntryType.php b/applications/blog/api/GraphQL/Types/EntryType.php new file mode 100644 index 00000000..556af162 --- /dev/null +++ b/applications/blog/api/GraphQL/Types/EntryType.php @@ -0,0 +1,58 @@ +Invision Power Services, Inc. + * @copyright (c) 2001 - 2016 Invision Power Services, Inc. + * @license http://www.invisionpower.com/legal/standards/ + * @package IPS Community Suite + * @since 10 May 2017 + * @version SVN_VERSION_NUMBER + */ + +namespace IPS\blog\api\GraphQL\Types; +use GraphQL\Type\Definition\ObjectType; +use IPS\Api\GraphQL\_TypeRegistry; +use IPS\Api\GraphQL\TypeRegistry; + +/* To prevent PHP errors (extending class does not exist) revealing path */ +if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) ) +{ + header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' ); + exit; +} + +/** + * Entry for GraphQL API + */ +class _EntryType extends \IPS\Content\Api\GraphQL\ItemType +{ + /* + * @brief The item classname we use for this type + */ + protected static $itemClass = \IPS\blog\Entry::class; + + /* + * @brief GraphQL type name + */ + protected static $typeName = 'blog_Entry'; + + /* + * @brief GraphQL type description + */ + protected static $typeDescription = 'A blog entry'; + + /* + * @brief Follow data passed in to FollowType resolver + */ + protected static $followData = array('app' => 'blogs', 'area' => 'entry'); + + /** + * Get the comment type that goes with this item type + * + * @return ObjectType + */ + protected static function getCommentType() + { + return \IPS\blog\api\GraphQL\TypeRegistry::comment(); + } +} diff --git a/applications/blog/api/blogs.php b/applications/blog/api/blogs.php index 162a2b51..1d67e9d7 100644 --- a/applications/blog/api/blogs.php +++ b/applications/blog/api/blogs.php @@ -34,6 +34,7 @@ class _blogs extends \IPS\Node\Api\NodeController * Get list of blogs * * @note For requests using an OAuth Access Token for a particular member, only blogs that are not disabled and not belonging to a particular club or social group will be included + * @apiparam string ids Comma-delimited list of blog ids * @apiparam string owners Comma-delimited list of member IDs - if provided, only blogs owned by those members are returned (can be used in conjection with groups or set to 0 to exclude member-created blogs) * @apiparam string groups Comma-delimited list of group IDs - if provided, only blogs owned by those groups are returned (can be used in conjection with members or set to 0 to exclude group blogs) * @apiparam int pinned If 1, only blogs which are pinned are returned, if 0 only not pinned @@ -46,8 +47,8 @@ class _blogs extends \IPS\Node\Api\NodeController public function GETindex() { /* Where clause */ - $where = array(); - + $where = $this->_globalWhere(); + /* Owners */ if ( isset( \IPS\Request::i()->owners ) and isset( \IPS\Request::i()->groups ) ) { diff --git a/applications/blog/api/categories.php b/applications/blog/api/categories.php index 06d8f18a..f55b27e1 100644 --- a/applications/blog/api/categories.php +++ b/applications/blog/api/categories.php @@ -33,6 +33,7 @@ class _categories extends \IPS\Node\Api\NodeController * GET /blog/categories * Get list of blog categories * + * @apiparam string ids Comma-delimited list of category ids * @apiparam string sortBy What to sort by. Can be 'count_entries' for number of entries, 'last_edate' for last entry date or do not specify for ID * @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc' * @apiparam int page Page number @@ -42,7 +43,7 @@ class _categories extends \IPS\Node\Api\NodeController public function GETindex() { /* Where clause */ - $where = array(); + $where = $this->_globalWhere(); /* Sort */ if ( isset( \IPS\Request::i()->sortBy ) and \in_array( \IPS\Request::i()->sortBy, array( 'position' ) ) ) diff --git a/applications/blog/api/entries.php b/applications/blog/api/entries.php index e72bcb1e..cb355409 100644 --- a/applications/blog/api/entries.php +++ b/applications/blog/api/entries.php @@ -33,6 +33,7 @@ class _entries extends \IPS\Content\Api\ItemController * Get list of entries * * @note For requests using an OAuth Access Token for a particular member, only entries that are published and in blogs that are not disabled and not belonging to a particular club or social group will be included + * @apiparam string ids Comma-delimited list of entry IDs * @apiparam string blogs Comma-delimited list of blog IDs * @apiparam string authors Comma-delimited list of member IDs - if provided, only entries started by those members are returned * @apiparam int locked If 1, only entries which are locked are returned, if 0 only unlocked diff --git a/applications/blog/api/entrycategories.php b/applications/blog/api/entrycategories.php index 246935a6..e0ca261d 100644 --- a/applications/blog/api/entrycategories.php +++ b/applications/blog/api/entrycategories.php @@ -45,6 +45,14 @@ class _entrycategories extends \IPS\Node\Api\NodeController /* Where clause */ $where = array(); + $class = $this->class; + + if ( isset( \IPS\Request::i()->ids ) ) + { + $idField = $class::$databaseTable . '.' . $class::$databasePrefix . '.' . $class::$databaseColumnId; + $where[] = array( \IPS\Db::i()->in( $idField, array_map( 'intval', explode( ',', \IPS\Request::i()->ids ) ) ) ); + } + /* Blog */ if ( isset( \IPS\Request::i()->blog ) ) { diff --git a/applications/blog/data/acpmenu.json b/applications/blog/data/acpmenu.json index a0f7fee7..1b195ed6 100644 --- a/applications/blog/data/acpmenu.json +++ b/applications/blog/data/acpmenu.json @@ -1,16 +1,16 @@ { "blogs": { - "settings": { - "tab": "community", - "controller": "settings", - "do": "", - "restriction": "settings_manage" - }, "blogs": { "tab": "community", "controller": "blogs", "do": "", "restriction": "blogs_manage" + }, + "settings": { + "tab": "community", + "controller": "settings", + "do": "", + "restriction": "settings_manage" } } } \ No newline at end of file diff --git a/applications/blog/data/javascript.xml b/applications/blog/data/javascript.xml index e914f054..e633ebe1 100644 --- a/applications/blog/data/javascript.xml +++ b/applications/blog/data/javascript.xml @@ -1,6 +1,6 @@ - - /** + /** * Invision Community * (c) Invision Power Services, Inc. - https://www.invisioncommunity.com * @@ -66,7 +66,7 @@ } }); }(jQuery, _)); - - {{#lang}}manage_cats_new_row{{/lang}}\ "); @@ -373,7 +373,6 @@ controllers underscore jquery mustache -jstz IntersectionObserver Debug.js app.js diff --git a/applications/blog/data/lang.xml b/applications/blog/data/lang.xml index aeea5371..1cb9fef3 100644 --- a/applications/blog/data/lang.xml +++ b/applications/blog/data/lang.xml @@ -1,6 +1,6 @@ - + Blogs Blogs a comment on a blog entry diff --git a/applications/blog/data/theme.xml b/applications/blog/data/theme.xml index c7e2334b..96cfd069 100644 --- a/applications/blog/data/theme.xml +++ b/applications/blog/data/theme.xml @@ -1270,7 +1270,7 @@
-
+