Add filenames to code boxes in migration guides
[GitHub/WoltLab/woltlab.github.io.git] / docs / migration / wsc30 / php.md
1 # Migrating from WSC 3.0 - PHP
2
3 ## Approval-System for Comments
4
5 Comments can now be set to require approval by a moderator before being published. This feature is disabled by default if you do not provide a permission in the manager class, enabling it requires a new permission that has to be provided in a special property of your manage implementation.
6
7 {jinja{ codebox(
8 language="php",
9 title="files/lib/system/comment/manager/ExampleCommentManager.class.php",
10 contents="""
11 <?php
12 class ExampleCommentManager extends AbstractCommentManager {
13 protected $permissionAddWithoutModeration = 'foo.bar.example.canAddCommentWithoutModeration';
14 }
15 """
16 ) }}
17
18 ## Raw HTML in User Activity Events
19
20 User activity events were previously encapsulated inside `<div class="htmlContent">…</div>`, with impacts on native elements such as lists. You can now disable the class usage by defining your event as raw HTML:
21
22
23 {jinja{ codebox(
24 language="php",
25 title="files/lib/system/user/activity/event/ExampleUserActivityEvent.class.php",
26 contents="""
27 <?php
28 class ExampleUserActivityEvent {
29 // enables raw HTML for output, defaults to `false`
30 protected $isRawHtml = true;
31 }
32 """
33 ) }}
34
35 ## Permission to View Likes of an Object
36
37 Being able to view the like summary of an object was restricted to users that were able to like the object itself. This creates situations where the object type in general is likable, but the particular object cannot be liked by the current users, while also denying them to view the like summary (but it gets partly exposed through the footer note/summary!).
38
39 Implement the interface `\wcf\data\like\IRestrictedLikeObjectTypeProvider` in your object provider to add support for this new permission check.
40
41 {jinja{ codebox(
42 language="php",
43 title="files/lib/data/example/LikeableExampleProvider.class.php",
44 contents="""
45 <?php
46 class LikeableExampleProvider extends ExampleProvider implements IRestrictedLikeObjectTypeProvider, IViewableLikeProvider {
47 public function canViewLikes(ILikeObject $object) {
48 // perform your permission checks here
49 return true;
50 }
51 }
52 """
53 ) }}
54
55 ## Developer Tools: Sync Feature
56
57 The synchronization feature of the newly added developer tools works by invoking a package installation plugin (PIP) outside of a regular installation, while simulating the basic environment that is already exposed by the API.
58
59 However, not all PIPs qualify for this kind of execution, especially because it could be invoked multiple times in a row by the user. This is solved by requiring a special marking for PIPs that have no side-effects (= idempotent) when invoked any amount of times with the same arguments.
60
61 There's another feature that allows all matching PIPs to be executed in a row using a single button click. In order to solve dependencies on other PIPs, any implementing PIP must also provide the method `getSyncDependencies()` that returns the dependent PIPs in an arbitrary order.
62
63 {jinja{ codebox(
64 language="php",
65 title="files/lib/data/package/plugin/ExamplePackageInstallationPlugin.class.php",
66 contents="""
67 <?php
68 class ExamplePackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin implements IIdempotentPackageInstallationPlugin {
69 public static function getSyncDependencies() {
70 // provide a list of dependent PIPs in arbitrary order
71 return [];
72 }
73 }
74 """
75 ) }}
76
77 ## Media Providers
78
79 Media providers were added through regular SQL queries in earlier versions, but this is neither convenient, nor did it offer a reliable method to update an existing provider. WoltLab Suite 3.1 adds a new `mediaProvider`-PIP that also offers a `className` parameter to off-load the result evaluation and HTML generation.
80
81 ### Example Implementation
82
83 {jinja{ codebox(
84 language="xml",
85 title="mediaProvider.xml",
86 filepath="migration/wsc-30/mediaProvider.xml"
87 ) }}
88
89 #### PHP Callback
90
91 The full match is provided for `$url`, while any capture groups from the regular expression are assigned to `$matches`.
92
93 ```php
94 <?php
95 class ExampleBBCodeMediaProvider implements IBBCodeMediaProvider {
96 public function parse($url, array $matches = []) {
97 return "final HTML output";
98 }
99 }
100 ```
101
102 ## Re-Evaluate HTML Messages
103
104 !!! warning "You need to manually set the disallowed bbcodes in order to avoid unintentional bbcode evaluation. Please see [this commit](https://github.com/WoltLab/WCF/commit/7e058783da1378dda5393a9bb4df9cfe94e5b394) for a reference implementation inside worker processes."
105
106 The HtmlInputProcessor only supported two ways to handle an existing HTML message:
107
108 1. Load the string through `process()` and run it through the validation and sanitation process, both of them are rather expensive operations and do not qualify for rebuild data workers.
109 2. Detect embedded content using `processEmbeddedContent()` which bypasses most tasks that are carried out by `process()` which aren't required, but does not allow a modification of the message.
110
111 The newly added method `reprocess($message, $objectType, $objectID)` solves this short-coming by offering a full bbcode and text re-evaluation while bypassing any input filters, assuming that the input HTML was already filtered previously.
112
113 ### Example Usage
114
115 ```php
116 <?php
117 // rebuild data workers tend to contain code similar to this:
118 foreach ($this->objectList as $message) {
119 // ...
120 if (!$message->enableHtml) {
121 // ...
122 }
123 else {
124 // OLD:
125 $this->getHtmlInputProcessor()->processEmbeddedContent($message->message, 'com.example.foo.message', $message->messageID);
126
127 // REPLACE WITH:
128 $this->getHtmlInputProcessor()->reprocess($message->message, 'com.example.foo.message', $message->messageID);
129 $data['message'] = $this->getHtmlInputProcessor()->getHtml();
130 }
131 // ...
132 }
133 ```