Révision 950416da
Ajouté par Assos Assos il y a plus de 5 ans
drupal7/sites/all/modules/field_collection/README.txt | ||
---|---|---|
44 | 44 |
are set to translatable or not, they will all be translatable as every |
45 | 45 |
language for the host will have a completely separate copy of the field |
46 | 46 |
collection item(s). |
47 |
|
|
48 |
* When using nested field collections the configuration of the fields and |
|
49 |
field collections is very important. The recommended approach is to first |
|
50 |
enable entity translation as defined in step 1, and set the outer |
|
51 |
field collection field as translatable, and all it’s sub-fields to language |
|
52 |
undefined. Also the sub-field collections and it’s sub-fields should be |
|
53 |
set to language undefined. This will ensure that every language of the host |
|
54 |
will have a completely separate copy of the field collection item(s) and |
|
55 |
it’s fields. |
drupal7/sites/all/modules/field_collection/ctools/relationships/field_collection_from_field.inc | ||
---|---|---|
43 | 43 |
$child_plugin['title'] = t( |
44 | 44 |
'!label field collection (!field_name) from !entity_type (!bundle)', |
45 | 45 |
array( |
46 |
'!label' => $instance['label'], |
|
47 |
'!field_name' => $instance['field_name'], |
|
48 |
'!entity_type' => $instance['entity_type'], |
|
49 |
'!bundle' => $instance['bundle']
|
|
46 |
'!label' => $instance['label'],
|
|
47 |
'!field_name' => $instance['field_name'],
|
|
48 |
'!entity_type' => $instance['entity_type'],
|
|
49 |
'!bundle' => $instance['bundle'],
|
|
50 | 50 |
) |
51 | 51 |
); |
52 | 52 |
$restrictions = array('type' => array($instance['bundle'])); |
... | ... | |
78 | 78 |
if (isset($entity->{$plugin_info['field_name']})) { |
79 | 79 |
|
80 | 80 |
$items = field_get_items($plugin_info['entity_type'], $entity, $plugin_info['field_name']); |
81 |
if (isset($items[$delta]['value'])) { |
|
81 |
if (!empty($items) && isset($items[$delta]['value'])) {
|
|
82 | 82 |
$field_collection_item = field_collection_item_load($items[$delta]['value']); |
83 | 83 |
} |
84 | 84 |
|
drupal7/sites/all/modules/field_collection/field-collection-item.tpl.php | ||
---|---|---|
5 | 5 |
* Default theme implementation for field collection items. |
6 | 6 |
* |
7 | 7 |
* Available variables: |
8 |
* - $content: An array of comment items. Use render($content) to print them all, or
|
|
9 |
* print a subset such as render($content['field_example']). Use |
|
8 |
* - $content: An array of comment items. Use render($content) to print them |
|
9 |
* all, or print a subset such as render($content['field_example']). Use
|
|
10 | 10 |
* hide($content['field_example']) to temporarily suppress the printing of a |
11 | 11 |
* given element. |
12 | 12 |
* - $title: The (sanitized) field collection item label. |
drupal7/sites/all/modules/field_collection/field_collection.admin.inc | ||
---|---|---|
12 | 12 |
$instances = field_info_instances(); |
13 | 13 |
$field_types = field_info_field_types(); |
14 | 14 |
$bundles = field_info_bundles(); |
15 |
$header = array(t('Field name'), t('Used in'), array('data' => t('Operations'), 'colspan' => '2')); |
|
15 |
$header = array( |
|
16 |
t('Field name'), |
|
17 |
t('Used in'), |
|
18 |
array('data' => t('Operations'), 'colspan' => '2'), |
|
19 |
); |
|
16 | 20 |
$rows = array(); |
17 | 21 |
foreach ($instances as $entity_type => $type_bundles) { |
18 | 22 |
foreach ($type_bundles as $bundle => $bundle_instances) { |
drupal7/sites/all/modules/field_collection/field_collection.api.php | ||
---|---|---|
16 | 16 |
* This hook allows modules to determine whether a field collection is empty |
17 | 17 |
* before it is saved. |
18 | 18 |
* |
19 |
* @param boolean $empty
|
|
19 |
* @param bool $is_empty
|
|
20 | 20 |
* Whether or not the field should be considered empty. |
21 | 21 |
* @param FieldCollectionItemEntity $item |
22 | 22 |
* The field collection we are currently operating on. |
... | ... | |
182 | 182 |
case 'field_my_first_collection': |
183 | 183 |
$item_wrapper = entity_metadata_wrapper('field_collection_item', $item); |
184 | 184 |
|
185 |
$title = $item_wrapper->field_title->value();
|
|
185 |
$title = $item_wrapper->field_title->value(); |
|
186 | 186 |
$author = $item_wrapper->field_author->value(); |
187 | 187 |
|
188 | 188 |
return "{$title} by {$author}"; |
drupal7/sites/all/modules/field_collection/field_collection.diff.inc | ||
---|---|---|
25 | 25 |
$view_mode = $context['view_mode']; |
26 | 26 |
$entity = entity_revision_load($entity_type, $item['revision_id']); |
27 | 27 |
|
28 |
if(empty($entity)) { |
|
29 |
return array(); |
|
30 |
} |
|
31 |
|
|
28 | 32 |
$field_context = $context; |
29 | 33 |
$field_context['entity_type'] = $entity_type; |
30 | 34 |
$field_context['bundle'] = $bundle_name; |
... | ... | |
56 | 60 |
|
57 | 61 |
// We provide a loose check on the field access. |
58 | 62 |
if (field_access('view', $field, $entity_type) || field_access('edit', $field, $entity_type)) { |
59 |
$langcode = field_language($entity_type, $entity, $field_name);
|
|
63 |
$langcode = !empty($entity) ? field_language($entity_type, $entity, $field_name) : LANGUAGE_NONE;
|
|
60 | 64 |
$field_context['language'] = $langcode; |
61 | 65 |
$field_context['field'] = $field; |
62 | 66 |
$field_context['instance'] = $instance; |
drupal7/sites/all/modules/field_collection/field_collection.entity.inc | ||
---|---|---|
192 | 192 |
list($this->hostEntityId, $this->hostEntityRevisionId) = entity_extract_ids($this->hostEntityType, $this->hostEntity); |
193 | 193 |
// If the host entity is not saved yet, set the id to FALSE. So |
194 | 194 |
// fetchHostDetails() does not try to load the host entity details. |
195 |
// Checking value of $this->hostEntityId. |
|
195 | 196 |
if (!isset($this->hostEntityId)) { |
196 | 197 |
$this->hostEntityId = FALSE; |
197 | 198 |
} |
... | ... | |
231 | 232 |
} |
232 | 233 |
list($recieved_id) = entity_extract_ids($this->hostEntityType, $entity); |
233 | 234 |
|
234 |
if ($this->isInUse()) { |
|
235 |
if ($this->isInUse() && !empty($this->hostEntityId)) {
|
|
235 | 236 |
$current_id = $this->hostEntityId; |
236 | 237 |
} |
237 | 238 |
else { |
... | ... | |
300 | 301 |
} |
301 | 302 |
|
302 | 303 |
protected function fetchHostDetails() { |
303 |
if (!isset($this->hostEntityId)) { |
|
304 |
if (!isset($this->hostEntityId) || (!$this->hostEntityId && $this->hostEntityRevisionId)) {
|
|
304 | 305 |
if ($this->item_id) { |
305 | 306 |
// For saved field collections, query the field data to determine the |
306 | 307 |
// right host entity. |
... | ... | |
310 | 311 |
$query->age(FIELD_LOAD_REVISION); |
311 | 312 |
} |
312 | 313 |
$result = $query->execute(); |
313 |
list($this->hostEntityType, $data) = each($result); |
|
314 |
|
|
315 |
if ($this->isInUse()) { |
|
316 |
$this->hostEntityId = $data ? key($data) : FALSE; |
|
317 |
$this->hostEntityRevisionId = FALSE; |
|
314 |
if ($result) { |
|
315 |
$this->hostEntityType = key($result); |
|
316 |
$data = current($result); |
|
317 |
|
|
318 |
if ($this->isInUse()) { |
|
319 |
$data_array_keys = array_keys($data); |
|
320 |
$this->hostEntityId = $data ? end($data_array_keys) : FALSE; |
|
321 |
$this->hostEntityRevisionId = FALSE; |
|
322 |
} |
|
323 |
// If we are querying for revisions, we get the revision ID. |
|
324 |
else { |
|
325 |
$data_array_keys = array_keys($data); |
|
326 |
$this->hostEntityId = FALSE; |
|
327 |
$this->hostEntityRevisionId = $data ? end($data_array_keys) : FALSE; |
|
328 |
} |
|
318 | 329 |
} |
319 |
// If we are querying for revisions, we get the revision ID. |
|
320 | 330 |
else { |
331 |
// No host entity available yet. |
|
321 | 332 |
$this->hostEntityId = FALSE; |
322 |
$this->hostEntityRevisionId = $data ? key($data) : FALSE; |
|
323 | 333 |
} |
324 | 334 |
} |
325 | 335 |
else { |
... | ... | |
465 | 475 |
/** |
466 | 476 |
* Deletes the field collection item and the reference in the host entity. |
467 | 477 |
*/ |
468 |
public function delete() { |
|
478 |
public function delete($skip_host_save = FALSE) {
|
|
469 | 479 |
parent::delete(); |
470 |
$this->deleteHostEntityReference(); |
|
480 |
if (!$skip_host_save) { |
|
481 |
$this->deleteHostEntityReference(); |
|
482 |
} |
|
471 | 483 |
} |
472 | 484 |
|
473 | 485 |
/** |
... | ... | |
570 | 582 |
} |
571 | 583 |
if (!$row && !isset($this->hostEntity()->{$this->field_name}[$this->langcode()][$this->delta()])) { |
572 | 584 |
// Delete if there is no existing revision or translation to be saved. |
573 |
$this->delete(); |
|
585 |
$this->delete($skip_host_update);
|
|
574 | 586 |
} |
575 | 587 |
} |
576 | 588 |
} |
drupal7/sites/all/modules/field_collection/field_collection.info | ||
---|---|---|
12 | 12 |
configure = admin/structure/field-collections |
13 | 13 |
package = Fields |
14 | 14 |
|
15 |
; Information added by Drupal.org packaging script on 2016-11-17
|
|
16 |
version = "7.x-1.0-beta12"
|
|
15 |
; Information added by Drupal.org packaging script on 2019-01-25
|
|
16 |
version = "7.x-1.0-beta13"
|
|
17 | 17 |
core = "7.x" |
18 | 18 |
project = "field_collection" |
19 |
datestamp = "1479402861" |
|
20 |
|
|
19 |
datestamp = "1548457085" |
drupal7/sites/all/modules/field_collection/field_collection.info.inc | ||
---|---|---|
27 | 27 |
return $info; |
28 | 28 |
} |
29 | 29 |
|
30 |
} |
|
30 |
} |
drupal7/sites/all/modules/field_collection/field_collection.install | ||
---|---|---|
124 | 124 |
->expression('revision_id', 'item_id') |
125 | 125 |
->execute(); |
126 | 126 |
|
127 |
// Add the archived column |
|
127 |
// Add the archived column.
|
|
128 | 128 |
$archived_spec = array( |
129 | 129 |
'description' => 'Boolean indicating whether the field collection item is archived.', |
130 | 130 |
'type' => 'int', |
... | ... | |
365 | 365 |
if ($field['translatable'] == 1 && isset($field['bundles']['field_collection_item'])) { |
366 | 366 |
$query = new EntityFieldQuery(); |
367 | 367 |
$query->entityCondition('entity_type', 'field_collection_item') |
368 |
->fieldLanguageCondition($f_name, LANGUAGE_NONE);
|
|
368 |
->fieldLanguageCondition($f_name, LANGUAGE_NONE); |
|
369 | 369 |
$query_result = $query->execute(); |
370 | 370 |
if (isset($query_result['field_collection_item'])) { |
371 | 371 |
$results = $results + $query_result['field_collection_item']; |
... | ... | |
373 | 373 |
} |
374 | 374 |
} |
375 | 375 |
if (count($results)) { |
376 |
$orphans = array(); |
|
376 | 377 |
$ids = array_keys($results); |
377 | 378 |
$field_collection_items = entity_load('field_collection_item', $ids); |
378 | 379 |
foreach ($field_collection_items as $item) { |
379 |
$item->copyTranslations(LANGUAGE_NONE); |
|
380 |
$item->save(); |
|
380 |
/** @var FieldCollectionItemEntity $item */ |
|
381 |
if ($item->hostEntity()) { |
|
382 |
$item->copyTranslations(LANGUAGE_NONE); |
|
383 |
$item->save(TRUE); |
|
384 |
} |
|
385 |
else { |
|
386 |
$orphans[] = $item->identifier(); |
|
387 |
} |
|
388 |
} |
|
389 |
if ($orphans) { |
|
390 |
$count = count($orphans); |
|
391 |
entity_delete_multiple('field_collection_item', $orphans); |
|
392 |
drupal_set_message("Deleted $count orphaned field collection items."); |
|
381 | 393 |
} |
382 | 394 |
} |
383 | 395 |
} |
drupal7/sites/all/modules/field_collection/field_collection.migrate.inc | ||
---|---|---|
25 | 25 |
* @see http://drupal.org/node/1900640 |
26 | 26 |
*/ |
27 | 27 |
|
28 |
// Avoid issues when migrate module is disabled. |
|
29 |
if (!class_exists('MigrateDestinationEntity')) { |
|
30 |
return; |
|
31 |
} |
|
32 |
|
|
28 | 33 |
/** |
29 | 34 |
* Destination class implementing migration into field_collection. |
30 | 35 |
*/ |
... | ... | |
84 | 89 |
* @param $row |
85 | 90 |
* Raw source data object - passed through to prepare/complete handlers. |
86 | 91 |
* |
87 |
* @return array|false
|
|
92 |
* @return array|bool
|
|
88 | 93 |
* Array of key fields (item_id only in this case) of the collection that |
89 | 94 |
* was saved or FALSE on failure. |
90 | 95 |
*/ |
... | ... | |
93 | 98 |
if (isset($row->migrate_map_destid1)) { |
94 | 99 |
// We're updated an existing entity - start from the previous data. |
95 | 100 |
// entity_load() returns an array, so we get the field collection entity |
96 |
// with array_shift(). |
|
97 |
if ($entity = array_shift(entity_load('field_collection_item', array($row->migrate_map_destid1), array(), TRUE))) { |
|
101 |
// with reset(). |
|
102 |
$result = entity_load('field_collection_item', array($row->migrate_map_destid1), array(), TRUE); |
|
103 |
$entity = reset($result); |
|
104 |
if ($entity) { |
|
98 | 105 |
$entity_old = clone $entity; |
99 | 106 |
$updating = TRUE; |
100 | 107 |
} |
... | ... | |
126 | 133 |
|
127 | 134 |
$this->prepare($entity, $row); |
128 | 135 |
|
129 |
// Restore fields from original field_collection_item if updating |
|
136 |
// Restore fields from original field_collection_item if updating.
|
|
130 | 137 |
if ($updating) { |
131 | 138 |
foreach ($entity as $field => $value) { |
132 | 139 |
if ('field_' != substr($field, 0, 6)) { |
... | ... | |
177 | 184 |
$this->completeRollback($item_id); |
178 | 185 |
return TRUE; |
179 | 186 |
} |
187 |
|
|
180 | 188 |
} |
181 | 189 |
|
182 | 190 |
/** |
drupal7/sites/all/modules/field_collection/field_collection.module | ||
---|---|---|
40 | 40 |
*/ |
41 | 41 |
function field_collection_form_field_ui_field_overview_form_alter(&$form, &$form_state) { |
42 | 42 |
if (count($form['#fields'])) { |
43 |
foreach($form['fields'] as $fieldname => $field) { |
|
43 |
foreach ($form['fields'] as $fieldname => $field) {
|
|
44 | 44 |
if (!isset($field['type']['#title'])) { |
45 | 45 |
continue; |
46 | 46 |
} |
... | ... | |
87 | 87 |
'full' => array( |
88 | 88 |
'label' => t('Full content'), |
89 | 89 |
'custom settings' => FALSE, |
90 |
),
|
|
90 |
), |
|
91 | 91 |
), |
92 | 92 |
'access callback' => 'field_collection_item_access', |
93 | 93 |
'deletion callback' => 'field_collection_item_delete', |
... | ... | |
145 | 145 |
* @param $entity_type |
146 | 146 |
* @param $entity |
147 | 147 |
* |
148 |
* @return |
|
148 |
* @return string
|
|
149 | 149 |
* A language code |
150 | 150 |
*/ |
151 | 151 |
function field_collection_entity_language($entity_type, $entity) { |
... | ... | |
172 | 172 |
/** |
173 | 173 |
* Loads a field collection item. |
174 | 174 |
* |
175 |
* @return field_collection_item
|
|
175 |
* @return |
|
176 | 176 |
* The field collection item entity or FALSE. |
177 | 177 |
*/ |
178 | 178 |
function field_collection_item_load($item_id, $reset = FALSE) { |
... | ... | |
322 | 322 |
*/ |
323 | 323 |
function field_collection_permission() { |
324 | 324 |
return array( |
325 |
'administer field collections' => array(
|
|
325 |
'administer field collections' => array( |
|
326 | 326 |
'title' => t('Administer field collections'), |
327 | 327 |
'description' => t('Create and delete fields on field collections.'), |
328 | 328 |
), |
... | ... | |
558 | 558 |
if (!isset($cleared_host_entity_cache)) { |
559 | 559 |
list($entity_id) = entity_extract_ids($host_entity_type, $host_entity); |
560 | 560 |
entity_get_controller($host_entity_type)->resetCache(array($entity_id)); |
561 |
$cleared_host_entity_cache = true;
|
|
561 |
$cleared_host_entity_cache = TRUE;
|
|
562 | 562 |
} |
563 | 563 |
$is_default = entity_revision_is_default($host_entity_type, $host_entity); |
564 | 564 |
// If an entity type does not support saving non-default entities, |
... | ... | |
761 | 761 |
'field_collection_list' => array( |
762 | 762 |
'label' => t('Links to field collection items'), |
763 | 763 |
'field types' => array('field_collection'), |
764 |
'settings' => array(
|
|
764 |
'settings' => array( |
|
765 | 765 |
'edit' => t('Edit'), |
766 | 766 |
'translate' => t('Translate'), |
767 | 767 |
'delete' => t('Delete'), |
... | ... | |
772 | 772 |
'field_collection_view' => array( |
773 | 773 |
'label' => t('Field collection items'), |
774 | 774 |
'field types' => array('field_collection'), |
775 |
'settings' => array(
|
|
775 |
'settings' => array( |
|
776 | 776 |
'edit' => t('Edit'), |
777 |
'translate' => t('Translate'), |
|
777 | 778 |
'delete' => t('Delete'), |
778 | 779 |
'add' => t('Add'), |
779 | 780 |
'description' => TRUE, |
... | ... | |
783 | 784 |
'field_collection_fields' => array( |
784 | 785 |
'label' => t('Fields only'), |
785 | 786 |
'field types' => array('field_collection'), |
786 |
'settings' => array(
|
|
787 |
'settings' => array( |
|
787 | 788 |
'view_mode' => 'full', |
788 | 789 |
), |
789 | 790 |
), |
... | ... | |
814 | 815 |
$elements['translate'] = array( |
815 | 816 |
'#type' => 'textfield', |
816 | 817 |
'#title' => t('Translate link title'), |
817 |
'#default_value' => $settings['translate'],
|
|
818 |
'#default_value' => isset($settings['translate']) ? $settings['translate'] : '',
|
|
818 | 819 |
'#description' => t('Leave the title empty, to hide the link.'), |
819 | 820 |
'#access' => field_collection_item_is_translatable(), |
820 | 821 |
); |
... | ... | |
874 | 875 |
if ($display['type'] !== 'field_collection_list') { |
875 | 876 |
$entity_type = entity_get_info('field_collection_item'); |
876 | 877 |
if (!empty($entity_type['view modes'][$settings['view_mode']]['label'])) { |
877 |
$output[] = t('View mode: @mode', array('@mode' => $entity_type['view modes'][$settings['view_mode']]['label']));
|
|
878 |
$output[] = t('View mode: @mode', array('@mode' => $entity_type['view modes'][$settings['view_mode']]['label'])); |
|
878 | 879 |
} |
879 | 880 |
} |
880 | 881 |
|
... | ... | |
915 | 916 |
$view_mode = !empty($display['settings']['view_mode']) ? $display['settings']['view_mode'] : 'full'; |
916 | 917 |
foreach ($items as $delta => $item) { |
917 | 918 |
if ($field_collection = field_collection_field_get_entity($item)) { |
918 |
$element[$delta]['entity'] = $field_collection->view($view_mode); |
|
919 |
$element[$delta]['entity'] = $field_collection->view($view_mode, $langcode);
|
|
919 | 920 |
$element[$delta]['#theme_wrappers'] = array('field_collection_view'); |
920 | 921 |
$element[$delta]['#attributes']['class'][] = 'field-collection-view'; |
921 | 922 |
$element[$delta]['#attributes']['class'][] = 'clearfix'; |
... | ... | |
948 | 949 |
$view_mode = !empty($display['settings']['view_mode']) ? $display['settings']['view_mode'] : 'full'; |
949 | 950 |
foreach ($items as $delta => $item) { |
950 | 951 |
if ($field_collection = field_collection_field_get_entity($item)) { |
951 |
$element[$delta]['entity'] = $field_collection->view($view_mode); |
|
952 |
$element[$delta]['entity'] = $field_collection->view($view_mode, $langcode);
|
|
952 | 953 |
} |
953 | 954 |
} |
954 | 955 |
break; |
... | ... | |
997 | 998 |
$path = field_collection_field_get_path($field); |
998 | 999 |
list($id) = entity_extract_ids($entity_type, $entity); |
999 | 1000 |
$element['#suffix'] = ''; |
1000 |
if (!empty($settings['description'])) { |
|
1001 |
if (!empty($settings['description']) && $entity_type != 'node') {
|
|
1001 | 1002 |
$element['#suffix'] .= '<div class="description field-collection-description">' . field_filter_xss($instance['description']) . '</div>'; |
1002 | 1003 |
} |
1003 | 1004 |
$title = entity_i18n_string("field:{$field['field_name']}:{$instance['bundle']}:setting_add", $settings['add']); |
... | ... | |
1177 | 1178 |
'#value' => t('Remove'), |
1178 | 1179 |
'#validate' => array(), |
1179 | 1180 |
'#submit' => array('field_collection_remove_submit'), |
1181 |
'#attributes' => array('class' => array('remove-button')), |
|
1180 | 1182 |
'#limit_validation_errors' => array(), |
1181 | 1183 |
'#ajax' => array( |
1182 | 1184 |
// 'wrapper' is filled in field_collection_field_attach_form(). |
... | ... | |
1430 | 1432 |
* The entity object or FALSE. |
1431 | 1433 |
*/ |
1432 | 1434 |
function field_collection_field_get_entity(&$item, $field_name = NULL) { |
1433 |
if (isset($item['entity'])) { |
|
1435 |
if (isset($item['entity']) && ($item['entity']->entityType() == 'field_collection_item')) {
|
|
1434 | 1436 |
return $item['entity']; |
1435 | 1437 |
} |
1436 | 1438 |
elseif (isset($item['value'])) { |
... | ... | |
1530 | 1532 |
|
1531 | 1533 |
// Copied from _form_validate(). |
1532 | 1534 |
if (isset($elements['#needs_validation'])) { |
1533 |
$is_empty_multiple = (!count($elements['#value'])); |
|
1535 |
$is_countable = is_array($elements['#value']) || $elements['#value'] instanceof Countable; |
|
1536 |
$is_empty_multiple = $is_countable && (!count($elements['#value'])); |
|
1534 | 1537 |
$is_empty_string = (is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0); |
1535 | 1538 |
$is_empty_value = ($elements['#value'] === 0); |
1536 | 1539 |
$is_empty_option = (isset($elements['#options']['_none']) && $elements['#value'] == '_none'); |
drupal7/sites/all/modules/field_collection/field_collection.test | ||
---|---|---|
23 | 23 |
|
24 | 24 |
// Create a field_collection field to use for the tests. |
25 | 25 |
$this->field_name = 'field_test_collection'; |
26 |
$this->field = array('field_name' => $this->field_name, 'type' => 'field_collection', 'cardinality' => 4); |
|
26 |
$this->field = array( |
|
27 |
'field_name' => $this->field_name, |
|
28 |
'type' => 'field_collection', |
|
29 |
'cardinality' => 4, |
|
30 |
); |
|
27 | 31 |
$this->field = field_create_field($this->field); |
28 | 32 |
$this->field_id = $this->field['id']; |
29 | 33 |
|
... | ... | |
83 | 87 |
* Message to display. |
84 | 88 |
* @param $group |
85 | 89 |
* The group this message belongs to, defaults to 'Other'. |
86 |
* @return |
|
90 |
* |
|
91 |
* @return bool |
|
87 | 92 |
* TRUE on pass, FALSE on fail. |
88 | 93 |
*/ |
89 | 94 |
protected function assertNoHookMessage($text, $message = NULL, $group = 'Other') { |
... | ... | |
282 | 287 |
$this->assertTrue($item->archived, 'Removed field collection item is archived.'); |
283 | 288 |
|
284 | 289 |
// Test removing an old node revision. Make sure that the field collection |
285 |
// is not removed |
|
290 |
// is not removed.
|
|
286 | 291 |
list ($node, $item) = $this->createNodeWithFieldCollection(); |
287 | 292 |
$node_vid = $node->vid; |
288 | 293 |
$node->revision = TRUE; |
... | ... | |
714 | 719 |
} |
715 | 720 |
|
716 | 721 |
/** |
717 |
* Install a specified language if it has not been already, otherwise make sure that the language is enabled. |
|
722 |
* Install a specified language if it has not been already, otherwise make |
|
723 |
* sure that the language is enabled. |
|
718 | 724 |
* |
719 |
* @param $langcode |
|
725 |
* @param string $langcode
|
|
720 | 726 |
* The language code to check. |
721 | 727 |
*/ |
722 | 728 |
function addLanguage($langcode) { |
... | ... | |
887 | 893 |
/** |
888 | 894 |
* Create a translation using the Entity Translation Form. |
889 | 895 |
* |
890 |
* @param $node |
|
896 |
* @param mixed $node
|
|
891 | 897 |
* Node of the basic page to create translation for. |
892 |
* @param $langcode |
|
898 |
* @param string $langcode
|
|
893 | 899 |
* The language code of the translation. |
894 |
* @param $source_langcode |
|
900 |
* @param string $source_langcode
|
|
895 | 901 |
* The original language code. |
896 | 902 |
*/ |
897 | 903 |
protected function createTranslationForm($node, $langcode, $source_langcode = 'en') { |
... | ... | |
947 | 953 |
* |
948 | 954 |
* @param mixed $node |
949 | 955 |
* The node to remove the translation from. |
950 |
* @param unknown $langcode
|
|
956 |
* @param string $langcode
|
|
951 | 957 |
* The language of the translation to remove. |
952 |
* @param unknown $source_langcode
|
|
958 |
* @param string $source_langcode
|
|
953 | 959 |
* The source language of the node. |
954 | 960 |
*/ |
955 | 961 |
protected function removeTranslationForm($node, $langcode, $source_langcode) { |
... | ... | |
981 | 987 |
/** |
982 | 988 |
* Creates a translation programmatically using Entity Translation. |
983 | 989 |
* |
984 |
* @param $node |
|
990 |
* @param mixed $node
|
|
985 | 991 |
* Node of the basic page to create translation for. |
986 |
* @param $langcode |
|
992 |
* @param string $langcode
|
|
987 | 993 |
* The language code of the translation. |
988 |
* @param $source_langcode |
|
989 |
* The source language code. |
|
990 | 994 |
*/ |
991 | 995 |
protected function createTranslation($node, $langcode) { |
992 | 996 |
$source_langcode = $node->language; |
... | ... | |
1023 | 1027 |
field_attach_update('node', $node); |
1024 | 1028 |
|
1025 | 1029 |
// Reload an return the node. |
1026 |
$node = node_load($node->nid, null, TRUE);
|
|
1030 |
$node = node_load($node->nid, NULL, TRUE);
|
|
1027 | 1031 |
return $node; |
1028 | 1032 |
} |
1029 | 1033 |
|
... | ... | |
1032 | 1036 |
* |
1033 | 1037 |
* @param mixed $node |
1034 | 1038 |
* The node to remove the translation from. |
1035 |
* @param unknown $langcode
|
|
1039 |
* @param string $langcode
|
|
1036 | 1040 |
* The language of the translation to remove. |
1037 | 1041 |
*/ |
1038 | 1042 |
protected function removeTranslation($node, $langcode) { |
... | ... | |
1044 | 1048 |
node_save($node); |
1045 | 1049 |
|
1046 | 1050 |
// Reload and return the node. |
1047 |
$node = node_load($node->nid, null, TRUE);
|
|
1051 |
$node = node_load($node->nid, NULL, TRUE);
|
|
1048 | 1052 |
|
1049 | 1053 |
return $node; |
1050 | 1054 |
} |
... | ... | |
1052 | 1056 |
/** |
1053 | 1057 |
* Creates a new revision of the node and checks the result. |
1054 | 1058 |
* |
1055 |
* @param $node |
|
1056 |
* @param $langcode |
|
1057 |
* @param $source_langcode |
|
1058 |
* @return |
|
1059 |
* @param mixed $node |
|
1060 |
* The node to remove the translation from. |
|
1061 |
* @param string $langcode |
|
1062 |
* The language of the translation to remove. |
|
1063 |
* @param string $source_langcode |
|
1064 |
* The source language of the node. |
|
1065 |
* |
|
1066 |
* @return mixed |
|
1059 | 1067 |
* The new revision of the node. |
1060 | 1068 |
*/ |
1061 | 1069 |
protected function createRevision($node, $langcode, $source_langcode) { |
... | ... | |
1089 | 1097 |
* The language to check. |
1090 | 1098 |
*/ |
1091 | 1099 |
protected function checkFieldCollectionContent($node, $langcode) { |
1092 |
switch($langcode) { |
|
1100 |
switch ($langcode) {
|
|
1093 | 1101 |
case 'en': |
1094 | 1102 |
$untrans_field = self::UNTRANS_FIELD_EN; |
1095 | 1103 |
$trans_field = self::TRANS_FIELD_EN; |
1096 | 1104 |
break; |
1105 |
|
|
1097 | 1106 |
case 'de': |
1098 | 1107 |
$untrans_field = self::UNTRANS_FIELD_DE; |
1099 | 1108 |
$trans_field = self::TRANS_FIELD_DE; |
drupal7/sites/all/modules/field_collection/field_collection.tokens.inc | ||
---|---|---|
131 | 131 |
|
132 | 132 |
if ($host_entity_types === FALSE) { |
133 | 133 |
$host_entity_types = array(); |
134 |
$entity_types = entity_get_info(); |
|
134 |
|
|
135 |
if (function_exists('entity_get_info')) { |
|
136 |
$entity_types = entity_get_info(); |
|
137 |
} |
|
138 |
|
|
135 | 139 |
// Look for all field instances, filter them by type == 'field_collection' |
136 | 140 |
// and map the entity type it's connected to to the returned list. |
137 | 141 |
foreach (field_info_field_map() as $field_instance) { |
drupal7/sites/all/modules/field_collection/views/field_collection.views.inc | ||
---|---|---|
44 | 44 |
} |
45 | 45 |
|
46 | 46 |
$data['field_collection_item'][$pseudo_field_name]['relationship'] = array( |
47 |
'title' => t('Entity with the @field (@field_name)', array('@entity' => $entity, '@field' => $label, '@field_name' => $field['field_name'])), |
|
47 |
'title' => t('Entity with the @field (@field_name)', array( |
|
48 |
'@entity' => $entity, |
|
49 |
'@field' => $label, |
|
50 |
'@field_name' => $field['field_name'], |
|
51 |
)), |
|
48 | 52 |
'help' => t('Relate each @entity using @field.', array('@entity' => $entity, '@field' => $label)), |
49 | 53 |
'handler' => 'views_handler_relationship_entity_reverse', |
50 | 54 |
'field_name' => $field['field_name'], |
drupal7/sites/all/modules/field_collection/views/field_collection_handler_relationship.inc | ||
---|---|---|
55 | 55 |
} |
56 | 56 |
return $this->table_alias; |
57 | 57 |
} |
58 |
|
|
58 | 59 |
} |
drupal7/sites/all/modules/rules/DEVELOPER.txt | ||
---|---|---|
23 | 23 |
outside of the rule admin module too. In fact the rules admin module is |
24 | 24 |
pretty small, as it just relies on the provided UI of the components. |
25 | 25 |
* The UI is incorporated using the faces object extension mechanism, see |
26 |
rules_rules_plugin_info() for an overview of the used UI extenders. |
|
26 |
rules_rules_plugin_info() for an overview of the used UI extenders. |
drupal7/sites/all/modules/rules/README.txt | ||
---|---|---|
9 | 9 |
The Rules module allows site administrators to define conditionally executed |
10 | 10 |
actions based on occurring events (ECA-rules). |
11 | 11 |
|
12 |
Project homepage: http://drupal.org/project/rules
|
|
12 |
Project homepage: https://www.drupal.org/project/rules
|
|
13 | 13 |
|
14 | 14 |
|
15 | 15 |
Installation |
... | ... | |
18 | 18 |
*Before* starting, make sure that you have read at least the introduction - so |
19 | 19 |
you know at least the basic concepts. You can find it here: |
20 | 20 |
|
21 |
http://drupal.org/node/298480
|
|
21 |
https://www.drupal.org/node/298480
|
|
22 | 22 |
|
23 | 23 |
* Rules depends on the Entity API module, download and install it from |
24 |
http://drupal.org/project/entity
|
|
24 |
https://www.drupal.org/project/entity
|
|
25 | 25 |
* Copy the whole rules directory to your modules directory |
26 | 26 |
(e.g. DRUPAL_ROOT/sites/all/modules) and activate the Rules and Rules UI |
27 | 27 |
modules. |
... | ... | |
30 | 30 |
|
31 | 31 |
Documentation |
32 | 32 |
------------- |
33 |
* Check out the general docs at http://drupal.org/node/298476
|
|
34 |
* Check out the developer targeted docs at http://drupal.org/node/878718
|
|
33 |
* Check out the general docs at https://www.drupal.org/node/298476
|
|
34 |
* Check out the developer targeted docs at https://www.drupal.org/node/878718
|
|
35 | 35 |
|
36 | 36 |
|
37 | 37 |
Rules Scheduler |
... | ... | |
41 | 41 |
to schedule the execution of Rules components. |
42 | 42 |
* Make sure that you have configured cron for your drupal installation as cron |
43 | 43 |
is used for scheduling the Rules components. For help see |
44 |
http://drupal.org/cron
|
|
45 |
* If the Views module (http://drupal.org/project/views) is installed, the module
|
|
46 |
displays the list of scheduled tasks in the UI. |
|
44 |
https://www.drupal.org/cron
|
|
45 |
* If the Views module (https://www.drupal.org/project/views) is installed, the
|
|
46 |
module displays the list of scheduled tasks in the UI.
|
|
47 | 47 |
|
48 | 48 |
|
49 | 49 |
Upgrade from Rules 6.x-1.x to Rules 7.x-2.x |
... | ... | |
60 | 60 |
* Note that for importing an export the export needs to pass the |
61 | 61 |
configuration integrity check, what might be troublesome if the |
62 | 62 |
conversion was not 100% successful. In that case, try choosing the |
63 |
immediate saving method and correct the configuration after conversion.
|
|
63 |
immediate saving method and correct the configuration after conversion. |
|
64 | 64 |
* A rule configuration might require multiple modules to be in place and |
65 | 65 |
upgraded to work properly. E.g. if you used an action provided |
66 | 66 |
by a third party module, make sure the module is in place and upgraded |
... | ... | |
85 | 85 |
for Drupal 7. The Drupal 6 tasks are preserved in the database as long as |
86 | 86 |
you do not clear your Rules 1.x configuration though. |
87 | 87 |
* The Rules Forms module has not been updated to Drupal 7 and there are no |
88 |
plans to do so, as unfortuntely the module's design does not allow for |
|
88 |
plans to do so, as unfortunately the module's design does not allow for
|
|
89 | 89 |
automatic configuration updates. |
90 | 90 |
Thus, a possible future Rules 2.x Forms module is likely to work |
91 | 91 |
different, e.g. by working only for entity forms on the field level. |
drupal7/sites/all/modules/rules/includes/faces.inc | ||
---|---|---|
1 | 1 |
<?php |
2 | 2 |
|
3 | 3 |
/** |
4 |
* @file Extendable Object Faces API. Provided by the faces module. |
|
4 |
* @file |
|
5 |
* Extendable Object Faces API. Provided by the faces module. |
|
5 | 6 |
*/ |
6 | 7 |
|
7 | 8 |
if (!interface_exists('FacesExtenderInterface', FALSE)) { |
... | ... | |
14 | 15 |
/** |
15 | 16 |
* Constructs an instance of the extender. |
16 | 17 |
*/ |
17 |
function __construct(FacesExtendable $object); |
|
18 |
public function __construct(FacesExtendable $object);
|
|
18 | 19 |
|
19 | 20 |
/** |
20 | 21 |
* Returns the extended object. |
21 | 22 |
*/ |
22 | 23 |
public function getExtendable(); |
24 |
|
|
23 | 25 |
} |
24 | 26 |
|
25 | 27 |
/** |
... | ... | |
31 | 33 |
|
32 | 34 |
if (!class_exists('FacesExtender', FALSE)) { |
33 | 35 |
/** |
34 |
* A common base class for FacesExtenders. Extenders may access protected |
|
35 |
* methods and properties of the extendable using the property() and call() |
|
36 |
* methods. |
|
36 |
* A common base class for FacesExtenders. |
|
37 |
* |
|
38 |
* Extenders may access protected methods and properties of the extendable |
|
39 |
* using the property() and call() methods. |
|
37 | 40 |
*/ |
38 | 41 |
abstract class FacesExtender implements FacesExtenderInterface { |
39 | 42 |
|
... | ... | |
42 | 45 |
*/ |
43 | 46 |
protected $object; |
44 | 47 |
|
45 |
|
|
46 |
function __construct(FacesExtendable $object) { |
|
48 |
public function __construct(FacesExtendable $object) { |
|
47 | 49 |
$this->object = $object; |
48 | 50 |
} |
49 | 51 |
|
... | ... | |
63 | 65 |
} |
64 | 66 |
|
65 | 67 |
/** |
66 |
* Invokes any method on the extended object. May be used to invoke |
|
67 |
* protected methods. |
|
68 |
* Invokes any method on the extended object, including protected methods. |
|
68 | 69 |
* |
69 |
* @param $name |
|
70 |
* @param string $name
|
|
70 | 71 |
* The method name. |
71 |
* @param $arguments
|
|
72 |
* @param array $args
|
|
72 | 73 |
* An array of arguments to pass to the method. |
73 | 74 |
*/ |
74 | 75 |
protected function call($name, array $args = array()) { |
75 | 76 |
return $this->object->call($name, $args); |
76 | 77 |
} |
78 |
|
|
77 | 79 |
} |
78 | 80 |
} |
79 | 81 |
|
... | ... | |
108 | 110 |
/** |
109 | 111 |
* Magic method: Invoke the dynamically implemented methods. |
110 | 112 |
*/ |
111 |
function __call($name, $arguments = array()) { |
|
113 |
public function __call($name, $arguments = array()) {
|
|
112 | 114 |
if (isset($this->facesMethods[$name])) { |
113 | 115 |
$method = $this->facesMethods[$name]; |
114 | 116 |
// Include code, if necessary. |
... | ... | |
134 | 136 |
} |
135 | 137 |
|
136 | 138 |
/** |
137 |
* Returns the extender object for the given class. May be used to |
|
138 |
* explicitly invoke a specific extender, e.g. a function overriding a |
|
139 |
* method may use that to explicitly invoke the original extender. |
|
139 |
* Returns the extender object for the given class. |
|
140 |
* |
|
141 |
* May be used to explicitly invoke a specific extender, e.g. a function |
|
142 |
* overriding a method may use that to explicitly invoke the original |
|
143 |
* extender. |
|
140 | 144 |
*/ |
141 | 145 |
public function extender($class) { |
142 | 146 |
if (!isset($this->facesClassInstances[$class])) { |
... | ... | |
146 | 150 |
} |
147 | 151 |
|
148 | 152 |
/** |
153 |
* Returns whether the object can face as the given interface. |
|
154 |
* |
|
149 | 155 |
* Returns whether the object can face as the given interface, thus it |
150 |
* returns TRUE if this oject has been extended by an appropriate |
|
156 |
* returns TRUE if this object has been extended by an appropriate
|
|
151 | 157 |
* implementation. |
152 | 158 |
* |
153 | 159 |
* @param $interface |
154 |
* Optional. A interface to test for. If it's omitted, all interfaces that |
|
155 |
* the object can be faced as are returned. |
|
156 |
* @return |
|
160 |
* Optional. An interface to test for. If it's omitted, all interfaces |
|
161 |
* that the object can be faced as are returned. |
|
162 |
* |
|
163 |
* @return bool |
|
157 | 164 |
* Whether the object can face as the interface or an array of interface |
158 | 165 |
* names. |
159 | 166 |
*/ |
... | ... | |
169 | 176 |
* |
170 | 177 |
* @param $interface |
171 | 178 |
* The interface name or an array of interface names. |
172 |
* @param $class |
|
179 |
* @param $className
|
|
173 | 180 |
* The extender class, which has to implement the FacesExtenderInterface. |
174 |
* @param $include
|
|
181 |
* @param array $includes
|
|
175 | 182 |
* An optional array describing the file to include before invoking the |
176 | 183 |
* class. The array entries known are 'type', 'module', and 'name' |
177 | 184 |
* matching the parameters of module_load_include(). Only 'module' is |
... | ... | |
206 | 213 |
* @param $interface |
207 | 214 |
* The interface name or FALSE to extend the object without a given |
208 | 215 |
* interface. |
209 |
* @param $methods
|
|
216 |
* @param array $callbacks
|
|
210 | 217 |
* An array, where the keys are methods of the given interface and the |
211 | 218 |
* values the callback functions to use. |
212 |
* @param $includes |
|
219 |
* @param array $includes
|
|
213 | 220 |
* An optional array to describe files to include before invoking the |
214 | 221 |
* callbacks. You may pass a single array describing one include for all |
215 | 222 |
* callbacks or an array of arrays, keyed by the method names. Look at the |
... | ... | |
234 | 241 |
/** |
235 | 242 |
* Override the implementation of an extended method. |
236 | 243 |
* |
237 |
* @param $methods
|
|
238 |
* An array of methods of the interface, that should be overriden, where |
|
244 |
* @param array $callbacks
|
|
245 |
* An array of methods of the interface, that should be overridden, where
|
|
239 | 246 |
* the keys are methods to override and the values the callback functions |
240 | 247 |
* to use. |
241 |
* @param $includes |
|
248 |
* @param array $includes
|
|
242 | 249 |
* An optional array to describe files to include before invoking the |
243 | 250 |
* callbacks. You may pass a single array describing one include for all |
244 | 251 |
* callbacks or an array of arrays, keyed by the method names. Look at the |
... | ... | |
257 | 264 |
|
258 | 265 |
/** |
259 | 266 |
* Adds in include files for the given methods while removing any old files. |
267 |
* |
|
260 | 268 |
* If a single include file is described, it's added for all methods. |
261 | 269 |
*/ |
262 | 270 |
protected function addIncludes($methods, $includes) { |
... | ... | |
272 | 280 |
} |
273 | 281 |
|
274 | 282 |
/** |
283 |
* Destroys all references to created instances. |
|
284 |
* |
|
275 | 285 |
* Destroys all references to created instances so that PHP's garbage |
276 | 286 |
* collection can do its work. This is needed as PHP's gc has troubles with |
277 | 287 |
* circular references until PHP < 5.3. |
... | ... | |
296 | 306 |
* This also allows to pass arguments by reference, so it may be used to |
297 | 307 |
* pass arguments by reference to dynamically extended methods. |
298 | 308 |
* |
299 |
* @param $name |
|
309 |
* @param string $name
|
|
300 | 310 |
* The method name. |
301 |
* @param $arguments
|
|
311 |
* @param array $args
|
|
302 | 312 |
* An array of arguments to pass to the method. |
303 | 313 |
*/ |
304 | 314 |
public function call($name, array $args = array()) { |
... | ... | |
307 | 317 |
} |
308 | 318 |
return $this->__call($name, $args); |
309 | 319 |
} |
320 |
|
|
310 | 321 |
} |
311 |
} |
|
322 |
|
|
323 |
} |
drupal7/sites/all/modules/rules/includes/rules.core.inc | ||
---|---|---|
7 | 7 |
|
8 | 8 |
// This is not necessary as the classes are autoloaded via the registry. However |
9 | 9 |
// it saves some possible update headaches until the registry is rebuilt. |
10 |
// @todo |
|
11 |
// Remove for a future release. |
|
10 |
// @todo Remove for a future release. |
|
12 | 11 |
require_once dirname(__FILE__) . '/faces.inc'; |
13 | 12 |
|
14 | 13 |
/** |
... | ... | |
29 | 28 |
|
30 | 29 |
/** |
31 | 30 |
* Overridden. |
31 |
* |
|
32 | 32 |
* @see DrupalDefaultEntityController::attachLoad() |
33 | 33 |
*/ |
34 | 34 |
protected function attachLoad(&$queried_entities, $revision_id = FALSE) { |
35 |
// Retrieve stdClass records and turn them in rules objects stored in 'data'
|
|
35 |
// Retrieve stdClass records and store them as rules objects in 'data'.
|
|
36 | 36 |
$ids = array_keys($queried_entities); |
37 | 37 |
$result = db_select('rules_tags') |
38 | 38 |
->fields('rules_tags', array('id', 'tag')) |
... | ... | |
68 | 68 |
|
69 | 69 |
/** |
70 | 70 |
* Override to support having events and tags as conditions. |
71 |
* @see EntityAPIController::applyConditions($entities, $conditions) |
|
71 |
* |
|
72 |
* @see EntityAPIController::applyConditions() |
|
72 | 73 |
* @see rules_query_rules_config_load_multiple_alter() |
73 | 74 |
*/ |
74 | 75 |
protected function applyConditions($entities, $conditions = array()) { |
... | ... | |
106 | 107 |
* @param $export |
107 | 108 |
* A serialized string in JSON format as produced by the |
108 | 109 |
* RulesPlugin::export() method, or the PHP export as usual PHP array. |
110 |
* @param string $error_msg |
|
111 |
* The error message. |
|
109 | 112 |
*/ |
110 | 113 |
public function import($export, &$error_msg = '') { |
111 | 114 |
$export = is_array($export) ? $export : drupal_json_decode($export); |
... | ... | |
202 | 205 |
foreach ($rules_config->events() as $event) { |
203 | 206 |
db_insert('rules_trigger') |
204 | 207 |
->fields(array( |
205 |
'id' => $rules_config->id, |
|
206 |
'event' => $event, |
|
207 |
)) |
|
208 |
->execute(); |
|
208 |
'id' => $rules_config->id,
|
|
209 |
'event' => $event,
|
|
210 |
))
|
|
211 |
->execute();
|
|
209 | 212 |
} |
210 | 213 |
} |
211 | 214 |
|
... | ... | |
217 | 220 |
foreach ($rules_config->dependencies as $dependency) { |
218 | 221 |
db_insert('rules_dependencies') |
219 | 222 |
->fields(array( |
220 |
'id' => $rules_config->id, |
|
221 |
'module' => $dependency, |
|
222 |
)) |
|
223 |
->execute(); |
|
223 |
'id' => $rules_config->id,
|
|
224 |
'module' => $dependency,
|
|
225 |
))
|
|
226 |
->execute();
|
|
224 | 227 |
} |
225 | 228 |
} |
226 | 229 |
} |
227 | 230 |
|
228 | 231 |
/** |
229 | 232 |
* Overridden to support tags and events in $conditions. |
233 |
* |
|
230 | 234 |
* @see EntityAPIControllerExportable::buildQuery() |
231 | 235 |
*/ |
232 | 236 |
protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { |
... | ... | |
234 | 238 |
$query_conditions =& $query->conditions(); |
235 | 239 |
foreach ($query_conditions as &$condition) { |
236 | 240 |
// One entry in $query_conditions is a string with key '#conjunction'. |
237 |
// @see QueryConditionInterface::conditions().
|
|
241 |
// @see QueryConditionInterface::conditions() |
|
238 | 242 |
if (is_array($condition)) { |
239 | 243 |
// Support using 'tags' => array('tag1', 'tag2') as condition. |
240 | 244 |
if ($condition['field'] == 'base.tags') { |
... | ... | |
255 | 259 |
|
256 | 260 |
/** |
257 | 261 |
* Overridden to also delete tags and events. |
262 |
* |
|
258 | 263 |
* @see EntityAPIControllerExportable::delete() |
259 | 264 |
*/ |
260 | 265 |
public function delete($ids, DatabaseTransaction $transaction = NULL) { |
... | ... | |
305 | 310 |
|
306 | 311 |
return $return; |
307 | 312 |
} |
313 |
|
|
308 | 314 |
} |
309 | 315 |
|
310 | 316 |
/** |
317 |
* Base class for RulesExtendables. |
|
318 |
* |
|
311 | 319 |
* The RulesExtendable uses the rules cache to setup the defined extenders |
312 | 320 |
* and overrides automatically. |
313 | 321 |
* As soon faces is used the faces information is autoloaded using setUp(). |
... | ... | |
316 | 324 |
|
317 | 325 |
/** |
318 | 326 |
* The name of the info definitions associated with info about this class. |
327 |
* |
|
319 | 328 |
* This would be defined abstract, if possible. Common rules hooks with class |
320 | 329 |
* info are e.g. plugin_info and data_info. |
321 | 330 |
*/ |
... | ... | |
326 | 335 |
*/ |
327 | 336 |
protected $itemName; |
328 | 337 |
|
329 |
protected $cache, $itemInfo = array();
|
|
330 |
|
|
338 |
protected $cache; |
|
339 |
protected $itemInfo = array(); |
|
331 | 340 |
|
332 | 341 |
public function __construct() { |
333 | 342 |
$this->setUp(); |
... | ... | |
340 | 349 |
if (isset($this->cache[$this->hook][$this->itemName])) { |
341 | 350 |
$this->itemInfo = &$this->cache[$this->hook][$this->itemName]; |
342 | 351 |
} |
343 |
// Set up the Faces Extenders |
|
352 |
// Set up the Faces Extenders.
|
|
344 | 353 |
if (!empty($this->itemInfo['faces_cache'])) { |
345 | 354 |
list($this->facesMethods, $this->facesIncludes, $this->faces) = $this->itemInfo['faces_cache']; |
346 | 355 |
} |
347 | 356 |
} |
348 | 357 |
|
349 | 358 |
/** |
350 |
* Force the object to be setUp, this executes setUp() if not done yet. |
|
359 |
* Forces the object to be setUp, this executes setUp() if not done yet.
|
|
351 | 360 |
*/ |
352 | 361 |
public function forceSetUp() { |
353 | 362 |
if (!isset($this->cache) || (!empty($this->itemInfo['faces_cache']) && !$this->faces)) { |
... | ... | |
402 | 411 |
* The info about the item as specified in the hook. |
403 | 412 |
* @param $interface |
404 | 413 |
* The interface to check for. |
405 |
* @return |
|
414 |
* |
|
415 |
* @return bool |
|
406 | 416 |
* Whether it supports the given interface. |
407 | 417 |
*/ |
408 | 418 |
public static function itemFacesAs(&$itemInfo, $interface) { |
409 | 419 |
return in_array($interface, class_implements($itemInfo['class'])) || isset($itemInfo['faces_cache'][2][$interface]); |
410 | 420 |
} |
421 |
|
|
411 | 422 |
} |
412 | 423 |
|
413 | 424 |
/** |
... | ... | |
439 | 450 |
|
440 | 451 |
/** |
441 | 452 |
* The parent element, if any. |
453 |
* |
|
442 | 454 |
* @var RulesContainerPlugin |
443 | 455 |
*/ |
444 | 456 |
protected $parent = NULL; |
445 | 457 |
|
446 |
protected $cache = NULL, $hook = 'plugin_info'; |
|
458 |
protected $cache = NULL; |
|
459 |
protected $hook = 'plugin_info'; |
|
447 | 460 |
|
448 | 461 |
/** |
449 | 462 |
* Identifies an element inside a configuration. |
... | ... | |
455 | 468 |
*/ |
456 | 469 |
protected $availableVariables; |
457 | 470 |
|
458 |
|
|
459 | 471 |
/** |
460 | 472 |
* Sets a new parent element. |
461 | 473 |
*/ |
... | ... | |
533 | 545 |
* Iterate over all elements nested below the current element. |
534 | 546 |
* |
535 | 547 |
* This helper can be used to recursively iterate over all elements of a |
536 |
* configuration. To iterate over the children only, just regulary iterate |
|
548 |
* configuration. To iterate over the children only, just regularly iterate
|
|
537 | 549 |
* over the object. |
538 | 550 |
* |
539 | 551 |
* @param $mode |
... | ... | |
586 | 598 |
/** |
587 | 599 |
* Evaluate the element on a given rules evaluation state. |
588 | 600 |
*/ |
589 |
abstract function evaluate(RulesState $state); |
|
601 |
abstract public function evaluate(RulesState $state);
|
|
590 | 602 |
|
591 | 603 |
protected static function compare(RulesPlugin $a, RulesPlugin $b) { |
592 | 604 |
if ($a->weight == $b->weight) { |
... | ... | |
611 | 623 |
/** |
612 | 624 |
* Returns info about parameters needed for executing the configured plugin. |
613 | 625 |
* |
614 |
* @param $optional |
|
626 |
* @param bool $optional
|
|
615 | 627 |
* Whether optional parameters should be included. |
616 | 628 |
* |
617 | 629 |
* @see self::pluginParameterInfo() |
... | ... | |
744 | 756 |
} |
745 | 757 |
|
746 | 758 |
/** |
747 |
* Returns asserted additions to the available variable info. Any returned |
|
748 |
* info is merged into the variable info, in case the execution flow passes |
|
749 |
* the element. |
|
759 |
* Returns asserted additions to the available variable info. |
|
760 |
* |
|
761 |
* Any returned info is merged into the variable info, in case the execution |
|
762 |
* flow passes the element. |
|
750 | 763 |
* E.g. this is used to assert the content type of a node if the condition |
751 |
* is met, such that the per node type properties are available.
|
|
764 |
* is met, such that the per-node type properties are available.
|
|
752 | 765 |
*/ |
753 | 766 |
protected function variableInfoAssertions() { |
754 | 767 |
return array(); |
755 | 768 |
} |
756 | 769 |
|
757 | 770 |
/** |
758 |
* Get the name of this plugin instance. The returned name should identify |
|
759 |
* the code which drives this plugin. |
|
771 |
* Gets the name of this plugin instance. |
|
772 |
* |
|
773 |
* The returned name should identify the code which drives this plugin. |
|
760 | 774 |
*/ |
761 | 775 |
public function getPluginName() { |
762 | 776 |
return $this->itemName; |
... | ... | |
813 | 827 |
* Usually settings get processed automatically, however if $this->settings |
814 | 828 |
* has been altered manually after element construction, it needs to be |
815 | 829 |
* invoked explicitly with $force set to TRUE. |
816 |
* |
|
817 | 830 |
*/ |
818 | 831 |
public function processSettings($force = FALSE) { |
819 | 832 |
// Process if not done yet. |
... | ... | |
839 | 852 |
} |
840 | 853 |
|
841 | 854 |
/** |
842 |
* Makes sure the plugin is configured right, e.g. all needed variables |
|
843 |
* are available in the element's scope and dependent modules are enabled. |
|
855 |
* Makes sure the plugin is configured right. |
|
856 |
* |
|
857 |
* "Configured right" means all needed variables are available in the |
|
858 |
* element's scope and dependent modules are enabled. |
|
844 | 859 |
* |
845 |
* @return RulesPlugin |
|
846 |
* Returns $this to support chained usage. |
|
860 |
* @return $this |
|
847 | 861 |
* |
848 | 862 |
* @throws RulesIntegrityException |
849 |
* In case of a failed integraty check, a RulesIntegrityException exception
|
|
863 |
* In case of a failed integrity check, a RulesIntegrityException exception
|
|
850 | 864 |
* is thrown. |
851 | 865 |
*/ |
852 | 866 |
public function integrityCheck() { |
... | ... | |
901 | 915 |
elseif (!$this->isRoot() && !isset($this->settings[$name]) && empty($info['optional']) && $info['type'] != 'hidden') { |
902 | 916 |
throw new RulesIntegrityException(t('Missing configuration for parameter %name.', array('%name' => $name)), array($this, 'parameter', $name)); |
903 | 917 |
} |
904 |
//TODO: Make sure used values are allowed. (key/value pairs + allowed values) |
|
918 |
// @todo Make sure used values are allowed. |
|
919 |
// (key/value pairs + allowed values). |
|
905 | 920 |
} |
906 | 921 |
} |
907 | 922 |
|
908 | 923 |
/** |
924 |
* Returns the argument for the parameter $name described with $info. |
|
925 |
* |
|
909 | 926 |
* Returns the argument as configured in the element settings for the |
910 | 927 |
* parameter $name described with $info. |
911 | 928 |
* |
912 |
* @param $name |
|
929 |
* @param string $name
|
|
913 | 930 |
* The name of the parameter for which to get the argument. |
914 | 931 |
* @param $info |
915 | 932 |
* Info about the parameter. |
916 | 933 |
* @param RulesState $state |
917 | 934 |
* The current evaluation state. |
918 |
* @param $langcode |
|
935 |
* @param string $langcode
|
|
919 | 936 |
* (optional) The language code used to get the argument value if the |
920 | 937 |
* argument value should be translated. By default (NULL) the current |
921 | 938 |
* interface language will be used. |
... | ... | |
968 | 985 |
if (!empty($this->settings[$name . ':process'])) { |
969 | 986 |
// For processing, make sure the data is unwrapped now. |
970 | 987 |
$return = rules_unwrap_data(array($arg), array($info)); |
971 |
// @todo for Drupal 8: Refactor to add the name and language code as
|
|
988 |
// @todo For Drupal 8: Refactor to add the name and language code as
|
|
972 | 989 |
// separate parameter to process(). |
973 | 990 |
$info['#name'] = $name; |
974 | 991 |
$info['#langcode'] = $langcode; |
... | ... | |
1005 | 1022 |
} |
1006 | 1023 |
|
1007 | 1024 |
/** |
1008 |
* Apply the given data selector by using the info about available variables. |
|
1009 |
* Thus it doesn't require an actual evaluation state. |
|
1025 |
* Applies the given data selector. |
|
1026 |
* |
|
1027 |
* Applies the given data selector by using the info about available |
|
1028 |
* variables. Thus it doesn't require an actual evaluation state. |
|
1010 | 1029 |
* |
1011 |
* @param $selector |
|
1030 |
* @param string $selector
|
|
1012 | 1031 |
* The selector string, e.g. "node:author:mail". |
1013 | 1032 |
* |
1014 | 1033 |
* @return EntityMetadataWrapper |
... | ... | |
1030 | 1049 |
} |
1031 | 1050 |
} |
1032 | 1051 |
} |
1033 |
// In case of an exception or we were unable to get a wrapper, return FALSE.
|
|
1052 |
// Return FALSE if there is no wrappper or we get an exception.
|
|
1034 | 1053 |
catch (EntityMetadataWrapperException $e) { |
1035 | 1054 |
return FALSE; |
1036 | 1055 |
} |
... | ... | |
1065 | 1084 |
} |
1066 | 1085 |
|
1067 | 1086 |
/** |
1068 |
* Saves the configuration to the database, regardless whether this is invoked |
|
1069 |
* on the rules configuration or a contained rule element. |
|
1087 |
* Saves the configuration to the database. |
|
1088 |
* |
|
1089 |
* The configuration is saved regardless whether this method is invoked on |
|
1090 |
* the rules configuration or a contained rule element. |
|
1070 | 1091 |
*/ |
1071 | 1092 |
public function save($name = NULL, $module = 'rules') { |
1072 | 1093 |
if (isset($this->parent)) { |
... | ... | |
1096 | 1117 |
// default configurations 'module' points to the module providing the |
1097 | 1118 |
// default configuration, so the module via which the rules is configured |
1098 | 1119 |
// is stored in the "owner" property. |
1099 |
// @todo: For Drupal 8 use "owner" for generating machine names also and
|
|
1120 |
// @todo For Drupal 8 use "owner" for generating machine names also and |
|
1100 | 1121 |
// module only for the modules providing default configurations. |
1101 | 1122 |
$this->module = !isset($this->module) || $module != 'rules' ? $module : $this->module; |
1102 | 1123 |
if (!isset($this->owner)) { |
... | ... | |
1191 | 1212 |
} |
1192 | 1213 |
|
1193 | 1214 |
/** |
1215 |
* Deletes configuration from database. |
|
1216 |
* |
|
1194 | 1217 |
* If invoked on a rules configuration it is deleted from database. If |
1195 | 1218 |
* invoked on a contained rule element, it's removed from the configuration. |
1196 | 1219 |
*/ |
... | ... | |
1235 | 1258 |
* A status constant, i.e. one of ENTITY_CUSTOM, ENTITY_IN_CODE, |
1236 | 1259 |
* ENTITY_OVERRIDDEN or ENTITY_FIXED. |
1237 | 1260 |
* |
1238 |
* @return |
|
1261 |
* @return bool
|
|
1239 | 1262 |
* TRUE if the configuration has the status, else FALSE. |
1240 | 1263 |
* |
1241 | 1264 |
* @see entity_has_status() |
... | ... | |
1245 | 1268 |
} |
1246 | 1269 |
|
1247 | 1270 |
/** |
1248 |
* Remove circular object references so the PHP garbage collector does its |
|
1249 |
* work. |
|
1271 |
* Removes circular object references so PHP garbage collector can work. |
|
1250 | 1272 |
*/ |
1251 | 1273 |
public function destroy() { |
1252 | 1274 |
parent::destroy(); |
... | ... | |
1254 | 1276 |
} |
1255 | 1277 |
|
1256 | 1278 |
/** |
1257 |
* Seamlessy invokes the method implemented via faces without having to think |
|
1258 |
* about references. |
|
1279 |
* Seamlessly invokes the method implemented via faces. |
|
1280 |
* |
|
1281 |
* Frees the caller from having to think about references. |
|
1259 | 1282 |
*/ |
1260 | 1283 |
public function form(&$form, &$form_state, array $options = array()) { |
1261 | 1284 |
$this->__call('form', array(&$form, &$form_state, $options)); |
... | ... | |
1339 | 1362 |
/** |
1340 | 1363 |
* Exports a rule configuration. |
1341 | 1364 |
* |
1342 |
* @param $prefix |
|
1365 |
* @param string $prefix
|
|
1343 | 1366 |
* An optional prefix for each line. |
1344 |
* @param $php |
|
1367 |
* @param bool $php
|
|
1345 | 1368 |
* Optional. Set to TRUE to format the export using PHP arrays. By default |
1346 | 1369 |
* JSON is used. |
1370 |
* |
|
1347 | 1371 |
* @return |
1348 |
* The exported confiugration.
|
|
1372 |
* The exported configuration.
|
|
1349 | 1373 |
* |
1350 | 1374 |
* @see rules_import() |
1351 | 1375 |
*/ |
... | ... | |
1395 | 1419 |
} |
1396 | 1420 |
|
1397 | 1421 |
/** |
1398 |
* Finalizies the configuration export by adding general attributes regarding |
|
1399 |
* the configuration and returns it in the right format. |
|
1422 |
* Finalizes the configuration export. |
|
1423 |
* |
|
1424 |
* Adds general attributes regarding the configuration and returns it in the |
|
1425 |
* right format for export. |
|
1426 |
* |
|
1427 |
* @param $export |
|
1428 |
* @param string $prefix |
|
1429 |
* An optional prefix for each line. |
|
1430 |
* @param bool $php |
|
1431 |
* Optional. Set to TRUE to format the export using PHP arrays. By default |
|
1432 |
* JSON is used. |
|
1400 | 1433 |
*/ |
1401 | 1434 |
protected function returnExport($export, $prefix = '', $php = FALSE) { |
1402 | 1435 |
$this->ensureNameExists(); |
... | ... | |
1442 | 1475 |
public function resetInternalCache() { |
1443 | 1476 |
$this->availableVariables = NULL; |
1444 | 1477 |
} |
1478 |
|
|
1445 | 1479 |
} |
1446 | 1480 |
|
1447 | 1481 |
/** |
1448 |
* Defines a common base class for so called "Abstract Plugins" like actions. |
|
1449 |
* Thus modules have to provide the concrete plugin implementation. |
|
1482 |
* Defines a common base class for so-called "Abstract Plugins" like actions. |
|
1483 |
* |
|
1484 |
* Modules have to provide the concrete plugin implementation. |
|
1450 | 1485 |
*/ |
1451 | 1486 |
abstract class RulesAbstractPlugin extends RulesPlugin { |
1452 | 1487 |
|
... | ... | |
1455 | 1490 |
protected $infoLoaded = FALSE; |
1456 | 1491 |
|
1457 | 1492 |
/** |
1458 |
* @param $name |
|
1493 |
* @param string $name
|
|
1459 | 1494 |
* The plugin implementation's name. |
1460 |
* @param $info
|
|
1495 |
* @param $settings
|
|
1461 | 1496 |
* Further information provided about the plugin. Optional. |
1462 | 1497 |
* @throws RulesException |
1463 | 1498 |
* If validation of the passed settings fails RulesExceptions are thrown. |
1464 | 1499 |
*/ |
1465 |
function __construct($name = NULL, $settings = array()) { |
|
1500 |
public function __construct($name = NULL, $settings = array()) {
|
|
1466 | 1501 |
$this->elementName = $name; |
1467 | 1502 |
$this->settings = (array) $settings + array('#_needs_processing' => TRUE); |
1468 | 1503 |
$this->setUp(); |
... | ... | |
1473 | 1508 |
if (isset($this->cache[$this->itemName . '_info'][$this->elementName])) { |
1474 | 1509 |
$this->info = $this->cache[$this->itemName . '_info'][$this->elementName]; |
1475 | 1510 |
// Remember that the info has been correctly setup. |
1476 |
// @see self::forceSetup().
|
|
1511 |
// @see self::forceSetup() |
|
1477 | 1512 |
$this->infoLoaded = TRUE; |
1478 | 1513 |
|
1479 | 1514 |
// Register the defined class, if any. |
... | ... | |
1653 | 1688 |
*/ |
1654 | 1689 |
abstract protected function executeCallback(array $args, RulesState $state = NULL); |
1655 | 1690 |
|
1656 |
|
|
1657 | 1691 |
public function evaluate(RulesState $state) { |
1658 | 1692 |
$this->processSettings(); |
1659 | 1693 |
try { |
... | ... | |
1677 | 1711 |
} |
1678 | 1712 |
|
1679 | 1713 |
public function getPluginName() { |
1680 |
return $this->itemName ." ". $this->elementName;
|
|
1714 |
return $this->itemName . " " . $this->elementName;
|
|
1681 | 1715 |
} |
1682 | 1716 |
|
1683 | 1717 |
/** |
... | ... | |
1697 | 1731 |
self::includeFiles(); |
1698 | 1732 |
|
1699 | 1733 |
// Get the plugin's own info data. |
1700 |
$cache[$this->itemName .'_info'] = rules_fetch_data($this->itemName .'_info');
|
|
1701 |
foreach ($cache[$this->itemName .'_info'] as $name => &$info) { |
|
1734 |
$cache[$this->itemName . '_info'] = rules_fetch_data($this->itemName . '_info');
|
|
1735 |
foreach ($cache[$this->itemName . '_info'] as $name => &$info) {
|
|
1702 | 1736 |
$info += array( |
1703 | 1737 |
'parameter' => isset($info['arguments']) ? $info['arguments'] : array(), |
1704 | 1738 |
'provides' => isset($info['new variables']) ? $info['new variables'] : array(), |
... | ... | |
1716 | 1750 |
// RulesPluginImplInterface. |
1717 | 1751 |
unset($this->faces['RulesPluginHandlerInterface']); |
1718 | 1752 |
|
1719 |
// Build up the per plugin implementation faces cache.
|
|
1753 |
// Build up the per-plugin implementation faces cache.
|
|
1720 | 1754 |
foreach ($this->faces as $interface) { |
1721 | 1755 |
$methods = $file_names = array(); |
1722 | 1756 |
$includes = self::getIncludeFiles($info['module']); |
... | ... | |
1739 | 1773 |
// Cache only the plugin implementation specific callbacks. |
1740 | 1774 |
$info['faces_cache'][$interface] = array($methods, array_filter($file_names)); |
1741 | 1775 |
} |
1742 |
// Filter out interfaces with no overriden methods. |
|
1776 |
// Filter out interfaces with no overridden methods.
|
|
1743 | 1777 |
$info['faces_cache'] = rules_filter_array($info['faces_cache'], 0, TRUE); |
Formats disponibles : Unified diff
Weekly update of contrib modules