array( 'label' => t('Showroom Location'), 'description' => t('Define material location by showroom'), 'default_widget' => 'materio_showroom_location_text', 'default_formatter' => 'materio_showroom_location_simple_text', ), ); // TODO: define in settings wich vocabulary is for showrooms } /** * Implements hook_field_validate(). * * This hook gives us a chance to validate content that's in our * field. We're really only interested in the $items parameter, since * it holds arrays representing content in the field we've defined. * We want to verify that the items only contain RGB hex values like * this: #RRGGBB. If the item validates, we do nothing. If it doesn't * validate, we add our own error notification to the $errors parameter. * * @see field_example_field_widget_error() */ // function materio_showroom_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { // foreach ($items as $delta => $item) { // // if (!empty($item['rgb'])) { // // if (!preg_match('@^#[0-9a-f]{6}$@', $item['rgb'])) { // // $errors[$field['field_name']][$langcode][$delta][] = array( // // 'error' => 'field_example_invalid', // // 'message' => t('Color must be in the HTML format #abcdef.'), // // ); // // } // // } // } // } /** * Implements hook_field_is_empty(). * * hook_field_is_empty() is where Drupal asks us if this field is empty. * Return TRUE if it does not contain data, FALSE if it does. This lets * the form API flag an error when required fields are empty. */ function materio_showroom_field_is_empty($item, $field) { // dsm($item,'item'); // dsm($field,'field'); return empty($item['location']); // && empty($item['showroom_tid']) } // ______ __ // / ____/___ _________ ___ ____ _/ /____ __________ // / /_ / __ \/ ___/ __ `__ \/ __ `/ __/ _ \/ ___/ ___/ // / __/ / /_/ / / / / / / / / /_/ / /_/ __/ / (__ ) // /_/ \____/_/ /_/ /_/ /_/\__,_/\__/\___/_/ /____/ /** * Implements hook_field_formatter_info(). * * We need to tell Drupal that we have two different types of formatters * for this field. One will change the text color, and the other will * change the background color. * * @see field_example_field_formatter_view() */ function materio_showroom_field_formatter_info() { return array( // This formatter just displays the hex value in the color indicated. 'materio_showroom_location_simple_text' => array( 'label' => t('Simple text-based formatter'), 'field types' => array('field_materio_showroom_location'), ), // This formatter changes the background color of the content region. // 'field_example_color_background' => array( // 'label' => t('Change the background of the output text'), // 'field types' => array('field_example_rgb'), // ), ); } /** * Implements hook_field_formatter_view(). * * Two formatters are implemented. * - field_example_simple_text just outputs markup indicating the color that * was entered and uses an inline style to set the text color to that value. * - field_example_color_background does the same but also changes the * background color of div.region-content. * * @see field_example_field_formatter_info() */ function materio_showroom_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); switch ($display['type']) { // This formatter simply outputs the field as text. case 'materio_showroom_location_simple_text': foreach ($items as $delta => $item) { if(!empty($item['location'])){ $term = taxonomy_term_load($item['showroom_tid']); $element[$delta] = array( '#type' => 'html_tag', '#tag' => 'p', '#value' => t('%showroom : @loc', array('%showroom' => $term->name, '@loc' => $item['location'])), ); } } break; } return $element; } // _ ___ __ __ // | | / (_)___/ /___ ____ / /______ // | | /| / / / __ / __ `/ _ \/ __/ ___/ // | |/ |/ / / /_/ / /_/ / __/ /_(__ ) // |__/|__/_/\__,_/\__, /\___/\__/____/ // /____/ /** * Implements hook_field_widget_info(). * * Three widgets are provided. * - A simple text-only widget where the user enters the '#ffffff'. * - A 3-textfield widget that gathers the red, green, and blue values * separately. * - A farbtastic colorpicker widget that chooses the value graphically. * * These widget types will eventually show up in hook_field_widget_form, * where we will have to flesh them out. * * @see field_example_field_widget_form() */ function materio_showroom_field_widget_info() { return array( 'materio_showroom_location_text' => array( 'label' => t('Location as text'), 'field types' => array('field_materio_showroom_location'), ), ); } /** * Implements hook_field_widget_form(). * * hook_widget_form() is where Drupal tells us to create form elements for * our field's widget. * * We provide one of three different forms, depending on the widget type of * the Form API item provided. * * The 'field_example_colorpicker' and 'field_example_text' are essentially * the same, but field_example_colorpicker adds a javascript colorpicker * helper. * * field_example_3text displays three text fields, one each for red, green, * and blue. However, the field type defines a single text column, * rgb, which needs an HTML color spec. Define an element validate * handler that converts our r, g, and b fields into a simulated single * 'rgb' form element. */ function materio_showroom_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { $locval = isset($items[$delta]['location']) ? $items[$delta]['location'] : ''; $showroom_tid = isset($items[$delta]['showroom_tid']) ? $items[$delta]['showroom_tid'] : 0; $widget = $element; $widget['#delta'] = $delta; switch ($instance['widget']['type']) { // TODO: loop through showrooms and don't allow more than one field by show room case 'materio_showroom_location_text': $widget['showroom_tid'] = array( '#type' => 'hidden', '#default_value' => $showroom_tid, // Allow a slightly larger size that the field length to allow for some // configurations where all characters won't fit in input field. '#size' => 10, '#maxlength' => 255, ); $widget['location'] = array( '#type' => 'textfield', '#title' => "Showroom", //$showroom_term->name, '#default_value' => $locval, // Allow a slightly larger size that the field length to allow for some // configurations where all characters won't fit in input field. '#size' => 10, '#maxlength' => 255, ); break; } return $widget; } /** * Implements hook_field_widget_settings_form(). */ function materio_showroom_field_widget_settings_form($field, $instance) { $widget = $instance['widget']; $settings = $widget['settings']; $vocs = taxonomy_get_vocabularies(); $options = array(); foreach ($vocs as $vid => $voc) { $options[$vid] = $voc->name; } $form['vocabulary'] = array( '#type' => 'select', '#title' => t('Vocabulary'), '#default_value' => $settings['vocabulary'], // '#element_validate' => array('_tode_widget_settings_maxlength_validate'), '#required' => TRUE, '#description' => t('Choose which vocabulary will be associated as showroom.'), '#options' => $options, ); return $form; } /** * Implements hook_form_alter(). */ function materio_showroom_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) { if($form['#field']['type'] == "field_materio_showroom_location"){ // dsm($form, 'form'); $form['field']['cardinality']['#disabled'] = 'true'; $form['field']['cardinality']['#default_value'] = -1; } // } /** * Implements hook_form_alter(). */ function materio_showroom_form_alter(&$form, &$form_state, $form_id) { // dsm($form_id); // act only on node edit form if(isset($form['#node_edit_form'])){ // dsm($form_id, 'form_id'); // dsm($form, 'form'); // dsm($form_state, 'form_state'); _materio_showroom_alter_location_field_form($form, $form_state, $form_id); } } function _materio_showroom_alter_location_field_form(&$form, &$form_state, $form_id){ // define some constants $field_type = 'field_materio_showroom_location'; $node = $form['#node']; $nodetype = $form['type']['#value']; global $user; $user = user_load($user->uid); // Make sure the user object is fully loaded // dsm($user, 'user'); $fieldsmap = field_info_field_map(); $showroomfieldinstances = array(); $user_termref_field_instances = array(); foreach ($fieldsmap as $field_name => $field) { // dsm($field,$field_name); // get all (probably one :p) showroom field instances from the current node if ($field['type'] == $field_type && isset($field['bundles']['node']) && in_array($nodetype, $field['bundles']['node'])) { $showroomfieldinstances[] = $field_name; } // get all term reference fields instance from users if (isset($field['bundles']['user']) && $field['type'] == 'taxonomy_term_reference') { $field_info = field_info_field($field_name); // dsm($field_info, "field_info"); $user_termref_field_instances[$field_info['settings']['allowed_values'][0]['vocabulary']] = $field_name; } } // dsm($showroomfieldinstances, 'showroomfieldinstances'); // dsm($user_termref_field_instances, 'user_termref_field_instances'); // if there is no showroom field instances do nothing if(!empty($showroomfieldinstances)){ // act on each field instance foreach ($showroomfieldinstances as $field_name) { // retrive various field infos $field_info = field_info_field($field_name); $field_instance = field_info_instance('node', $field_name, $nodetype); // dsm($field_info, 'field_info'); // get all terms from chosen vocabulary in field instance widget settings $vid = $field_instance['widget']['settings']['vocabulary']; $voc = taxonomy_vocabulary_load($vid); $tree = taxonomy_get_tree($vid); foreach ($tree as $key => $term) { $terms[$term->tid] = $term->name; } // dsm($terms, 'terms'); // get user own term for current vocabulary (if any) if(isset($user_termref_field_instances[$voc->machine_name])){ $user_field_name = $user_termref_field_instances[$voc->machine_name]; foreach (field_get_items('user', $user, $user_field_name) as $key => $value) { $user_showrooms[] = $value['tid']; } // dsm($user_showrooms, "user_showrooms"); } // get already recorded values $old_items = field_get_items('node', $node, $field_name); foreach ($old_items as $i => $value) { $values[$value['showroom_tid']] = $value['location']; } // dsm($values, 'values'); // build new item list foreach ($terms as $tid => $name) { $items[] = array( 'showroom_tid' => $tid, 'location' => isset($values[$tid]) ? $values[$tid] : '' ); } // dsm($items, 'items'); // retrieve new field form with our custom items $new_field_form = field_default_form('node', $node, $field_info, $field_instance, LANGUAGE_NONE, $items, $form, $form_state); // dsm($new_field_form, 'default_form'); // change items location field title // and check access comparing term id with user taged with $i = 0; foreach ($terms as $tid => $name) { $item = $new_field_form[$field_name][LANGUAGE_NONE][$i]; $new_field_form[$field_name][LANGUAGE_NONE][$i]['location']['#title'] = $terms[$item['showroom_tid']['#default_value']]; $new_field_form[$field_name][LANGUAGE_NONE][$i]['location']['#disabled'] = !in_array($tid, $user_showrooms); $i++; } // remove the last one more item added by default unset($new_field_form[$field_name][LANGUAGE_NONE][$i]); // delete normal field form and replace it with our new custom field form unset($form[$field_name]); $form[$field_name] = $new_field_form[$field_name]; // remove "add more" button unset($form[$field_name]['und']['add_more']); } } } // TODO: migrate old location field to new one /** * Implements hook_permission(). */ function materio_showroom_permission() { return array( 'materio showroom migrate fields' => array( 'title' => t('Migrate materio showroom location fields'), 'description' => t('Migrate materio showroom location fields'), ), ); } /** * Implements hook_menu_local_tasks_alter(). */ function materio_showroom_menu_local_tasks_alter(&$data, $router_item, $root_path) { switch($root_path){ case 'admin/content/showrooms' : $item = menu_get_item('node/add/showroom'); if ($item['access']) { $data['actions']['output'][] = array( '#theme' => 'menu_local_action', '#link' => $item, ); } // TODO: prepopulate user role and showroom taxo (https://www.drupal.org/project/prepopulate) // $item = menu_get_item('admin/people/create'); // if ($item['access']) { // $data['actions']['output'][] = array( // '#theme' => 'menu_local_action', // '#link' => $item, // ); // } break; } } // __ ____ __ _ // / |/ (_)___ __________ _/ /_(_)___ ____ // / /|_/ / / __ `/ ___/ __ `/ __/ / __ \/ __ \ // / / / / / /_/ / / / /_/ / /_/ / /_/ / / / / // /_/ /_/_/\__, /_/ \__,_/\__/_/\____/_/ /_/ // /____/ /** * Implements hook_menu(). */ function materio_showroom_menu() { $items['admin/config/content/materio_showroom'] = array( 'title' => 'Showrooms location fields migration settings', 'page callback' => 'drupal_get_form', 'page arguments' => array('materio_showroom_migrate_location_fields_settings_form'), 'access arguments' => array('materio showroom migrate fields'), 'type' => MENU_LOCAL_ACTION, // 'file' => , ); // $items['admin/config/content/materio_showroom/migrate'] = array( // 'title' => 'Migrate showrooms location fields', // 'page callback' => 'materio_showroom_migrate_location_fields', // // 'page arguments' => array('materio_showroom_migrate_location_fields'), // 'access arguments' => array('materio showroom migrate fields'), // 'type' => MENU_LOCAL_TASK, // // 'file' => , // ); return $items; } function materio_showroom_migrate_location_fields_settings_form(){ drupal_set_title('Showroom Migration settings', PASS_THROUGH); $field_type = 'field_materio_showroom_location'; $types = node_type_get_types(); // dsm($types, 'types'); $nt_options = array(); foreach ($types as $mn => $type) { $nt_options[$mn] = $type->name; } $node_type = variable_get('materio_showroom_migrate_node_type', null); // source field (must be a text field) $form['node_type'] = array( '#type'=>'select', '#options'=>$nt_options, '#default_value' => $node_type, '#title' => t('Content type'), '#multiple' => false, ); if($node_type){ $fieldsmap = field_info_field_map(); $src_options = array(); $target_options = array(); foreach ($fieldsmap as $field_name => $field) { // dsm($field, $field_name); if ($field['type'] == 'text' && isset($field['bundles']['node']) && in_array($node_type, $field['bundles']['node'])) { $src_options[$field_name] = $field_name; } if ($field['type'] == $field_type && isset($field['bundles']['node']) && in_array($node_type, $field['bundles']['node'])) { $target_options[$field_name] = $field_name; } } // source field (must be a text field) $form['source_field'] = array( '#type'=>'select', '#options'=>$src_options, '#default_value' => variable_get('materio_showroom_migrate_source_field', null), '#title' => t('source field (must be a text field)'), '#multiple' => false, ); // target field (must be a showroom location field) $form['target_field'] = array( '#type'=>'select', '#options'=>$target_options, '#default_value' => variable_get('materio_showroom_migrate_target_field', null), '#title' => t('target field (must be a showroom location field)'), '#multiple' => false, ); $vocs = taxonomy_get_vocabularies(); $voc_options = array(); foreach ($vocs as $vid => $voc) { $voc_options[$vid] = $voc->name; } // vocabulary for showrooms $vid = variable_get('materio_showroom_migrate_vocabulary', null); $form['vocabulary'] = array( '#type'=>'select', '#options'=>$voc_options, '#default_value' => $vid, '#title' => t('vocabulary for showrooms'), '#multiple' => false, ); // default taxonomy term if($vid){ $tree = taxonomy_get_tree($vid); foreach ($tree as $key => $term) { $terms_options[$term->tid] = $term->name; } $term = variable_get('materio_showroom_migrate_default_term', null); $form['default_term'] = array( '#type'=>'select', '#options'=>$terms_options, '#default_value' => $term, '#title' => t('default taxonomy term'), '#multiple' => false, ); if($term){ $form['migrate'] = array( '#type' => 'submit', '#value' => 'Migrate', // '#submit' => array('materio_showroom_migrate_location_fields_migrate'), ); } } } $form['submit'] = array( '#type' => 'submit', '#value' => 'Save', // '#submit' => array('materio_showroom_migrate_location_fields_migrate'), ); return $form; } function materio_showroom_migrate_location_fields_settings_form_submit($form, &$form_state){ // dsm($form_state, 'form_state'); $node_type = $form_state['values']['node_type']; $src_field = $form_state['values']['source_field']; $target_field = $form_state['values']['target_field']; $vid = $form_state['values']['vocabulary']; $default_term = $form_state['values']['default_term']; variable_set('materio_showroom_migrate_node_type', $node_type); variable_set('materio_showroom_migrate_source_field', $src_field); variable_set('materio_showroom_migrate_target_field', $target_field); variable_set('materio_showroom_migrate_vocabulary', $vid); variable_set('materio_showroom_migrate_default_term', $default_term); // dsm($node_type, 'node_type'); // dsm($src_field,"src_field"); // dsm($target_field,"target_field"); // dsm($vid,"vid"); // dsm($default_term,"default_term"); if ($form_state['values']['op'] == 'Migrate'){ _materio_showroom_batch_migration($node_type, $src_field, $target_field, $vid, $default_term); } // $query = "INSERT INTO field_data_field_screenshot SELECT a.* FROM field_data_field_image a LEFT JOIN field_data_field_screenshot b ON a.entity_id = b.entity_id AND a.entity_type = b.entity_type WHERE b.entity_id IS NULL"; // // $query2 = "INSERT INTO field_revision_field_screenshot SELECT a.* FROM field_revision_field_image a LEFT JOIN field_revision_field_screenshot b ON a.entity_id = b.entity_id AND a.entity_type = b.entity_type WHERE b.entity_id IS NULL"; } function _materio_showroom_batch_migration($node_type, $src_field, $target_field, $vid, $tid){ // Reset counter for debug information. $_SESSION['http_request_count'] = 0; $batch = array( 'title' => t('Migrating Showroom fields ...'), 'operations' => array(), 'init_message' => t('Commencing'), 'progress_message' => t('Processed @current out of @total.'), 'error_message' => t('An error occurred during processing'), 'finished' => '_materio_showroom_batch_migration_finished', ); $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'node') ->entityCondition('bundle', $node_type) ->fieldCondition($src_field, 'value', '', '!='); $result = $query->execute(); // dsm($result, 'result'); if (isset($result['node'])) { $voc = taxonomy_vocabulary_load($vid); $tree = taxonomy_get_tree($vid); foreach ($tree as $key => $term) { $terms[$term->tid] = $term->name; } if(!empty($terms)){ foreach ($result['node'] as $nid => $value) { $batch['operations'][] = array( '_materio_showroom_batch_migration_op', array( $nid, $src_field, $target_field, $terms, $tid, ) ); } } } batch_set($batch); } function _materio_showroom_batch_migration_op($nid, $src_field, $target_field, $terms, $default_tid, &$context){ $context['results']['field_migrated']++; $node = node_load($nid); $src_items = field_get_items('node', $node, $src_field); $src_value = $src_items ? $src_items[0]['value'] : ''; // $src_value = str_replace('/', '-', $src_value); // // build new item list $items = array(LANGUAGE_NONE => array()); foreach ($terms as $tid => $name) { $items[LANGUAGE_NONE][] = array( 'showroom_tid' => $tid, 'location' => $default_tid == $tid ? $src_value : '', ); } $node->$target_field = $items; node_save($node); //Simply show the import row count. $context['message'] = t('Migrating node !c : %title (%nid)', array( '!c' => $context['results']['field_migrated'], '%title'=>$node->title, '%nid'=>$nid )); // In order to slow importing and debug better, // we can uncomment this line to make each import slightly slower. // usleep(2500); if ( false ) { $context['results']['failed_nodes'][] = $nid ; } _materio_showroom_update_http_requests(); } function _materio_showroom_batch_migration_finished($success, $results, $operations){ // dsm($success, 'success'); // dsm($results, 'results'); // dsm($operations, 'operations'); if ($success) { // Here we could do something meaningful with the results. // We just display the number of nodes we processed... drupal_set_message(t('@count results processed in @requests HTTP requests.', array('@count' => count($results), '@requests' => _materio_showroom_get_http_requests()))); drupal_set_message(t('The final result was "%final"', array('%final' => end($results)))); } else { // An error occurred. // $operations contains the operations that remained unprocessed. drupal_set_message( t('operations : @args', array( '@args' => print_r(current($operations), TRUE), ) ), 'error' ); $error_operation = reset($operations); drupal_set_message( t('An error occurred while processing @operation with arguments : @args', array( '@operation' => $error_operation[0], '@args' => print_r($error_operation[0], TRUE), ) ), 'error' ); } } /** * Utility function to increment HTTP requests in a session variable. */ function _materio_showroom_update_http_requests() { $_SESSION['http_request_count']++; } /** * Utility function to count the HTTP requests in a session variable. * * @return int * Number of requests. */ function _materio_showroom_get_http_requests() { return !empty($_SESSION['http_request_count']) ? $_SESSION['http_request_count'] : 0; }