Projet

Général

Profil

Paste
Télécharger (6,8 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / entity / entity.i18n.inc @ 082b75eb

1 85ad3d82 Assos Assos
<?php
2
/**
3
 * @file
4
 * Internationalization (i18n) integration.
5
 */
6
7
/**
8
 * Gets the i18n controller for a given entity type.
9
 *
10
 * @return EntityDefaultI18nStringController|array|false
11
 *   If a type is given, the controller for the given entity type. Else an array
12
 *   of all enabled controllers keyed by entity type is returned.
13
 */
14
function entity_i18n_controller($type = NULL) {
15
  $static = &drupal_static(__FUNCTION__);
16
17
  if (!isset($type)) {
18
    // Invoke the function for each type to ensure we have fully populated the
19
    // static variable.
20
    foreach (entity_get_info() as $entity_type => $info) {
21
      entity_i18n_controller($entity_type);
22
    }
23
    return array_filter($static);
24
  }
25
26
  if (!isset($static[$type])) {
27
    $info = entity_get_info($type);
28
    // Do not activate it by default. Modules have to explicitly enable it by
29
    // specifying EntityDefaultI18nStringController or their customization.
30
    $class = isset($info['i18n controller class']) ? $info['i18n controller class'] : FALSE;
31
    $static[$type] = $class ? new $class($type, $info) : FALSE;
32
  }
33
34
  return $static[$type];
35
}
36
37
/**
38
 * Implements hook_i18n_string_info().
39
 */
40
function entity_i18n_string_info() {
41
  $groups = array();
42
  foreach (entity_i18n_controller() as $entity_type => $controller) {
43
    $groups += $controller->hook_string_info();
44
  }
45
  return $groups;
46
}
47
48
/**
49
 * Implements hook_i18n_object_info().
50
 */
51
function entity_i18n_object_info() {
52
  $info = array();
53
  foreach (entity_i18n_controller() as $entity_type => $controller) {
54
    $info += $controller->hook_object_info();
55
  }
56
  return $info;
57
}
58
59
/**
60
 * Implements hook_i18n_string_objects().
61
 */
62
function entity_i18n_string_objects($type) {
63
  if ($controller = entity_i18n_controller($type)) {
64
    return $controller->hook_string_objects();
65
  }
66
}
67
68
/**
69
 * Default controller handling i18n integration.
70
 *
71
 * Implements i18n string translation for all non-field properties marked as
72
 * 'translatable' and having the flag 'i18n string' set. This translation
73
 * approach fits in particular for translating configuration, i.e. exportable
74
 * entities.
75
 *
76
 * Requirements for the default controller:
77
 *  - The entity type providing module must be specified using the 'module' key
78
 *    in hook_entity_info().
79
 *  - An 'entity class' derived from the provided class 'Entity' must be used.
80
 *  - Properties must be declared as 'translatable' and the 'i18n string' flag
81
 *    must be set to TRUE using hook_entity_property_info().
82
 *  - i18n must be notified about changes manually by calling
83
 *    i18n_string_object_update(), i18n_string_object_remove() and
84
 *    i18n_string_update_context(). Ideally, this is done in a small integration
85
 *    module depending on the entity API and i18n_string. Look at the provided
86
 *    testing module "entity_test_i18n" for an example.
87
 *  - If the entity API admin UI is used, the "translate" tab will be
88
 *    automatically enabled and linked from the UI.
89
 *  - There are helpers for getting translated values which work regardless
90
 *    whether the i18n_string module is enabled, i.e. entity_i18n_string()
91
 *    and Entity::getTranslation().
92
 *
93
 *  Current limitations:
94
 *   - Translatable property values cannot be updated via the metadata wrapper,
95
 *     however reading works fine. See Entity::getTranslation().
96
 */
97
class EntityDefaultI18nStringController {
98
99
  protected $entityType, $entityInfo;
100
101
  /**
102
   * The i18n textgroup we are using.
103
   */
104
  protected $textgroup;
105
106
  public function __construct($type) {
107
    $this->entityType = $type;
108
    $this->entityInfo = entity_get_info($type);
109
    // By default we go with the module name as textgroup.
110
    $this->textgroup = $this->entityInfo['module'];
111
  }
112
113
  /**
114
   * Implements hook_i18n_string_info() via entity_i18n_string_info().
115
   */
116
  public function hook_string_info() {
117
    $list = system_list('module_enabled');
118
    $info = $list[$this->textgroup]->info;
119
120
    $groups[$this->textgroup] = array(
121
      'title' => $info['name'],
122
      'description' => !empty($info['description']) ? $info['description'] : NULL,
123
      'format' => FALSE,
124
      'list' => TRUE,
125
    );
126
    return $groups;
127
  }
128
129
  /**
130
   * Implements hook_i18n_object_info() via entity_i18n_object_info().
131
   *
132
   * Go with the same default values as the admin UI as far as possible.
133
   */
134
  public function hook_object_info() {
135
    $wildcard = $this->menuWildcard();
136
    $id_key = !empty($this->entityInfo['entity keys']['name']) ? $this->entityInfo['entity keys']['name'] : $this->entityInfo['entity keys']['id'];
137
138
    $info[$this->entityType] = array(
139
      // Generic object title.
140
      'title' => $this->entityInfo['label'],
141
      // The object key field.
142
      'key' => $id_key,
143
      // Placeholders for automatic paths.
144
      'placeholders' => array(
145
        $wildcard => $id_key,
146
      ),
147
148
      // Properties for string translation.
149
      'string translation' => array(
150
        // Text group that will handle this object's strings.
151
        'textgroup' => $this->textgroup,
152
        // Object type property for string translation.
153
        'type' => $this->entityType,
154
        // Translatable properties of these objects.
155
        'properties' => $this->translatableProperties(),
156
      ),
157
    );
158
159
    // Integrate the translate tab into the admin-UI if enabled.
160
    if ($base_path = $this->menuBasePath()) {
161
      $info[$this->entityType] += array(
162
        // To produce edit links automatically.
163
        'edit path' => $base_path . '/manage/' . $wildcard,
164
        // Auto-generate translate tab.
165
        'translate tab' => $base_path . '/manage/' . $wildcard . '/translate',
166
      );
167
      $info[$this->entityType]['string translation'] += array(
168
        // Path to translate strings to every language.
169
        'translate path' => $base_path . '/manage/' . $wildcard . '/translate/%i18n_language',
170
      );
171
    }
172
    return $info;
173
  }
174
175
  /**
176
   * Defines the menu base path used by self::hook_object_info().
177
   */
178
  protected function menuBasePath() {
179
    return !empty($this->entityInfo['admin ui']['path']) ? $this->entityInfo['admin ui']['path'] : FALSE;
180
  }
181
182
  /**
183
   * Defines the menu wildcard used by self::hook_object_info().
184
   */
185
  protected function menuWildcard() {
186
    return isset($this->entityInfo['admin ui']['menu wildcard']) ? $this->entityInfo['admin ui']['menu wildcard'] : '%entity_object';
187
  }
188
189
  /**
190
   * Defines translatable properties used by self::hook_object_info().
191
   */
192
  protected function translatableProperties() {
193
    $list = array();
194
    foreach (entity_get_all_property_info($this->entityType) as $name => $info) {
195
      if (!empty($info['translatable']) && !empty($info['i18n string'])) {
196
        $list[$name] = array(
197
          'title' => $info['label'],
198
        );
199
      }
200
    }
201
    return $list;
202
  }
203
204
  /**
205
   * Implements hook_i18n_string_objects() via entity_i18n_string_objects().
206
   */
207
  public function hook_string_objects() {
208
    return entity_load_multiple_by_name($this->entityType, FALSE);
209
  }
210
}