Projet

Général

Profil

Paste
Télécharger (12,5 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / i18n / i18n_translation / i18n_translation.inc @ 76df55b7

1
<?php
2
/**
3
 * @file
4
 * Internationalization (i18n) module - Translation set
5
 */
6
class i18n_translation_set {
7
  public $tsid = NULL;
8
  public $type;
9
  public $bundle = '';
10
  public $status = 0;
11
  public $master_id = 0;
12
  // It may optionally have a title
13
  public $title = '';
14
  // Translations indexed by language
15
  protected $translations = NULL;
16
  // Translation languages indexed by oid
17
  protected $object_languages = array();
18
  // Related translation sets indexed by tsid
19
  // Keep track of old translation sets objects belong to.
20
  protected $related_translations = array();
21
  /**
22
   * Constructor from object/array
23
   */
24
  public function __construct($translation = NULL) {
25
    if ($translation) {
26
      foreach ((array)$translation as $key => $value) {
27
        $this->$key = $value;
28
      }
29
    }
30
  }
31

    
32
  /**
33
   * Delete a translation set
34
   * 
35
   * @param $delete_translations
36
   *   Whether to unlink translations from the set. Detaults to TRUE.
37
   */
38
  public function delete($delete_translations = TRUE) {
39
    db_delete('i18n_translation_set')
40
      ->condition('tsid', $this->tsid)
41
      ->execute();
42
    if ($delete_translations) {
43
      $this->delete_translations();
44
    }
45
    $this->invoke_all('delete');
46
    $this->tsid = NULL;
47
  }
48

    
49
  /**
50
   * Invoke all modules
51
   */
52
  public function invoke_all($op) {
53
    module_invoke_all('i18n_translation_set_' . $op, $this);
54
    module_invoke_all('entity_' . $op, $this, 'i18n_translation');
55
  }
56

    
57
  /**
58
   * Create a new translation set
59
   * 
60
   * @param $save_translations
61
   *   Whether to update linked objects so they belong to this set.
62
   */
63
  public function insert($save_translations = TRUE) {
64
    $this->created = $this->changed = REQUEST_TIME;
65
    $status = drupal_write_record('i18n_translation_set', $this);
66
    if ($save_translations) {
67
      $this->save_translations();
68
      $this->update_related();
69
    }
70
    $this->invoke_all('insert');
71
    return $status;
72
  }
73

    
74
  /**
75
   * Save translation set
76
   * 
77
   * @param $save_translations
78
   *   Whether to update linked objects so they belong to this set.
79
   */
80
  public function save($save_translations = TRUE) {
81
    $this->invoke_all('presave');
82
    return empty($this->tsid) ? $this->insert($save_translations) : $this->update($save_translations);
83
  }
84

    
85
  /**
86
   * Update a translation set
87
   * 
88
   * @param $update_translations
89
   *   Whether to update objects linked to this set.
90
   */
91
  public function update($update_translations = TRUE) {
92
    $this->changed = REQUEST_TIME;
93
    $status = drupal_write_record('i18n_translation_set', $this, 'tsid');
94
    if ($update_translations) {
95
      $this->clean_translations();
96
      $this->save_translations();
97
      $this->update_related();
98
    }
99
    $this->invoke_all('update');
100
    return $status;
101
  }
102

    
103
  /**
104
   * Update a translation set or delete if empty.
105
   */
106
  public function update_delete() {
107
    if ($this->get_translations()) {
108
      $result = $this->save(TRUE);
109
      // Update related translation sets too.
110
      $this->update_related();
111
      return $result;
112
    }
113
    else {
114
      return $this->delete(TRUE);
115
    }
116
  }
117

    
118
  /**
119
   * Update related translation sets
120
   */
121
  protected function update_related($op = 'update_delete') {
122
    foreach ($this->related_translations as $translation_set) {
123
      $translation_set->$op();
124
    }    
125
  }
126
  
127
  /**
128
   * Clean all items in this translation set
129
   *
130
   * Unlink other items (not current translations from this translation set)
131
   */
132
  public function clean_translations() {
133
    if (($table = $this->get_table()) && ($field = $this->get_field())) {
134
      $query = db_update($table)
135
        ->fields(array($field => 0))
136
        ->condition($field, $this->tsid);
137
      if ($translations = $this->get_translations()) {
138
        $query->condition('language', array_keys($translations), 'NOT IN');
139
      }
140
      return $query->execute();
141
    }
142
  }
143

    
144
  /**
145
   * Save translations in this translation set
146
   */
147
  public function save_translations() {
148
    if (($table = $this->get_table()) && ($field = $this->get_field())) {
149
      if ($keys = $this->get_translations_keys()) {
150
        return db_update($table)
151
          ->fields(array($field => $this->tsid))
152
          ->condition($this->key_field(), $keys)
153
          ->execute();
154
      }
155
      else {
156
        return $this->delete_translations();
157
      }
158
    }
159
  }
160

    
161
  /**
162
   * Delete translations in this translation set
163
   *
164
   * It won't delete objects, just unlink them from translation set
165
   */
166
  public function delete_translations() {
167
    if (($table = $this->get_table()) && ($field = $this->get_field())) {
168
      return db_update($table)
169
        ->fields(array($field => 0))
170
        ->condition($field, $this->tsid)
171
        ->execute();
172
    }
173
  }
174

    
175
  /**
176
   * Get translations, indexed by language
177
   */
178
  public function get_translations() {
179
    $translations = array();
180
    foreach ($this->get_objects() as $lang => $object) {
181
      $translations[$lang] = $object->get_object();
182
    }
183
    return $translations;
184
  }
185
  /**
186
   * Reset translations, set empty array or new array of translations.
187
   * 
188
   * @param $translations array
189
   *   Array of langcode => item
190
   */
191
  public function reset_translations($translations = array()) {
192
    $this->translations = array();
193
    $this->add_translations($translations);
194
    return $this;
195
  }
196
  /**
197
   * Get translations as i18n objects, indexed by language
198
   */
199
  public function get_objects() {
200
    if (!isset($this->translations)) {
201
      $this->translations = array();
202
      // Disable selection query altering, just in case
203
      $previous = i18n_select(FALSE);
204
      $this->add_translations($this->load_translations());
205
      i18n_select($previous);
206
    }
207
    return $this->translations;
208
  }
209

    
210
  /**
211
   * Get item for language
212
   */
213
  public function get_item($langcode) {
214
    if (($translations = $this->get_translations()) && isset($translations[$langcode])) {
215
      return $translations[$langcode];
216
    }
217
    else {
218
      return NULL;
219
    }
220
  }
221
  /**
222
   * Get translations keys, indexed by language
223
   */
224
  public function get_translations_keys() {
225
    $keys = array();
226
    foreach ($this->get_objects() as $lang => $object) {
227
      if ($id = $object->get_key()) {
228
        $keys[$lang] = $id;
229
      }
230
    }
231
    return array_filter($keys);
232
  }
233
  /**
234
   * Get edit path for this translation set
235
   */
236
  public function get_edit_path() {
237
    if ($path = $this->get_info('edit path')) {
238
      return strtr($path, $this->get_path_placeholders('delete'));
239
    }
240
    else {
241
      return '';
242
    }
243
  }
244
  /**
245
   * Get operations as renderable links
246
   */
247
  public function get_operations() {
248
    $destination = drupal_get_destination();
249
    $operations = array();
250
    if ($path = $this->get_edit_path()) {
251
      $operations['edit'] = array(
252
        'title' => t('edit'),
253
        'href' => $path,
254
        'query' => $destination,
255
      );
256
    }
257
    if ($path = $this->get_delete_path()) {
258
      $operations['delete'] = array(
259
        'title' => t('delete'),
260
        'href' => $path,
261
        'query' => $destination,
262
      );
263
    }
264
    return $operations;  
265
  }
266
  /**
267
   * Get items as renderable links
268
   */
269
  public function get_links() {
270
    $language_list = language_list();
271
    $items = array();
272
    foreach ($this->get_objects() as $langcode => $object) {
273
      $title = $object->get_title();
274
      $path = $object->get_path();
275
      $language = isset($language_list[$langcode]) ? $language_list[$langcode] : NULL;
276
      $items[$langcode] = array(
277
        'title' => $title,
278
        'href' => $path ? $path : NULL,
279
        'language' => $language,
280
      );
281
      if ($language && function_exists('languageicons_link_add')) {
282
        languageicons_link_add($items[$langcode]);
283
      }
284
    }
285
    return $items;    
286
  }
287
  /**
288
   * Get overview (list) path for this translation set
289
   */
290
  public function get_list_path() {
291
    return $this->get_info('list path');
292
  }
293
  /**
294
   * Get delete path for this translation set
295
   */
296
  public function get_delete_path() {
297
    if ($path = $this->get_info('delete path')) {
298
      return strtr($path, $this->get_path_placeholders('delete'));
299
    }
300
    else {
301
      return '';
302
    }
303
  }
304
  /**
305
   * Get placeholder values for path replacement
306
   */
307
  function get_path_placeholders($op = 'list') {
308
    $values['%operation'] = $op;
309
    $values['%type'] = $this->type;
310
    $values['%i18n_translation_set'] = $this->tsid;
311
    if ($placeholder = $this->get_info('placeholder')) {
312
      $values[$placeholder] = $this->tsid;
313
    }
314
    return $values;
315
  }
316
  
317
  /**
318
   * Get field on translations table that stores the translation set id (tsid)
319
   */
320
  protected function get_field() {
321
    return $this->get_info('field');
322
  }
323

    
324
  /**
325
   * Get property from translation set info
326
   */
327
  public function get_info($property, $default = NULL) {
328
    $info = i18n_translation_set_info($this->type);
329
    return $info && isset($info[$property]) ? $info[$property] : $default;
330
  }
331

    
332
  /**
333
   * Get table name, where translation items are stored.
334
   */
335
  protected function get_table() {
336
    return $this->get_info('table');
337
  }
338

    
339
  /**
340
   * Get title for this set
341
   */
342
  public function get_title() {
343
    if (!empty($this->title)) {
344
      return $this->title;
345
    }
346
    elseif ($translations = $this->get_objects()) {
347
      foreach ($translations as $object) {
348
        $names[] = $object->get_title();
349
      }
350
      return implode(' / ', $names);
351
    }
352
    else {
353
      return t('Undefined');
354
    }
355
  }
356

    
357
  /**
358
   * Get item list
359
   */
360
  public function item_list() {
361
    $language_list = language_list();
362
    $items = array();
363
    foreach ($this->get_objects() as $langcode => $object) {
364
      $title = $object->get_title();
365
      $path = $object->get_path();
366
      if ($title && $path) {
367
        $options = isset($language_list[$langcode]) ? array('language' => $language_list[$langcode]) : array();
368
        $items[$langcode] = l($title, $path, $options);
369
      }
370
      elseif ($title) {
371
        $items[$langcode] = check_plain($title);
372
      }
373
    }
374
    return $items;
375
  }
376

    
377
  /**
378
   * Add array of translation items
379
   * 
380
   * @param $translations array
381
   *   Translation items indexed by language code
382
   */
383
  public function add_translations($translations) {
384
    foreach ($translations as $langcode => $item) {
385
      $this->add_item($item, $langcode);
386
    }
387
    return $this;
388
  }
389

    
390
  /**
391
   * Add translation item
392
   */
393
  public function add_item($item, $langcode = NULL) {
394
    $object = i18n_object($this->type, $item);
395
    $langcode = $langcode ? $langcode : $object->get_langcode();
396
    // Check whether this item belongs to another translation set
397
    $old_tsid = $object->get_tsid();
398
    if ($old_tsid && $old_tsid != $this->tsid) {
399
      $this->related_translations[$old_tsid] = i18n_translation_set_load($old_tsid);
400
      $this->related_translations[$old_tsid]->remove_object($object);
401
    }    
402
    if ($langcode) {
403
      $this->get_translations();
404
      $object->set_tsid($this->tsid);
405
      $this->translations[$langcode] = $object;
406
      $this->object_languages[$object->get_index()] = $langcode;
407
    }
408
    return $this;
409
  }
410

    
411
  /**
412
   * Remove item / language from translation set
413
   * 
414
   * @param $item
415
   *   Item to remove from this translation set, it must have a language property.
416
   */
417
  public function remove_item($item) {
418
    $this->remove_object(i18n_object($this->type, $item));
419
    return $this;
420
  }
421
  
422
  /**
423
   * Remove i18n object from translation set.
424
   */
425
  public function remove_object($object) {
426
    // As object's language may have changed, we use our object_languages index better.
427
    $index = $object->get_index();
428
    $this->get_translations();
429
    if (isset($this->object_languages[$index])) {
430
      $langcode = $this->object_languages[$index];
431
      unset($this->translations[$langcode]);
432
      unset($this->object_languages[$index]);
433
    }
434
    return $this;
435
  }
436

    
437
  /**
438
   * Remove language from translation set.
439
   * 
440
   * @param $langcode
441
   *   Language to remove from this translation set.
442
   */
443
  public function remove_language($langcode) {
444
    $this->get_translations();
445
    if (isset($this->translations[$langcode])) {
446
      $this->remove_object($this->translations[$langcode]);
447
    }
448
    return $this;   
449
  }
450

    
451
  /**
452
   * Load all translations as objects indexed by language
453
   */
454
  public function load_translations() {
455
    if (($table = $this->get_table()) && ($field = $this->get_field())) {
456
      return db_select($table, 't')
457
        ->fields('t')
458
        ->condition('t.' . $field, $this->tsid)
459
        ->execute()
460
        ->fetchAllAssoc('language');
461
    }
462
    else {
463
      return array();
464
    }
465
  }
466

    
467
  /**
468
   * Get key field for this translation items
469
   */
470
  protected function key_field() {
471
    $info = i18n_object_info($this->type);
472
    return $info['key'];
473
  }
474
}