Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / views / src / Plugin / views / join / FieldOrLanguageJoin.php
1 <?php
2
3 namespace Drupal\views\Plugin\views\join;
4
5 use Drupal\Core\Database\Query\SelectInterface;
6
7 /**
8  * Implementation for the "field OR language" join.
9  *
10  * If the extra conditions contain either ".langcode" or ".bundle", they will be
11  * grouped and joined with OR instead of AND. The entire group will then be
12  * joined to the other conditions with AND.
13  *
14  * This is needed for configurable fields that are translatable on some bundles
15  * and untranslatable on others. The correct field values to fetch in this case
16  * have a langcode that matches the entity record *or* have a bundle on which
17  * the field is untranslatable. Thus, the entity base table (or data table, or
18  * revision data table, respectively) must join the field data table (or field
19  * revision table) on a matching langcode *or* a bundle where the field is
20  * untranslatable. The following example views data achieves this for a node
21  * field named 'field_tags' which is translatable on an 'article' node type, but
22  * not on the 'news' and 'page' node types:
23  *
24  * @code
25  *   $data['node__field_tags']['table']['join']['node_field_data'] = [
26  *     'join_id' => 'field_or_language_join',
27  *     'table' => 'node__field_tags',
28  *     'left_field' => 'nid',
29  *     'field' => 'entity_id',
30  *     'extra' => [
31  *       [
32  *         'field' => 'deleted',
33  *         'value' => 0,
34  *         'numeric' => TRUE,
35  *       ],
36  *       [
37  *         'left_field' => 'langcode',
38  *         'field' => 'langcode',
39  *       ],
40  *       [
41  *         'field' => 'bundle',
42  *         'value' => ['news', 'page'],
43  *       ],
44  *     ],
45  *   ];
46  * @endcode
47  *
48  * The resulting join condition for this example would be the following:
49  *
50  * @code
51  *   ON node__field_tags.deleted = 0
52  *     AND (
53  *       node_field_data.langcode = node__field_tags.langcode
54  *       OR node__field.tags.bundle IN ['news', 'page']
55  *     )
56  * @endcode
57  *
58  * @see views_field_default_views_data()
59  *
60  * @ingroup views_join_handlers
61  *
62  * @ViewsJoin("field_or_language_join")
63  */
64 class FieldOrLanguageJoin extends JoinPluginBase {
65
66   /**
67    * {@inheritdoc}
68    */
69   protected function joinAddExtra(&$arguments, &$condition, $table, SelectInterface $select_query, $left_table = NULL) {
70     if (empty($this->extra)) {
71       return;
72     }
73
74     if (is_array($this->extra)) {
75       $extras = [];
76       foreach ($this->extra as $extra) {
77         $extras[] = $this->buildExtra($extra, $arguments, $table, $select_query, $left_table);
78       }
79
80       // Remove and store the langcode OR bundle join condition extra.
81       $language_bundle_conditions = [];
82       foreach ($extras as $key => $extra) {
83         if (strpos($extra, '.langcode') !== FALSE || strpos($extra, '.bundle') !== FALSE) {
84           $language_bundle_conditions[] = $extra;
85           unset($extras[$key]);
86         }
87       }
88
89       if (count($extras) > 1) {
90         $condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')';
91       }
92       elseif ($extras) {
93         $condition .= ' AND ' . array_shift($extras);
94       }
95
96       // Tack on the langcode OR bundle join condition extra.
97       if (!empty($language_bundle_conditions)) {
98         $condition .= ' AND (' . implode(' OR ', $language_bundle_conditions) . ')';
99       }
100     }
101     elseif (is_string($this->extra)) {
102       $condition .= " AND ($this->extra)";
103     }
104   }
105
106 }