From a7631c48b4f0b105f38ec4c2bdbdc0b4c8305d84 Mon Sep 17 00:00:00 2001
From: OnkelTem <OnkelTem@239962.no-reply.drupal.org>
Date: Sat, 22 Sep 2012 18:05:33 +0400
Subject: [PATCH] Issue 1358682 by ydnar79: Add Language property to ECK

---
 eck.bundle.inc                         |   58 ++++++++++++++++
 eck.classes.inc                        |    3 +-
 eck.entity.inc                         |   14 ++++
 eck.install                            |   28 ++++++--
 eck.module                             |    6 ++
 eck.properties.inc                     |   28 ++++++++
 plugins/property_behavior/language.inc |  114 ++++++++++++++++++++++++++++++++
 views/eck.views.inc                    |    6 +-
 8 files changed, 247 insertions(+), 10 deletions(-)
 create mode 100644 plugins/property_behavior/language.inc

diff --git a/eck.bundle.inc b/eck.bundle.inc
index 34fc0b9..f0fa91e 100644
--- a/eck.bundle.inc
+++ b/eck.bundle.inc
@@ -263,6 +263,64 @@ function eck__bundle__add_submit($form, &$form_state) {
 }
 
 /**
+ * Form constructor for the entity bundle editing form.
+ *
+ * @param $entity_type_name
+ *   Entity type name
+ *
+ * @param $bundle_name
+ *   Entity bundle name
+ *
+ */
+
+function eck__bundle__edit_form($form, &$form_state, $entity_type_name, $bundle_name) {
+  $path = eck__entity_type__path();
+  $entity_type = entity_type_load($entity_type_name);
+  $bundle = bundle_load($entity_type_name, $bundle_name);
+  $form = array();
+
+  $form['entity_type'] =
+      array(
+        '#type' => 'value',
+        '#value' => $entity_type,
+  );
+
+  $form['bundle'] =
+      array(
+        '#type' => 'value',
+        '#value' => $bundle,
+  );
+
+  // Let the behaviors to modify form
+  $vars = eck_property_behavior_invoke_plugin_alter($entity_type, 'bundle_form', array('form' => $form, 'form_state' => $form_state));
+  $form = $vars['form'];
+  $form_state = $vars['form_state'];
+
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save bundle'),
+    '#weight' => 40,
+  );
+  return $form;
+}
+
+function eck__bundle__edit_form_submit($form, &$form_state) {
+  $bundle = $form_state['values']['bundle'];
+  // Save all form values starting from 'config_' to the $bundle->config array.
+  $bundle_config = array();
+  foreach ($form_state['values'] as $name => $value) {
+    if (strpos($name, 'config_') === 0) {
+      // We don't need 'config_' prefix
+      $bundle_config[substr($name, 7)] = $form_state['values'][$name];
+    }
+  }
+  $bundle->config = $bundle_config;
+  // Save the bundle object to the database
+  $bundle->save();
+}
+
+/**
  * Delete the bundle of a given entity type
  * @param $entity_type
  *  (EntityType) The entity type of the bundle that will be deleted
diff --git a/eck.classes.inc b/eck.classes.inc
index 592d723..91fa890 100644
--- a/eck.classes.inc
+++ b/eck.classes.inc
@@ -257,7 +257,7 @@ class EntityType extends DBObject{
   
   public function save(){
     if($this->is_new){
-      module_load_include('inc', 'eck', 'eck.enttiy_type');
+      module_load_include('inc', 'eck', 'eck.entity_type');
       $schema = eck__entity_type__schema($this);
       db_create_table("eck_{$this->name}", $schema);
       
@@ -317,6 +317,7 @@ class Bundle extends DBObject{
   
   public function __construct(){
     parent::__construct('eck_bundle');
+    $this->config = array();
   }
   
   private function createMachineName(){
diff --git a/eck.entity.inc b/eck.entity.inc
index 50a643f..0f6eb39 100644
--- a/eck.entity.inc
+++ b/eck.entity.inc
@@ -33,6 +33,20 @@ function eck__entity__menu($entity_type, $bundle) {
     'type' => MENU_LOCAL_TASK
   );
   
+  $menu["{$path}/{$entity_type->name}/{$bundle->name}/edit"] = array(
+    'title' => 'Edit',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('eck__bundle__edit_form', $entity_type->name, $bundle->name),
+    'access callback' => 'eck__multiple_access_check',
+    'access arguments' => array( array( 'eck administer bundles',
+                                        'eck edit bundles',
+                                        "eck administer {$entity_type->name} bundles",
+                                        "eck edit {$entity_type->name} bundles",
+                                      ) ),
+    'file' => 'eck.bundle.inc',
+    'type' => MENU_LOCAL_TASK,
+  );
+
   //The entity autocomplete module does a great job at providing generalize
   //autocomplete function that will work for any entity that declares the label
   //property in the entity_info array, but there is not a general solution to
diff --git a/eck.install b/eck.install
index ace59a2..a986d38 100644
--- a/eck.install
+++ b/eck.install
@@ -133,7 +133,14 @@ function eck_schema() {
         'type' => 'varchar',
         'length' => 128,
         'not null' => TRUE
-      )
+      ),
+      'config' => array(
+        'description' => 'A serialized list of the bundle settings.',
+        'type' => 'text',
+        'serialize' => TRUE,
+        'initial' => serialize(array()),
+        'not null' => TRUE,
+      ),
     ),
     'primary key' => array('id'/*, 'machine_name'*/), //sad.. taken this out until I figure out how to make it work
     'indexes' => array(
@@ -498,10 +505,17 @@ function eck_update_7008() {
   }
 }
 
-
-
-
-
-
-
+/**
+ * Add 'config' field to eck_bundle table.
+ */
+function eck_update_7009() {
+  // Add config field for bundles
+  db_add_field('eck_bundle', 'config', array(
+    'description' => 'A serialized list of the bundle settings.',
+    'type' => 'text',
+    'serialize' => TRUE,
+    'initial' => serialize(array()),
+    'not null' => TRUE,
+  ));
+}
 
diff --git a/eck.module b/eck.module
index 5666d0e..41eea23 100644
--- a/eck.module
+++ b/eck.module
@@ -48,6 +48,12 @@ function eck_eck_default_properties(){
     'type' => "integer",
     'behavior' => 'changed'
   );
+  $default_properties['language'] =
+  array(
+    'label' => "Entity language",
+    'type' => "language",
+    'behavior' => 'language'
+  );
   
   return $default_properties;
 }
diff --git a/eck.properties.inc b/eck.properties.inc
index dbe7317..626c6b1 100644
--- a/eck.properties.inc
+++ b/eck.properties.inc
@@ -27,6 +27,7 @@ function eck_property_types() {
     'integer' => t('Integer'), 
     'decimal' => t('Decimal'), 
     'positive_integer' => t('Unsigned Integer'),
+    'language' => t('Language'),
   );
 
   drupal_alter('eck_property_types', $default_types);
@@ -92,6 +93,16 @@ function eck_property_type_schema($type) {
       );
       break;
       
+    case 'language':
+      $schema = array(
+        'description' => 'Language',
+        'type' => 'varchar',
+        'length' => 12,
+        'not null' => TRUE,
+        'default' => '',
+      );
+      break;
+
     default:
       $schema = NULL;
       break;
@@ -324,6 +335,23 @@ function eck_deactivate_on_save($element, &$state){
   return $element;
 }
 
+function eck__properties__form_validate($form, &$state){
+  if($state['values']['op'] == t('Add Property'){
+    if (isset($state['values']['property_behavior'])) {
+      $property_behavior = $state['values']['property_behavior'];
+      $behavior_plugins = ctools_get_plugins('eck', 'property_behavior');
+      if (isset($behavior_plugins[$property_behavior]['unique']) && $behavior_plugins[$property_behavior]['unique']) {
+        foreach ($state['values']['new_properties'] as $property_name => $property_info) {
+          if ($property_info['behavior'] == $property_behavior) {
+            form_set_error('property_behavior', t('There can be only one property with \'@name\' behavior per entity.',
+              array('@name' => $behavior_plugins[$property_behavior]['label'])));
+          }
+        }
+      }
+    }
+  }
+}
+
 function eck__properties__form_submit($form, &$state){
   if($state['values']['op'] == t('Add Property')) {
     $state['rebuild'] = TRUE;
diff --git a/plugins/property_behavior/language.inc b/plugins/property_behavior/language.inc
new file mode 100644
index 0000000..82938f0
--- /dev/null
+++ b/plugins/property_behavior/language.inc
@@ -0,0 +1,114 @@
+<?php
+/*
+* Implementation of Language property behavior, which represents the language of an entity.
+*
+*/
+$plugin = array(
+  'label' => "Language",
+  'entity_info' => 'eck_language_property_entity_info',
+  'entity_save' => 'eck_language_property_entity_save',
+  'property_info' => 'eck_language_property_property_info',
+  'default_widget' => 'eck_language_property_widget',
+  'views_data_alter' => 'eck_language_property_views_data_alter',
+  'bundle_form' => 'eck_language_property_bundle_form',
+  'unique' => TRUE,
+);
+
+function eck_language_property_entity_info($property, $var){
+  $info = $var;
+  // Nodes also put its language into entity keys, so we do the same
+  $info['entity keys']['language'] = $property;
+  return $info;
+}
+
+function eck_language_property_entity_save($property, $vars) {
+  $entity = $vars['entity'];
+  if (module_exists('locale')) {
+    if (isset($entity->is_new) && $entity->is_new && empty($entity->{$property})) {
+      $default = language_default();
+      $entity->{$property} = $default->language;
+    }
+  } else {
+    $entity->{$property} = LANGUAGE_NONE;
+  }
+}
+
+function eck_language_property_property_info($property, $vars) {
+  $vars['properties'][$property] += array(
+    'type' => 'token',
+    'options list' => 'entity_metadata_language_list',
+    'description' => t('Entity language.'),
+  );
+  return $vars;
+}
+
+function eck_language_property_widget($property, $vars) {
+  if (module_exists('locale')) {
+    $entity = $vars['entity'];
+    $language = isset($entity->{$property}) ? $entity->{$property} : '';
+    if (eck_language_bundle_multilingual($entity)) {
+      return array(
+        '#type' => 'select',
+        '#title' => $vars['properties'][$property]['label'],
+        '#default_value' => $language,
+        '#options' => array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name'),
+      );
+    } else {
+      $default = language_default();
+      return array(
+        '#type' => 'value',
+        '#value' => !empty($language) ? $language : $default->language,
+      );
+    }
+  }
+}
+
+function eck_language_bundle_multilingual($entity) {
+  if ($bundle = Bundle::loadByMachineName($entity->entityType() . '_' . $entity->type)) {
+    return isset($bundle->config['multilingual']) && $bundle->config['multilingual'];
+  }
+  return FALSE;
+}
+
+function eck_language_property_views_data_alter($property, $vars) {
+  $entity_type = $vars['entity_type'];
+  if (module_exists('locale')) {
+    $property_info = $entity_type->properties[$property];
+    $vars['data']["eck_{$entity_type->name}"][$property] = array(
+      'title' => $property_info['label'],
+      'help' => t('Entity language'),
+      'field' => array(
+        'handler' => 'views_handler_field_locale_language',
+        'click sortable' => TRUE,
+      ),
+      'filter' => array(
+        'handler' => 'views_handler_filter_locale_language',
+      ),
+      'argument' => array(
+        'handler' => 'views_handler_argument_locale_language',
+      ),
+      'sort' => array(
+        'handler' => 'views_handler_sort',
+      ),
+    );
+  } else {
+    unset($vars['data']["eck_{$entity_type->name}"][$property]);
+  }
+  return $vars;
+}
+
+function eck_language_property_bundle_form($property, $vars) {
+  if (module_exists('locale')) {
+    $entity_type = $vars['form']['entity_type']['#value'];
+    $bundle = $vars['form']['bundle']['#value'];
+    $property_info = $entity_type->properties[$property];
+    $vars['form']['config_multilingual'] = array(
+      '#type' => 'radios',
+      '#title' => t('Multilingual support'),
+      '#default_value' => isset($bundle->config["multilingual"]) ? $bundle->config["multilingual"] : 0,
+      '#options' => array(t('Disabled'), t('Enabled')),
+      '#description' => t('Enable multilingual support for this bundle. If enabled, a language selection field will be added to the editing form, allowing you to select from one of the <a href="!languages">enabled languages</a>. If disabled, new posts are saved with the default language. Existing content will not be affected by changing this option.', array('!languages' => url('admin/config/regional/language'))),
+    );
+  }
+  return $vars;
+}
diff --git a/views/eck.views.inc b/views/eck.views.inc
index c85af08..cf145b5 100644
--- a/views/eck.views.inc
+++ b/views/eck.views.inc
@@ -30,5 +30,7 @@
         'handler' => 'eck_views_handler_field_link_delete',
       ),
     );
-  }  
-}
\ No newline at end of file
+    $vars = eck_property_behavior_invoke_plugin_alter($entity_type, 'views_data_alter', array('entity_type' => $entity_type, 'data' => $data));
+    $data = $vars['data'];
+  }
+}
-- 
1.7.9.5

