Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ContentMetadataCollectorCompat
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 2
12
0.00% covered (danger)
0.00%
0 / 1
 setNumericPageProperty
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 setUnsortedPageProperty
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Core;
5
6/**
7 * Helper trait for implementations of ContentMetadataCollector.
8 *
9 * This trait is ideally empty.  However, all implementations of
10 * ContentMetadataCollector should `use` it.  Then, when a method is
11 * changed in the ContentMetadataCollector implementation, compatibility
12 * code can be temporarily added to this trait in order to facilitate
13 * migration.
14 *
15 * For example, suppose that the method `getFoo()` in ContentMetadataCollector`
16 * was renamed to `getBar()`.  Before, third-party code contains:
17 * ```
18 * class MyCollector implements ContentMetadataCollector {
19 *   use ContentMetadataCollectorCompat;
20 *
21 *   public function getFoo() { ... }
22 * }
23 * ```
24 * When the method is renamed in the `ContentMetadataCollector` interface
25 * we then add the following to `ContentMetadataCollectorCompat`:
26 * ```
27 * trait ContentMetadataCollectorCompat {
28 *   public function getBar() {
29 *     return $this->getFoo();
30 *   }
31 * }
32 * ```
33 *
34 * This prevents `MyCollector` from failing to implement
35 * `ContentMetadataCollector` when Parsoid is upgraded to the latest version.
36 * Over time, `MyCollector` will rename the method in its own implementation
37 * and that will override the default implementation inherited from the
38 * `ContentMetadataCollectorCompat` class.  Then eventually the
39 * compatibility method can be removed from this trait and we're back
40 * where we started.
41 *
42 * Similarly, if we want to collect some new type of metadata, the
43 * collection method can be added to `ContentMetadataCollector` at the
44 * same time a default implementation is added to
45 * `ContentMetadataCollectorCompat`; again ensuring that we don't
46 * unnecessarily break classes which implement
47 * `ContentMetadataCollector`.  The default implementation could do
48 * nothing, effectively ignoring the collection request, or it could
49 * record portions of the metadata using other collection methods.
50 */
51trait ContentMetadataCollectorCompat {
52    /* This trait is empty, in an ideal world. */
53
54    // ContentMetadataCollector::setPageProperty() should be removed
55    // at the same time these transitional methods are removed from
56    // Compat, leaving only ::setIndexedPageProperty and
57    // ::setUnindexedPageProperty in CMC.
58
59    /**
60     * Set a numeric page property whose *value* is intended to be sorted
61     * and indexed.  The sort key used for the property will be the value,
62     * coerced to a number.
63     *
64     * See `::setPageProperty()` for details.
65     *
66     * In the future, we may allow the value to be specified independent
67     * of sort key (T357783).
68     *
69     * @param string $propName The name of the page property
70     * @param int|float|string $numericValue the numeric value
71     * @since 1.42
72     */
73    public function setNumericPageProperty( string $propName, $numericValue ): void {
74        if ( !is_numeric( $numericValue ) ) {
75            throw new \TypeError( __METHOD__ . " with non-numeric value" );
76        }
77        // @phan-suppress-next-line PhanUndeclaredMethod in CMC interface
78        $this->setPageProperty( $propName, 0 + $numericValue );
79    }
80
81    /**
82     * Set a page property whose *value* is not intended to be sorted and
83     * indexed.
84     *
85     * See `::setPageProperty()` for details.  It is recommended to
86     * use the empty string if you need a placeholder value (ie, if
87     * it is the *presence* of the property which is important, not
88     * the *value* the property is set to).
89     *
90     * It is still possible to efficiently look up all the pages with
91     * a certain property (the "presence" of it *is* indexed; see
92     * Special:PagesWithProp, list=pageswithprop).
93     *
94     * @param string $propName The name of the page property
95     * @param string $value Optional value; defaults to the empty string.
96     * @since 1.42
97     */
98    public function setUnsortedPageProperty( string $propName, string $value = '' ): void {
99        // $value is already coerced to string by the argument type hint
100        // @phan-suppress-next-line PhanUndeclaredMethod in CMC interface
101        $this->setPageProperty( $name, $value );
102    }
103}