diff --git a/android/BOINC/res/values-es/strings.xml b/android/BOINC/res/values-es/strings.xml
index 490c4fdb6f2..f604a285c0b 100644
--- a/android/BOINC/res/values-es/strings.xml
+++ b/android/BOINC/res/values-es/strings.xml
@@ -1,3 +1,361 @@
-
+
-
\ No newline at end of file
+
+ BOINC
+
+ Cargando, por favor espere...
+ Continuar
+ Finalizar
+
+
+ Seleccione los proyectos científicos a los que queires contribuir:
+ Elegir un proyecto
+ Añadir un proyecto por URL
+ URL del proyecto:
+ Añadir proyecto
+ URL del proyecto:
+ Añadir administrador de cuentas
+ Sin conexión a Internet
+
+ Introduzca la información de la cuenta
+ Introduzca la información de la cuenta para los proyectos seleccionados
+ Mostrar contraseña
+ Adjuntar proyectos individualmente
+
+ Hubo problemas adjuntando los proyectos científicos:
+ No se pudo conectar
+ La cuenta existe con otra contraseña
+ Contraseña incorrecta
+ La cuenta no existe
+ La cuenta no existe, visita la web del proyecto para registrarte
+
+ Adjuntando
+
+
+ Sugerencia
+
+ Como contribuir:
+ 1. Conectate al WiFi
+ 2. Conecta el cargador
+ 3. Apaga la pantalla
+ Visita las webs de los proyectos para:
+ Aprende mas sobre ciencia
+ Ver las estadísticas de contribución
+ Conecta con otros voluntarios
+ BOINC también esta disponible para tu PC o portatil, visita boinc.berkeley.edu para saber más.
+
+ Contactando con el servidor del proyecto...
+ Logo de proyecto.
+ Área general:
+ Área específica:
+ Descripción:
+ Inicio:
+ Web:
+ Android:
+ Tu dispositivo es soportado por este proyecto
+ Tu dispositivo no está soportado por este proyecto
+ Terminos de uso de
+ Creando una cuenta en este proyecto, aceptas los términos mostrados arriba.
+ Inicia sesión con una cuenta existente
+ eMail:
+ Nombre:
+ Contraseña:
+ Nuevo a
+ Registra una cuenta para participar:
+ Visita la web del proyecto para crar una cuenta:
+ Este proyecto no acepta actualmente nuevas cuentas.
+ Registrarse:
+ Iniciar sesión
+ Olvidó su contraseña
+ Fallo al contactar con el proyecto
+ Adjuntado
+
+ Registro de la cuenta para
+ Proyecto:
+ eMail:
+ Nombre:
+ Equipo:
+ Clave:
+ ... Reescribe:
+ Crear
+
+ Usa el administrador de cuentas de BOINC para añadir y manejar múltiples proyectos
+ Añadir administrador de cuentas
+ URL
+ Usuario:
+ Clave:
+ ... Reescribe:
+ Añadir
+
+ Usuario no encontrado
+ Contraseña muy corta
+ Fallo de conexión
+ Las contraseñas no coinciden
+ Por favor escriba la contraseña de nuevo
+ Introduzca la URL
+ Introduzca su eMail
+ Introduzca una contraseña
+ Introduzca su usuario
+ falló
+ Usuario rechazado
+ El eMail ya está en uso
+ El proyecto está offline
+ eMail rechazado
+ Contraseña rechazada
+ La creación de cuentas está deshabilitada para este proyecto
+ URL inválida
+
+ Atrás
+ Finalizar
+ Éxito
+ Fallo
+ ...
+ .
+ :
+ Conectar
+ Verificar cuenta
+ Registrarse
+ Iniciar sesión
+ Añadir administrador de cuentas
+ Sincronizar
+
+ Pulsa aquí para escoger un proyecto.
+ Whooops
+ ...esto no debería pasar. Pulsa en el icono para volverlo a intentar.
+ Icono de BOINC
+
+ Estado
+ Proyectos
+ Tareas
+ Transferencias
+ Preferencias
+ Avisos
+ Navegación
+
+ Procesando
+ Gracias por participar.
+ Suspendido
+ Nada que hacer
+ Esperando tareas...
+ Suspendido
+ Pulsa play para continuar con la computación y red
+ Iniciando...
+ Escoge un proyecto en el que participar.
+ Cerrando...
+ Calculando rendimiento...
+ Imagen del proyecto
+
+ Leyendo preferencias...
+ Guardar
+ Introduzca un nuevo valor:
+ Seleccionar:
+ General
+ Red
+ Fuente
+ CPU
+ Almacenamiento
+ Memoria
+ Depurar
+ Mostrar opciones avanzadas...
+ Pausar la computación cuando la pantalla esté encendida
+ Modo de dispositivo estacionario
+ Permite el cómputo independientemente de las preferencias de Energía. Solo habilitar si el dispositivo no utiliza una batería.
+ Fuentes para la computación
+ Selecciona las fuentes que BOINC usa para la computación.
+ Enchufe
+ Conexión USB
+ Cargador inalámbrico
+ Batería
+ Batería mínima
+ BOINC suspende la computación por debajo del nivel de batería escogido.
+ Temperatura máx. de la batería
+ BOINC suspende la computación por encima de una temperatura de batería definida. No está recomendado cambiar este valor
+ Espacio máximo usado
+ ¿Cuánto de su almacenamiento del teléfono puede usar BOINC?
+ Almacenamiento libre min.
+ ¿Cuánto espacio debe quedar libre?
+ Intervalo de acceso
+ Intervalo entre accesos del disco
+ Límite de transferencia diaria
+ Limita el tráfico diario usado por BOINC
+ Transmitir datos solo por WiFi
+ Auto inciar
+ Mostrar notificación para nuevas noticias
+ Mostrar notificación cuando se suspenda
+ Núcleos CPU usados
+ Limita la cantidad de núcleos de CPU que BOINC usará.
+ Pausar cuando el uso de CPU este por encima de
+ Determina cuando BOINC es pausado por el uso de CPU por otras aplicaciones.
+ Límite de CPU
+ Limita la CPU que BOINC usa para la computación.
+ Límite de RAM
+ Limita la cantidad de RAM que puede usar.
+ Banderas de registro del cliente de BOINC
+ Nivel de log de la GUI
+ Especifica el detalle de los mensajes de log de la interfaz gráfica.
+ MB
+ GB
+ %
+ ºC
+ seg
+
+ Leyendo proyectos...
+ Añadir proyecto
+ Icono del proyecto
+ Creditos:
+ (En este dispositivo)
+ (En total)
+
+ Suspendido por el usuario
+ No se descargarán nuevas tareas
+ Proyecto finalizado - listo para eliminarlo
+ Se eliminará cuando las tareas estén terminadas
+ Pendiente petición al Planificador
+ Petición al planificador en progreso
+ Mensaje trickle up pendiente
+ Comunicación aplazada a:
+
+ Comandos del proyecto:
+ Visitar web
+ Actualizar
+ Eliminar
+ Suspender
+ Reanudar
+ No pedir nuevas tareas
+ Permitir nuevas tareas
+ Reset
+ Comandos del administrador de cuentas:
+ Sincronizar
+ Deshabilitar
+
+ ¿Borrar proyecto?
+ Seguro que quieres borrarlo
+ de BOINC?
+ Eliminar
+ Reiniciar proyecto
+ Seguro que quieres reinciar
+ \?
+ Reset
+ Deshabilitar el administrador de cuentas
+ Está seguro de que quiere dejar de usar
+ \?
+ Deshabilitar
+
+ Nombre de la tarea:
+ Tiempo transcurrido:
+ (suspendido)
+ Límite para informar:
+ Nuevo
+ Esperando para descargar
+ Descarga completa
+ Error de ejecución
+ Enviando
+ Enviado
+ Cancelado
+ Envío fallido
+ Listo
+ Ejecutando
+ suspendido
+ suspendiendo
+ suspendiendo
+ suspendido
+ proyecto suspendido
+ listo para informar
+
+ ¿Cancelar tarea?
+ Cancelar tarea:
+ Cancelar
+ Cancelar
+ Mensaje de confirmación
+
+ Leyendo transferencias...
+ Enviar
+ Descargar
+ reintentar en
+ falló
+ suspendido
+ activo
+ pendiente
+ proyecto lárgate
+
+ Archivo:
+ reintentar transferencias
+ ¿Cancelar transferencias?
+ Cancelar archivo:
+ Cancelar
+
+ Leyendo noticias...
+
+ Leyendo mensajes del log...
+ Mensajes del cliente
+ Mensajes de la GUI
+ Log copiado al portapapeles.
+ Registro de sucesos para BOINC en Android:
+
+ Computación suspendida.
+ Conecta tu dispositivo a un cargador para seguir procesando.
+ Apaga la pantalla para seguir procesando.
+ El usuario está activo
+ Fuera del marco de tiempo de cómputo.
+ BOINC está calculando el rendimiento de su dispositivo...
+ Sin espacio en el disco
+ Acelerador de CPU programado.
+ Sin actividad del usuario reciente.
+ Inicio pospuesto.
+ Se está ejecutando una aplicación de manera exclusiva.
+ Su dispositivo está ocupado con otras aplicaciones.
+ BOINC ha alcanzado el ĺímite de transferencia de datos.
+ Parado por Android
+ No conectado al WiFi.
+ Esperando a la batería para cargar.
+ La computación continuará cuando la batería llegue a
+
+ actualmente
+ Esperando a que la batería se enfríe
+ Reanudando la computación...
+ manualmente.
+
+ Pedido por el usuario
+ Buscar trabajo
+ Informar las tareas completadas
+ Enviar mensaje trickle-up
+ Pedido por el administrador de cuentas
+ Iniciación del proyecto
+ Pedido por el proyecto
+ Razón desconocida
+
+ Actualizar
+ Enviar por Email
+ Copiar al portapapeles
+ Registro de sucesos
+ Salir de BOiNC
+ Suspender
+ Reanudar
+ Acerca de
+ Ayuda
+
+ Volver
+ Acerca de
+ BOINC
+ Versión
+ Infraestructura Abierta de Berkeley para Computación en Red
+ 2003–2014 University of California, Berkeley.
+ Todos los derechos reservados.
+ Gracias al \"Max Planck Institute for Gravitational Physics\", IBM Corporation y HTC Corporation por su apoyo.
+
+ Nueva noticia de
+
+ nuevas noticias
+
+
+ Aplicación de computación voluntaria detectada
+ Otra aplicación de otro voluntario está ejecutándose en este dispositivo. Sólo se puede ejecutar una versión a la vez.
+ Salir
+
+ Invitar amigos
+ ¿Cómo quieres compartirlo?
+ ¡Estoy haciendo ciencia con mi smartphone!
+ Estoy usando mi %1$s para hacer computación por la ciencia. ¡Tú también puedes! Descarga la app desde: %2$s
+
+ https://play.google.com/store/apps/details?id=edu.berkeley.boinc
+
diff --git a/client/app.cpp b/client/app.cpp
index 3fb3fdee5c2..96209f1ae4e 100644
--- a/client/app.cpp
+++ b/client/app.cpp
@@ -310,7 +310,7 @@ void procinfo_show(PROC_MAP& pm) {
PROCINFO pi;
pi.clear();
PROC_MAP::iterator i;
- for (i=pm.begin(); i!=pm.end(); i++) {
+ for (i=pm.begin(); i!=pm.end(); ++i) {
PROCINFO& p = i->second;
msg_printf(NULL, MSG_INFO, "%d %s: boinc? %d low_pri %d (u%f k%f)",
diff --git a/client/cs_prefs.cpp b/client/cs_prefs.cpp
index 2b83a49ef10..8572b2ff673 100644
--- a/client/cs_prefs.cpp
+++ b/client/cs_prefs.cpp
@@ -485,8 +485,10 @@ void CLIENT_STATE::check_suspend_network() {
done:
if (log_flags.suspend_debug) {
- msg_printf(0, MSG_INFO, "[suspend] net_susp %d file_xfer_susp %d reason %d",
- network_suspended, file_xfers_suspended, network_suspend_reason
+ msg_printf(0, MSG_INFO, "[suspend] net_susp: %s; file_xfer_susp: %s; reason: %s",
+ network_suspended?"yes":"no",
+ file_xfers_suspended?"yes":"no",
+ suspend_reason_string(network_suspend_reason)
);
}
}
diff --git a/client/result.cpp b/client/result.cpp
index 8a278486fc4..71177928db0 100644
--- a/client/result.cpp
+++ b/client/result.cpp
@@ -690,7 +690,7 @@ void print_old_results(MIOFILE& mf) {
ores.completed_time,
ores.create_time
);
- i++;
+ ++i;
}
mf.printf("\n");
}
diff --git a/clientgui/DlgAdvPreferencesBase.cpp b/clientgui/DlgAdvPreferencesBase.cpp
index 808d2056e7c..c663c10e8a9 100644
--- a/clientgui/DlgAdvPreferencesBase.cpp
+++ b/clientgui/DlgAdvPreferencesBase.cpp
@@ -416,7 +416,7 @@ wxPanel* CDlgAdvPreferencesBase::createProcessorTab(wxNotebook* notebook)
addNewRowToSizer(miscProcBoxSizer, ProcSwitchEveryTT, staticText18, m_txtProcSwitchEvery, staticText19);
- wxString DiskWriteToDiskTT(_("This controls how often tasks save their state to disk, so that they can be restarted later."));
+ wxString DiskWriteToDiskTT(_("This controls how often tasks save their state to disk, so that they later can be continued from that point."));
wxStaticText* staticText46 = new wxStaticText(
miscProcStaticBox, ID_DEFAULT,
// context: Request tasks to checkpoint at most every ___ seconds
diff --git a/clientgui/DlgEventLog.cpp b/clientgui/DlgEventLog.cpp
index fb63e3d7fed..a064b76b9c3 100644
--- a/clientgui/DlgEventLog.cpp
+++ b/clientgui/DlgEventLog.cpp
@@ -111,8 +111,8 @@ CDlgEventLog::CDlgEventLog( wxWindow* parent, wxWindowID id, const wxString& cap
CDlgEventLog::~CDlgEventLog() {
wxLogTrace(wxT("Function Start/End"), wxT("CDlgEventLog::CDlgEventLog - Destructor Function Begin"));
-#ifdef __WXGTK__
- m_pList->PopEventHandler(true);
+#ifdef __WXGTK__
+ (m_pList->GetMainWin())->PopEventHandler(true);
#endif
if (m_pMessageInfoAttr) {
diff --git a/clientgui/browser.cpp b/clientgui/browser.cpp
index 9c56f77a33d..9c1841efac9 100644
--- a/clientgui/browser.cpp
+++ b/clientgui/browser.cpp
@@ -372,7 +372,7 @@ static int find_site_cookie_mozilla_v3(
sscanf( argv[0], "%255s", host );
sscanf( argv[1], "%255s", cookie_name );
- sscanf( argv[2], "%4096s", cookie_value );
+ sscanf( argv[2], "%4095s", cookie_value );
sscanf( argv[3],
#ifdef _WIN32
"%I64d",
@@ -572,7 +572,7 @@ static int find_site_cookie_chrome(
sscanf( argv[0], "%255s", host );
sscanf( argv[1], "%255s", cookie_name );
- sscanf( argv[2], "%4096s", cookie_value );
+ sscanf( argv[2], "%4095s", cookie_value );
sscanf( argv[3],
#ifdef _WIN32
"%I64d",
diff --git a/configure.ac b/configure.ac
index 07c79463b51..07324a610d8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,7 +14,7 @@ AC_SUBST([LIBBOINC_VERSION])
WRAPPER_RELEASE=26015
AC_SUBST([WRAPPER_RELEASE])
-VBOXWRAPPER_RELEASE=26171
+VBOXWRAPPER_RELEASE=26175
AC_SUBST([VBOXWRAPPER_RELEASE])
AC_CANONICAL_TARGET
diff --git a/dcapi/condor/condor_utils.c b/dcapi/condor/condor_utils.c
index 63fe59de3b9..f105a70c716 100644
--- a/dcapi/condor/condor_utils.c
+++ b/dcapi/condor/condor_utils.c
@@ -173,7 +173,7 @@ _DC_get_file(char *fn)
if ((f= fopen(fn, "r")) != NULL)
{
int bs= 100, i;
- char c;
+ int c;
buf= malloc(bs);
i= 0;
@@ -185,10 +185,10 @@ _DC_get_file(char *fn)
bs+= 100;
buf= realloc(buf, bs);
}
- buf[i]= c;
+ buf[i]= (char)c;
i++;
- buf[i]= '\0';
}
+ buf[i]= '\0';
fclose(f);
}
return(buf);
@@ -363,7 +363,7 @@ _DC_read_message(char *box, char *name, int del_msg)
if ((f= fopen(fn, "r")) != NULL)
{
int bs= 100, i;
- char c;
+ int c;
buf= malloc(bs);
i= 0;
@@ -375,10 +375,10 @@ _DC_read_message(char *box, char *name, int del_msg)
bs+= 100;
buf= realloc(buf, bs);
}
- buf[i]= c;
+ buf[i]= (char)c;
i++;
- buf[i]= '\0';
}
+ buf[i]= '\0';
fclose(f);
if (del_msg)
unlink(fn);
diff --git a/dcapi/condor/tc.c b/dcapi/condor/tc.c
index 6c57df86b4d..a36d652f636 100644
--- a/dcapi/condor/tc.c
+++ b/dcapi/condor/tc.c
@@ -32,7 +32,7 @@ get_file(char *fn)
if ((f= fopen(fn, "r")) != NULL)
{
int bs= 100, i;
- char c;
+ int c;
buf= malloc(bs);
i= 0;
@@ -44,10 +44,10 @@ get_file(char *fn)
bs+= 100;
buf= realloc(buf, bs);
}
- buf[i]= c;
+ buf[i]= (char)c;
i++;
- buf[i]= '\0';
}
+ buf[i]= '\0';
fclose(f);
}
return(buf);
diff --git a/dcapi/local/local_utils.c b/dcapi/local/local_utils.c
index bd9fa9c7ff9..50f24c725a1 100644
--- a/dcapi/local/local_utils.c
+++ b/dcapi/local/local_utils.c
@@ -177,7 +177,7 @@ _DC_get_file(char *fn)
if ((f= fopen(fn, "r")) != NULL)
{
int bs= 100, i;
- char c;
+ int c;
buf= malloc(bs);
i= 0;
@@ -189,10 +189,10 @@ _DC_get_file(char *fn)
bs+= 100;
buf= realloc(buf, bs);
}
- buf[i]= c;
+ buf[i]= (char)c;
i++;
- buf[i]= '\0';
}
+ buf[i]= '\0';
fclose(f);
}
return(buf);
@@ -367,7 +367,7 @@ _DC_read_message(char *box, char *name, int del_msg)
if ((f= fopen(fn, "r")) != NULL)
{
int bs= 100, i;
- char c;
+ int c;
buf= malloc(bs);
i= 0;
@@ -379,10 +379,10 @@ _DC_read_message(char *box, char *name, int del_msg)
bs+= 100;
buf= realloc(buf, bs);
}
- buf[i]= c;
+ buf[i]= (char)c;
i++;
- buf[i]= '\0';
}
+ buf[i]= '\0';
fclose(f);
if (del_msg)
unlink(fn);
diff --git a/doc/projects.inc b/doc/projects.inc
index b58054c95c5..0362970a490 100644
--- a/doc/projects.inc
+++ b/doc/projects.inc
@@ -741,6 +741,16 @@ $math = array(
"",
"",
),
+ array(
+ "SRBase",
+ "http://srbase.myfirewall.org/sr5/",
+ "Private",
+ "Mathematics",
+ "SRBase is a mathematical research project that uses Internet-connected computers trying to solve Sierpinski / Riesel Bases up to 1030.",
+ "",
+ "",
+ ""
+ ),
),
);
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/CHANGELOG.txt b/drupal/sites/default/boinc/modules/contrib/cck/CHANGELOG.txt
new file mode 100644
index 00000000000..5a1a7910499
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/CHANGELOG.txt
@@ -0,0 +1,624 @@
+//$Id$
+
+CCK 6.x-2.10
+============
+
+Security: Open Redirect - SA-CONTRIB-2015-126
+
+CCK 6.x-2.9
+===========
+
+Features
+- #932680 by Dave Reid: Token integration - allow using of Token API's new $options param
+- #1008184 by merlinofchaos, bojanz, dereine, yched: Adapt to Views 3 "semantic views" feature (backwards compatible with Views 2)
+
+Bugfixes:
+- #863226 by KarenS: make sure we have a function that will return inactive instances when other instances of the same field are still active.
+- #887742 by yched: fix notices in _content_get_formatter() in some Views
+- #736440 by yched, dhthwy: fix memory leaks on long running migration scripts (e.g. migrate.module)
+- #705512 by cha0s, roderick: 'add more' button - fix PHP 5.3 compatibility
+- #894880 by yched: fix notices in check_plain() when rendering empty 'plain text' values
+- #728472 by Darren Oh: Ensure the module's preprocess functions run first
+- #986612 by Dave Reid: Token integration - fix variable name clash (harmless in normal cases)
+- #435520 by yched, sun: Fix text fields rendered as 'n/a' in some cases
+- #739490 by foripepe: Token integration - fix notices during token generation
+
+CCK 6.x-2.8
+===========
+
+Bugfixes:
+- SA-CONTRIB-2010-088 follow up fix for nodereference_autocomplete_access() and content_access().
+
+CCK 6.x-2.7
+===========
+
+Features:
+- #692822 by Dave Reid, add authoring info and publishing options to CCK extra fields.
+- #670344 by dagmar: Make CCK compatible with both, views 2 and views 3.
+
+Bugfixes:
+- #470470 by neilnz, use iLIKE for postgres selects.
+- #769592 by vkareh, add default values to nodeapi.
+- #714762 by Robbert, make diff module integration PHP5 compliant.
+- Add db_rewrite_sql() check to nodereference formatters.
+- #625768 CCK 6.x-2.6, got fatal error on update.php while running userreference_update_6002().
+- #649106 by thekevinday: Fix content_copy_form_alter(), where $form_state argument is not passed by reference.
+- #446390 by mani.atico and fago: improve rules condition to be more robust when checking for empty values.
+
+CCK 6.x-2.6
+===========
+
+Please visit update.php apply pending updates after uploading the new files.
+
+This release:
+- The main reason to pack this release is to keep CCK in sync with recent changes in Views 2.7 that broke the advanced views feature in Node reference fields.
+
+Features:
+- #244896 by stella, canaryMason - Add incremental classes for multiple value fields in views.
+- #227129 by igor.ro - Expose "delta" column in multiple value fields to Views.
+- #531662 by neochief - i18n support. Allow external modules to translate field labels, descriptions and allowed values list as typed in the field settings form.
+- #531662 i18n support for fieldgroups.
+- #558420 Accept trimmed titles in nodereference autocomplete validation to prevent title mismatch errors when title ends with space.
+- #596428 by NancyDru - Allow external modules alter the content type list.
+
+Bugfixes:
+- #416134 Userreference, impossible to filter allowed values by blocked users. Requires update.php.
+- #545942 warning: array_filter() [function.array-filter]: The first argument should be an array in userreference_update_6002().
+- #521002 Fix validation errors when using optgroups in allowed values for select elements.
+- #550252 by GuyPaddock - content_db_index_exists produces SQL errors when creating node reference fields for MySQL 4 (related to #231453).
+- #551280 by xurizaemon - Typo fix for "this field cannot hold more that 3 values" error message.
+- #558744 by chellomere - Fix one of the swedish translation strings to be correct, and much clearer.
+- #562260 by przadka - content_db_index_exists() has wrong syntax for PostgreSQL.
+- #567168 by jcmarco - Checkbox required not defined for on/off widgets.
+- #568430 by Jody Lynn - Bad @see in content-field.tpl.php.
+- #572672 by Jan van Diepen - Remove redundant (and bad) inclusion of node/content_types.inc in content_copy_import_form_submit().
+- #585048 Setting "All users" in "User status that can be referenced" option reverts to "Blocked users".
+- #589306 warning: Invalid argument supplied for foreach() in includes/panels/content_types/content_field.inc on line 166.
+- #605152 by pokurek - Missing number formatter fr_2.
+- #604830 by mattyoung - 32 characters limit on field and group identifiers in "Manage fields" screen.
+- #464030 by eojthebrave - Typo in content_copy.module help.
+- #614292 by DeFr - Fix CCK Reference fields based on views broken by recent change in views_plugin_style Views 2.7 (#502348).
+
+CCK 6.x-2.5
+===========
+
+A few files have been added and/or removed in this package. It is recommended to replace the whole CCK directory with the new one.
+Please visit update.php apply pending updates after installing the new files.
+It also worths to mention that Panels 3 integration has been reviewed and enhanced with display options for fiels and field groups.
+IMPORTANT: All sites using Diff module with CCK for Drupal 6 are strongly encouraged to upgrade to CCK 2.5 (see #538872 below).
+
+Features:
+- #428650 Conditional cache/menu rebuild for content CRUD methods.
+- #334945 Save default values when field is hidden because of access permissions.
+- #503258 by eaton: allow 'extra fields' to provide 'configure' and 'remove' links.
+- #505278 Panels 3 and multiple node type fields.
+- #495582 Reviewed Panels 3 integration (prep work for combo / multigroups).
+ Implementation of fieldgroup_view_group() that can be used to render field groups.
+- #417122 by quicksketch: allow drupal_alter on field and widget settings.
+- #514452 Add new argument $node to content_access() to enhance the context for hook_field_access().
+- #523072 by merlinofchaos - Have nodereference relationships limit CCK field availability as well.
+- #519870 by joachim - Add a note to say offset starts from 0 in grouping options for views handler for multiple values fields.
+- #231453 Allow fields index their columns. Implemented for reference value column in node and user reference fields. Needs update.php.
+- #521002 by mh86 - Support for optgroups in allowed values for select elements.
+
+Bugfixes:
+- #499696 by DeFr - Noderefernce / Userreference: fix Views mode when the view has exposed filters.
+- #498924 #multiple FAPI attribute is used for a radios and checkboxes in content export forms.
+- #409144 Review extra elements for node edit form provided by core modules.
+- #361473 CCK fieldgroup panels doesn't respect CCK field privacy settings.
+- #515984 Multiple field delta ORDER BY incorrect.
+- #414298 by Michelle, merlinofchaos - Follow up to remove fieldgroup.panels.inc (it was moved to panels/content_types).
+- #522112 by hefox, prevent malformed condition for vid IN () in views handler for multiple values fields.
+- #505278 by Michelle, merlinofchaos - Provide backward compatibility with previous method to build Panels 3 subtype names for fields.
+- #523864 Minor coding style issues in Panels 3 relationships implementations.
+- #481568 by merlinofchaos - Empty property error when attempting to save a user reference in Panels.
+- #510396 by yched - Use field/type definition to render fields in views.
+- #393020 by auth - Fieldgroup data is lost when importing to module provided content type with group info for existing fields.
+- #538872 Diff does not respect field permissions.
+
+CCK 6.x-2.4
+===========
+
+Hotfix release for 2.3:
+- #482774 Update breaks when CCK is disabled.
+
+CCK 6.x-2.3
+===========
+
+Please visit update.php apply pending updates after uploading the new files.
+
+This release:
+- fixes a few bugs,
+- adss initial Panels 3 support (Panels 2 not supported),
+- removes the unfinished Multigroup feature (work on this will continue in an experimental branch)
+
+Features:
+- #414298 by Michelle, merlinofchaos - Add Panels 3 integration for fields and fieldgroups.
+- #419678 Views integration: expose CCK fields to 'Node revision' Views.
+- #399778 by Benjamin Melençon - Nodereference / Userreference: Add 'size' setting to autocomplete widgets.
+- #479044 by merlinofchaos - Add Panels 3 relatioships for nodereference and userreference fields.
+
+Bugfixes:
+- #407446 by quicksketch: prevent double serialization during per-field to per-type migration.
+ Followup: update function to fix potentially existing corrupted data.
+- #407344 fix html appearing in selects in Views filters.
+- #409320 by bengtan: Nodereference / Userreference - fix 'this post cannot be referenced' for views-defined referenceable nodes/users, when the view definition has a 'limit'.
+- #409398 by markus_petrux - fix handling of fieldgroup_types() (prep work for combo / multigroups)
+- #356908 Number : Correclty filter 'prefix' and 'suffix' properties.
+- #412058 by fago - Rules integration: Fixed condition 'field has value' when operating on viewed nodes.
+- #413792 Views integration: fix fields using 'multiple formatters' and not 'group multiple fields'. Thanks Crell and quicksketch for the detective work.
+- #421126 Views integration: Use value aliases in argument title replacements for text / number fields.
+- #397358 by Darren Oh, yched, markus_petrux - Views integration: Use node title / user name in argument title replacements for nodereference and userreference argument fields.
+- #428400 Views integration: Fix fatal error with Views 2.4 (views_handler_filter_float has moved). Preserved compatibility with Views 2.3.
+- #447562 by markus_petrux: fix non-XHTML markup on 'Manage fields' screen.
+- #369364 Views integration: fix non-XHTML markup when displaying fields with the 'group multiple values' option.
+- #441412 by jcnventura - Add 'Print' display context on 'Display fields' pages when book.module is enabled.
+- #458952 Let different modules defined the same build_mode information.
+- #383038 by markDrupal - Userreference: fix broken 'reverse links' with fields in per-type table.
+- #479074 by rickward: prevent minor XSS vulnerability when displaying user-submitted 'Body field' labels.
+- #479994 by quicksketch: fix "add more' button with devel.module's query logging.
+
+CCK 6.x-2.2
+===========
+
+IMPORTANT:
+This release fixes a security issue (XSS vulnerability) in nodereference and userreference modules.
+All sites are using CCK for Drupal 6 are strongly encouraged to upgrade to CCK 2.2.
+Note that the Drupal 5 versions are not affected.
+See the Security Annoucement on http://drupal.org/node/406520 for more informations.
+
+
+Features:
+- #361311 Add poll settings forms to Manage fields screen.
+- Add book form to Manage fields screen.
+- #131953 by markus_petrux - Views integration: expose additional db columns.
+- #349987 by Michelle - Panels integration for fieldgroups.
+- #362216 by markus_petrux - sort the admin/content/types/fields overview by field name.
+- #242583 by jmiccolis - Number: Push maximum 'scale' setting up to 10 for decimal fields.
+- Correct RTL display.
+- #405452 - Views integration: Update to Views 2.3 API ('link to node'), with 2.2 compatibility preserved.
+
+Bugfixes:
+- #392476 Make sure CCK textarea fields in a View don't have a span wrapped around a block-level element.
+- Fix devel_generate for decimal and float values.
+- #358700 Can't use array_slice() on assoc array in PHP4.
+- #196421 Prefixed tables weren't getting queried correctly.
+- Don't assume display_settings[$context] always exists, newly enabled modules may add new contexts that weren't there when the field was last edited.
+- #339537 by markus_petrux: fix orphan fields in {content_group_fields} table when fields are removed.
+- Views integration: use shorter titles in Views admin summaries (see http://drupal.org/node/326034).
+- #334290 by drewish - Userreference: user names not displayed in Views summaries.
+- #343138 by duellj - Fix tokens for empty noderef / userref fields.
+- #343306 Validate text 'max length' to be a positive integer
+- #344004 by markus_petrux - Diff integration : fix error on non-'core CCK' field types.
+- Diff integration: limit the number of additional queries for noderef/userref.
+- Diff integration: refactored around a new hook_content_diff_values() to save contrib field modules the
+burden of implementing hook_diff. For most field types, the default content_field_content_diff_values()
+should be enough, though.
+- #344216 by dbabbage: Fix incorrect url to Schema module in tests descriptions.
+- #336174 Move actual field access check in content.module, with content_permission.module providing one permission-based implementation.
+- #336174 (followup) Make sure content_view_field() and content_format() both respect field access rules.
+- #351929 by lyricnz - Views integration: make sure formatters get a pseudo-node with enough info.
+- #355712 by fractile81 - Fieldgroup: fix extraneous cache clears.
+- #356666 by flobruit - fix 'exclude' display setting wrongly set across shared instances of a field.
+- Fix 'undefined variable' notice when submitting field settings form with 'php code for default value.
+- #353012 User reference - fix duplicate 'reverse links' on user profile pages when the same user is referenced by several userref fields in a node. Also improves performance.
+- #342427 Views integration - fix summaries for nodereference and userreference fields.
+- #363456 by dww - Fix some cases of bogus d-n-d reordering of 'pseudo-fields'.
+- #366935 by drewish - Make the 'Views mode' feature in noderef / ueserref visible even if no usable View exists yet.
+- #371306 fix duplicate HTML when using the JS-'add more' button.
+- #370004 by dopry - Fix JS-'add more' button breaking fielfield's AHAH upload.
+- #374213 by rpanna - Fieldgroup: All field instances removed their groups when one instance is deleted from a content type.
+- #356158 by markus_petrux - Fix more (hopefully all ?) cases of bogus d-n-d reordering of 'pseudo-fields'.
+- #381876 by DamienMcKenna - Content Copy: Fix formatting glitch in exported type definitions.
+- #346202 Fieldgroup: let the 'simple' template be overridable (thks fiskit) + allow template variants.
+- #382004 by elcuco - Field name and group name fields should stay LTR for RTL languages.
+- #360712 by tombigel - CSS tweaks for RTL languages.
+- #375316 Nodereference/Userreference: Ensure allowed values always return at least an empty array.
+- #368155 Nodereference/Userreference: Fix performance issue on large sites when validating empty noderef/userref fields.
+- #319778 Optionwidgets: Fix double encoding issues for &, >, <,... chars in select lists.
+
+CCK 6.x-2.1
+===========
+
+This release fixes two critical issues:
+- #331293 by Timo.Kissing - Content copy: no fields proposed for export (#320632 followup).
+- #331033 Views integration: Fix fatal error in content_handler_field.inc in some circumstances.
+
+Other fixes:
+- #331179 Userreference: 'reverse link' checkbox stayed unchecked.
+- Uninstall forgot to remove some variables.
+- #331794 Fix false positives for "The default value is invalid" error message.
+- #331995 Fix 'invalid argument for foreach' warning on nodes with inexistent type.
+- Views integration: make sure our own render_link doesn't output empty links (see #332679).
+
+CCK 6.x-2.0
+===========
+
+IMPORTANT : this release fixes (minor) cross-site scripting (XSS) vulnerabilities
+in nodereference.module, userreference.module, content_copy.module, and CCK's Views integration
+See the Security Annoucement on http://drupal.org/node/330546 for more information.
+
+Note: Filters available for CCK fields in Views have changed slightly since the RC releases.
+If upgrading from a RC release, you might need to check your views, and if needed.
+This only applies to filters defined on Text or Number fields that specify a list of 'Allowed values'.
+Filters on other CCK fields are not affected.
+
+Main new features since RC10:
+- #300368 Add option on Display fields screen to omit fields or groups from the $content value passed to the node template.
+- #298651 by smk-ka, yched - Nodereference/Userreference: Enhance performance on large sites.
+ This also adds 'autocomplete mode' widget settings (full string / beginning of string).
+- #329447 add content_view_field() API function to display a single field, fully themed with label and multiple values, to be used by 3rd party code.
+
+Other changes:
+- Content_generate should be passing field info and updating $items.
+- Fix bug in content_generate that was adding fully formatted textarea values to textfield fields.
+- #329037 Fix small bug in content_generate function method of calling fields that handle their own multiple values.
+- #324826 Change Advanced help path and topic to use & prefix per latest change in Advanced help.
+- #324610 Add Advanced help files for basic fields and hooks so they'll show up in the CCK advanced help documentation. Intended to be used as examples by other field modules for a way to add more field documentation.
+- #321024 Add content_associate_fields() to the content_check_update() function because it can get skipped when updates are aborted or the content module is not yet updated.
+- Fix bad logic in testing content version variable to prevent warning messages before content module is updated.
+- Get rid of t() around Views field label since Views already has it marked as a translatable option.
+- #285470 by jhuckabee, store field label in the view in all cases, previously only custom labels were stored.
+- #266309 by abbasmousavi, change silent fix to error message for invalid input into number fields.
+- #318224 by brmassa, error in Content Copy handling of fieldgroups.
+- #198508 Add messages to Manage fields screen about inactive fields.
+- #320743 Revert group names uniqueness rules as per D5 behavior (group names unique only inside content types).
+- #310219 followup : numeric (core) rendering modes were not preserved in some cases.
+- Fix 'unknown index' warnings on fieldgroups settings pages.
+- #320139 by Moonshine - Noderef / Userref: Fix single-quotes encoding in 'Views' mode with option widgets.
+- #318143 by Douggreen - Panels integration: make widget label translatable.
+- #321147 Views integration: float/decimal filters round values to integers.
+- #321702 Views integration: fix rendering of multiple-values formatters.
+- #322917 Upgrade path: Missing information text on update 6000 when content.module not enabled.
+- Replaced theming instructions in theme/README.txt with advanced_help pages.
+- #323436 by hass: fix a few strings + translation bugs.
+- #323745 by robertgarrigos: Fix performance issue when submitting 'display fields' form.
+- #316292 by fractile81: Turn potentially time-consuming updates into multi-pass updates.
+- Remove unwanted 'N/A' option on noderef/userref fields using checkboxes.
+- #319131 by Moonshine - Add 'title-raw' token for noderef fields.
+- #324300 Views integration: fix sorting for multiple fields by allowing the sort to act on one specific delta.
+ Also disable tablesorting for multiple fields with 'group multiple values' option.
+- Views integration: fix broken query for fields retrieved through relationships when relation is empty.
+- #325262 Fix flawed logic in filtering out empty values.
+- #297322 Views integration: display node title / user name for argument summaries with noderef / userref fields.
+- #324301 Optionwidgets: check for maximum number of values.
+- #320632 Content Copy: Make fields/groups checked for export by default + display the list in an overview table.
+- Content Copy: Import / export weights of dnd-enabled non-CCK fields.
+- #327715 Babysit 'invalid foreach' warnings caused by invalid incoming $node objects.
+- #328763 Adjust weight of non-cck fields even if there are no CCK fields for the content type.
+- Views integration: fixed a few non-relationship safe areas.
+- Views integration: fix 'link this field to its node'+'group multiple'+relationships.
+- #323681 Panels integration: make 'field as pane' work again.
+- #311912 Views integration: The many_to_one filters for fields with 'allowed values' gain should not replace the regular 'starts with'/'greater than' filters.
+
+CCK 6.x-2.0-rc10
+================
+
+- Get rid of helper function content_is_updated(), we can do it better using the content version variable.
+- #318224 by brmassa, fix several errors in Content Copy.
+- #318387 Make sure old fieldgroup updates don't run if tables were never created.
+- #318227 Clean up update abort logic to more clearly explain what still needs to be done, add a helper function to prevent dangerous database operations until database is updated.
+- #317232 Change css file name from content.css to content-module.css to avoid namespace collisions.
+- #316656 Default weight must be zero, not NULL, or form ordering will be incorrect.
+- #107407 by dopry, optimization patch, do nothing in hook_form_alter() and hook_nodeapi() if there are no fields.
+- #317932 Fix userreference documentation typo.
+
+CCK 6.x-2.0-rc9
+===============
+
+- Change update instructions to recommend leaving CCK modules out of the modules folder until they're enabled.
+- #317036 by hass, context-sensitive translation fixes.
+- #316354 by fago, hass, fix translation issues in rules.inc files.
+- #312546 by stella, code cleanup.
+- #311146 by Brian294, dheffron, yched, and others, fix critical javascript problem in new Manage fields UI screen in some themes.
+- #317032 by hass, code cleanup.
+
+CCK 6.x-2.0-rc8
+===============
+
+Be sure to visit update.php after uploading this release.
+
+- #314986 by moshe weitzman, remove hook_devel_caches(), deprecated in favor of content_flush_caches().
+- Clean up inconsistencies in unsetting _error_element, sometimes not unsetting it, sometimes not testing before unsetting it causing undefined index errors.
+- Add more documentation of how nested nodereference and userreference items work.
+- #119102 Combo field prep, Use === in userreference and nodereference validation to be sure we get right results if parent is a zero (delta) value instead of a string name.
+- #119102, #314843 Make sure module process code doesn't override #element_validate set by other modules.
+- #119102 Combo field prep, rework fieldgroup name validation into API to be used by other modules.
+- #312546 by stella - Change some links to make translation easier.
+- Added the #delta value to the wrong place in the element, it was inaccessible to the formatter theme.
+- #119102 Combo field prep, rework the field overview form so it can hanle other kinds of groups.
+- #119102 Combo field prep, add hooks to the fieldgroup module so other modules can alter group info.
+- #119102 Combo field prep, add group_type information to the Manage fields screen.
+- #119102 Combo field prep, add group_type column to content_group table.
+- #310420 Make sure fields created by disabled modules get marked inactive in the database.
+- #119102 Combo field prep, allow way to override multiple values settings for optionwidgets.
+- #119102 Combo field prep, add prev_parent and group info to display fields overview.
+- #119102 Combo field prep, add a helper function that can determine if a field is in use and the max delta value in use.
+- #309667 Add Panels integration in. This is still experimental since Panels for D6 is still experimental.
+- #307909 Don't create Views tables for fields that don't create db columns.
+- Make incompatibility with older Views releases stand out more.
+- Fix errors when rendering fieldgroups in 'advanced' contexts (RSS, search...).
+- Do not insert field and group labels in search index.
+- Fix drag-n-drop order lost when node form is redisplayed after node preview or failed validation.
+- Fix drag-n-drop order not accounted for in node previews.
+- #306572 Number: Incorrect validation of allowed values for Float and Decimal fields.
+- #306963 by p.brouwers - Number : fix missing formatter for '9.999,99' (be_2).
+- Views integration : Add default label for userref and noderef relationships.
+- #234774 Nifty new UI to add fields and groups (requires a cache clear) + initial integration with advanced_help module.
+- #281749 by asimmonds: fix '0' not parsed as an alias for allowed values.
+- #309365 Views integration: Consider relationships when force-adding the 'Node: Type' field - thks jhuckabee.
+- #308215 by Reg - Nodereference: Do not filter on empty string when querying for referenceable nodes.
+- #308778 Fix $item['view'] element missing for tokens and contemplate.
+- #310414 Fix broken redirects when adding fields to content types with an underscore in their machine names.
+- #310484 by merlinofchaos - Views integration: Allow relationships to work nicely with multiple values.
+- Views integration: reorder elements in the field's settings to ba a little more logical.
+- #306604 Views integration: fix relationships with 'group multiple values' option. Thx merlinofchaos for the help.
+- Add a message on the 'Manage fields' screen about the benefits of advanced_help module.
+- #311883 by hass : Fix a string to give translators better context.
+- #310873 Upgrade path : abort updates if content.module and/or field modules are disabled, and fix existing sites possibly affected.
+- #310219 Let modules expose additional display modes iunder the 'Display fields' tab : hook_content_build_modes().
+
+CCK 6.x-2.0-rc7
+===============
+
+Note:
+- There has been a few files moved around since RC6, so be sure to *delete* the previous contents
+of your cck/ folder before uploading the new files, in order to avoid duplicates.
+- The admin forms (field creation, field edition...) have been renamed to comply with usual form
+naming conventions. Modules and custom code that rely on those form ids through hook_form_alter() or
+drupal_execute() will need to be updated.
+- The final 6.x-2.0 release is currently targetted for the second half of September.
+
+Main bugs fixed since RC6:
+- Content Copy: Fix multiple bugs when importing/exporting content types :
+exporting field definition can alter the actual field's settings
+'this post cannot be referenced' error when exporting nodereference fields
+no export of default values
+- #198502 D5 upgrade path: Prevent field module upgrades from running before content.module upgrades.
+- #293698 Views integration: make 'show n values starting from m' actually work.
+- #292872 Data loss issue: fields and field data deleted for content types defined by disabled modules.
+IMPORTANT: Since disabling all contrib modules is a recommended step prior to upgrading a D5 site to D6,
+it is highly advised that D5 sites using CCK are updated to CCK 5.x-1.8 (which contains the same fix)
+before starting the D6 upgrade process.
+
+Main new features since RC6:
+- Updated to latest Views 2 API. Views integration requires Views 6.x-2.x-dev newer than Sep 3, 2008.
+- #295556 by CPyle - Userreference: let referenceable users be defined by a View.
+- Userreference: Add 'Radios / checkboxes' widget.
+- #294797 New $FIELD_NAME_rendered and $GROUP_NAME_rendered variables for node.tpl.php.
+- Nodereference: Allow specific node templates for nodes displayed as values of a noderef field.
+- #301736 by nedjo - Nodereference: Multilingual support; if available, propose translations of referenced nodes when creating a new translation.
+- #196468 by Nedjo - Content copy: Provide a link to automatically import a file into Content Copy.
+
+Other changes:
+- Avoid undefined index error in Content Copy when fieldgroup is enabled but there are no groups.
+- #296077 Add delta to formatter information.
+- #128038 Alter _content_admin_form() to provide the raw widget default values as well as the default value widget so programmed forms will have those values available. You can't tell when you construct the form if it's a programmed form or not, so we will always have to create the default value widget, but we don't always have to use it. This will also get the default values into the Content Copy export in a way that Content Copy import can pick them up, and alter validation to unset the default value widget and skip the default value widget processing if it's a programmed form. Since we are now provided the actual default value (not just the default value widget) in the export, we can safely pick it up in the import.
+- #128038 Use content_field_instance_collapse() to send form values in the Content Copy export to be sure we get the original field values for checkboxes instead of the true/false values we will get otherwise.
+- #300108 Add group value back to field settings form so it will appear in the Content Copy export.
+- #283985 Force Content Copy export to use current field values to avoid storing mangled data back to field.
+- #298440 by Moonshine and KarenS: move form permission checking to content_field_form() and don't call hook_widget for users w/out permission.
+- #294726 by profix898 and yched: _content_type_info() does not reset on content type changes.
+- #293273 Nodereference: update 'referenceable types' when type name changes.
+- #295914 Fix additional problems when installing CCK in install profiles.
+- #295664 Views integration: let summaries display 'allowed values' aliases if any.
+- Views integration: prevent empty links for the 'no value' items in summaries.
+- #296748 Text: Fix PHP warning when $node->build_mode not set.
+- #297915 Fix content_copy.
+- #298674 Content copy doesn't import all type properties.
+- #293471 Remove fieldgroup selection on field settings form.
+- Userref / Noderef : Add a 'none' choice for non-required, single fields with 'Radios / checkboxes' widget.
+- #298823 Views integration: do not step into views_* namespace.
+- #299698 Userreference: autocompletion query when typed string is '0'.
+- #300236 Fix inconsistent schema for 'locked' column between install and updates.
+- Do not display 'label' settings on 'advanced' subtab of 'Display fields'.
+- #266205 by sun: add zebra classes for field items.
+- #299870 Incorrect handling of custom weight for 'Language' node form element.
+- Fieldgroups: display options were not supported for 'advanced' contexts (RSS, search index...).
+- Fieldgroups: do not display group label when building the search index.
+- Fieldgroups: Remove tinyint (127) limitation on group weights.
+- #301984 by joetsuihk - Views Integration: do not display empty divs on empty fields.
+- Views integration : prevent possible 'invalid argument for foreach' warnings with 'group multiple values'.
+- Fix tests to work with simpletest 2.x.
+- #296301 by Moonshine - Fieldgroups: fix call_user_func_array() error on add / configure / remove pages.
+- #118364 Number (decimal): fix unneeded information message when using comma as a separator ("150,00 was changed to 150.00").
+- Fieldgroup: New groups are not styled on node view until 'display fields' form is submitted.
+- #303664 Views integration: update to new Views API for handler / plugins.
+- #303475 by wrunt - Optionwidgets : unchecked 'single on/off checkbox' stores 0/'0' instead of the 'off' value.
+- #304450 Userreference - fix broken autocomplete for 'simple' mode / fix broken 'advanced - views' mode after Views API changes.
+- Fix PHP warnings on node display for hidden fields inside fieldgroups.
+- #305048 by asimmonds: fix incorrect link on 'start update' page when updates were aborted.
+- Content copy: Fix broken group export as a result of #296301.
+- #304828 Clean up function names in content.admin.inc.
+- #285557 Added 'img' to the list of allowed tags in fields descriptions.
+- Content copy: wrong page title after export code has been generated.
+- Fieldgroup: fix broken node preview.
+
+CCK 6.x-2.0-rc6
+===============
+
+Hotfix release for:
+- #295537 fix warnings in update 6004 when site has no actual cck fields.
+Those errors were harmless, no need to worry or run update.php again if you had them.
+
+Minor fix:
+- #265795 by smk-ka: formatter labels go through t() twice in Views exposed data.
+
+CCK 6.x-2.0-rc5
+===============
+
+Main bugs fixed :
+- #281388 Optionwidgets: Unselect values doesn't take.
+- #286457 Fix menu not being always rebuilt when needed.
+- #285138 by quicksketch and yched: Allow CCK to be installed in install profiles.
+
+Main new features :
+- #282183 by chx: Nodereference - 'Checkboxes/radios' widget.
+- #289138 by dopry: Add support for 'locked' fields (for module-defined fields).
+
+Other changes :
+- #273502 Add descriptions to the non-CCK form elements on the Manage fields screen.
+- Fix PHP warnings when field display is set to 'hidden' and field is in a fieldgroup.
+- Re-introduce '' choice for multiselect widgets (optionwidgets, noderef/userref select).
+- #281449 Text: maxlength on textfield widget is 128 even when the field has no maximum length.
+- Add tests for optionwidgets.
+- #282175: Don't mention 'add more' button when the widget opts out of it.
+- Optionwidgets: use '- None -' for 'no selection' option (like core's taxonomy.module).
+- #286637 by poiu: clearer example for default value with php-code.
+- #93436 Add $form parameter to content_validate.
+- #277310 by fractile81: update node object by reference in content_load().
+- #285771 Views integration: use the new 'float' filter handler where applicable.
+- Fix PHP warnings when renaming a content type.
+- #280410 Number: Fix prefix / suffix displayed when field is empty.
+- #282937 Fix warnings on uninstall.
+- #287540 Add index on nid in data tables, to optimize node deletion (requires update.php)
+- #288578 Text: Fix max length to use utf8 length.
+- #222214 by aaron, deviantintegral : support tokens for nodererf / userref paths aliases.
+- #211306 by asimmonds: Fix error in D5 update with SQL strict mode.
+- #292338 by mh89: Set fieldgroup.module's weight to 9 (missing for new D6 installs).
+- #292463 Fieldgroup: missing update for fieldgroup table names (didn't actually break anything).
+- #292855 by Tgr - Fieldgroup: missing } in query on field instance deletion.
+- #292925 by greggles - Text: Fix PHP notice under some circumstances with textarea widget.
+- #292675 Support d-n-d reordering of non-cck "fields" for types that have no cck fields.
+- #289888 Nodereference: Fix 'full node' and 'teaser' formatters.
+- Display field type human names instead of machine names on 'Manage Fields' and 'Fields' overview pages.
+- #292884 Better help text for field template suggestions.
+- #293163 Use FAPI validation instead of field|widget_settings($op 'validate').
+ (the 'validate' op is still supported, though)
+- #75423 by mh89 - Text: 'size' setting for textfield widget.
+
+
+CCK 6.x-2.0-rc4
+===============
+
+This RC Mainly fixes a critical bug :
+http://www.drupal.org/node/277968 - Saving 'Display Fields' wipes widget settings.
+
+- #278325 Nodereference/Userreference - autocomplete widget does not check nodes/users are 'referenceable'.
+- #278325 followup: Unify the mechanism used to assign hook_field('validate') errors to form elements across fields and widgets.
+- Userreference - Turn the 'Reverse link' radios into a checkbox in the field settings.
+- Nodereference - Only list 'node' Views in the 'advanced mode', and differenciate default views as in D5.
+- Optionwidgets - fix PHP warning when creating a new 'on/off checkbox' and no allowed values could be set yet.
+- Optionwidgets - fix PHP warning on 'on/off checkbox' only one 'allowed value'.
+- Optionwidgets - add a 'warning' message to remind the admins they need to set allowed values.
+- #278676 by hass: fix untranslated field and widget type names.
+- Do not validate the fields settings form when the 'change label / widget' submits the form.
+- #273502 Let the 'menu settings' node-form fieldset on node forms be repositioned.
+- #273502 followup: add a description for non-CCK 'fields' on 'Manage fields' tab.
+- #278793 by hass: fix untranslated PHP code example.
+- Nodereference/Userreference - There were two 'no selection' choices on 'select list' widget for non-required fields.
+- #277486 Nodereference/Userreference - no selection with 'select list' widget stores 0 instead of NULL.
+- #278789 better wording for the 'PHP default value invalid' error message.
+- #267771 orignal patch by quicksketch: Richer label settings for views fields.
+- #279204 by eMPee584: fix edit paths inconsistency.
+- #276990 Nodereference - error message when no valid node with that title (autocomplete widget).
+- Widget (FAPI-)validation messages do not display the field 'label' when the error is on a nth value (n > 1).
+- Unify field validation error messages.
+- #269319 Reintroduce field template variants; add theme instructions text file.
+- #179419 by smk-ka: Content Copy - Import fails when language not English.
+- #278899 Nodereference - Refactor 'advanced (Views-defined referenceable nodes)' to use views rendering.
+- #279190 content_crud_instance_update wiped existing widget settings in some cases.
+ Also added a tests for a few basic properties of the CRUD API.
+
+CCK 6.x-2.0-rc3
+===============
+
+- #278116 by Damien Tournoud: Make some strings easier to translate in views intergration forms.
+- #278135 fix some translation quirks + fix french typography for ':' :-)
+- Nodereference: 'Title mismatch. Please check your selection' error should break validation (+ fix typo).
+- #277968 by jpetso: Fix fatal error when cck folder lives in the main /modules folder.
+
+CCK 6.x-2.0-rc2
+===============
+
+- #276994 Follow up, remove conditional loading for content.views.inc, Views handles it.
+
+CCK 6.x-2.0-rc1
+===============
+
+- #276994 Remove views_include_handlers() from content.views.inc, no longer needed.
+- Change 'allow_empty' to 'allow empty' so that Views filters work correctly.
+- #272871 Pass #node to formatters to be consistent with the values that were available in the D5 version.
+- #271294 Add TODO to get rid of content_write_record() once drupal_write_record() is patched.
+- #271294 Add documentation for the reason for having a custom version of drupal_write_record.
+- Avoid E_All error when prefixes and suffixes are not defined in number module.
+- Avoid E_All error, don't try to return $item[0] if there are no items.
+- #266590 Make sure a view is valid before trying to use it in the nodereference module to fix upgrade errors when the view has not been updated to Views 2.
+- #258127 Get rid of content_menu_needs_rebuild() in remaining places and only rebuild the menu when absolutely needed.
+- Alter content_types_install() to make sure it picks up all the regular field and widget values out of the database. Some of the field values were missing, which caused some of the other values to get set incorrectly during updates and when modules are enabled.
+- #235063 Fix jumbled multiple values when hitting the 'add-more' button with more than 10 values.
+ Keep 'add more' button text consistent.
+- #270014 by yang_yi_cn: form for multiple values didn't call the right hook_widget
+- fix 'Undefined index: #access' notice when content_permissions.module is disabled
+- #270315 Mention dependency on schema.module in the desciptions of the CRUD tests.
+- #227951 by pwolanin: Add a permission for PHP 'default values' and 'allowed values'
+- #271682 by pwolanin: Make simpletests easier by not duplicating field name in same form.
+- #270315 by pwolanin: Update simpletest to use DrupalWebTestCase.
+- #227951 by pwolanin: Add permission for ability to use php code for default values and allowed values.
+- #270827 by pwolanin: Validity checks for the AHAH-'add more' request.
+- #271087 Properly handle values '0' for text and number fields.
+- #258407 Fix field template name to allow for easy overridability.
+- #274038 by jpetso: Fix non-JS mode for 'add more' button.
+- #275192 by jpetso: Attach AHAH behaviors to newly inserted widgets on JS 'add more'.
+- #271710 by pwolanin: tests for UI field CRUD, and node form generation.
+- #266696 by pwolanin: Unable to change the label or widget type for a field.
+- #201329 by pwolanin and yched: Fix content_field_instance_delete() not cleaning tables.
+- #271577 by pwolanin: Fix unsanitized text (optionwidgets, number, text, field labels, field descriptions)
+- #273539 by jpetso: Fix JS-'add more' for complex widgets (e.g. filefield)
+- #227435 by pwolanin: Usability - Put fields links on content type overview page
+- #277101: Hide fieldset-based fieldgroups when all fields empty
+- #198508: Prevent data loss for disabled fields.
+
+CCK 6.2.beta
+============
+
+Content Generate (new feature)
+- #257874 and #187599 provide a way to auto-generate field content for the devel module.
+- #261633 E_All fix for content_generate.
+
+Usability
+- #227439, #227437, #227945 Rework field and widget type handling to simplify the intial screen when choosing a field and widget type by making it a two-step process where you see only the widgets that apply to the field. Move the setting of the field label to the same place where you set the field name. Change the field edit screen to keep it from showing all the different widgets again and instead just display the current widget. Then add a button to change the widget which will take you to another screen to make the change since the rest of the page will need to change when the widget changes. Keep the changes to the widget label in that separate process, too, since that affects the menu tabs that need to be changed before redirecting back to the main page.
+
+Update processing
+- #256141 Add old updates back to fieldgroup.install for situations where the module was briefly enabled and then disabled and never used so the update process doesn't throw an error for the missing updates.
+- Fix potential E_All error in userreference after update.
+- Fix E_All error that can come up after update if text module is using format column.
+- Change the check in _content_type_info to be sure the new 'active' column exists before trying to query the table during installation and updates. Also fix E_All notice for non-existant db_columns during install and update.
+- #237585 Try to avoid foreach errors on missing content type information by creating empty arrays in content_info.
+
+Optionwidgets
+- #224391 Get default values working again for optionwidgets.
+- #251157 Make sure optionwidgets selections are not lost when previewing node.
+- #253038 Make sure empty optionwidget values are always arrays.
+
+Nodereference
+- #264345 Create a nodereference wrapper for setting and rendering a view and store the rendered view in a static variable to ensure the same view is not rendered over and over in the same session.
+- #263936 Make sure nodereference select views do not try to use paging and do not limit the items per page.
+- Clean up autocomplete handling that uses Views as a selector.
+- #262112 Add missing hook_theme definition for the plain formatter.
+- #256440 Nodereference was passing wrong object to Views for the Views node selection option. Also need to limit available views to those that have fields defined so we can add the title to the view and so there is something meaningful to display in the select list.
+
+Views Integration
+- #264479 Make sure we don't try to init() a view for fields that don't have one selected.
+- #263936 Set arguments in execute_display. Also make sure to pass $string and $exact_string to the view.
+- #257566 Move all content fields into a single group in the Views UI.
+- #242856 Make sure the node.nid is aliased when creating our grouped fields query so the parent node isn't confused with nodereference's nid column.
+- #261528 Add in missing code to create the link to the node if that option is requested.
+
+Content Copy
+- #225664 Make sure groups get imported as well as fields.
+
+Formatters
+- #264768 Make sure handling for all possible states of #single is properly set up.
+- #260253 $node->type isn't always set, and if missing the formatters that use $fields($field_name, $type_name) to retrieve the field array end up with an empty value. Add the node type to all content fields views so we can be sure it's available and alter the content_format logic to look for the node type both at $node->type and at $node->node_type, where Views will put it, to properly set the content type.
+
+General
+- #256116 Add a TODO to reconsider handling of CCK data when a content type is deleted.
+- Small fix to content_generate to get auto-generation of number values working.
+- #265334 Avoid format error messages in the unusual case where you have created CCK content and then delete the content type without deleting the node, since core does not delete the nodes in that case.
+- #227256 Add an additional check when creating a new field that the length is no more than 32 characters.
+- #260253 When content_type is set but empty, nothing is returned from content_fields(). Fix that by checking for empty() instead of isset(). This is a more general problem that should be fixed in content_fields().
+- #258127 Eliminate need to defer the rebuild of the menu, also adding TODO to see if content_menu_needs_rebuild() can be eliminated.
+- #257304 Make sure the widget description is never NULL to avoid problems when a NULL value gets wrapped with t().
+- #259704 Make sure help text always appears.
+- #255113 Make sure empty filtered text fields don't pick up unintended values from check_plain().
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/DEVELOPER.txt b/drupal/sites/default/boinc/modules/contrib/cck/DEVELOPER.txt
new file mode 100644
index 00000000000..251d5863146
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/DEVELOPER.txt
@@ -0,0 +1,6 @@
+// $Id$
+
+DEVELOPER DOCUMENTATION
+UPDATING FROM 5.x TO 6.x
+
+See http://drupal.org/node/191796 for a guide to updating field modules.
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/LICENSE.txt b/drupal/sites/default/boinc/modules/contrib/cck/LICENSE.txt
new file mode 100644
index 00000000000..d159169d105
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/LICENSE.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/README.txt b/drupal/sites/default/boinc/modules/contrib/cck/README.txt
new file mode 100644
index 00000000000..edf51ee9e66
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/README.txt
@@ -0,0 +1,48 @@
+// $Id$
+
+Content Construction Kit
+------------------------
+
+NOTE: Install the advanced_help module (http://drupal.org/project/advanced_help)
+to access more help (writing still in progress...)
+
+To install, place the entire CCK folder into your modules directory.
+Go to Administer -> Site building -> Modules and enable the Content module and one or
+more field type modules:
+
+- text.module
+- number.module
+- userreference.module
+- nodereference.module
+
+Now go to Administer -> Content management -> Content types. Create a new
+content type and edit it to add some fields. Then test by creating
+a new node of your new type using the Create content menu link.
+
+The included optionswidget.module provides radio and check box selectors
+for the various field types.
+
+The included fieldgroup.module allows you to group fields together
+in fieldsets to help organize them.
+
+A comprehensive guide to using CCK is available as a CCK Handbook
+at http://drupal.org/node/101723.
+
+Known incompatibilitie
+----------------------
+
+The Devel Themer module that ships with Devel is known to mess with CCK admin pages.
+As a general rule, Devel Themer should only be switched on intermittently when doing
+theme work on a specific page, and switched off immediately after that, for it adds
+massive processing overhead.
+
+Maintainers
+-----------
+The Content Construction Kit was originally developped by:
+John Van Dyk
+Jonathan Chaffer
+
+Current maintainers:
+Karen Stevenson
+Yves Chedemois
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/UPGRADE.txt b/drupal/sites/default/boinc/modules/contrib/cck/UPGRADE.txt
new file mode 100644
index 00000000000..1cb5b61aaff
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/UPGRADE.txt
@@ -0,0 +1,87 @@
+// $Id$
+
+================================================================
+UPDATING FROM VERSION 4.7 to 6.x
+================================================================
+
+THERE IS NO DIRECT UPGRADE PATH FROM 4.7 TO 6.x!! FIRST UPGRADE
+YOUR DATABASE FROM 4.7 TO THE LATEST 5.x VERSION, THEN UPGRADE
+TO 6.x.
+
+ALWAYS BACKUP YOUR DATABASE BEFORE UPGRADING!
+
+1) While 4.7 is still installed, upload the latest 4.7 version of
+ all the CCK files, go to update.php, and run all possible
+ updates for the Content module and all field modules.
+
+2) Install Drupal version 5. Once it is running, upload and install
+ the latest 5.x versions of all CCK modules, go to update.php and
+ run all possible updates.
+
+Jump to the instructions for updating from version 5.x to 6.x.
+
+================================================================
+UPDATING FROM VERSION 5.x to 6.x
+================================================================
+
+YOU MUST RUN ALL POSSIBLE UPDATES TO YOUR DATABASE IN 5.x USING
+THE LATEST 5.x CODE, BEFORE UPGRADING FROM 5.x to 6.x.
+
+ALWAYS BACKUP YOUR DATABASE BEFORE UPGRADING!
+
+1) Before upgrading to 6.x, upload the latest 5.x versions of all
+ CCK modules, go to update.php and run all possible updates.
+
+2) Disable all CCK modules and remove them from the modules folder
+ before upgrading.
+
+3) Install Drupal version 6. Leave all contributed modules out of
+ the modules folder until core modules are up and running.
+ Set your administration theme to a core theme like Garland until
+ everything has been updated to help ensure you don't encounter
+ theme-related problems accessing the administration area.
+
+4) Once core is running, upload and install the latest 6.x versions
+ of ONLY CCK CORE FILES (the ones in the tarball on the CCK
+ project page). Enable them, then go to update.php and run all
+ possible updates. DO NOT add any other CCK modules to the
+ modules folder until the core CCK files are updated and working
+ correctly.
+
+5) After updating CCK core modules, you may get messages saying that
+ some updates failed and that you need to run update.php again.
+ If you get messages like that, keep re-running update.php until
+ you get no more messages.
+
+6) Once the core CCK modules are updated and working correctly,
+ add other CCK modules to the modules folder, enable them,
+ and run update.php. For best results, do this one module at a
+ time so you can tell immediately if any of them create problems
+ without letting those problems interfere with other updates.
+
+
+Your database should now be ready to run in CCK version 6.x
+
+================================================================
+
+The 4.7 to 5.x steps are necessary because of significant changes
+in the database structure between the 4.7 and 6.x versions. These changes
+make it extremely difficult to create an automatic upgrade path that
+will work reliably in every possible situation.
+
+The extra steps in the 5.x to 6.x upgrade are because all modules
+in the modules folder are automatically updated in Drupal 6, even if they
+are not enabled. That means that modules that rely on core CCK may try
+to run their updates even if core CCK is not enabled, and contributed
+CCK modules that have broken updates will have their broken updates
+run even if they are not enabled.
+
+A number of updates are dependent on other updates and won't work
+until previous updates are finished or specific modules are enabled,
+so you may get messages that other modules need to be enabled or that
+update.php needs to be re-run, and you need to follow those instructions
+until all the updates complete.
+
+Taking extra time during the upgrade by leaving modules out of the
+modules folder altogether until you are ready to enable and update them
+should reduce or eliminate update problems.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.info b/drupal/sites/default/boinc/modules/contrib/cck/content.info
new file mode 100644
index 00000000000..6f398eb6445
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/content.info
@@ -0,0 +1,11 @@
+; $Id$
+name = Content
+description = Allows administrators to define new content types.
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.install b/drupal/sites/default/boinc/modules/contrib/cck/content.install
new file mode 100644
index 00000000000..9faaac45580
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/content.install
@@ -0,0 +1,621 @@
+ $t('CCK - No Views integration'),
+ 'description' => $t("CCK integration with Views module requires Views 6.x-2.0-rc2 or greater."),
+ 'severity' => REQUIREMENT_ERROR,
+ );
+ }
+ return $requirements;
+}
+
+/**
+ * 'Safe' version of content_types() to use in updates and installs.
+ *
+ * Can't safely use content_fields() or content_types() in an update to get
+ * a fields array, especially without knowing what field modules are enabled,
+ * or the current state of the database and cache, so create a fields array
+ * from database info that is limited to fields from modules that are
+ * currently enabled.
+ */
+function content_types_install() {
+ drupal_load('module', 'content');
+ module_load_include('inc', 'content', '/includes/content.crud');
+ $module_field_types = $module_widgets = array();
+ foreach (module_list() as $module) {
+ if ($field_type = module_invoke($module, 'field_info')) {
+ $module_field_types[$module] = $field_type;
+ }
+ if ($widget_type = module_invoke($module, 'widget_info')) {
+ $module_widgets[$module] = $widget_type;
+ }
+ }
+ $fields = array();
+ $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ".
+ " LEFT JOIN {". content_field_tablename() ."} nf ON nf.field_name = nfi.field_name");
+ while ($row = db_fetch_array($db_result)) {
+ $field = array_merge($row, unserialize($row['global_settings']));
+ unset($field['global_settings']);
+
+ // There may be module data available for currently disabled modules,
+ // or missing module data for currently enabled modules, so start over
+ // to get only field info for enabled modules.
+ unset($field['module']);
+ unset($field['widget_module']);
+ // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
+ $field['columns'] = isset($field['db_columns']) ? $field['db_columns'] : array();
+ unset($field['db_columns']);
+
+ foreach ($module_field_types as $module => $types) {
+ foreach ($types as $type_name => $type) {
+ if ($field['type'] == $type_name) {
+ $field['module'] = $module;
+ }
+ }
+ }
+ foreach ($module_widgets as $module => $types) {
+ foreach ($types as $type_name => $type) {
+ if ($field['widget_type'] == $type_name) {
+ $field['widget_module'] = $module;
+ }
+ }
+ }
+ if (!empty($field['module']) && !empty($field['widget_module'])) {
+ $field['widget_settings'] = unserialize($field['widget_settings']);
+ $field['display_settings'] = unserialize($field['display_settings']);
+ $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);
+ $field = content_field_instance_expand($field);
+ $fields[$field['type_name']][$field['field_name']] = $field;
+ }
+ }
+ return $fields;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function content_install() {
+ variable_set('content_schema_version', 6009);
+ drupal_install_schema('content');
+}
+
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function content_uninstall() {
+ drupal_uninstall_schema('content');
+ // The variable is used during the uninstall process,
+ // so we removed it at the very end.
+ variable_del('content_schema_version');
+ // Remove extra weights.
+ foreach (node_get_types('names') as $type_name) {
+ variable_del("content_extra_weights_$type_name");
+ }
+}
+
+/**
+ * Implementation of hook_enable().
+ */
+function content_enable() {
+ // Make sure old data is emptied out of the caches, since it
+ // may no longer be valid since the module was last enabled,
+ // especially if not all the same field modules are enabled
+ // as before. Especially needed during updates.
+ cache_clear_all('*', 'cache_content', TRUE);
+ content_clear_type_cache(TRUE);
+}
+
+/**
+ * Implementation of hook_disable().
+ */
+function content_disable() {
+ // Make sure old data is emptied out of the caches, since it
+ // may no longer be valid when the module is re-enabled.
+ cache_clear_all('*', 'cache_content', TRUE);
+ content_clear_type_cache(TRUE);
+}
+
+/**
+ * Implementation of hook_schema.
+ */
+function content_schema() {
+
+ // Static (meta) tables.
+
+ $schema['content_node_field'] = array(
+ 'fields' => array(
+ 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'type' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''),
+ 'global_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE),
+ 'required' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0),
+ 'multiple' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0),
+ 'db_storage' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 1),
+ 'module' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''),
+ 'db_columns' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE),
+ 'active' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0),
+ 'locked' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0),
+ ),
+ 'primary key' => array('field_name'),
+ );
+ $schema['content_node_field_instance'] = array(
+ 'fields' => array(
+ 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+ 'label' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+ 'widget_type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'widget_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE),
+ 'display_settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'serialize' => TRUE),
+ 'description' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE),
+ 'widget_module' => array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''),
+ 'widget_active' => array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0),
+ ),
+ 'primary key' => array('field_name', 'type_name'),
+ );
+ $schema['cache_content'] = drupal_get_schema_unprocessed('system', 'cache');
+
+ // When the module is first installed, the remaining code in the schema
+ // will create errors, since these tables have not yet been created.
+ // We don't need to create data tables on initial installation anyway
+ // since no fields have been created yet, so just return with this much
+ // of the schema.
+
+ if (!db_table_exists('content_node_field') || !db_table_exists('content_node_field_instance')) {
+ return $schema;
+ }
+
+ // Dynamic (data) tables.
+
+ drupal_load('module', 'content');
+
+ // We can't use many helper functions here, like content_fields() or
+ // content_types() or we risk creating a fatal loop from circular
+ // logic when they call other functions that use this schema, so create
+ // the schema directly from a fresh query of the database.
+
+ // content_table_schema() and content_database_info() have no
+ // circular logic and are safe to use here.
+
+ $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ".
+ " LEFT JOIN {". content_field_tablename() ."} nf ON nf.field_name = nfi.field_name WHERE nf.active = 1 AND nfi.widget_active = 1");
+ while ($field = db_fetch_array($db_result)) {
+ // 'columns' is a reserved word in MySQL4, so our db column is named 'db_columns'.
+ $field['columns'] = unserialize($field['db_columns']);
+ unset($field['db_columns']);
+
+ $content_table = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ $field_table = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD);
+
+
+ // We always add a 'per content type' table for each content type that
+ // has fields.
+ if (!isset($schema[$content_table])) {
+ $schema[$content_table] = content_table_schema();
+ }
+
+ $base_schema = content_table_schema($field);
+ if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
+ // Per-field storage: add the 'per field' table if needed.
+ if (!isset($schema[$field_table])) {
+ $schema[$field_table] = $base_schema;
+ }
+ }
+ else {
+ // Per-type storage: merge the information for the field
+ // in the existing table.
+ $schema[$content_table]['fields'] = array_merge($schema[$content_table]['fields'], $base_schema['fields']);
+ $schema[$content_table]['content fields'] = array_merge($schema[$content_table]['content fields'], $base_schema['content fields']);
+ }
+ }
+ return $schema;
+}
+
+function content_update_last_removed() {
+ return 1008;
+}
+
+/**
+ * Helper function for module updates :
+ * - checks no updates are pending for content.module
+ * - checks content module and the module being updated are both enabled.
+ *
+ * @param $module
+ * The name of the module being updated.
+ */
+function content_check_update($module = NULL) {
+ $ret = array();
+ // Check that modules are enabled before running their updates.
+ if (!module_exists('content') || ($module && !module_exists($module))) {
+ drupal_set_message(t("Updates for CCK-related modules are not run until the modules are enabled on the administer modules page. When you enable them, you'll need to return to update.php and run the remaining updates.", array('@admin-modules-path' => url('admin/build/modules'), '@update-php' => base_path() .'update.php?op=selection')), 'warning', FALSE);
+ // The content module is not enabled, nothing else can happen.
+ if ($module && !module_exists('content') && module_exists($module)) {
+ $query_message = t('!module.module has updates but cannot be updated because content.module is not enabled. If and when content.module is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run.', array('!module' => $module));
+ }
+ // The requested module is not enabled, which may be intentional.
+ // Just let the user know there are updates to be processed if enabled later.
+ else {
+ $query_message = t('!module.module has updates and is available in the modules folder but is not enabled. If and when it is enabled, you will need to re-run the update script. You will continue to see this message until the module is enabled and updates are run.', array('!module' => $module ? $module : 'content'));
+ }
+ $ret['#abort'] = array('success' => FALSE, 'query' => $query_message);
+ return $ret;
+ }
+ // Check that content.module is up-to-date before running field module updates.
+ if ($module && (drupal_get_installed_schema_version('content', TRUE) < max(drupal_get_schema_versions('content')))) {
+ drupal_set_message(t('Some updates are still pending. Please return to update.php and run the remaining updates.', array('@update-php' => base_path() .'update.php?op=selection')), 'warning', FALSE);
+ $ret['#abort'] = array('success' => FALSE, 'query' => t('Some updates are still pending. Please re-run the update script.'));
+ return $ret;
+ }
+ // If everything is OK and updates are not aborted, make sure
+ // content_associate_fields() gets run. With all the complexity of
+ // the dependent updates, it can get missed when an update is aborted.
+ // It won't hurt anything to do this more than once in order to be sure
+ // it doesn't get skipped. Without this step, we can end up with
+ // field modules that are enabled and updated, but not marked as active
+ // in the content_node_field table.
+ if ($module and module_exists($module)) {
+ content_associate_fields($module);
+ }
+}
+
+/**
+ * Add module name to fields table to make it easier to identify the fields to delete when a module
+ * is uninstalled.
+ *
+ * Needed because the value drops out of content_info() when module is disabled, so there
+ * is no other way to find the associated fields.
+ */
+function content_update_6000() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+
+ drupal_load('module', 'content');
+ if (db_column_exists(content_field_tablename(), 'active')) {
+ return $ret;
+ }
+ db_add_field($ret, content_field_tablename(), 'module', array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''));
+ db_add_field($ret, content_field_tablename(), 'db_columns', array('type' => 'text', 'size' => 'medium', 'not null' => TRUE, 'initial' => ''));
+ db_add_field($ret, content_field_tablename(), 'active', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
+ db_add_field($ret, content_instance_tablename(), 'widget_module', array('type' => 'varchar', 'length' => 127, 'not null' => TRUE, 'default' => ''));
+ db_add_field($ret, content_instance_tablename(), 'widget_active', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
+
+ // This will update the table for any modules enabled at this time.
+ foreach (module_list() as $module) {
+ content_associate_fields($module);
+ }
+
+ // Fix the cache_content schema
+ if (db_table_exists('cache_content')) {
+ db_drop_table($ret, 'cache_content');
+ }
+ db_create_table($ret, 'cache_content', drupal_get_schema_unprocessed('system', 'cache'));
+ variable_set('content_schema_version', 6000);
+
+ // The cache table had to be used to store data until this update ran,
+ // so clear cache out now that we're switching back to the cache_content table.
+ $ret[] = update_sql('DELETE FROM {cache}');
+
+ return $ret;
+}
+
+/**
+ * Rename node_field and node_field_instance tables.
+ *
+ * This is a carryover from when the data tables were renamed,
+ * postponed so we wouldn't create any more havoc than necessary
+ * until a major version change.
+ *
+ * Using 'content_node_field' instead of 'content_field'
+ * to avoid conflicts with field tables that will be prefixed
+ * with 'content_field'.
+ */
+function content_update_6001() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+ drupal_load('module', 'content');
+ if (db_table_exists('content_node_field')) {
+ return $ret;
+ }
+ db_rename_table($ret, 'node_field', 'content_node_field');
+ db_rename_table($ret, 'node_field_instance', 'content_node_field_instance');
+ variable_set('content_schema_version', 6001);
+ content_clear_type_cache(TRUE);
+ return $ret;
+}
+
+/**
+ * Get rid of automatic per content tables for content types that have no fields.
+ * Switching to adding those tables only when needed.
+ */
+function content_update_6002() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+
+ drupal_load('module', 'content');
+ $db_types = content_types_install();
+ $field_types = array();
+
+ $result = db_query("SELECT DISTINCT type_name FROM {". content_instance_tablename() ."}");
+ while ($type = db_fetch_array($result)) {
+ $field_types[] = $type['type_name'];
+ }
+
+ foreach ($db_types as $content_type => $content_info) {
+ if (!in_array($content_type, $field_types)) {
+ $table = _content_tablename($content_type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ if (db_table_exists($table)) {
+ db_drop_table($ret, $table);
+ }
+ }
+ }
+ variable_set('content_schema_version', 6002);
+ content_clear_type_cache(TRUE);
+ return $ret;
+}
+
+/**
+ * 'db_columns' column 1st got introduced as 'columns', which is forbidden in MySQL 4.
+ * This update function will only be useful for early D6 testers...
+ */
+function content_update_6003() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+ if (db_column_exists('content_node_field', 'columns')) {
+ db_change_field($ret, 'content_node_field', 'columns', 'db_columns', array('type' => 'text', 'size' => 'medium', 'not null' => TRUE));
+ }
+ variable_set('content_schema_version', 6003);
+ return $ret;
+}
+
+/**
+ * Index the 'nid' column on data tables to optimize node deletion.
+ * Large tables might deserve a multipass update.
+ */
+function content_update_6004(&$sandbox) {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+
+ // Do nothing if the indexes were already created by D5's content_update_1009.
+ if (variable_get('content_update_1009', FALSE)) {
+ return $ret;
+ }
+
+ // Gather list of tables.
+ if (!isset($sandbox['tables'])) {
+ drupal_load('module', 'content');
+ $sandbox['tables'] = array();
+ $result = db_query('SELECT * FROM {'. content_instance_tablename() .'} nfi '.
+ ' LEFT JOIN {'. content_field_tablename() .'} nf ON nf.field_name = nfi.field_name');
+ while ($field = db_fetch_array($result)) {
+ if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
+ $table = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD);
+ }
+ else {
+ $table = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ }
+ $sandbox['tables'][$table] = $table;
+ }
+ $sandbox['count'] = count($sandbox['tables']);
+ }
+
+ // One pass : add index on one table.
+ if ($table = array_shift($sandbox['tables'])) {
+ db_add_index($ret, $table, 'nid', array('nid'));
+ }
+
+ if ($sandbox['count']) {
+ $ret['#finished'] = 1 - count($sandbox['tables']) / $sandbox['count'];
+ }
+ variable_set('content_schema_version', 6004);
+ return $ret;
+}
+
+/**
+ * Add 'locked' property for fields.
+ */
+function content_update_6005() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+ drupal_load('module', 'content');
+ db_add_field($ret, content_field_tablename(), 'locked', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
+ variable_set('content_schema_version', 6005);
+ return $ret;
+}
+
+/**
+ * Make sure the 'locked' column is NOT NULL (error in previous content_update_6005().
+ */
+function content_update_6006() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+ drupal_load('module', 'content');
+ db_change_field($ret, content_field_tablename(), 'locked', 'locked', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
+ variable_set('content_schema_version', 6006);
+ return $ret;
+}
+
+/**
+ * Dummy update function to make sure the theme registry and css / JS aggregated files
+ * are updated.
+ */
+function content_update_6007() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ variable_set('content_schema_version', 6007);
+ return array();
+}
+
+/**
+ * Dummy update function to make sure schema version gets updated.
+ */
+function content_update_6008() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ variable_set('content_schema_version', 6008);
+ return array();
+}
+
+/**
+ * Add the 'exclude from $content' display setting to all existing field instances.
+ */
+function content_update_6009() {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+
+ $ret = array();
+ $result = db_query("SELECT * FROM {content_node_field_instance}");
+ while ($type = db_fetch_array($result)) {
+ $new_settings = array();
+ $display_settings = unserialize($type['display_settings']);
+ if (!empty($display_settings)) {
+ foreach ($display_settings as $key => $val) {
+ $new_settings[$key] = $val;
+ if ($key !== 'label' && is_array($val)) {
+ $new_settings[$key]['exclude'] = 0;
+ }
+ }
+ }
+ else {
+ $new_settings = array(
+ 'label' => array('format' => 'above'),
+ 'full' => array('format' => 'default', 'exclude' => 0),
+ 'teaser' => array('format' => 'default', 'exclude' => 0),
+ );
+ }
+ db_query("UPDATE {content_node_field_instance} SET display_settings='%s' WHERE field_name='%s' AND type_name='%s'", serialize($new_settings), $type['field_name'], $type['type_name']);
+ }
+ variable_set('content_schema_version', 6009);
+ return $ret;
+}
+
+/**
+ * Fix multiple serialization caused by per-field to per-type migration.
+ * See http://drupal.org/node/407446.
+ */
+function content_update_6010(&$sandbox) {
+ if ($abort = content_check_update()) {
+ return $abort;
+ }
+ $ret = array();
+
+ drupal_load('module', 'content');
+
+ // Gather list of tables and columns that need to be updated.
+ if (!isset($sandbox['tables'])) {
+ $sandbox['tables'] = array();
+ $fields = content_fields();
+ foreach ($fields as $name => $field) {
+ $db_info = content_database_info($field);
+ foreach ($db_info['columns'] as $column => $attributes) {
+ if (isset($attributes['serialize']) && $attributes['serialize']) {
+ $sandbox['tables'][$db_info['table']]['table'] = $db_info['table'];
+ $sandbox['tables'][$db_info['table']]['columns'][] = $attributes['column'];
+ $sandbox['tables'][$db_info['table']]['multiple'] = $field['multiple'];
+ }
+ }
+ }
+ $sandbox['count'] = count($sandbox['tables']);
+ $sandbox['current_vid'] = 0;
+ $sandbox['current_delta'] = 0;
+ }
+
+ // Number of rows to fix in one pass.
+ $limit = 500;
+ // Start correcting data.
+ if ($table_info = array_shift($sandbox['tables'])) {
+ $table = $table_info['table'];
+ $columns = $table_info['columns'];
+
+ if ($table_info['multiple']) {
+ $query = "SELECT * FROM {" . $table . "} WHERE (vid = %d AND delta > %d) OR (vid > %d) ORDER BY vid ASC, delta ASC";
+ $args = array($sandbox['current_vid'], $sandbox['current_delta'], $sandbox['current_vid']);
+ }
+ else {
+ $query = "SELECT * FROM {" . $table . "} WHERE vid > %d ORDER BY vid ASC";
+ $args = array($sandbox['current_vid']);
+ }
+ $result = db_query_range($query, $args, 0, $limit);
+ $count = 0;
+ while ($row = db_fetch_array($result)) {
+ $update_query = $update_args = array();
+ foreach ($columns as $column) {
+ $data = $row[$column];
+ // No need to do anything if the data is NULL.
+ if (!empty($data)) {
+ // Unserialize until we get something that is not a string
+ while (is_string($data)) {
+ $unserialized = @unserialize($data);
+ if ($unserialized !== FALSE) {
+ $data = $unserialized;
+ }
+ else {
+ // TODO : test with a serialized string, just in case...
+ break;
+ }
+ }
+ // Re-serialize once.
+ $data = serialize($data);
+ // If we end up with something different than what we started with, update.
+ if ($data !== $row[$column]) {
+ $update_query[] = "$column = '%s'";
+ $update_args[] = $data;
+ }
+ }
+ }
+ if ($update_query) {
+ $update_args[] = $row['vid'];
+ db_query("UPDATE {" . $table . "} SET ". implode(', ', $update_query) ." WHERE vid = %d", $update_args);
+ }
+ $sandbox['current_vid'] = $row['vid'];
+ $sandbox['current_delta'] = isset($row['delta']) ? $row['delta'] : 0;
+ $count++;
+ }
+ if ($count == $limit) {
+ // Add the table back into the list of tables to be processed if rows remain.
+ array_unshift($sandbox['tables'], $table_info);
+ }
+ else {
+ // Done with this table: reset vid and delta markers.
+ $sandbox['current_vid'] = 0;
+ $sandbox['current_delta'] = 0;
+ $ret[] = array('success' => TRUE, 'query' => "Fixed serialized values in table $table");
+ }
+ }
+
+ if ($sandbox['count']) {
+ $ret['#finished'] = 1 - count($sandbox['tables']) / $sandbox['count'];
+ }
+ return $ret;
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.js b/drupal/sites/default/boinc/modules/contrib/cck/content.js
new file mode 100644
index 00000000000..72a2f2a7a7e
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/content.js
@@ -0,0 +1,80 @@
+// $Id$
+
+Drupal.behaviors.cckManageFields = function(context) {
+ attachUpdateSelects(context);
+};
+
+function attachUpdateSelects(context) {
+ var widgetTypes = Drupal.settings.contentWidgetTypes;
+ var fields = Drupal.settings.contentFields;
+
+ // Store the default text of widget selects.
+ $('#content-field-overview .content-widget-type-select', context).each(function() {
+ this.initialValue = this.options[0].text;
+ });
+
+ // 'Field type' select updates its 'Widget' select.
+ $('#content-field-overview .content-field-type-select', context).each(function() {
+ this.targetSelect = $('.content-widget-type-select', $(this).parents('tr').eq(0));
+
+ $(this).change(function() {
+ var selectedFieldType = this.options[this.selectedIndex].value;
+ var options = (selectedFieldType in widgetTypes) ? widgetTypes[selectedFieldType] : [ ];
+ this.targetSelect.contentPopulateOptions(options);
+ });
+
+ // Trigger change on initial pageload to get the right widget options
+ // when field type comes pre-selected (on failed validation).
+ $(this).trigger('change');
+ });
+
+ // 'Existing field' select updates its 'Widget' select and 'Label' textfield.
+ $('#content-field-overview .content-field-select', context).each(function() {
+ this.targetSelect = $('.content-widget-type-select', $(this).parents('tr').eq(0));
+ this.targetTextfield = $('.content-label-textfield', $(this).parents('tr').eq(0));
+
+ $(this).change(function(e, updateText) {
+ var updateText = (typeof(updateText) == 'undefined') ? true : updateText;
+ var selectedField = this.options[this.selectedIndex].value;
+ var selectedFieldType = (selectedField in fields) ? fields[selectedField].type : null;
+ var selectedFieldWidget = (selectedField in fields) ? fields[selectedField].widget : null
+ var options = (selectedFieldType && (selectedFieldType in widgetTypes)) ? widgetTypes[selectedFieldType] : [ ];
+ this.targetSelect.contentPopulateOptions(options, selectedFieldWidget);
+
+ if (updateText) {
+ $(this.targetTextfield).attr('value', (selectedField in fields) ? fields[selectedField].label : '');
+ }
+ });
+
+ // Trigger change on initial pageload to get the right widget options
+ // and label when field type comes pre-selected (on failed validation).
+ $(this).trigger('change', false);
+ });
+}
+
+jQuery.fn.contentPopulateOptions = function(options, selected) {
+ return this.each(function() {
+ var disabled = false;
+ if (options.length == 0) {
+ options = [this.initialValue];
+ disabled = true;
+ }
+
+ // If possible, keep the same widget selected when changing field type.
+ // This is based on textual value, since the internal value might be
+ // different (optionwidgets_buttons vs. nodereference_buttons).
+ var previousSelectedText = this.options[this.selectedIndex].text;
+
+ var html = '';
+ jQuery.each(options, function(value, text) {
+ // Figure out which value should be selected. The 'selected' param
+ // takes precedence.
+ var is_selected = ((typeof(selected) !== 'undefined' && value == selected) || (typeof(selected) == 'undefined' && text == previousSelectedText));
+ html += '';
+ });
+
+ $(this)
+ .html(html)
+ .attr('disabled', disabled ? 'disabled' : '');
+ });
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/content.module b/drupal/sites/default/boinc/modules/contrib/cck/content.module
new file mode 100644
index 00000000000..b679339ecf8
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/content.module
@@ -0,0 +1,2709 @@
+'. t('The content module, a required component of the Content Construction Kit (CCK), allows administrators to associate custom fields with content types. In Drupal, content types are used to define the characteristics of a post, including the title and description of the fields displayed on its add and edit pages. Using the content module (and the other helper modules included in CCK), custom fields beyond the default "Title" and "Body" may be added. CCK features are accessible through tabs on the content types administration page. (See the node module help page for more information about content types.)', array('@content-types' => url('admin/content/types'), '@node-help' => url('admin/help/node'))) .'
';
+ $output .= '
'. t('When adding a custom field to a content type, you determine its type (whether it will contain text, numbers, or references to other objects) and how it will be displayed (either as a text field or area, a select box, checkbox, radio button, or autocompleting field). A field may have multiple values (i.e., a "person" may have multiple e-mail addresses) or a single value (i.e., an "employee" has a single employee identification number). As you add and edit fields, CCK automatically adjusts the structure of the database as necessary. CCK also provides a number of other features, including intelligent caching for your custom data, an import and export facility for content type definitions, and integration with other contributed modules.') .'
';
+ $output .= '
'. t('Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The modules page allows you to enable or disable CCK components. A default installation of CCK includes:', array('@modules' => url('admin/build/modules'))) .'
';
+ $output .= '
';
+ $output .= '
'. t('number, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available.') .'
';
+ $output .= '
'. t("text, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values.") .'
';
+ $output .= '
'. t('nodereference, which creates custom references between Drupal nodes. By adding a nodereference field and two different content types, for instance, you can easily create complex parent/child relationships between data (multiple "employee" nodes may contain a nodereference field linking to an "employer" node).') .'
';
+ $output .= '
'. t('userreference, which creates custom references to your sites\' user accounts. By adding a userreference field, you can create complex relationships between your site\'s users and posts. To track user involvement in a post beyond Drupal\'s standard Authored by field, for instance, add a userreference field named "Edited by" to a content type to store a link to an editor\'s user account page.') .'
';
+ $output .= '
'. t('fieldgroup, which creates collapsible fieldsets to hold a group of related fields. A fieldset may either be open or closed by default. The order of your fieldsets, and the order of fields within a fieldset, is managed via a drag-and-drop interface provided by content module.') .'
';
+ $output .= '
';
+ $output .= '
'. t('For more information, see the online handbook entry for CCK or the CCK project page.', array('@handbook-cck' => 'http://drupal.org/handbook/modules/cck', '@project-cck' => 'http://drupal.org/project/cck')) .'
';
+ return $output;
+ }
+}
+
+/**
+ * Implementation of hook_flush_caches.
+ */
+function content_flush_caches() {
+ return array(content_cache_tablename());
+}
+
+/**
+ * Implementation of hook_init().
+ */
+function content_init() {
+ drupal_add_css(drupal_get_path('module', 'content') .'/theme/content-module.css');
+ if (module_exists('token') && !function_exists('content_token_values')) {
+ module_load_include('inc', 'content', 'includes/content.token');
+ }
+ if (module_exists('diff') && !function_exists('content_diff')) {
+ module_load_include('inc', 'content', 'includes/content.diff');
+ }
+}
+
+/**
+ * Implementation of hook_perm().
+ */
+function content_perm() {
+ return array('Use PHP input for field settings (dangerous - grant with care)');
+}
+
+/**
+ * Implementation of hook_menu_alter().
+ */
+function content_menu_alter(&$items) {
+ // Customize the content types page with our own callback
+ $items['admin/content/types']['page callback'] = 'content_types_overview';
+ $items['admin/content/types']['file'] = 'content.admin.inc';
+ $items['admin/content/types']['file path'] = drupal_get_path('module', 'content') .'/includes';
+}
+
+/**
+ * Implementation of hook_menu().
+ */
+function content_menu() {
+ $items = array();
+ $items['admin/content/types/fields'] = array(
+ 'title' => 'Fields',
+ 'page callback' => 'content_fields_list',
+ 'access arguments' => array('administer content types'),
+ 'file' => 'includes/content.admin.inc',
+ 'type' => MENU_LOCAL_TASK,
+ );
+ // Callback for AHAH add more buttons.
+ $items['content/js_add_more'] = array(
+ 'page callback' => 'content_add_more_js',
+ 'access arguments' => array('access content'),
+ 'file' => 'includes/content.node_form.inc',
+ 'type' => MENU_CALLBACK,
+ );
+
+ // Make sure this doesn't fire until content_types is working,
+ // and tables are updated, needed to avoid errors on initial installation.
+ if (!defined('MAINTENANCE_MODE') && variable_get('content_schema_version', -1) >= 6007) {
+ foreach (node_get_types() as $type) {
+ $type_name = $type->type;
+ $content_type = content_types($type_name);
+ $type_url_str = $content_type['url_str'];
+ $items['admin/content/node-type/'. $type_url_str .'/fields'] = array(
+ 'title' => 'Manage fields',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('content_field_overview_form', $type_name),
+ 'access arguments' => array('administer content types'),
+ 'file' => 'includes/content.admin.inc',
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 1,
+ );
+ $items['admin/content/node-type/'. $type_url_str .'/display'] = array(
+ 'title' => 'Display fields',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('content_display_overview_form', $type_name),
+ 'access arguments' => array('administer content types'),
+ 'file' => 'includes/content.admin.inc',
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ );
+ $contexts = content_build_modes('_tabs');
+ foreach ($contexts as $key => $tab) {
+ $items['admin/content/node-type/'. $type_url_str .'/display/'. $key] = array(
+ 'title' => $tab['title'],
+ 'page arguments' => array('content_display_overview_form', $type_name, $key),
+ 'access arguments' => array('administer content types'),
+ 'type' => $key == 'basic' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+ 'weight' => $key == 'basic' ? 0 : 1,
+ );
+ }
+ // Cast as an array in case this is called before any fields have
+ // been added, like when a new content type is created.
+ foreach ((array) $content_type['fields'] as $field) {
+ $field_name = $field['field_name'];
+ $items['admin/content/node-type/'. $type_url_str .'/fields/'. $field_name] = array(
+ 'title' => $field['widget']['label'],
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('content_field_edit_form', $type_name, $field_name),
+ 'access arguments' => array('administer content types'),
+ 'file' => 'includes/content.admin.inc',
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['admin/content/node-type/'. $type_url_str .'/fields/'. $field_name .'/remove'] = array(
+ 'title' => 'Remove field',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('content_field_remove_form', $type_name, $field_name),
+ 'access arguments' => array('administer content types'),
+ 'file' => 'includes/content.admin.inc',
+ 'type' => MENU_CALLBACK,
+ );
+ }
+ }
+ }
+ return $items;
+}
+
+/**
+ * Hook elements().
+ *
+ * Used to add multiple value processing, validation, and themes.
+ *
+ * FAPI callbacks can be declared here, and the element will be
+ * passed to those callbacks.
+ *
+ * Drupal will automatically theme the element using a theme with
+ * the same name as the hook_elements key.
+ */
+function content_elements() {
+ return array(
+ 'content_multiple_values' => array(),
+ 'content_field' => array(),
+ );
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function content_theme() {
+ $path = drupal_get_path('module', 'content') .'/theme';
+ require_once "./$path/theme.inc";
+
+ return array(
+ 'content_field' => array(
+ 'template' => 'content-field',
+ 'arguments' => array('element' => NULL),
+ 'path' => $path,
+ ),
+ 'content_overview_links' => array(
+ 'arguments' => array(),
+ ),
+ 'content_field_overview_form' => array(
+ 'template' => 'content-admin-field-overview-form',
+ 'file' => 'theme.inc',
+ 'path' => $path,
+ 'arguments' => array('form' => NULL),
+ ),
+ 'content_display_overview_form' => array(
+ 'template' => 'content-admin-display-overview-form',
+ 'file' => 'theme.inc',
+ 'path' => $path,
+ 'arguments' => array('form' => NULL),
+ ),
+ 'content_exclude' => array(
+ 'arguments' => array('content' => NULL, 'object' => array(), 'context' => NULL),
+ ),
+ 'content_view_multiple_field' => array(
+ 'arguments' => array('items' => NULL, 'field' => NULL, 'data' => NULL),
+ ),
+ 'content_multiple_values' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_views_api().
+ */
+function content_views_api() {
+ return array(
+ 'api' => 2,
+ 'path' => drupal_get_path('module', 'content') . '/includes/views',
+ );
+}
+
+/**
+ * Implementation of hook_ctools_plugin_directory().
+ */
+function content_ctools_plugin_directory($module, $plugin) {
+ if ($module == 'ctools' && $plugin == 'content_types') {
+ return 'includes/panels/' . $plugin;
+ }
+}
+
+/**
+ * Load data for a node type's fields.
+ * Implementation of hook_nodeapi 'load' op.
+ *
+ * When loading one of the content.module nodes, we need to let each field handle
+ * its own loading. This can make for a number of queries in some cases, so we
+ * cache the loaded object structure and invalidate it during the update process.
+ */
+function content_load(&$node) {
+ $cid = 'content:'. $node->nid .':'. $node->vid;
+ if ($cached = cache_get($cid, content_cache_tablename())) {
+ foreach ($cached->data as $key => $value) {
+ $node->$key = $value;
+ }
+ }
+ else {
+ $default_additions = _content_field_invoke_default('load', $node);
+ if ($default_additions) {
+ foreach ($default_additions as $key => $value) {
+ $node->$key = $value;
+ }
+ }
+ $additions = _content_field_invoke('load', $node);
+ if ($additions) {
+ foreach ($additions as $key => $value) {
+ $node->$key = $value;
+ $default_additions[$key] = $value;
+ }
+ }
+ cache_set($cid, $default_additions, content_cache_tablename());
+ }
+}
+
+/**
+ * Implementation of hook_nodeapi 'validate' op.
+ *
+ */
+function content_validate(&$node, $form = NULL) {
+ _content_field_invoke('validate', $node, $form);
+ _content_field_invoke_default('validate', $node, $form);
+}
+
+/**
+ * Implementation of hook_nodeapi 'presave' op.
+ *
+ */
+function content_presave(&$node) {
+ _content_field_invoke('presave', $node);
+ _content_field_invoke_default('presave', $node);
+}
+
+/**
+ * Implementation of hook_nodeapi 'insert' op.
+ *
+ * Insert node type fields.
+ */
+function content_insert(&$node) {
+ _content_field_invoke('insert', $node);
+ _content_field_invoke_default('insert', $node);
+}
+
+/**
+ * Implementation of hook_nodeapi 'update' op.
+ *
+ * Update node type fields.
+ */
+function content_update(&$node) {
+ _content_field_invoke('update', $node);
+ _content_field_invoke_default('update', $node);
+ cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename());
+}
+
+/**
+ * Implementation of hook_nodeapi 'delete' op.
+ *
+ * Delete node type fields.
+ */
+function content_delete(&$node) {
+ _content_field_invoke('delete', $node);
+ _content_field_invoke_default('delete', $node);
+ cache_clear_all('content:'. $node->nid .':', content_cache_tablename(), TRUE);
+}
+
+/**
+ * Implementation of hook_nodeapi 'delete_revision' op.
+ *
+ * Delete node type fields for a revision.
+ */
+function content_delete_revision(&$node) {
+ _content_field_invoke('delete revision', $node);
+ _content_field_invoke_default('delete revision', $node);
+ cache_clear_all('content:'. $node->nid .':'. $node->vid, content_cache_tablename());
+}
+
+/**
+ * Implementation of hook_nodeapi 'view' op.
+ *
+ * Generate field render arrays.
+ */
+function content_view(&$node, $teaser = FALSE, $page = FALSE) {
+ // Let field modules sanitize their data for output.
+ _content_field_invoke('sanitize', $node, $teaser, $page);
+
+ // Merge fields.
+ $additions = _content_field_invoke_default('view', $node, $teaser, $page);
+ $node->content = array_merge((array) $node->content, $additions);
+}
+
+/**
+ * Render a single field, fully themed with label and multiple values.
+ *
+ * To be used by third-party code (Views, Panels...) that needs to output
+ * an isolated field. Do *not* use inside node templates, use the
+ * $FIELD_NAME_rendered variables instead.
+ *
+ * By default, the field is displayed using the settings defined for the
+ * 'full node' or 'teaser' contexts (depending on the value of the $teaser param).
+ * Set $node->build_mode to a different value to use a different context.
+ *
+ * Different settings can be specified by adjusting $field['display_settings'].
+ *
+ * @param $field
+ * The field definition.
+ * @param $node
+ * The node containing the field to display. Can be a 'pseudo-node', containing
+ * at least 'type', 'nid', 'vid', and the field data.
+ * @param $teaser
+ * @param $page
+ * Similar to hook_nodeapi('view')
+ * @return
+ * The themed output for the field.
+ */
+function content_view_field($field, $node, $teaser = FALSE, $page = FALSE) {
+ $output = '';
+ if (isset($node->$field['field_name'])) {
+ $items = $node->$field['field_name'];
+
+ // Use 'full'/'teaser' if not specified otherwise.
+ $node->build_mode = isset($node->build_mode) ? $node->build_mode : NODE_BUILD_NORMAL;
+
+ // One-field equivalent to _content_field_invoke('sanitize').
+ $field_types = _content_field_types();
+ $module = $field_types[$field['type']]['module'];
+ $function = $module .'_field';
+ if (function_exists($function)) {
+ $function('sanitize', $node, $field, $items, $teaser, $page);
+ $node->$field['field_name'] = $items;
+ }
+
+ $view = content_field('view', $node, $field, $items, $teaser, $page);
+ // content_field('view') adds a wrapper to handle variables and 'excluded'
+ // fields for node templates. We bypass it and render the actual field.
+ $output = drupal_render($view[$field['field_name']]['field']);
+ }
+ return $output;
+}
+
+/**
+ * Implementation of hook_nodeapi 'alter' op.
+ *
+ * Add back the formatted values in the 'view' element for all fields,
+ * so that node templates can use it.
+ */
+function content_alter(&$node, $teaser = FALSE, $page = FALSE) {
+ _content_field_invoke_default('alter', $node, $teaser, $page);
+}
+
+/**
+ * Implementation of hook_nodeapi 'prepare translation' op.
+ *
+ * Generate field render arrays.
+ */
+function content_prepare_translation(&$node) {
+ $default_additions = _content_field_invoke_default('prepare translation', $node);
+ $additions = _content_field_invoke('prepare translation', $node);
+ // Merge module additions after the default ones to enable overriding
+ // of field values.
+ $node = (object) array_merge((array) $node, $default_additions, $additions);
+}
+
+/**
+ * Implementation of hook_nodeapi().
+ */
+function content_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+ // Prevent against invalid 'nodes' built by broken 3rd party code.
+ if (isset($node->type)) {
+ $type = content_types($node->type);
+ // Save cycles if the type has no CCK fields.
+ if (!empty($type['fields'])) {
+ $callback = 'content_'. str_replace(' ', '_', $op);
+ if (function_exists($callback)) {
+ $callback($node, $a3, $a4);
+ }
+ }
+
+ // Special case for 'view' op, we want to adjust weights of non-cck fields
+ // even if there are no actual fields for this type.
+ if ($op == 'view') {
+ $node->content['#pre_render'][] = 'content_alter_extra_weights';
+ $node->content['#content_extra_fields'] = $type['extra'];
+ }
+ }
+}
+
+/**
+ * Implementation of hook_form_alter().
+ */
+function content_form_alter(&$form, $form_state, $form_id) {
+ if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
+ $type = content_types($form['#node']->type);
+ if (!empty($type['fields'])) {
+ module_load_include('inc', 'content', 'includes/content.node_form');
+ // Merge field widgets.
+ $form = array_merge($form, content_form($form, $form_state));
+ }
+ $form['#pre_render'][] = 'content_alter_extra_weights';
+ $form['#content_extra_fields'] = $type['extra'];
+ }
+}
+
+/**
+ * Pre-render callback to adjust weights of non-CCK fields.
+ */
+function content_alter_extra_weights($elements) {
+ if (isset($elements['#content_extra_fields'])) {
+ foreach ($elements['#content_extra_fields'] as $key => $value) {
+ // Some core 'fields' use a different key in node forms and in 'view'
+ // render arrays. Check we're not on a form first.
+ if (!isset($elements['#build_id']) && isset($value['view']) && isset($elements[$value['view']])) {
+ $elements[$value['view']]['#weight'] = $value['weight'];
+ }
+ elseif (isset($elements[$key])) {
+ $elements[$key]['#weight'] = $value['weight'];
+ }
+ }
+ }
+ return $elements;
+}
+
+/**
+ * Proxy function to call content_add_more_submit(), because it might not be
+ * included yet when the form is processed and invokes the callback.
+ */
+function content_add_more_submit_proxy($form, &$form_state) {
+ module_load_include('inc', 'content', 'includes/content.node_form');
+ content_add_more_submit($form, $form_state);
+}
+
+/**
+ * Theme an individual form element.
+ *
+ * Combine multiple values into a table with drag-n-drop reordering.
+ */
+function theme_content_multiple_values($element) {
+ $field_name = $element['#field_name'];
+ $field = content_fields($field_name);
+ $output = '';
+
+ if ($field['multiple'] >= 1) {
+ $table_id = $element['#field_name'] .'_values';
+ $order_class = $element['#field_name'] .'-delta-order';
+ $required = !empty($element['#required']) ? '*' : '';
+
+ $header = array(
+ array(
+ 'data' => t('!title: !required', array('!title' => $element['#title'], '!required' => $required)),
+ 'colspan' => 2
+ ),
+ t('Order'),
+ );
+ $rows = array();
+
+ // Sort items according to '_weight' (needed when the form comes back after
+ // preview or failed validation)
+ $items = array();
+ foreach (element_children($element) as $key) {
+ if ($key !== $element['#field_name'] .'_add_more') {
+ $items[] = &$element[$key];
+ }
+ }
+ usort($items, '_content_sort_items_value_helper');
+
+ // Add the items as table rows.
+ foreach ($items as $key => $item) {
+ $item['_weight']['#attributes']['class'] = $order_class;
+ $delta_element = drupal_render($item['_weight']);
+ $cells = array(
+ array('data' => '', 'class' => 'content-multiple-drag'),
+ drupal_render($item),
+ array('data' => $delta_element, 'class' => 'delta-order'),
+ );
+ $rows[] = array(
+ 'data' => $cells,
+ 'class' => 'draggable',
+ );
+ }
+
+ $output .= theme('table', $header, $rows, array('id' => $table_id, 'class' => 'content-multiple-table'));
+ $output .= $element['#description'] ? '
'. $element['#description'] .'
' : '';
+ $output .= drupal_render($element[$element['#field_name'] .'_add_more']);
+
+ drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class);
+ }
+ else {
+ foreach (element_children($element) as $key) {
+ $output .= drupal_render($element[$key]);
+ }
+ }
+
+ return $output;
+}
+
+/**
+ * Modules notify Content module when uninstalled, disabled, etc.
+ *
+ * @param string $op
+ * the module operation: uninstall, install, enable, disable
+ * @param string $module
+ * the name of the affected module.
+ * @TODO
+ * figure out exactly what needs to be done by content module when
+ * field modules are installed, uninstalled, enabled or disabled.
+ */
+function content_notify($op, $module) {
+ switch ($op) {
+ case 'install':
+ content_clear_type_cache();
+ break;
+ case 'uninstall':
+ module_load_include('inc', 'content', 'includes/content.crud');
+ content_module_delete($module);
+ break;
+ case 'enable':
+ content_associate_fields($module);
+ content_clear_type_cache();
+ break;
+ case 'disable':
+ // When CCK modules are disabled before content module's update is run
+ // to add the active column, we can't do this.
+ if (variable_get('content_schema_version', -1) < 6007) {
+ return FALSE;
+ }
+ db_query("UPDATE {". content_field_tablename() ."} SET active=0 WHERE module='%s'", $module);
+ db_query("UPDATE {". content_instance_tablename() ."} SET widget_active=0 WHERE widget_module='%s'", $module);
+ content_clear_type_cache(TRUE);
+ break;
+ }
+}
+
+/**
+ * Allows a module to update the database for fields and columns it controls.
+ *
+ * @param string $module
+ * The name of the module to update on.
+ */
+function content_associate_fields($module) {
+ // When CCK modules are enabled before content module's update is run,
+ // to add module and active columns, we can't do this.
+ if (variable_get('content_schema_version', -1) < 6007) {
+ return FALSE;
+ }
+ $module_fields = module_invoke($module, 'field_info');
+ if ($module_fields) {
+ foreach ($module_fields as $name => $field_info) {
+ watchdog('content', 'Updating field type %type with module %module.', array('%type' => $name, '%module' => $module));
+ db_query("UPDATE {". content_field_tablename() ."} SET module = '%s', active = %d WHERE type = '%s'", $module, 1, $name);
+ }
+ }
+ $module_widgets = module_invoke($module, 'widget_info');
+ if ($module_widgets) {
+ foreach ($module_widgets as $name => $widget_info) {
+ watchdog('content', 'Updating widget type %type with module %module.', array('%type' => $name, '%module' => $module));
+ db_query("UPDATE {". content_instance_tablename() ."} SET widget_module = '%s', widget_active = %d WHERE widget_type = '%s'", $module, 1, $name);
+ }
+ }
+ // This is called from updates and installs, so get the install-safe
+ // version of a fields array.
+ $fields_set = array();
+ module_load_include('install', 'content');
+ $types = content_types_install();
+ foreach ($types as $type_name => $fields) {
+ foreach ($fields as $field) {
+ if ($field['module'] == $module && !in_array($field['field_name'], $fields_set)) {
+ $columns = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);
+ db_query("UPDATE {". content_field_tablename() ."} SET db_columns = '%s' WHERE field_name = '%s'", serialize($columns), $field['field_name']);
+ $fields_set[] = $field['field_name'];
+ }
+ }
+ }
+}
+
+/**
+ * Implementation of hook_field(). Handles common field housekeeping.
+ *
+ * This implementation is special, as content.module does not define any field
+ * types. Instead, this function gets called after the type-specific hook, and
+ * takes care of default stuff common to all field types.
+ *
+ * Db-storage ops ('load', 'insert', 'update', 'delete', 'delete revisions')
+ * are not executed field by field, and are thus handled separately in
+ * content_storage.
+ *
+ * The 'view' operation constructs the $node in a way that you can use
+ * drupal_render() to display the formatted output for an individual field.
+ * i.e. print drupal_render($node->countent['field_foo']);
+ *
+ * The code now supports both single value formatters, which theme an
+ * individual item value as has been done in previous version of CCK,
+ * and multiple value formatters, which theme all values for the field
+ * in a single theme. The multiple value formatters could be used, for
+ * instance, to plot field values on a single map or display them
+ * in a graph. Single value formatters are the default, multiple value
+ * formatters can be designated as such in formatter_info().
+ *
+ * The node array will look like:
+ * $node->content['field_foo']['wrapper'] = array(
+ * '#type' => 'content_field',
+ * '#title' => 'label'
+ * '#field_name' => 'field_name',
+ * '#node' => $node,
+ * // Value of the $teaser param of hook_nodeapi('view').
+ * '#teaser' => $teaser,
+ * // Value of the $page param of hook_nodeapi('view').
+ * '#page' => $page,
+ * // The curent rendering context ('teaser', 'full', NODE_BUILD_SEARCH_INDEX...).
+ * '#context' => $context,
+ * 'items' =>
+ * 0 => array(
+ * '#item' => $items[0],
+ * // Only for 'single-value' formatters
+ * '#theme' => $theme,
+ * '#field_name' => 'field_name',
+ * '#type_name' => $node->type,
+ * '#formatter' => $formatter_name,
+ * '#node' => $node,
+ * '#delta' => 0,
+ * ),
+ * 1 => array(
+ * '#item' => $items[1],
+ * // Only for 'single-value' formatters
+ * '#theme' => $theme,
+ * '#field_name' => 'field_name',
+ * '#type_name' => $node->type,
+ * '#formatter' => $formatter_name,
+ * '#node' => $node,
+ * '#delta' => 1,
+ * ),
+ * // Only for 'multiple-value' formatters
+ * '#theme' => $theme,
+ * '#field_name' => 'field_name',
+ * '#type_name' => $node->type,
+ * '#formatter' => $formatter_name,
+ * ),
+ * );
+ */
+function content_field($op, &$node, $field, &$items, $teaser, $page) {
+ switch ($op) {
+ case 'validate':
+ // TODO: here we could validate that the number of multiple data is correct ?
+ // We're controlling the number of fields to fill out and saving empty
+ // ones if a specified number is requested, so no reason to do any validation
+ // here right now, but if later create a method to indicate whether
+ // 'required' means all values must be filled out, we can come back
+ // here and check that they're not empty.
+ break;
+
+ case 'presave':
+ if (!empty($node->devel_generate)) {
+ include_once('./'. drupal_get_path('module', 'content') .'/includes/content.devel.inc');
+ content_generate_fields($node, $field);
+ $items = $node->{$field['field_name']};
+ }
+
+ // Manual node_save calls might not have all fields filled in.
+ // On node insert, we need to make sure all tables get at least an empty
+ // record, or subsequent edits, using drupal_write_record() in update mode,
+ // won't insert any data.
+ // Missing fields on node update are handled in content_storage().
+ if (empty($items) && !isset($node->nid)) {
+ foreach (array_keys($field['columns']) as $column) {
+ $items[0][$column] = NULL;
+ }
+ $node->$field['field_name'] = $items;
+ }
+
+ // If there was an AHAH add more button in this field, don't save it.
+ // TODO: is it still needed ?
+ unset($items[$field['field_name'] .'_add_more']);
+
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
+ // Reorder items to account for drag-n-drop reordering.
+ $items = _content_sort_items($field, $items);
+ }
+
+ // Filter out empty values.
+ $items = content_set_empty($field, $items);
+
+ break;
+
+ case 'view':
+ $addition = array();
+
+ // Previewed nodes bypass the 'presave' op, so we need to some massaging.
+ if ($node->build_mode == NODE_BUILD_PREVIEW && content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
+ // Reorder items to account for drag-n-drop reordering.
+ $items = _content_sort_items($field, $items);
+ }
+
+ // Filter out empty values.
+ $items = content_set_empty($field, $items);
+ }
+
+ // NODE_BUILD_NORMAL is 0, and ('whatever' == 0) is TRUE, so we need a ===.
+ if ($node->build_mode === NODE_BUILD_NORMAL || $node->build_mode == NODE_BUILD_PREVIEW) {
+ $context = $teaser ? 'teaser' : 'full';
+ }
+ else {
+ $context = $node->build_mode;
+ }
+ // The field may be missing info for $contexts added by modules
+ // enabled after the field was last edited.
+ $formatter_name = isset($field['display_settings'][$context]) && isset($field['display_settings'][$context]['format']) ? $field['display_settings'][$context]['format'] : 'default';
+ if ($formatter = _content_get_formatter($formatter_name, $field['type'])) {
+ $theme = $formatter['module'] .'_formatter_'. $formatter_name;
+ $single = (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE);
+
+ $label_display = isset($field['display_settings']['label']['format']) ? $field['display_settings']['label']['format'] : 'above';
+ // Do not include field labels when indexing content.
+ if ($context == NODE_BUILD_SEARCH_INDEX) {
+ $label_display = 'hidden';
+ }
+
+ $element = array(
+ '#type' => 'content_field',
+ '#title' => check_plain(t($field['widget']['label'])),
+ '#field_name' => $field['field_name'],
+ '#access' => $formatter_name != 'hidden' && content_access('view', $field, NULL, $node),
+ '#label_display' => $label_display,
+ '#node' => $node,
+ '#teaser' => $teaser,
+ '#page' => $page,
+ '#context' => $context,
+ '#single' => $single,
+ 'items' => array(),
+ );
+
+ // Fill-in items.
+ foreach ($items as $delta => $item) {
+ $element['items'][$delta] = array(
+ '#item' => $item,
+ '#weight' => $delta,
+ );
+ }
+
+ // Append formatter information either on each item ('single-value' formatter)
+ // or at the upper 'items' level ('multiple-value' formatter)
+ $format_info = array(
+ '#theme' => $theme,
+ '#field_name' => $field['field_name'],
+ '#type_name' => $node->type,
+ '#formatter' => $formatter_name,
+ '#node' => $node,
+ );
+ if ($single) {
+ foreach ($items as $delta => $item) {
+ $element['items'][$delta] += $format_info;
+ $element['items'][$delta]['#item']['#delta'] = $delta;
+ }
+ }
+ else {
+ $element['items'] += $format_info;
+ }
+
+ // The wrapper lets us get the themed output for the whole field
+ // to populate the $FIELD_NAME_rendered variable for node templates,
+ // and hide it from the $content variable if needed.
+ // See 'preprocess_node' op and theme_content_field_wrapper()?
+ $wrapper = array(
+ 'field' => $element,
+ '#weight' => $field['widget']['weight'],
+ '#post_render' => array('content_field_wrapper_post_render'),
+ '#field_name' => $field['field_name'],
+ '#type_name' => $node->type,
+ '#context' => $context,
+ );
+
+ $addition = array($field['field_name'] => $wrapper);
+ }
+ return $addition;
+
+ case 'alter':
+ // Add back the formatted values in the 'view' element,
+ // so that tokens and node templates can use it.
+ // Note: Doing this in 'preprocess_node' breaks token integration.
+
+ // The location of the field's rendered output depends on whether the
+ // field is in a fieldgroup or not.
+ $wrapper = NULL;
+ if (isset($node->content[$field['field_name']])) {
+ $wrapper = $node->content[$field['field_name']];
+ }
+ elseif (module_exists('fieldgroup') && ($group_name = fieldgroup_get_group($node->type, $field['field_name'])) && isset($node->content[$group_name]['group'][$field['field_name']])) {
+ $wrapper = $node->content[$group_name]['group'][$field['field_name']];
+ }
+
+ if ($wrapper) {
+ $element = $wrapper['field'];
+ // '#single' is not set if the field is hidden or inaccessible.
+ if (isset($element['#single'])) {
+ if (!empty($element['#single'])) {
+ // Single value formatter.
+ foreach (element_children($element['items']) as $delta) {
+ // '#chilren' is not set if the field is empty.
+ $items[$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : '';
+ }
+ }
+ elseif (isset($element['items']['#children'])) {
+ // Multiple values formatter.
+ $items[0]['view'] = $element['items']['#children'];
+ }
+ }
+ else {
+ // Hidden or inaccessible field.
+ $items[0]['view'] = '';
+ }
+ }
+ break;
+
+ case 'preprocess_node':
+ // Add $FIELD_NAME_rendered variables.
+ $addition = array();
+
+ // The location of the field's rendered output depends on whether the
+ // field is in a fieldgroup or not.
+ $wrapper = NULL;
+ if (isset($node->content[$field['field_name']])) {
+ $wrapper = $node->content[$field['field_name']];
+ }
+ elseif (module_exists('fieldgroup') && ($group_name = fieldgroup_get_group($node->type, $field['field_name'])) && isset($node->content[$group_name]['group'][$field['field_name']])) {
+ $wrapper = $node->content[$group_name]['group'][$field['field_name']];
+ }
+
+ if ($wrapper) {
+ // '#chilren' is not set if the field is empty.
+ $addition[$field['field_name'] .'_rendered'] = isset($wrapper['#children']) ? $wrapper['#children'] : '';
+ }
+
+ return $addition;
+
+ case 'prepare translation':
+ $addition = array();
+ if (isset($node->translation_source->$field['field_name'])) {
+ $addition[$field['field_name']] = $node->translation_source->$field['field_name'];
+ }
+ return $addition;
+ }
+}
+
+/**
+ * Helper function to filter out empty values.
+ *
+ * On order to keep marker rows in the database, the function ensures
+ * that the right number of 'all columns NULL' values is kept.
+ *
+ * @param array $field
+ * @param array $items
+ * @return array
+ * returns filtered and adjusted item array
+ */
+function content_set_empty($field, $items) {
+ // Filter out empty values.
+ $filtered = array();
+ $function = $field['module'] .'_content_is_empty';
+ foreach ((array) $items as $delta => $item) {
+ if (!$function($item, $field)) {
+ $filtered[] = $item;
+ }
+ }
+
+ // Make sure we store the right number of 'empty' values.
+ $empty = array();
+ foreach (array_keys($field['columns']) as $column) {
+ $empty[$column] = NULL;
+ }
+ $pad = $field['multiple'] > 1 ? $field['multiple'] : 1;
+ $filtered = array_pad($filtered, $pad, $empty);
+
+ return $filtered;
+}
+
+/**
+ * Helper function to sort items in a field according to
+ * user drag-n-drop reordering.
+ */
+function _content_sort_items($field, $items) {
+ if ($field['multiple'] >= 1 && isset($items[0]['_weight'])) {
+ usort($items, '_content_sort_items_helper');
+ foreach ($items as $delta => $item) {
+ if (is_array($items[$delta])) {
+ unset($items[$delta]['_weight']);
+ }
+ }
+ }
+ return $items;
+}
+
+/**
+ * Sort function for items order.
+ * (copied form element_sort(), which acts on #weight keys)
+ */
+function _content_sort_items_helper($a, $b) {
+ $a_weight = (is_array($a) && isset($a['_weight'])) ? $a['_weight'] : 0;
+ $b_weight = (is_array($b) && isset($b['_weight'])) ? $b['_weight'] : 0;
+ if ($a_weight == $b_weight) {
+ return 0;
+ }
+ return ($a_weight < $b_weight) ? -1 : 1;
+}
+
+/**
+ * Same as above, using ['_weight']['#value']
+ */
+function _content_sort_items_value_helper($a, $b) {
+ $a_weight = (is_array($a) && isset($a['_weight']['#value'])) ? $a['_weight']['#value'] : 0;
+ $b_weight = (is_array($b) && isset($b['_weight']['#value'])) ? $b['_weight']['#value'] : 0;
+ if ($a_weight == $b_weight) {
+ return 0;
+ }
+ return ($a_weight < $b_weight) ? -1 : 1;
+}
+
+/**
+ * Handle storage ops for _content_field_invoke_default().
+ */
+function content_storage($op, $node) {
+ // Don't try this before content module's update is run to add
+ // the active and module columns.
+ if (variable_get('content_schema_version', -1) < 6007) {
+ return FALSE;
+ }
+
+ $type_name = $node->type;
+ $type = content_types($type_name);
+
+ switch ($op) {
+ case 'load':
+ // OPTIMIZE: load all non multiple fields in a single JOIN query ?
+ // warning: 61-join limit in MySQL ?
+ $additions = array();
+ // For each table used by this content type,
+ foreach ($type['tables'] as $table) {
+ $schema = drupal_get_schema($table);
+ // The per-type table might not have any fields actually stored in it.
+ if (!$schema['content fields']) {
+ continue;
+ }
+ $query = 'SELECT * FROM {'. $table .'} WHERE vid = %d';
+
+ // If we're loading a table for a multiple field,
+ // we fetch all rows (values) ordered by delta,
+ // else we only fetch one row.
+ $result = isset($schema['fields']['delta']) ? db_query($query .' ORDER BY delta', $node->vid) : db_query_range($query, $node->vid, 0, 1);
+
+ // For each table row, populate the fields.
+ while ($row = db_fetch_array($result)) {
+ // For each field stored in the table, add the field item.
+ foreach ($schema['content fields'] as $field_name) {
+ $item = array();
+ $field = content_fields($field_name, $type_name);
+ $db_info = content_database_info($field);
+ // For each column declared by the field, populate the item.
+ foreach ($db_info['columns'] as $column => $attributes) {
+ $item[$column] = $row[$attributes['column']];
+ }
+
+ // Add the item to the field values for the node.
+ if (!isset($additions[$field_name])) {
+ $additions[$field_name] = array();
+ }
+ $additions[$field_name][] = $item;
+ }
+ }
+ }
+ return $additions;
+
+ case 'insert':
+ case 'update':
+ foreach ($type['tables'] as $table) {
+ $schema = drupal_get_schema($table);
+ $record = array();
+ foreach ($schema['content fields'] as $field_name) {
+ if (isset($node->$field_name)) {
+ $field = content_fields($field_name, $type_name);
+ // Multiple fields need specific handling, we'll deal with them later on.
+ if ($field['multiple']) {
+ continue;
+ }
+ $db_info = content_database_info($field);
+ foreach ($db_info['columns'] as $column => $attributes) {
+ $record[$attributes['column']] = $node->{$field_name}[0][$column];
+ }
+ }
+ }
+ // $record might be empty because
+ // - the table stores a multiple field :
+ // we do nothing, this is handled later on
+ // - this is the per-type table and no field is actually stored in it :
+ // we still store the nid and vid
+ if (count($record) || empty($schema['content fields'])) {
+ $record['nid'] = $node->nid;
+ $record['vid'] = $node->vid;
+ // Can't rely on the insert/update op of the node to decide if this
+ // is an insert or an update, a node or revision may have existed
+ // before any fields were created, so there may not be an entry here.
+
+ // TODO - should we auto create an entry for all existing nodes when
+ // fields are added to content types -- either a NULL value
+ // or the default value? May need to offer the user an option of
+ // how to handle that.
+ if (db_result(db_query("SELECT COUNT(*) FROM {". $table ."} WHERE vid = %d", $node->vid))) {
+ content_write_record($table, $record, array('vid'));
+ }
+ else {
+ content_write_record($table, $record);
+ }
+ }
+ }
+
+ // Handle multiple fields.
+ foreach ($type['fields'] as $field) {
+ if ($field['multiple'] && isset($node->$field['field_name'])) {
+ $db_info = content_database_info($field);
+ // Delete and insert, rather than update, in case a value was added.
+ if ($op == 'update') {
+ db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid);
+ }
+ foreach ($node->$field['field_name'] as $delta => $item) {
+ $record = array();
+ foreach ($db_info['columns'] as $column => $attributes) {
+ $record[$attributes['column']] = $item[$column];
+ }
+ $record['nid'] = $node->nid;
+ $record['vid'] = $node->vid;
+ $record['delta'] = $delta;
+ content_write_record($db_info['table'], $record);
+ }
+ }
+ }
+ break;
+
+ case 'delete':
+ foreach ($type['tables'] as $table) {
+ db_query('DELETE FROM {'. $table .'} WHERE nid = %d', $node->nid);
+ }
+ break;
+
+ case 'delete revision':
+ foreach ($type['tables'] as $table) {
+ db_query('DELETE FROM {'. $table .'} WHERE vid = %d', $node->vid);
+ }
+ break;
+ }
+}
+
+/**
+ * Save a record to the database based upon the schema.
+ *
+ * Directly copied from core's drupal_write_record, which can't update a
+ * column to NULL. See http://drupal.org/node/227677 and
+ * http://drupal.org/node/226264 for more details about that problem.
+ *
+ * TODO - get rid of this function and change references back to
+ * drupal_write_record() if the patch gets into core. Will need a method
+ * of protecting people on older versions, though.
+ *
+ * Default values are filled in for missing items, and 'serial' (auto increment)
+ * types are filled in with IDs.
+ *
+ * @param $table
+ * The name of the table; this must exist in schema API.
+ * @param $object
+ * The object to write. This is a reference, as defaults according to
+ * the schema may be filled in on the object, as well as ID on the serial
+ * type(s). Both array an object types may be passed.
+ * @param $update
+ * If this is an update, specify the primary keys' field names. It is the
+ * caller's responsibility to know if a record for this object already
+ * exists in the database. If there is only 1 key, you may pass a simple string.
+ * @return
+ * Failure to write a record will return FALSE. Otherwise SAVED_NEW or
+ * SAVED_UPDATED is returned depending on the operation performed. The
+ * $object parameter contains values for any serial fields defined by
+ * the $table. For example, $object->nid will be populated after inserting
+ * a new node.
+ */
+function content_write_record($table, &$object, $update = array()) {
+ // Standardize $update to an array.
+ if (is_string($update)) {
+ $update = array($update);
+ }
+
+ // Convert to an object if needed.
+ if (is_array($object)) {
+ $object = (object) $object;
+ $array = TRUE;
+ }
+ else {
+ $array = FALSE;
+ }
+
+ $schema = drupal_get_schema($table);
+ if (empty($schema)) {
+ return FALSE;
+ }
+
+ $fields = $defs = $values = $serials = $placeholders = array();
+
+ // Go through our schema, build SQL, and when inserting, fill in defaults for
+ // fields that are not set.
+ foreach ($schema['fields'] as $field => $info) {
+ // Special case -- skip serial types if we are updating.
+ if ($info['type'] == 'serial' && count($update)) {
+ continue;
+ }
+
+ // For inserts, populate defaults from Schema if not already provided
+ if (!isset($object->$field) && !count($update) && isset($info['default'])) {
+ $object->$field = $info['default'];
+ }
+
+ // Track serial fields so we can helpfully populate them after the query.
+ if ($info['type'] == 'serial') {
+ $serials[] = $field;
+ // Ignore values for serials when inserting data. Unsupported.
+ unset($object->$field);
+ }
+
+ // Build arrays for the fields, placeholders, and values in our query.
+ if (isset($object->$field) || array_key_exists($field, $object)) {
+ $fields[] = $field;
+ if (isset($object->$field)) {
+ $placeholders[] = db_type_placeholder($info['type']);
+
+ if (empty($info['serialize'])) {
+ $values[] = $object->$field;
+ }
+ else {
+ $values[] = serialize($object->$field);
+ }
+ }
+ else {
+ $placeholders[] = 'NULL';
+ }
+ }
+ }
+
+ // Build the SQL.
+ $query = '';
+ if (!count($update)) {
+ $query = "INSERT INTO {". $table ."} (". implode(', ', $fields) .') VALUES ('. implode(', ', $placeholders) .')';
+ $return = SAVED_NEW;
+ }
+ else {
+ $query = '';
+ foreach ($fields as $id => $field) {
+ if ($query) {
+ $query .= ', ';
+ }
+ $query .= $field .' = '. $placeholders[$id];
+ }
+
+ foreach ($update as $key) {
+ $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']);
+ $values[] = $object->$key;
+ }
+
+ $query = "UPDATE {". $table ."} SET $query WHERE ". implode(' AND ', $conditions);
+ $return = SAVED_UPDATED;
+ }
+
+ // Execute the SQL.
+ if (db_query($query, $values)) {
+ if ($serials) {
+ // Get last insert ids and fill them in.
+ foreach ($serials as $field) {
+ $object->$field = db_last_insert_id($table, $field);
+ }
+ }
+
+ // If we began with an array, convert back so we don't surprise the caller.
+ if ($array) {
+ $object = (array) $object;
+ }
+
+ return $return;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Invoke a field hook.
+ *
+ * For each operation, both this function and _content_field_invoke_default() are
+ * called so that the default database handling can occur.
+ */
+function _content_field_invoke($op, &$node, $teaser = NULL, $page = NULL) {
+ $type_name = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
+ $type = content_types($type_name);
+ $field_types = _content_field_types();
+
+ $return = array();
+ foreach ($type['fields'] as $field) {
+ $items = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
+
+ // Make sure AHAH 'add more' button isn't sent to the fields for processing.
+ unset($items[$field['field_name'] .'_add_more']);
+
+ $module = $field_types[$field['type']]['module'];
+ $function = $module .'_field';
+ if (function_exists($function)) {
+ $result = $function($op, $node, $field, $items, $teaser, $page);
+ if (is_array($result)) {
+ $return = array_merge($return, $result);
+ }
+ else if (isset($result)) {
+ $return[] = $result;
+ }
+ }
+ // test for values in $items in case modules added items on insert
+ if (isset($node->$field['field_name']) || count($items)) {
+ $node->$field['field_name'] = $items;
+ }
+ }
+ return $return;
+}
+
+/**
+ * Invoke content.module's version of a field hook.
+ */
+function _content_field_invoke_default($op, &$node, $teaser = NULL, $page = NULL) {
+ $type_name = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
+ $type = content_types($type_name);
+ $field_types = _content_field_types();
+
+ $return = array();
+ // The operations involving database queries are better off handled by table
+ // rather than by field.
+ if (in_array($op, array('load', 'insert', 'update', 'delete', 'delete revision'))) {
+ return content_storage($op, $node);
+ }
+ else {
+ foreach ($type['fields'] as $field) {
+ $items = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
+ $result = content_field($op, $node, $field, $items, $teaser, $page);
+ if (is_array($result)) {
+ $return = array_merge($return, $result);
+ }
+ else if (isset($result)) {
+ $return[] = $result;
+ }
+ if (isset($node->$field['field_name'])) {
+ $node->$field['field_name'] = $items;
+ }
+ }
+ }
+ return $return;
+}
+
+/**
+ * Return a list of all content types.
+ *
+ * @param $content_type_name
+ * If set, return information on just this type.
+ *
+ * Do some type checking and set up empty arrays for missing
+ * info to avoid foreach errors elsewhere in the code.
+ */
+function content_types($type_name = NULL) {
+ // handle type name with either an underscore or a dash
+ $type_name = !empty($type_name) ? str_replace('-', '_', $type_name) : NULL;
+
+ $info = _content_type_info();
+ if (isset($info['content types'])) {
+ if (!isset($type_name)) {
+ return $info['content types'];
+ }
+ if (isset($info['content types'][$type_name])) {
+ return $info['content types'][$type_name];
+ }
+ }
+ return array('tables' => array(), 'fields' => array(), 'extra' => array());
+}
+
+/**
+ * Return a list of all fields.
+ *
+ * @param $field_name
+ * If not empty, return information on just this field.
+ * @param $content_type_name
+ * If not empty, return information of the field within the context of this content
+ * type.
+ *
+ * Be sure to check empty() instead of isset() on field_name and
+ * content_type_name to avoid bad results when the value is set
+ * but empty, as sometimes happens in the formatter.
+ */
+function content_fields($field_name = NULL, $content_type_name = NULL) {
+ $info = _content_type_info();
+ if (isset($info['fields'])) {
+ if (empty($field_name)) {
+ return $info['fields'];
+ }
+ if (isset($info['fields'][$field_name])) {
+ if (empty($content_type_name)) {
+ return $info['fields'][$field_name];
+ }
+ if (isset($info['content types'][$content_type_name]['fields'][$field_name])) {
+ return $info['content types'][$content_type_name]['fields'][$field_name];
+ }
+ }
+ }
+}
+
+/**
+ * Return a list of field types.
+ */
+function _content_field_types() {
+ $info = _content_type_info();
+ return isset($info['field types']) ? $info['field types'] : array();
+}
+
+/**
+ * Return a list of widget types.
+ */
+function _content_widget_types() {
+ $info = _content_type_info();
+ return isset($info['widget types']) ? $info['widget types'] : array();
+}
+
+/**
+ * Return the formatter description corresponding to a formatter name,
+ * defaulting to 'default' if none is found.
+ */
+function _content_get_formatter($formatter_name, $field_type) {
+ $field_types = _content_field_types();
+ $formatters = $field_types[$field_type]['formatters'];
+
+ if (!isset($formatters[$formatter_name]) && $formatter_name != 'hidden') {
+ // This might happen when the selected formatter has been renamed in the
+ // module, or if the module has been disabled since then.
+ $formatter_name = 'default';
+ }
+
+ return isset($formatters[$formatter_name]) ? $formatters[$formatter_name] : FALSE;
+}
+
+/**
+ * Collate all information on content types, fields, and related structures.
+ *
+ * @param $reset
+ * If TRUE, clear the cache and fetch the information from the database again.
+ */
+function _content_type_info($reset = FALSE) {
+ global $language;
+ static $info;
+
+ if ($reset || !isset($info)) {
+ // Make sure this function doesn't run until the tables have been created,
+ // For instance: when first enabled and called from content_menu(),
+ // or when uninstalled and some subsequent field module uninstall
+ // attempts to refresh the data.
+
+ // Don't try this before content module's update is run
+ // to add module and active columns to the table.
+ if (variable_get('content_schema_version', -1) < 6007) {
+ return array();
+ }
+
+ if (!$reset && $cached = cache_get('content_type_info:'. $language->language, content_cache_tablename())) {
+ $info = $cached->data;
+ }
+ else {
+ $info = array(
+ 'field types' => array(),
+ 'widget types' => array(),
+ 'fields' => array(),
+ 'content types' => array(),
+ );
+
+ // Populate field types.
+ foreach (module_list() as $module) {
+ $module_field_types = module_invoke($module, 'field_info');
+ if ($module_field_types) {
+ foreach ($module_field_types as $name => $field_info) {
+ // Truncate names to match the value that is stored in the database.
+ $db_name = substr($name, 0, 32);
+ $info['field types'][$db_name] = $field_info;
+ $info['field types'][$db_name]['module'] = $module;
+ $info['field types'][$db_name]['formatters'] = array();
+ }
+ }
+ }
+
+ // Populate widget types and formatters for known field types.
+ foreach (module_list() as $module) {
+ if ($module_widgets = module_invoke($module, 'widget_info')) {
+ foreach ($module_widgets as $name => $widget_info) {
+ // Truncate names to match the value that is stored in the database.
+ $db_name = substr($name, 0, 32);
+ $info['widget types'][$db_name] = $widget_info;
+ $info['widget types'][$db_name]['module'] = $module;
+ // Replace field types with db_compatible version of known field types.
+ $info['widget types'][$db_name]['field types'] = array();
+ foreach ($widget_info['field types'] as $field_type) {
+ $field_type_db_name = substr($field_type, 0, 32);
+ if (isset($info['field types'][$field_type_db_name])) {
+ $info['widget types'][$db_name]['field types'][] = $field_type_db_name;
+ }
+ }
+ }
+ }
+
+ if ($module_formatters = module_invoke($module, 'field_formatter_info')) {
+ foreach ($module_formatters as $name => $formatter_info) {
+ foreach ($formatter_info['field types'] as $field_type) {
+ // Truncate names to match the value that is stored in the database.
+ $db_name = substr($field_type, 0, 32);
+ if (isset($info['field types'][$db_name])) {
+ $info['field types'][$db_name]['formatters'][$name] = $formatter_info;
+ $info['field types'][$db_name]['formatters'][$name]['module'] = $module;
+ }
+ }
+ }
+ }
+ }
+
+ // Populate actual field instances.
+ module_load_include('inc', 'content', 'includes/content.crud');
+ foreach (node_get_types('types', NULL, TRUE) as $type_name => $data) {
+ $type = (array) $data;
+ $type['url_str'] = str_replace('_', '-', $type['type']);
+ $type['fields'] = array();
+ $type['tables'] = array();
+ if ($fields = content_field_instance_read(array('type_name' => $type_name))) {
+ foreach ($fields as $field) {
+ $db_info = content_database_info($field);
+ $type['tables'][$db_info['table']] = $db_info['table'];
+
+ // Allow external modules to translate field strings.
+ $field_strings = array(
+ 'widget_label' => $field['widget']['label'],
+ 'widget_description' => $field['widget']['description'],
+ );
+ drupal_alter('content_field_strings', $field_strings, $field['type_name'], $field['field_name']);
+ $field['widget']['label'] = $field_strings['widget_label'];
+ $field['widget']['description'] = $field_strings['widget_description'];
+
+ $type['fields'][$field['field_name']] = $field;
+ // This means that content_fields($field_name) (no type name)
+ // returns the last instance loaded.
+ $info['fields'][$field['field_name']] = $field;
+ }
+ // Make sure the per-type table is added, even if no field is actually
+ // stored in it.
+ $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ $type['tables'][$table] = $table;
+ }
+
+ // Gather information about non-CCK 'fields'.
+ $extra = module_invoke_all('content_extra_fields', $type_name);
+ drupal_alter('content_extra_fields', $extra, $type_name);
+ // Add saved weights.
+ foreach (variable_get('content_extra_weights_'. $type_name, array()) as $key => $value) {
+ // Some stored entries might not exist anymore, for instance if uploads
+ // have been disabled, or vocabularies removed...
+ if (isset($extra[$key])) {
+ $extra[$key]['weight'] = $value;
+ }
+ }
+ $type['extra'] = $extra;
+
+ $info['content types'][$type_name] = $type;
+ }
+
+ cache_set('content_type_info:'. $language->language, $info, content_cache_tablename());
+ }
+ }
+ return $info;
+}
+
+/**
+ * Implementation of hook_node_type()
+ * React to change in node types
+ */
+function content_node_type($op, $info) {
+ switch ($op) {
+ case 'insert':
+ module_load_include('inc', 'content', 'includes/content.crud');
+ content_type_create($info);
+ break;
+ case 'update':
+ module_load_include('inc', 'content', 'includes/content.crud');
+ content_type_update($info);
+ break;
+ case 'delete':
+ module_load_include('inc', 'content', 'includes/content.crud');
+ content_type_delete($info);
+ break;
+ }
+}
+
+/**
+ * Clear the cache of content_types; called in several places when content
+ * information is changed.
+ */
+function content_clear_type_cache($rebuild_schema = FALSE) {
+ cache_clear_all('*', content_cache_tablename(), TRUE);
+ _content_type_info(TRUE);
+
+ // Refresh the schema to pick up new information.
+ if ($rebuild_schema) {
+ $schema = drupal_get_schema(NULL, TRUE);
+ }
+
+ if (module_exists('views')) {
+ // Needed because this can be called from .install files
+ module_load_include('module', 'views');
+ views_invalidate_cache();
+ }
+}
+
+/**
+ * Retrieve the database storage location(s) for a field.
+ *
+ * TODO: add a word about why it's not included in the global _content_type_info array.
+ *
+ * @param $field
+ * The field whose database information is requested.
+ * @return
+ * An array with the keys:
+ * "table": The name of the database table where the field data is stored.
+ * "columns": An array of columns stored for this field. Each is a collection
+ * of information returned from hook_field_settings('database columns'),
+ * with the addition of a "column" attribute which holds the name of the
+ * database column that stores the data.
+ */
+function content_database_info($field) {
+ $db_info = array();
+ if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
+ $db_info['table'] = _content_tablename($field['field_name'], CONTENT_DB_STORAGE_PER_FIELD);
+ }
+ else {
+ $db_info['table'] = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ }
+
+ $db_info['columns'] = (array) $field['columns'];
+ // Generate column names for this field from generic column names.
+ foreach ($db_info['columns'] as $column_name => $attributes) {
+ $db_info['columns'][$column_name]['column'] = $field['field_name'] .'_'. $column_name;
+ }
+
+ return $db_info;
+}
+
+/**
+ * Helper function for identifying the storage type for a field.
+ */
+function content_storage_type($field) {
+ if ($field['multiple'] > 0) {
+ return CONTENT_DB_STORAGE_PER_FIELD;
+ }
+ else {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $instances = content_field_instance_read(array('field_name' => $field['field_name']));
+ if (count($instances) > 1) {
+ return CONTENT_DB_STORAGE_PER_FIELD;
+ }
+ }
+ return CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
+}
+
+/**
+ * Manipulate a 2D array to reverse rows and columns.
+ *
+ * The default data storage for fields is delta first, column names second.
+ * This is sometimes inconvenient for field modules, so this function can be
+ * used to present the data in an alternate format.
+ *
+ * @param $array
+ * The array to be transposed. It must be at least two-dimensional, and
+ * the subarrays must all have the same keys or behavior is undefined.
+ * @return
+ * The transposed array.
+ */
+function content_transpose_array_rows_cols($array) {
+ $result = array();
+ if (is_array($array)) {
+ foreach ($array as $key1 => $value1) {
+ if (is_array($value1)) {
+ foreach ($value1 as $key2 => $value2) {
+ if (!isset($result[$key2])) {
+ $result[$key2] = array();
+ }
+ $result[$key2][$key1] = $value2;
+ }
+ }
+ }
+ }
+ return $result;
+}
+
+/**
+ * Helper function to flatten an array of allowed values.
+ *
+ * @param $array
+ * A single or multidimensional array.
+ * @return
+ * A flattened array.
+ */
+function content_array_flatten($array) {
+ $result = array();
+ if (is_array($array)) {
+ foreach ($array as $key => $value) {
+ if (is_array($value)) {
+ $result += content_array_flatten($value);
+ }
+ else {
+ $result[$key] = $value;
+ }
+ }
+ }
+ return $result;
+}
+
+/**
+ * Create an array of the allowed values for this field.
+ *
+ * Used by number and text fields, expects to find either
+ * PHP code that will return the correct value, or a string
+ * with keys and labels separated with '|' and with each
+ * new value on its own line.
+ *
+ * @param $field
+ * The field whose allowed values are requested.
+ * @param $flatten
+ * Optional. Use TRUE to return a flattened array (default).
+ * FALSE can be used to support optgroups for select widgets
+ * when allowed values list is generated using PHP code.
+ */
+function content_allowed_values($field, $flatten = TRUE) {
+ static $allowed_values;
+
+ $cid = $field['field_name'] .':'. ($flatten ? '1' : '0');
+ if (isset($allowed_values[$cid])) {
+ return $allowed_values[$cid];
+ }
+
+ $allowed_values[$cid] = array();
+
+ if (isset($field['allowed_values_php'])) {
+ ob_start();
+ $result = eval($field['allowed_values_php']);
+ if (is_array($result)) {
+ if ($flatten) {
+ $result = content_array_flatten($result);
+ }
+ $allowed_values[$cid] = $result;
+ }
+ ob_end_clean();
+ }
+
+ if (empty($allowed_values[$cid]) && isset($field['allowed_values'])) {
+ $list = explode("\n", $field['allowed_values']);
+ $list = array_map('trim', $list);
+ $list = array_filter($list, 'strlen');
+ foreach ($list as $opt) {
+ // Sanitize the user input with a permissive filter.
+ $opt = content_filter_xss($opt);
+ if (strpos($opt, '|') !== FALSE) {
+ list($key, $value) = explode('|', $opt);
+ $allowed_values[$cid][$key] = (isset($value) && $value !=='') ? $value : $key;
+ }
+ else {
+ $allowed_values[$cid][$opt] = $opt;
+ }
+ }
+ // Allow external modules to translate allowed values list.
+ drupal_alter('content_allowed_values', $allowed_values[$cid], $field);
+ }
+ return $allowed_values[$cid];
+}
+
+/**
+ * Filter out HTML from allowed values array while leaving entities unencoded.
+ *
+ * @see content_allowed_values()
+ * @see optionwidgets_select_process()
+ * @see content_handler_filter_many_to_one::allowed_values()
+ */
+function content_allowed_values_filter_html(&$options) {
+ foreach ($options as $key => $opt) {
+ if (is_array($opt)) {
+ content_allowed_values_filter_html($options[$key]);
+ }
+ else {
+ $options[$key] = html_entity_decode(strip_tags($opt), ENT_QUOTES);
+ }
+ }
+}
+
+/**
+ * Like filter_xss_admin(), but with a shorter list of allowed tags.
+ *
+ * Used for items entered by administrators, like field descriptions,
+ * allowed values, where some (mainly inline) mark-up may be desired
+ * (so check_plain() is not acceptable).
+ */
+function content_filter_xss($string) {
+ return filter_xss($string, _content_filter_xss_allowed_tags());
+}
+
+/**
+ * List of tags allowed by content_filter_xss().
+ */
+function _content_filter_xss_allowed_tags() {
+ return array('a', 'b', 'big', 'code', 'del', 'em', 'i', 'ins', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ol', 'ul', 'li', 'p', 'br', 'img');
+}
+
+/**
+ * Human-readable list of allowed tags, for display in help texts.
+ */
+function _content_filter_xss_display_allowed_tags() {
+ return '<'. implode('> <', _content_filter_xss_allowed_tags()) .'>';
+}
+
+/**
+ * Format a field item for display.
+ *
+ * Used to display a field's values outside the context of the $node, as
+ * when fields are displayed in Views, or to display a field in a template
+ * using a different formatter than the one set up on the Display Fields tab
+ * for the node's context.
+ *
+ * @param $field
+ * Either a field array or the name of the field.
+ * @param $item
+ * The field item(s) to be formatted (such as $node->field_foo[0],
+ * or $node->field_foo if the formatter handles multiple values itself)
+ * @param $formatter_name
+ * The name of the formatter to use.
+ * @param $node
+ * Optionally, the containing node object for context purposes and
+ * field-instance options.
+ *
+ * @return
+ * A string containing the contents of the field item(s) sanitized for display.
+ * It will have been passed through the necessary check_plain() or check_markup()
+ * functions as necessary.
+ */
+function content_format($field, $item, $formatter_name = 'default', $node = NULL) {
+ if (!is_array($field)) {
+ $field = content_fields($field);
+ }
+
+ if (content_access('view', $field, NULL, $node) && $formatter = _content_get_formatter($formatter_name, $field['type'])) {
+ $theme = $formatter['module'] .'_formatter_'. $formatter_name;
+
+ $element = array(
+ '#theme' => $theme,
+ '#field_name' => $field['field_name'],
+ '#type_name' => isset($node->type) ? $node->type :'',
+ '#formatter' => $formatter_name,
+ '#node' => $node,
+ '#delta' => isset($item['#delta']) ? $item['#delta'] : NULL,
+ );
+
+ if (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE) {
+ // Single value formatter.
+
+ // hook_field('sanitize') expects an array of items, so we build one.
+ $items = array($item);
+ $function = $field['module'] .'_field';
+ if (function_exists($function)) {
+ $function('sanitize', $node, $field, $items, FALSE, FALSE);
+ }
+
+ $element['#item'] = $items[0];
+ }
+ else {
+ // Multiple values formatter.
+ $items = $item;
+ $function = $field['module'] .'_field';
+ if (function_exists($function)) {
+ $function('sanitize', $node, $field, $items, FALSE, FALSE);
+ }
+
+ foreach ($items as $delta => $item) {
+ $element[$delta] = array(
+ '#item' => $item,
+ '#weight' => $delta,
+ );
+ }
+ }
+
+ return theme($theme, $element);
+ }
+}
+
+/**
+ * Registry of available node build modes.
+ *
+ * @param $selector
+ * Determines what information should be returned.
+ * @return
+ * Depending on the value of the $selector parameter:
+ * - NULL: a flat list of all available build modes.
+ * The other two options are mainly used internally by CCK's UI:
+ * - '_tabs': the list of tabs to be shown on the 'Display fields' screens.
+ * - a string tab id: the build modes in this tab.
+ */
+function content_build_modes($selector = NULL) {
+ static $info;
+
+ if (!isset($info)) {
+ $data = array();
+ foreach (module_implements('content_build_modes') as $module) {
+ $function = $module .'_content_build_modes';
+ $data = array_merge($data, (array) $function());
+ }
+ $flat = array();
+ foreach ($data as $tab) {
+ // Use the + operator to preserve numeric indexes (core build modes).
+ $flat += (array) $tab['build modes'];
+ }
+ $info = array('tabs' => $data, 'build modes' => $flat);
+ }
+
+ if ($selector === '_tabs') {
+ return $info['tabs'];
+ }
+ elseif (isset($selector) && isset($info['tabs'][$selector])) {
+ return isset($info['tabs'][$selector]) ? $info['tabs'][$selector]['build modes'] : array();
+ }
+ else {
+ return $info['build modes'];
+ }
+}
+
+/**
+ * Implementations of hook_content_build_modes
+ * on behalf of core modules.
+ *
+ * @return
+ * An array describing the build modes used by the module.
+ * They are grouped by secondary tabs on CCK's 'Display fields' screens.
+ *
+ * Expected format:
+ * array(
+ * // The first level keys (tab1_url, tab2_url) will be used to generate
+ * // the url of the tab: admin/content/node-type/[type_name]/display/[tab1_url]
+ * // A module can add its render modes to a tab defined by another module.
+ * // In this case, there's no need to provide a 'title' for this tab.
+ * 'tab1_url' => array(
+ * 'title' => t('The human-readable title of the tab'),
+ * 'build modes' => array(
+ * // The keys of the 'context' array are the values used in $node->build_mode.
+ * 'mymodule_mode1' => array(
+ * 'title' => t('The human-readable name of the build mode'),
+ * // The 'views style' property determines if the render mode should be
+ * // available as an option in Views' 'node' row style (not implemented yet).
+ * 'views style' => TRUE,
+ * ),
+ * 'mymodule_mode2' => array(
+ * 'title' => t('Mode 2'),
+ * 'views style' => TRUE,
+ * ),
+ * ),
+ * ),
+ * 'tab2_url' => array(
+ * // ...
+ * ),
+ * );
+ */
+function node_content_build_modes() {
+ return array(
+ 'basic' => array(
+ 'title' => t('Basic'),
+ 'build modes' => array(
+ 'teaser' => array(
+ 'title' => t('Teaser'),
+ 'views style' => TRUE,
+ ),
+ 'full' => array(
+ 'title' => t('Full node'),
+ 'views style' => TRUE,
+ ),
+ ),
+ ),
+ 'rss' => array(
+ 'title' => t('RSS'),
+ 'build modes' => array(
+ NODE_BUILD_RSS => array(
+ 'title' => t('RSS'),
+ 'views style' => FALSE,
+ ),
+ ),
+ ),
+ );
+}
+function search_content_build_modes() {
+ return array(
+ 'search' => array(
+ 'title' => t('Search'),
+ 'build modes' => array(
+ NODE_BUILD_SEARCH_INDEX => array(
+ 'title' => t('Search Index'),
+ 'views style' => FALSE,
+ ),
+ NODE_BUILD_SEARCH_RESULT => array(
+ 'title' => t('Search Result'),
+ 'views style' => FALSE,
+ ),
+ ),
+ ),
+ );
+}
+function book_content_build_modes() {
+ return array(
+ 'print' => array(
+ 'title' => t('Print'),
+ 'build modes' => array(
+ NODE_BUILD_PRINT => array(
+ 'title' => t('Print'),
+ 'views style' => TRUE,
+ ),
+ ),
+ ),
+ );
+}
+
+/**
+ * Generate a table name for a field or a content type.
+ *
+ * @param $name
+ * The name of the content type or content field
+ * @param $storage
+ * CONTENT_DB_STORAGE_PER_FIELD or CONTENT_DB_STORAGE_PER_CONTENT_TYPE
+ * @return
+ * A string containing the generated name for the database table
+ */
+function _content_tablename($name, $storage, $version = NULL) {
+ if (is_null($version)) {
+ $version = variable_get('content_schema_version', 0);
+ }
+
+ if ($version < 1003) {
+ $version = 0;
+ }
+ else {
+ $version = 1003;
+ }
+
+ $name = str_replace('-', '_', $name);
+ switch ("$version-$storage") {
+ case '0-'. CONTENT_DB_STORAGE_PER_CONTENT_TYPE :
+ return "node_$name";
+ case '0-'. CONTENT_DB_STORAGE_PER_FIELD :
+ return "node_data_$name";
+ case '1003-'. CONTENT_DB_STORAGE_PER_CONTENT_TYPE :
+ return "content_type_$name";
+ case '1003-'. CONTENT_DB_STORAGE_PER_FIELD :
+ return "content_$name";
+ }
+}
+
+/**
+ * Generate table name for the content field table.
+ *
+ * Needed because the table name changes depending on version.
+ * Using 'content_node_field' instead of 'content_field'
+ * to avoid conflicts with field tables that will be prefixed
+ * with 'content_field'.
+ */
+function content_field_tablename($version = NULL) {
+ if (is_null($version)) {
+ $version = variable_get('content_schema_version', 0);
+ }
+ return $version < 6001 ? 'node_field' : 'content_node_field';
+}
+
+/**
+ * Generate table name for the content field instance table.
+ *
+ * Needed because the table name changes depending on version.
+ */
+function content_instance_tablename($version = NULL) {
+ if (is_null($version)) {
+ $version = variable_get('content_schema_version', 0);
+ }
+ return $version < 6001 ? 'node_field_instance' : 'content_node_field_instance';
+}
+
+/**
+ * Generate table name for the content cache table.
+ *
+ * Needed because the table name changes depending on version. Because of
+ * a new database column, the content_cache table will be unusable until
+ * update 6000 runs, so the cache table will be used instead.
+ */
+function content_cache_tablename() {
+ if (variable_get('content_schema_version', -1) < 6000) {
+ return 'cache';
+ }
+ else {
+ return 'cache_content';
+ }
+}
+
+/**
+ * A basic schema used by all field and type tables.
+ *
+ * This will only add the columns relevant for the specified field.
+ * Leave $field['columns'] empty to get only the base schema,
+ * otherwise the function will return the whole thing.
+ */
+function content_table_schema($field = NULL) {
+ $schema = array(
+ 'fields' => array(
+ 'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+ 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)
+ ),
+ 'primary key' => array('vid'),
+ 'indexes' => array(
+ 'nid' => array('nid'),
+ ),
+ );
+
+ // Add delta column if needed.
+ if (!empty($field['multiple'])) {
+ $schema['fields']['delta'] = array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0);
+ $schema['primary key'][] = 'delta';
+ }
+ $schema['content fields'] = array();
+
+ // Add field columns column if needed.
+ // This function is called from install files where it is not safe
+ // to use content_fields() or content_database_info(), so we
+ // just used the column values stored in the $field.
+ // We also need the schema to include fields from disabled modules
+ // or there will be no way to delete those fields.
+
+ if (!empty($field['columns'])) {
+ foreach ($field['columns'] as $column => $attributes) {
+ $column_name = $field['field_name'] .'_'. $column;
+ if (isset($attributes['index']) && $attributes['index']) {
+ $schema['indexes'][$column_name] = array($column_name);
+ unset($attributes['index']);
+ }
+ unset($attributes['column']);
+ unset($attributes['sortable']);
+ $schema['fields'][$column_name] = $attributes;
+ }
+ $schema['content fields'][] = $field['field_name'];
+ }
+ return $schema;
+}
+
+/**
+ * Checks if an index exists.
+ *
+ * @todo: May we remove this funcion when implemented by Drupal core itself?
+ * @link http://drupal.org/node/360854
+ * @link http://dev.mysql.com/doc/refman/5.0/en/extended-show.html
+ *
+ * @param $table
+ * Name of the table.
+ * @param $name
+ * Name of the index.
+ * @return
+ * TRUE if the table exists. Otherwise FALSE.
+ */
+function content_db_index_exists($table, $name) {
+ global $db_type;
+ if ($db_type == 'mysql' || $db_type == 'mysqli') {
+ if (version_compare(db_version(), '5.0.3') < 0) {
+ // Earlier versions of MySQL don't support a WHERE clause for SHOW.
+ $result = db_query('SHOW INDEX FROM {'. $table .'}');
+ while ($row = db_fetch_array($result)) {
+ if ($row['Key_name'] == $name) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ return (bool)db_result(db_query("SHOW INDEX FROM {". $table ."} WHERE key_name = '$name'"));
+ }
+ elseif ($db_type == 'pgsql') {
+ // Note that the index names in Schema API for PostgreSQL are prefixed by
+ // the table name and suffixed by '_idx'.
+ return (bool)db_result(db_query("SELECT COUNT(indexname) FROM pg_indexes WHERE indexname = '{". $table ."}_{$name}_idx'"));
+ }
+ return FALSE;
+}
+
+/**
+ * Helper function for determining the behavior of a field or a widget
+ * with respect to a given operation. (currently used for field 'view',
+ * and widget 'default values' and 'multiple values')
+ *
+ * @param $entity
+ * 'field' or 'widget'
+ * @param $op
+ * the name of the operation ('view', 'default value'...)
+ * @param $field
+ * The field array, including widget info.
+ * @return
+ * CONTENT_CALLBACK_NONE - do nothing for this operation
+ * CONTENT_CALLBACK_CUSTOM - use the module's callback function.
+ * CONTENT_CALLBACK_DEFAULT - use content module default behavior
+ *
+ */
+function content_callback($entity, $op, $field) {
+ switch ($entity) {
+ case 'field':
+ $info = module_invoke($field['module'], "field_info");
+ return isset($info[$field['type']]['callbacks'][$op]) ? $info[$field['type']]['callbacks'][$op] : CONTENT_CALLBACK_DEFAULT;
+
+ case 'widget':
+ $info = module_invoke($field['widget']['module'], "widget_info");
+ return isset($info[$field['widget']['type']]['callbacks'][$op]) ? $info[$field['widget']['type']]['callbacks'][$op] : CONTENT_CALLBACK_DEFAULT;
+ }
+}
+
+/**
+ * Helper function for determining the handling of a field, widget or
+ * formatter with respect to a given operation.
+ *
+ * Currently used for widgets and formatters 'multiple values'.
+ *
+ * @param $entity
+ * 'field', 'widget' or 'formatter'
+ * @param $op
+ * the name of the operation ('default values'...)
+ * @param $object
+ * - if $entity is 'field' or 'widget': the field array,
+ * including widget info.
+ * - if $entity is 'formater': the formatter array.
+ * @return
+ * CONTENT_HANDLE_CORE - the content module handles this operation.
+ * CONTENT_HANDLE_MODULE - the implementing module handles this operation.
+ */
+function content_handle($entity, $op, $object) {
+ switch ($entity) {
+ case 'field':
+ $info = module_invoke($object['module'], "field_info");
+ return isset($info[$object['type']][$op]) ? $info[$object['type']][$op] : CONTENT_HANDLE_CORE;
+
+ case 'widget':
+ $info = module_invoke($object['widget']['module'], "widget_info");
+ return isset($info[$object['widget']['type']][$op]) ? $info[$object['widget']['type']][$op] : CONTENT_HANDLE_CORE;
+
+ case 'formatter':
+ // Much simpler, formatters arrays *are* the 'formatter_info' itself.
+ // We let content_handle deal with them only for code consistency.
+ return isset($object[$op]) ? $object[$op] : CONTENT_HANDLE_CORE;
+ }
+}
+
+/**
+ * Helper function to return the correct default value for a field.
+ *
+ * @param $node
+ * The node.
+ * @param $field
+ * The field array.
+ * @param $items
+ * The value of the field in the node.
+ * @return
+ * The default value for that field.
+ */
+function content_default_value(&$form, &$form_state, $field, $delta) {
+ $widget_types = _content_widget_types();
+ $module = $widget_types[$field['widget']['type']]['module'];
+
+ $default_value = array();
+ if (!empty($field['widget']['default_value_php'])) {
+ ob_start();
+ $result = eval($field['widget']['default_value_php']);
+ ob_end_clean();
+ if (is_array($result)) {
+ $default_value = $result;
+ }
+ }
+ elseif (!empty($field['widget']['default_value'])) {
+ $default_value = $field['widget']['default_value'];
+ }
+ return (array) $default_value;
+}
+
+/**
+ * Determine whether the user has access to a given field.
+ *
+ * @param $op
+ * The operation to be performed. Possible values:
+ * - "edit"
+ * - "view"
+ * @param $field
+ * The field on which the operation is to be performed.
+ * @param $account
+ * (optional) The account to check, if not given use currently logged in user.
+ * @param $node
+ * (optional) The node on which the operation is to be performed.
+ * @return
+ * TRUE if the operation is allowed;
+ * FALSE if the operation is denied.
+ */
+function content_access($op, $field, $account = NULL, $node = NULL) {
+ global $user;
+
+ if (is_null($account)) {
+ $account = $user;
+ }
+ // Check for valid field data.
+ if (!isset($field['field_name'])) {
+ return FALSE;
+ }
+ $access = module_invoke_all('field_access', $op, $field, $account, $node);
+ foreach ($access as $value) {
+ if ($value === FALSE) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+ /**
+ * Hide specified fields from the $content variable in node templates.
+ */
+function content_field_wrapper_post_render($content, $element) {
+ $field = content_fields($element['#field_name'], $element['#type_name']);
+ if (theme('content_exclude', $content, $field, $element['#context'])) {
+ return '';
+ }
+ return $content;
+}
+
+
+/**
+ * 'Theme' function for a field's addition to $content.
+ *
+ * Adapts the all-inclusive $content variable in node templates to allow
+ * some field content to be excluded. This is a theme function, so it can be
+ * overridden in different themes to produce different results.
+ *
+ * The html for individual fields and groups are available in the
+ * $FIELD_NAME_rendered and $GROUP_NAME_rendered variables.
+ *
+ * This allows more flexibility in node templates : you can use custom markup
+ * around a few specific fields, and print the rest of the node with $content.
+ *
+ * @param $content
+ * The themed content for this field or group.
+ *
+ * @param $object
+ * The field or group array for this item.
+ * $object['#type_name'] holds the content type.
+ * $object['#field_name'] holds the field name (if a field).
+ * $object['#group_name'] holds the group name (if a group).
+ * $object['display_settings'] holds the display settings
+ * for all contexts, in an array like:
+ * $object['display_settings'] => array(
+ * 'full' => array(
+ * 'format' => 'default',
+ * 'exclude' => 0,
+ * ),
+ * 'teaser' => array(
+ * 'format' => 'default',
+ * 'exclude' => 1,
+ * ),
+ * );
+ *
+ * @param $context
+ * The context for which the node is being rendered.
+ * Can be one of the following values :
+ * - 'teaser'
+ * - 'full'
+ * - NODE_BUILD_SEARCH_INDEX
+ * - NODE_BUILD_SEARCH_RESULT
+ * - NODE_BUILD_RSS
+ * - NODE_BUILD_PRINT
+ * - ... any other custom build mode exposed by 3rd party modules using
+ * hook_content_build_modes().
+ *
+ * @return
+ * Whether or not content is to be added to $content in this context.
+ * Uses the value of the 'Exclude' checkbox for this field
+ * as set on the Manage fields screen.
+ */
+function theme_content_exclude($content, $object, $context) {
+ // The field may be missing info for $contexts added by modules
+ // enabled after the field was last edited.
+ if (empty($object['display_settings'])
+ || empty($object['display_settings'][$context])
+ || !is_array($object['display_settings'][$context])
+ || empty($object['display_settings'][$context]['exclude'])) {
+ return FALSE;
+ }
+ else {
+ return TRUE;
+ }
+}
+
+/**
+ * Theme preprocess function for field.tpl.php.
+ *
+ * The $variables array contains the following arguments:
+ * - $node
+ * - $field
+ * - $items
+ * - $teaser
+ * - $page
+ *
+ * @see field.tpl.php
+ *
+ * TODO : this should live in theme/theme.inc, but then the preprocessor
+ * doesn't get called when the theme overrides the template. Bug in theme layer ?
+ */
+function template_preprocess_content_field(&$variables) {
+ $element = $variables['element'];
+ $field = content_fields($element['#field_name'], $element['#node']->type);
+
+ $variables['node'] = $element['#node'];
+ $variables['field'] = $field;
+ $variables['items'] = array();
+
+ if ($element['#single']) {
+ // Single value formatter.
+ foreach (element_children($element['items']) as $delta) {
+ $variables['items'][$delta] = $element['items'][$delta]['#item'];
+ // Use isset() to avoid undefined index message on #children when field values are empty.
+ $variables['items'][$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : '';
+ }
+ }
+ else {
+ // Multiple values formatter.
+ // We display the 'all items' output as $items[0], as if it was the
+ // output of a single valued field.
+ // Raw values are still exposed for all items.
+ foreach (element_children($element['items']) as $delta) {
+ $variables['items'][$delta] = $element['items'][$delta]['#item'];
+ }
+ $variables['items'][0]['view'] = $element['items']['#children'];
+ }
+
+ $variables['teaser'] = $element['#teaser'];
+ $variables['page'] = $element['#page'];
+
+ $field_empty = TRUE;
+
+ foreach ($variables['items'] as $delta => $item) {
+ if (!isset($item['view']) || (empty($item['view']) && (string)$item['view'] !== '0')) {
+ $variables['items'][$delta]['empty'] = TRUE;
+ }
+ else {
+ $field_empty = FALSE;
+ $variables['items'][$delta]['empty'] = FALSE;
+ }
+ }
+
+ $additions = array(
+ 'field_type' => $field['type'],
+ 'field_name' => $field['field_name'],
+ 'field_type_css' => strtr($field['type'], '_', '-'),
+ 'field_name_css' => strtr($field['field_name'], '_', '-'),
+ 'label' => check_plain(t($field['widget']['label'])),
+ 'label_display' => $element['#label_display'],
+ 'field_empty' => $field_empty,
+ 'template_files' => array(
+ 'content-field',
+ 'content-field-'. $element['#field_name'],
+ 'content-field-'. $element['#node']->type,
+ 'content-field-'. $element['#field_name'] .'-'. $element['#node']->type,
+ ),
+ );
+ $variables = array_merge($variables, $additions);
+}
+
+/**
+ * Theme preprocess function for node.
+ *
+ * - Adds $FIELD_NAME_rendered variables
+ * containing the themed output for the whole field.
+ * - Adds the formatted values in the 'view' key of the items.
+ */
+function content_preprocess_node(&$vars) {
+ $additions = _content_field_invoke_default('preprocess_node', $vars['node']);
+ $vars = array_merge($vars, $additions);
+}
+
+/**
+ * Debugging using hook_content_fieldapi.
+ *
+ * @TODO remove later
+ *
+ * @param $op
+ * @param $field
+ */
+function content_content_fieldapi($op, $field) {
+ if (module_exists('devel')) {
+ //dsm($op);
+ //dsm($field);
+ }
+}
+
+/**
+ * Implementation of hook_content_extra_fields.
+ *
+ * Informations for non-CCK 'node fields' defined in core.
+ */
+function content_content_extra_fields($type_name) {
+ $type = node_get_types('type', $type_name);
+ $extra = array();
+
+ if ($type->has_title) {
+ $extra['title'] = array(
+ 'label' => $type->title_label,
+ 'description' => t('Node module form.'),
+ 'weight' => -5
+ );
+ }
+ if ($type->has_body) {
+ $extra['body_field'] = array(
+ 'label' => $type->body_label,
+ 'description' => t('Node module form.'),
+ 'weight' => 0,
+ 'view' => 'body'
+ );
+ }
+ $extra['revision_information'] = array(
+ 'label' => t('Revision information'),
+ 'description' => t('Node module form.'),
+ 'weight' => 20
+ );
+ $extra['author'] = array(
+ 'label' => t('Authoring information'),
+ 'description' => t('Node module form.'),
+ 'weight' => 20,
+ );
+ $extra['options'] = array(
+ 'label' => t('Publishing options'),
+ 'description' => t('Node module form.'),
+ 'weight' => 25,
+ );
+ if (module_exists('comment')) {
+ $extra['comment_settings'] = array(
+ 'label' => t('Comment settings'),
+ 'description' => t('Comment module form.'),
+ 'weight' => 30
+ );
+ }
+ if (module_exists('locale') && variable_get("language_content_type_$type_name", 0)) {
+ $extra['language'] = array(
+ 'label' => t('Language'),
+ 'description' => t('Locale module form.'),
+ 'weight' => 0
+ );
+ }
+ if (module_exists('translation') && translation_supported_type($type_name)) {
+ $extra['translation'] = array(
+ 'label' => t('Translation settings'),
+ 'description' => t('Translation module form.'),
+ 'weight' => 30
+ );
+ }
+ if (module_exists('menu')) {
+ $extra['menu'] = array(
+ 'label' => t('Menu settings'),
+ 'description' => t('Menu module form.'),
+ 'weight' => -2
+ );
+ }
+ if (module_exists('taxonomy') && taxonomy_get_vocabularies($type_name)) {
+ $extra['taxonomy'] = array(
+ 'label' => t('Taxonomy'),
+ 'description' => t('Taxonomy module form.'),
+ 'weight' => -3
+ );
+ }
+ if (module_exists('book')) {
+ $extra['book'] = array(
+ 'label' => t('Book'),
+ 'description' => t('Book module form.'),
+ 'weight' => 10
+ );
+ }
+ if (module_exists('path')) {
+ $extra['path'] = array(
+ 'label' => t('Path settings'),
+ 'description' => t('Path module form.'),
+ 'weight' => 30
+ );
+ }
+ if ($type_name == 'poll' && module_exists('poll')) {
+ $extra['title'] = array(
+ 'label' => t('Poll title'),
+ 'description' => t('Poll module title.'),
+ 'weight' => -5
+ );
+ $extra['choice_wrapper'] = array(
+ 'label' => t('Poll choices'),
+ 'description' => t('Poll module choices.'),
+ 'weight' => -4
+ );
+ $extra['settings'] = array(
+ 'label' => t('Poll settings'),
+ 'description' => t('Poll module settings.'),
+ 'weight' => -3
+ );
+ }
+ if (module_exists('upload') && variable_get("upload_$type_name", TRUE)) {
+ $extra['attachments'] = array(
+ 'label' => t('File attachments'),
+ 'description' => t('Upload module form.'),
+ 'weight' => 30,
+ 'view' => 'files'
+ );
+ }
+
+ return $extra;
+}
+
+/**
+ * Retrieve the user-defined weight for non-CCK node 'fields'.
+ *
+ * CCK's 'Manage fields' page lets users reorder node fields, including non-CCK
+ * items (body, taxonomy, other hook_nodeapi-added elements by contrib modules...).
+ * Contrib modules that want to have their 'fields' supported need to expose
+ * them with hook_content_extra_fields, and use this function to retrieve the
+ * user-defined weight.
+ *
+ * @param $type_name
+ * The content type name.
+ * @param $pseudo_field_name
+ * The name of the 'field'.
+ * @return
+ * The weight for the 'field', respecting the user settings stored
+ * by content.module.
+ */
+function content_extra_field_weight($type_name, $pseudo_field_name) {
+ $type = content_types($type_name);
+
+ // If we don't have the requested item, this may be because the cached
+ // information for 'extra' fields hasn't been refreshed yet.
+ if (!isset($type['extra'][$pseudo_field_name])) {
+ content_clear_type_cache();
+ $type = content_types($type_name);
+ }
+
+ if (isset($type['extra'][$pseudo_field_name])) {
+ return $type['extra'][$pseudo_field_name]['weight'];
+ }
+}
+
+/**
+ * Find max delta value actually in use for a field.
+ *
+ * Helper function to do things like tell when we should prevent a
+ * change in multiple value settings that would result in data loss,
+ * or know if content actually exists for a field.
+ *
+ * @param $field_name
+ * The field name to examine.
+ * @param $type_name
+ * If provided, search only for existing data in that type,
+ * otherwise search for all instances of field data in all types.
+ * @return
+ * NULL if field is not in use, or the maximum delta value in use.
+ *
+ * TODO
+ * Go back to the field settings validation and use this function
+ * to prevent (or confirm) changes in multiple values that
+ * would destroy data.
+ *
+ * Fields with only NULL data will show up as being in use.
+ * Do we want to eliminate them from the results?
+ */
+function content_max_delta($field_name, $type_name = NULL) {
+ $fields = content_fields();
+ $field = $fields[$field_name];
+
+ // Non-multiple value fields don't use the delta column,
+ // but could exist in multiple databases. If any value
+ // exists in any examined table, the max delta will be zero.
+ if (empty($field['multiple'])) {
+ $content_types = content_types();
+ foreach ($content_types as $content_type) {
+ if (empty($type_name) || $content_type['type'] == $type_name) {
+ foreach ($content_type['fields'] as $field) {
+ $db_info = content_database_info($field);
+ if (db_result(db_query("SELECT COUNT(*) FROM {". $db_info['table'] ."}")) >= 1) {
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ // Multiple value fields always share the same table and use the delta.
+ // If we want to find delta values for a particular type, we join
+ // in the node table to limit the type.
+ else {
+ $db_info = content_database_info($field);
+ if (!empty($type_name)) {
+ $delta = db_result(db_query("SELECT MAX(delta) FROM {". $db_info['table'] ."} f LEFT JOIN {node} n ON f.vid = n.vid WHERE n.type = '%s'", $type_name));
+ }
+ else {
+ $delta = db_result(db_query("SELECT MAX(delta) FROM {". $db_info['table'] ."}"));
+ }
+ if ($delta >= 0) {
+ return $delta;
+ }
+ }
+ // If we got this far, there is no data for this field.
+ return NULL;
+}
+
+/**
+ * Helper function to identify inactive fields.
+ */
+function content_inactive_fields($type_name = NULL) {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ if (!empty($type_name)) {
+ $param = array('type_name' => $type_name);
+ $inactive = array($type_name => array());
+ }
+ else {
+ $param = array();
+ $inactive = array();
+ }
+ $all = content_field_instance_read($param, TRUE);
+ $active = array_keys(content_fields());
+ foreach ($all as $field) {
+ if (!in_array($field['field_name'], $active)) {
+ $inactive[$field['type_name']][$field['field_name']] = content_field_instance_expand($field);
+ }
+ }
+ if (!empty($type_name)) {
+ return $inactive[$type_name];
+ }
+ return $inactive;
+}
+
+
+/**
+ * Helper function to identify inactive instances.
+ * This will be the same results as content_inactive_fields(),
+ * EXCEPT that his function will return inactive instances even
+ * if the fields have other (shared) instances that are still active.
+ */
+function content_inactive_instances($type_name = NULL) {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ if (!empty($type_name)) {
+ $param = array('type_name' => $type_name);
+ $inactive = array($type_name => array());
+ }
+ else {
+ $param = array();
+ $inactive = array();
+ }
+ $all = content_field_instance_read($param, TRUE);
+ foreach ($all as $field) {
+ $inactive[$field['type_name']][$field['field_name']] = content_field_instance_expand($field);
+ }
+ if (!empty($type_name)) {
+ return $inactive[$type_name];
+ }
+ return $inactive;
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.html
new file mode 100644
index 00000000000..024007cae58
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.html
@@ -0,0 +1,47 @@
+
+
Using a field across several content type can be handy if a piece of data
+is relevant for several content types. A typical use case is a 'Phone number'
+field, used in both 'Restaurant' and 'Hotel' content types, even if hotels
+and restaurants are different enough to deserve their own specific set of
+fields and thus their own dedicated content types.
+
+
When a field has been added to more than one content type, we also say it is
+"shared", and that it as "several instances".
+
+
At the bottom of the Manage fields page for a content type,
+you'll find this:
+
+
+
+
In order to add a new instance of an existing field to a content type, you
+need to provide the following information:
+
+
Label:
+
+ A human-readable name for the field. It will be used in input forms and
+ on displayed content.
+ All characters are allowed, including spaces, accentuated or non-european
+ characters.
+
+
+
Field:
+
+ The field to be shared.
+ A field cannot appear more than once in each content type. Thus, only
+ fields that are not already present in the current content type will be
+ proposed as "shareable". If none, the Add existing field
+ option is not available on the Manage fields page for
+ this content type.
+ Selecting a field automatically populates the Label and
+ Widget values with the ones used by the previous field
+ instance, but you can change them if needed before submitting the form.
+
+
+
Widget:
+
+ The form element that will be used to input data for this field on
+ content forms : text input, select list, etc...
+ Each field type has its own list of available widgets. When selecting a
+ field to share, the list of widgets you can select is automatically updated.
+
+
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.png
new file mode 100644
index 00000000000..4b126650ccf
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-existing-field.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.html
new file mode 100644
index 00000000000..7c9de37ee95
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.html
@@ -0,0 +1,58 @@
+
+
At the bottom of the Manage fields page for a content type,
+you'll find this:
+
+
+
+
In order to add a new field to a content type, you need to provide the
+following information:
+
+
Label:
+
+ A human-readable name for the field. It will be used in input forms and
+ on displayed content.
+ All characters are allowed, including spaces, accentuated or non-european
+ characters.
+
+
+
Field name:
+
+ A machine-readable name for the field. It is used internally to identify
+ the field and handle database storage. When doing custom theming, it is
+ this identifier that you'll use to refer to that field.
+ Important: The field name cannot be changed once the field has been
+ created.
+ Allowed characters: a-z (unaccentuated), 0-9 and the underscore (_).
+ The length of the field name cannot exceed 32 characters (including the
+ 'field_' prefix that gets added automatically - that is, 26 free characters)
+
+
+
Field type:
+
+ The type of data to be stored in that field.
+ Important: The field type cannot be changed once the field has been
+ created.
+ The available field types depend on the modules you have enabled on your site. CCK comes with 6
+ basic field types :
+
+ The form element that will be used to input data for this field on
+ content forms : text input, select list, etc...
+ Each field type has its own list of available widgets. When selecting a
+ field type, the list of widgets you can select is automatically updated.
+
+
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.png
new file mode 100644
index 00000000000..a7290443adb
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-field.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.html
new file mode 100644
index 00000000000..0e3a61bc72c
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.html
@@ -0,0 +1,40 @@
+
+
Field groups are used to visually gather several fields that are associated
+by some sort of logic, for instance several text fields that hold the different
+parts of an 'Address'. On input forms and displayed content, the corresponding
+fields are enclosed inside an HTML fieldset.
+
+
+
+
+
At the bottom of the Manage fields page for a content type,
+you'll find this:
+
+
+
+
In order to add a new group to a content type, you need to provide the
+following information:
+
+
Label:
+
+ A human-readable name for the group. It will be used in input forms and
+ on displayed content.
+ All characters are allowed, including spaces, accentuated or non-european
+ characters.
+
+
+
Group name:
+
+ A machine-readable name for the group. It is used internally to identify
+ the group. When doing custom theming, it is this identifier that you'll use
+ to refer to that group.
+ Important: The group name cannot be changed once the group has been
+ created.
+ Allowed characters: a-z (unaccentuated), 0-9 and the underscore (_).
+ The length of the group name cannot exceed 32 characters (including the
+ 'group_' prefix that gets added automatically - that is, 26 free characters)
+
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.png
new file mode 100644
index 00000000000..cedbe445a32
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new-group.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add-new.png b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new.png
new file mode 100644
index 00000000000..bda9a223f0b
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/add-new.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/add.html b/drupal/sites/default/boinc/modules/contrib/cck/help/add.html
new file mode 100644
index 00000000000..91ff3a62862
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/add.html
@@ -0,0 +1,16 @@
+
+
The form elements at the bottom of the Manage fields page
+let you add fields and groups to your content types.
+
+
+
+
(The Add existing field row is
+displayed only if there are fields available in other content types.
+The Add new group rows is displayed only if Fieldgroup module
+is enabled.)
+
Your fields and groups will be created after you click the Save
+button at the bottom of the page. In subsequent pages you will be presented
+with the settings form for each field you added.
+
+
You will find more details on the required informations in the
+following pages:
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/content.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/help/content.help.ini
new file mode 100644
index 00000000000..89120a983ce
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/content.help.ini
@@ -0,0 +1,60 @@
+; $Id$
+
+[advanced help settings]
+name = CCK
+index name = "CCK (Content Construction Kit)"
+
+[fields]
+title = Fields and Widgets
+weight = -10
+
+[manage-fields]
+title = 'Manage fields' tab
+
+[add]
+title = Add fields and groups
+parent = manage-fields
+weight = 1
+
+[add-new-field]
+title = Add a new field
+parent = add
+weight = 1
+
+[add-existing-field]
+title = Add an existing field : share a field across content types
+parent = add
+weight = 2
+
+[add-new-group]
+title = Add a new group
+parent = add
+weight = 3
+
+[rearrange]
+title = Rearrange fields and groups
+parent = manage-fields
+weight = 2
+
+[remove]
+title = Remove fields and groups
+parent = manage-fields
+weight = 3
+
+[theme]
+title = Theming CCK data in nodes
+
+[theme-node-templates]
+title = Node templates
+parent = theme
+weight = 1
+
+[theme-field-templates]
+title = Field templates
+parent = theme
+weight = 2
+
+[theme-formatters]
+title = Formatter theme functions
+parent = theme
+weight = 3
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/drag-groups.png b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-groups.png
new file mode 100644
index 00000000000..8d13dc8eba6
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-groups.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/drag-new.png b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-new.png
new file mode 100644
index 00000000000..05c2c6959e1
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/drag-new.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/draggable.png b/drupal/sites/default/boinc/modules/contrib/cck/help/draggable.png
new file mode 100644
index 00000000000..3ab0bb89e9a
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/draggable.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/fields.html b/drupal/sites/default/boinc/modules/contrib/cck/help/fields.html
new file mode 100644
index 00000000000..789fa5fa1f4
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/fields.html
@@ -0,0 +1 @@
+
The Content Construction Kit (CCK) is composed of numerous field and widget modules that can be used to add fields to any content type.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-display.png b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-display.png
new file mode 100644
index 00000000000..78ce35bf54c
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-display.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-edit-form.png b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-edit-form.png
new file mode 100644
index 00000000000..831dd76cc0f
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/group-node-edit-form.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/manage-fields.html b/drupal/sites/default/boinc/modules/contrib/cck/help/manage-fields.html
new file mode 100644
index 00000000000..73eba4c0a95
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/manage-fields.html
@@ -0,0 +1,4 @@
+
+
This page lets you manage the CCK fields in your content type : add fields and
+groups, rearrange them, access their configuration pages, remove them from the
+content type.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/rearrange.html b/drupal/sites/default/boinc/modules/contrib/cck/help/rearrange.html
new file mode 100644
index 00000000000..fc9fe8bb910
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/rearrange.html
@@ -0,0 +1,25 @@
+
+
To change the order of fields, grab a drag-and-drop handle
+ and drag the field to a new location in the list
+(grab a handle by clicking and holding the mouse while hovering over a handle
+icon). Remember that your changes will not be saved until you click the
+Save button at the bottom of the page.
+
+
The order you define will be used both on input forms (when creating or
+editing a post), and on content display (teasers, content page, RSS items...)
+
You can also change the order of non-CCK 'fields' like Title
+or File attachments. Depending on the 'field', this will
+affect input forms and/or content display (some of those 'fields' are not
+displayed in both contexts).
+
If your content type has groups (requires the Fieldgroup module), you can
+move a field inside a group by dragging it below the row of the group, and
+then slightly to the right before dropping it. Note that groups can also be
+reordered, but can currently not be nested inside other groups.
+
+
+
+
When adding a field or a group, you can drag them directly to the
+intended spot in the list of fields and groups that are already present in your
+content type, before clicking Save:
+
+
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/remove.html b/drupal/sites/default/boinc/modules/contrib/cck/help/remove.html
new file mode 100644
index 00000000000..d0c7b31cd76
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/remove.html
@@ -0,0 +1,17 @@
+
+
Removing a field
+
+
When you remove a field from a content type, the data it holds are
+permanently erased. You will be asked to confirm this action
+
+
You will have to manually update your Views, pathauto settings, etc... if
+needed.
+
+
Note : if the field is shared across several content types, removing it from
+one content type does not affect the data for the other content
+types.
+
+
Removing a group
+
+
Removing a group from a content type does not remove the fields
+it contains, and therefore erases no field data.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme-field-templates.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-field-templates.html
new file mode 100644
index 00000000000..63be7a3518f
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-field-templates.html
@@ -0,0 +1,76 @@
+
+
Field-level theming determines how the values of a given field are
+displayed. The resulting output ends up in the $content
+and $<FIELD_NAME>_rendered variables in the node
+templates.
+
+
Template files
+
+
In order to customize field themeing:
+
+
+
+ Copy the content-field.tpl.php template file into
+ your theme's root folder (please keep the contents of the
+ cck/theme folder untouched. For the same reason,
+ need to copy the file instead of just moving it).
+
+
+ Edit that copy to your liking. See the comments in
+ cck/theme/content/content-field.tpl.php for a list
+ of all variables available in this template.
+
+
+
+
Template suggestions
+
+
In addition, the theme layer will also look for field-specific variants
+(suggestions), in the following order of precedence:
+ ex: content-field-field_myfield-story.tpl.php -
+ If present, will be used to theme the 'field_myfield' field when displaying
+ a 'story' node.
+
+
+
content-field-<CONTENT_TYPE_NAME>.tpl.php
+
+ ex: content-field-story.tpl.php - If present,
+ will be used to theme all fields of 'story' nodes.
+
+
+
content-field-<FIELD_NAME>.tpl.php
+
+ ex: content-field-field_myfield.tpl.php -
+ If present, will be used to theme all 'field_myfield' field in all the
+ content types it appears in.
+
+
+
content-field.tpl.php
+
+ If none of the above is present, the base template will be used.
+
+
+
+Important:
+
+
+ Suggestions work only if the theme also has the base template file.
+ If your theme has content-field-*.tpl.php files,
+ it must also have a content-field.tpl.php file.
+
+
+ Whenever you add new template files in your theme, you need to
+ rebuild the theme registry, or the theme engine won't see them.
+ You can do that by :
+ - visiting the Administer modules page
+ - or using Devel module's
+ 'clear cache' link.
+
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme-formatters.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-formatters.html
new file mode 100644
index 00000000000..efbe6e0a446
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-formatters.html
@@ -0,0 +1,14 @@
+
+
Formatters are used to turn the raw data for a single field value into html.
+The Display Fields tab lets you chose which formatter you want to use
+for each of your fields.
+
+
In CCK 2.0 for Drupal 6, all formatters now go through the theme layer.
+Therefore, overriding a formatter's theme is another way you can alter how your
+values are displayed (whereas changing content-field.tpl.php
+lets you change the html that "wraps" the values).
+
+
Most formatters come as theme functions, but some might use templates instead.
+Either way, you can override them using the usual Drupal 6 theme override
+practices. For more informations, see the Theme guide for Drupal 6,
+and more specifically the Overriding themable output section.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme-node-templates.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-node-templates.html
new file mode 100644
index 00000000000..8118da0a34f
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme-node-templates.html
@@ -0,0 +1,131 @@
+
+
Template files
+
+
All themes usually come with a default node.tpl.php
+template. Drupal core lets you use the following variant (suggestion):
+
+
+
node-<CONTENT_TYPE_NAME>.tpl.php
+
+ ex: node-story.tpl.php - If present, will be used
+ to theme a 'story' node.
+
+
+
+
Important: whenever you add new template files in your theme, you
+need to rebuild the theme registry, or the theme engine won't see them.
+You can do that by :
+- visiting the Administer modules page
+- or using Devel module's
+'clear cache' link.
+
+
Template variables
+
+
CCK makes the following variables available in your theme's node templates:
+
+
+
$<FIELD_NAME>_rendered
+
+ Contains the rendered html for the field, including the label and all the
+ field's values, with the settings defined on the Display fields tab.
+
+
+
$<GROUP_NAME>_rendered
+
+ Contains the rendered html for the fieldgroup (if any), including the label
+ and all the group's fields, with the settings defined on the Display
+ fields tab.
+ This variable therefore includes the html contained in all the
+ $<FIELD_NAME>_rendered variables for the
+ group's fields.
+
+
+
$FIELD_NAME
+
+ Contains the raw values of the fields, in the usual array-format used
+ internally by CCK. What you find in there depends on the field type.
+ Each value also contains a 'view' element, that
+ holds the ready-to-display value as rendered by the formatter. For instance:
+
+ Raw data are not sanitized for output, it is therefore not
+ advised to use them directly. Use the 'view'
+ value, or run the values through content_format().
+
+
+
+
Excluding fields from the $content variable
+
+
By default, the $content variable used in node
+templates contains the rendered html for the whole node : CCK fields and
+fieldgroups, but also body, file attachments, fivestar widgets, ...
+
+
If for some fields you want to use the more fine-grained variables described
+above, you might want to use the Exclude checkboxes on the Display
+fields screen, so that the output of those fields is excluded from the
+$content variable.
+
+
You can then customize the display and layout of some CCK fields or groups
+using the $<FIELD_NAME>_rendered /
+$<GROUP_NAME>_rendered variables, and trust
+$content to display 'the rest' without getting
+duplicate information.
+
+
Advanced trick
+
The Exclude checkboxes affect all active themes. On sites with multiple
+themes, however, the list of fields to exclude from $content
+might need to be different across the themes, depending on how their respective
+node templates are structured.
+
+
A theme can bypass those settings by overriding the theme_content_exclude()
+function to specify the list of fields to exclude for this theme (see the
+PHPDoc of the function for more information).
+
+
+
Special case : nodes in nodereference fields
+
+
In addition to the above, the following suggestions will be looked for
+in priority for nodes that are displayed as values of a nodereference field using
+the 'teaser' or 'full node' formatters:
+ ex: node-nodereference-field_noderef-story.tpl.php -
+ If present, will be used to theme a 'story' node when refererenced in the
+ 'field_noderef' field.
+
+
+
node-nodereference-<TYPE_NAME>.tpl.php
+
+ ex: node-nodereference-story.tpl.php - If present,
+ will be used to theme a 'story' node when refererenced in any nodereference
+ field.
+
+
+
node-nodereference-<REFERRING_FIELD_NAME>.tpl.php
+
+ ex: node-nodereference-field_noderef.tpl.php - If
+ present, will be used to a node refererenced in the 'field_noderef' field.
+
+
+
node-nodereference.tpl.php
+
+ If present, will be used to theme nodes referenced in nodereference fields.
+
+
+
+
The following additional variables are available in templates for referenced nodes:
+
+
+
$referring_field
+
The nodereference field that references the current node.
+
+
$referring_node
+
The node referencing the current node.
+
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme.html b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.html
new file mode 100644
index 00000000000..e2f60fa45ed
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.html
@@ -0,0 +1,10 @@
+
+
Note: these instructions assume you are familiar with the basic concepts
+of Drupal 6 theming. For more informations, see the Theme guide for Drupal 6,
+and more specifically the Overriding themable output
+section.
+
+
There are 3 levels where you can customize how the data in CCK fields
+is displayed in nodes:
+
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/help/theme.png b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.png
new file mode 100644
index 00000000000..d9281002edd
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/help/theme.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.admin.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.admin.inc
new file mode 100644
index 00000000000..e0050f5b421
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.admin.inc
@@ -0,0 +1,1916 @@
+ t('Operations'), 'colspan' => '4'),);
+ $rows = array();
+
+ foreach ($names as $key => $name) {
+ $type = $types[$key];
+ if (node_hook($type, 'form')) {
+ $type_url_str = str_replace('_', '-', $type->type);
+ $row = array(
+ check_plain($name),
+ check_plain($type->type),
+ );
+ // Make the description smaller
+ $row[] = array('data' => filter_xss_admin($type->description), 'class' => 'description');
+ // Set the edit column.
+ $row[] = array('data' => l(t('edit'), 'admin/content/node-type/'. $type_url_str));
+ // Set links for managing fields.
+ // TODO: a hook to allow other content modules to add more stuff?
+ $row[] = array('data' => l(t('manage fields'), 'admin/content/node-type/'. $type_url_str .'/fields'));
+ // Set the delete column.
+ if ($type->custom) {
+ $row[] = array('data' => l(t('delete'), 'admin/content/node-type/'. $type_url_str .'/delete'));
+ }
+ else {
+ $row[] = array('data' => '');
+ }
+
+ $rows[] = $row;
+ }
+ }
+
+ // Allow external modules alter the table headers and rows.
+ foreach (module_implements('content_types_overview_alter') as $module) {
+ $function = $module .'_content_types_overview_alter';
+ $function($header, $rows);
+ }
+
+ if (empty($rows)) {
+ $rows[] = array(array('data' => t('No content types available.'), 'colspan' => '7', 'class' => 'message'));
+ }
+
+ return theme('table', $header, $rows) .theme('content_overview_links');
+}
+
+function theme_content_overview_links() {
+ return '
'. l(t('» Add a new content type'), 'admin/content/types/add') .'
';
+}
+
+/**
+ * Menu callback; lists all defined fields for quick reference.
+ */
+function content_fields_list() {
+ $fields = content_fields();
+ $field_types = _content_field_types();
+
+ // Sort fields by field name.
+ ksort($fields);
+
+ $header = array(t('Field name'), t('Field type'), t('Used in'));
+ $rows = array();
+ foreach ($fields as $field) {
+ $row = array();
+ $row[] = $field['locked'] ? t('@field_name (Locked)', array('@field_name' => $field['field_name'])) : $field['field_name'];
+ $row[] = t($field_types[$field['type']]['label']);
+
+ $types = array();
+ $result = db_query("SELECT nt.name, nt.type FROM {". content_instance_tablename() ."} nfi ".
+ "LEFT JOIN {node_type} nt ON nt.type = nfi.type_name ".
+ "WHERE nfi.field_name = '%s' ".
+ // Keep disabled modules out of table.
+ "AND nfi.widget_active = 1 ".
+ "ORDER BY nt.name ASC", $field['field_name']);
+ while ($type = db_fetch_array($result)) {
+ $content_type = content_types($type['type']);
+ $types[] = l($type['name'], 'admin/content/node-type/'. $content_type['url_str'] .'/fields');
+ }
+ $row[] = implode(', ', $types);
+
+ $rows[] = array('data' => $row, 'class' => $field['locked'] ? 'menu-disabled' : '');
+ }
+ if (empty($rows)) {
+ $output = t('No fields have been defined for any content type yet.');
+ }
+ else {
+ $output = theme('table', $header, $rows);
+ }
+ return $output;
+}
+
+/**
+ * Helper function to display a message about inactive fields.
+ */
+function content_inactive_message($type_name) {
+ $inactive_fields = content_inactive_fields($type_name);
+ if (!empty($inactive_fields)) {
+ $field_types = _content_field_types();
+ $widget_types = _content_widget_types($type_name);
+ drupal_set_message(t('This content type has inactive fields. Inactive fields are not included in lists of available fields until their modules are enabled.'), 'error');
+ foreach ($inactive_fields as $field_name => $field) {
+ drupal_set_message(t('!field (!field_name) is an inactive !field_type field that uses a !widget_type widget.', array(
+ '!field' => $field['widget']['label'],
+ '!field_name' => $field['field_name'],
+ '!field_type' => array_key_exists($field['type'], $field_types) ? $field_types[$field['type']]['label'] : $field['type'],
+ '!widget_type' => array_key_exists($field['widget']['type'], $widget_types) ? $widget_types[$field['widget']['type']]['label'] : $field['widget']['type'],
+ )));
+ }
+ }
+}
+
+/**
+ * Menu callback; listing of fields for a content type.
+ *
+ * Allows fields to be reordered and nested in fieldgroups using
+ * JS drag-n-drop. Non-CCK form elements can also be moved around.
+ */
+function content_field_overview_form(&$form_state, $type_name) {
+
+ content_inactive_message($type_name);
+
+ // When displaying the form, make sure the list of fields
+ // is up-to-date.
+ if (empty($form_state['post'])) {
+ content_clear_type_cache();
+ }
+
+ // Gather type information.
+ $type = content_types($type_name);
+ $fields = $type['fields'];
+ $field_types = _content_field_types();
+
+ $extra = $type['extra'];
+ $groups = $group_options = $group_types = array();
+ if (module_exists('fieldgroup')) {
+ $groups = fieldgroup_groups($type['type']);
+ $group_types = fieldgroup_types();
+ $group_options = _fieldgroup_groups_label($type['type']);
+ // Add the ability to group under the newly created row.
+ $group_options['_add_new_group'] = '_add_new_group';
+ }
+
+ // Store the default weights as we meet them, to be able to put the
+ //'add new' rows after them.
+ $weights = array();
+
+ $form = array(
+ '#tree' => TRUE,
+ '#type_name' => $type['type'],
+ '#fields' => array_keys($fields),
+ '#groups' => array_keys($groups),
+ '#extra' => array_keys($extra),
+ '#field_rows' => array(),
+ '#group_rows' => array(),
+ );
+
+ // Fields.
+ foreach ($fields as $name => $field) {
+ $weight = $field['widget']['weight'];
+ $form[$name] = array(
+ 'label' => array('#value' => check_plain($field['widget']['label'])),
+ 'field_name' => array('#value' => $field['field_name']),
+ 'type' => array('#value' => t($field_types[$field['type']]['label'])),
+ 'configure' => array('#value' => l(t('Configure'), 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name'])),
+ 'remove' => array('#value' => l(t('Remove'), 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name'] .'/remove')),
+ 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
+ 'parent' => array('#type' => 'select', '#options' => $group_options, '#default_value' => ''),
+ 'prev_parent' => array('#type' => 'hidden', '#value' => ''),
+ 'hidden_name' => array('#type' => 'hidden', '#default_value' => $field['field_name']),
+ '#leaf' => TRUE,
+ '#row_type' => 'field',
+ 'field' => array('#type' => 'value', '#value' => $field),
+ );
+ if ($field['locked']) {
+ $form[$name]['configure'] = array('#value' => t('Locked'));
+ $form[$name]['remove'] = array();
+ $form[$name]['#disabled_row'] = TRUE;
+ }
+ $form['#field_rows'][] = $name;
+ $weights[] = $weight;
+ }
+
+ // Groups.
+ foreach ($groups as $name => $group) {
+ $weight = $group['weight'];
+ $form[$name] = array(
+ 'label' => array('#value' => check_plain($group['label'])),
+ 'group_name' => array('#value' => $group['group_name']),
+ 'group_type' => array('#value' => t($group_types[$group['group_type']])),
+ 'configure' => array('#value' => l(t('Configure'), 'admin/content/node-type/'. $type['url_str'] .'/groups/'. $group['group_name'])),
+ 'remove' => array('#value' => l(t('Remove'), 'admin/content/node-type/'. $type['url_str'] .'/groups/'. $group['group_name'] .'/remove')),
+ 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
+ 'parent' => array('#type' => 'hidden', '#default_value' => ''),
+ 'hidden_name' => array('#type' => 'hidden', '#default_value' => $group['group_name']),
+ '#root' => TRUE,
+ '#row_type' => 'group',
+ 'group' => array('#type' => 'value', '#value' => $group),
+ );
+ // Adjust child fields rows.
+ foreach ($group['fields'] as $field_name => $field) {
+ $form[$field_name]['parent']['#default_value'] = $name;
+ $form[$field_name]['prev_parent']['#value'] = $name;
+ }
+ $form['#group_rows'][] = $name;
+ $weights[] = $weight;
+ }
+
+ // Non-CCK 'fields'.
+ foreach ($extra as $name => $label) {
+ $weight = $extra[$name]['weight'];
+ $form[$name] = array(
+ 'label' => array('#value' => check_plain(t($extra[$name]['label']))),
+ 'description' => array('#value' => isset($extra[$name]['description']) ? $extra[$name]['description'] : ''),
+ 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
+ 'parent' => array('#type' => 'hidden', '#default_value' => ''),
+ 'configure' => array('#value' => isset($extra[$name]['configure']) ? $extra[$name]['configure'] : ''),
+ 'remove' => array('#value' => isset($extra[$name]['remove']) ? $extra[$name]['remove'] : ''),
+ 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name),
+ '#leaf' => TRUE,
+ '#root' => TRUE,
+ '#disabled_row' => TRUE,
+ '#row_type' => 'extra',
+ );
+ $form['#field_rows'][] = $name;
+ $weights[] = $weight;
+ }
+
+ // Additional row : add new field.
+ $weight = max($weights) + 1;
+ $field_type_options = content_field_type_options();
+ $widget_type_options = content_widget_type_options(NULL, TRUE);
+ if ($field_type_options && $widget_type_options) {
+ array_unshift($field_type_options, t('- Select a field type -'));
+ array_unshift($widget_type_options, t('- Select a widget -'));
+ $name = '_add_new_field';
+ $form[$name] = array(
+ 'label' => array(
+ '#type' => 'textfield',
+ '#size' => 15,
+ '#description' => t('Label'),
+ ),
+ 'field_name' => array(
+ '#type' => 'textfield',
+ // This field should stay LTR even for RTL languages.
+ '#field_prefix' => 'field_',
+ '#field_suffix' => '',
+ '#attributes' => array('dir'=>'ltr'),
+ '#size' => 15,
+ // Field names are limited to 32 characters including the 'field_'
+ // prefix which is 6 characters long.
+ '#maxlength' => 26,
+ '#description' => t('Field name (a-z, 0-9, _)'),
+ ),
+ 'type' => array(
+ '#type' => 'select',
+ '#options' => $field_type_options,
+ '#description' => theme('advanced_help_topic', 'content', 'fields') . t('Type of data to store.'),
+ ),
+ 'widget_type' => array(
+ '#type' => 'select',
+ '#options' => $widget_type_options,
+ '#description' => t('Form element to edit the data.'),
+ ),
+ 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
+ 'parent' => array('#type' => 'select', '#options' => $group_options, '#default_value' => ''),
+ 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name),
+ '#leaf' => TRUE,
+ '#add_new' => TRUE,
+ '#row_type' => 'add_new_field',
+ );
+ $form['#field_rows'][] = $name;
+ }
+
+ // Additional row : add existing field.
+ $existing_field_options = content_existing_field_options($type_name);
+ if ($existing_field_options && $widget_type_options) {
+ $weight++;
+ array_unshift($existing_field_options, t('- Select an existing field -'));
+ $name = '_add_existing_field';
+ $form[$name] = array(
+ 'label' => array(
+ '#type' => 'textfield',
+ '#size' => 15,
+ '#description' => t('Label'),
+ ),
+ 'field_name' => array(
+ '#type' => 'select',
+ '#options' => $existing_field_options,
+ '#description' => t('Field to share'),
+ ),
+ 'widget_type' => array(
+ '#type' => 'select',
+ '#options' => $widget_type_options,
+ '#description' => t('Form element to edit the data.'),
+ ),
+ 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
+ 'parent' => array('#type' => 'select', '#options' => $group_options, '#default_value' => ''),
+ 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name),
+ '#leaf' => TRUE,
+ '#add_new' => TRUE,
+ '#row_type' => 'add_existing_field',
+ );
+ $form['#field_rows'][] = $name;
+ }
+
+ // Additional row : add new group.
+ if (!empty($group_types)) {
+ $weight++;
+ $name = '_add_new_group';
+ $form[$name] = array(
+ 'label' => array(
+ '#type' => 'textfield',
+ '#size' => 15,
+ '#description' => t('Label'),
+ ),
+ 'group_name' => array(
+ '#type' => 'textfield',
+ // This field should stay LTR even for RTL languages.
+ '#field_prefix' => 'group_',
+ '#field_suffix' => '',
+ '#attributes' => array('dir'=>'ltr'),
+ '#size' => 15,
+ // Group names are limited to 32 characters including the 'group_'
+ // prefix which is 6 characters long.
+ '#maxlength' => 26,
+ '#description' => t('Group name (a-z, 0-9, _)'),
+ ),
+ 'group_option' => array(
+ '#type' => 'hidden',
+ '#value' => '',
+ ),
+ 'group_type' => array(
+ '#type' => 'hidden',
+ '#value' => 'standard',
+ ),
+ 'weight' => array('#type' => 'textfield', '#default_value' => $weight, '#size' => 3),
+ 'parent' => array('#type' => 'hidden', '#default_value' => ''),
+ 'hidden_name' => array('#type' => 'hidden', '#default_value' => $name),
+ '#root' => TRUE,
+ '#add_new' => TRUE,
+ '#row_type' => 'add_new_group',
+ );
+ if (count($group_types) > 1) {
+ $form[$name]['group_type'] = array(
+ '#type' => 'select',
+ '#description' => t('Type of group.'),
+ '#options' => $group_types,
+ '#default_value' => 'standard',
+ );
+ }
+ $form['#group_rows'][] = $name;
+ }
+
+ $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
+ return $form;
+}
+
+function content_field_overview_form_validate($form, &$form_state) {
+ _content_field_overview_form_validate_add_new($form, $form_state);
+ _content_field_overview_form_validate_add_existing($form, $form_state);
+}
+
+/**
+ * Helper function for content_field_overview_form_validate.
+ *
+ * Validate the 'add new field' row.
+ */
+function _content_field_overview_form_validate_add_new($form, &$form_state) {
+ $field = $form_state['values']['_add_new_field'];
+
+ // Validate if any information was provided in the 'add new field' row.
+ if (array_filter(array($field['label'], $field['field_name'], $field['type'], $field['widget_type']))) {
+ // No label.
+ if (!$field['label']) {
+ form_set_error('_add_new_field][label', t('Add new field: you need to provide a label.'));
+ }
+
+ // No field name.
+ if (!$field['field_name']) {
+ form_set_error('_add_new_field][field_name', t('Add new field: you need to provide a field name.'));
+ }
+ // Field name validation.
+ else {
+ $field_name = $field['field_name'];
+
+ // Add the 'field_' prefix.
+ if (substr($field_name, 0, 6) != 'field_') {
+ $field_name = 'field_'. $field_name;
+ form_set_value($form['_add_new_field']['field_name'], $field_name, $form_state);
+ }
+
+ // Invalid field name.
+ if (!preg_match('!^field_[a-z0-9_]+$!', $field_name)) {
+ form_set_error('_add_new_field][field_name', t('Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores.', array('%field_name' => $field_name)));
+ }
+ if (strlen($field_name) > 32) {
+ form_set_error('_add_new_field][field_name', t('Add new field: the field name %field_name is too long. The name is limited to 32 characters, including the \'field_\' prefix.', array('%field_name' => $field_name)));
+ }
+ // A field named 'field_instance' would cause a tablename clash with {content_field_instance}
+ if ($field_name == 'field_instance') {
+ form_set_error('_add_new_field][field_name', t("Add new field: the name 'field_instance' is a reserved name."));
+ }
+
+ // Field name already exists.
+ // We need to check inactive fields as well, so we can't use content_fields().
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $fields = content_field_instance_read(array(), TRUE);
+ $used = FALSE;
+ foreach ($fields as $existing_field) {
+ $used |= ($existing_field['field_name'] == $field_name);
+ }
+ if ($used) {
+ form_set_error('_add_new_field][field_name', t('Add new field: the field name %field_name already exists.', array('%field_name' => $field_name)));
+ }
+ }
+
+ // No field type.
+ if (!$field['type']) {
+ form_set_error('_add_new_field][type', t('Add new field: you need to select a field type.'));
+ }
+
+ // No widget type.
+ if (!$field['widget_type']) {
+ form_set_error('_add_new_field][widget_type', t('Add new field: you need to select a widget.'));
+ }
+ // Wrong widget type.
+ elseif ($field['type']) {
+ $widget_types = content_widget_type_options($field['type']);
+ if (!isset($widget_types[$field['widget_type']])) {
+ form_set_error('_add_new_field][widget_type', t('Add new field: invalid widget.'));
+ }
+ }
+ }
+}
+
+/**
+ * Helper function for content_field_overview_form_validate.
+ *
+ * Validate the 'add existing field' row.
+ */
+function _content_field_overview_form_validate_add_existing($form, &$form_state) {
+ // The form element might be absent if no existing fields can be added to
+ // this content type
+ if (isset($form_state['values']['_add_existing_field'])) {
+ $field = $form_state['values']['_add_existing_field'];
+
+ // Validate if any information was provided in the 'add existing field' row.
+ if (array_filter(array($field['label'], $field['field_name'], $field['widget_type']))) {
+ // No label.
+ if (!$field['label']) {
+ form_set_error('_add_existing_field][label', t('Add existing field: you need to provide a label.'));
+ }
+
+ // No existing field.
+ if (!$field['field_name']) {
+ form_set_error('_add_existing_field][field_name', t('Add existing field: you need to select a field.'));
+ }
+
+ // No widget type.
+ if (!$field['widget_type']) {
+ form_set_error('_add_existing_field][widget_type', t('Add existing field: you need to select a widget.'));
+ }
+ // Wrong widget type.
+ elseif ($field['field_name'] && ($existing_field = content_fields($field['field_name']))) {
+ $widget_types = content_widget_type_options($existing_field['type']);
+ if (!isset($widget_types[$field['widget_type']])) {
+ form_set_error('_add_existing_field][widget_type', t('Add existing field: invalid widget.'));
+ }
+ }
+ }
+ }
+}
+
+function content_field_overview_form_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+
+ $type_name = $form['#type_name'];
+ $type = content_types($type_name);
+
+ // Update field weights.
+ $extra = array();
+ foreach ($form_values as $key => $values) {
+ // Groups are handled in fieldgroup_content_overview_form_submit().
+ if (in_array($key, $form['#fields'])) {
+ db_query("UPDATE {". content_instance_tablename() ."} SET weight = %d WHERE type_name = '%s' AND field_name = '%s'",
+ $values['weight'], $type_name, $key);
+ }
+ elseif (in_array($key, $form['#extra'])) {
+ $extra[$key] = $values['weight'];
+ }
+ }
+
+ if ($extra) {
+ variable_set('content_extra_weights_'. $type_name, $extra);
+ }
+ else {
+ variable_del('content_extra_weights_'. $type_name);
+ }
+
+ content_clear_type_cache();
+
+ $destinations = array();
+
+ // Create new field.
+ if (!empty($form_values['_add_new_field']['field_name'])) {
+ $field = $form_values['_add_new_field'];
+ $field['type_name'] = $type_name;
+
+ module_load_include('inc', 'content', 'includes/content.crud');
+ if (content_field_instance_create($field)) {
+ // Store new field information for fieldgroup submit handler.
+ $form_state['fields_added']['_add_new_field'] = $field['field_name'];
+ $destinations[] = 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name'];
+ }
+ else {
+ drupal_set_message(t('There was a problem creating field %label.', array(
+ '%label' => $field['label'])));
+ }
+ }
+
+ // Add existing field.
+ if (!empty($form_values['_add_existing_field']['field_name'])) {
+ $field = $form_values['_add_existing_field'];
+ $field['type_name'] = $type_name;
+ $existing_field = content_fields($field['field_name']);
+
+ if ($existing_field['locked']) {
+ drupal_set_message(t('The field %label cannot be added to a content type because it is locked.', array('%label' => $field['field_name'])));
+ }
+ else {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ if (content_field_instance_create($field)) {
+ // Store new field information for fieldgroup submit handler.
+ $form_state['fields_added']['_add_existing_field'] = $field['field_name'];
+ $destinations[] = 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $field['field_name'];
+ }
+ else {
+ drupal_set_message(t('There was a problem adding field %label.', array('%label' => $field['field_name'])));
+ }
+ }
+ }
+
+ if ($destinations) {
+ $destinations[] = urldecode(substr(drupal_get_destination(), 12));
+ unset($_REQUEST['destination']);
+ $form_state['redirect'] = content_get_destinations($destinations);
+ }
+
+}
+
+/**
+ * Menu callback; presents a listing of fields display settings for a content type.
+ *
+ * Form includes form widgets to select which fields appear for teaser, full node
+ * and how the field labels should be rendered.
+ */
+function content_display_overview_form(&$form_state, $type_name, $contexts_selector = 'basic') {
+ content_inactive_message($type_name);
+
+ // Gather type information.
+ $type = content_types($type_name);
+ $field_types = _content_field_types();
+ $fields = $type['fields'];
+
+ $groups = array();
+ if (module_exists('fieldgroup')) {
+ $groups = fieldgroup_groups($type['type']);
+ }
+ $contexts = content_build_modes($contexts_selector);
+
+ $form = array(
+ '#tree' => TRUE,
+ '#type_name' => $type['type'],
+ '#fields' => array_keys($fields),
+ '#groups' => array_keys($groups),
+ '#contexts' => $contexts_selector,
+ );
+
+ if (empty($fields)) {
+ drupal_set_message(t('There are no fields configured for this content type. You can add new fields on the Manage fields page.', array(
+ '@link' => url('admin/content/node-type/'. $type['url_str'] .'/fields'))), 'warning');
+ return $form;
+ }
+
+ // Fields.
+ $label_options = array(
+ 'above' => t('Above'),
+ 'inline' => t('Inline'),
+ 'hidden' => t(''),
+ );
+ foreach ($fields as $name => $field) {
+ $field_type = $field_types[$field['type']];
+ $defaults = $field['display_settings'];
+ $weight = $field['widget']['weight'];
+
+ $form[$name] = array(
+ 'human_name' => array('#value' => check_plain($field['widget']['label'])),
+ 'weight' => array('#type' => 'value', '#value' => $weight),
+ 'parent' => array('#type' => 'value', '#value' => ''),
+ );
+
+ // Label
+ if ($contexts_selector == 'basic') {
+ $form[$name]['label']['format'] = array(
+ '#type' => 'select',
+ '#options' => $label_options,
+ '#default_value' => isset($defaults['label']['format']) ? $defaults['label']['format'] : 'above',
+ );
+ }
+
+ // Formatters.
+ $options = array();
+ foreach ($field_type['formatters'] as $formatter_name => $formatter_info) {
+ $options[$formatter_name] = $formatter_info['label'];
+ }
+ $options['hidden'] = t('');
+
+ foreach ($contexts as $key => $value) {
+ $form[$name][$key]['format'] = array(
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => isset($defaults[$key]['format']) ? $defaults[$key]['format'] : 'default',
+ );
+ // exclude from $content
+ $form[$name][$key]['exclude'] = array(
+ '#type' => 'checkbox',
+ '#options' => array(0 => t('Include'), 1 => t('Exclude')),
+ '#default_value' => isset($defaults[$key]['exclude']) ? $defaults[$key]['exclude'] : 0,
+ );
+ }
+ }
+
+ // Groups.
+ $label_options = array(
+ 'above' => t('Above'),
+ 'hidden' => t(''),
+ );
+ $options = array(
+ 'no_style' => t('no styling'),
+ 'simple' => t('simple'),
+ 'fieldset' => t('fieldset'),
+ 'fieldset_collapsible' => t('fieldset - collapsible'),
+ 'fieldset_collapsed' => t('fieldset - collapsed'),
+ 'hidden' => t(''),
+ );
+ foreach ($groups as $name => $group) {
+ $defaults = $group['settings']['display'];
+ $weight = $group['weight'];
+
+ $form[$name] = array(
+ 'human_name' => array('#value' => check_plain($group['label'])),
+ 'weight' => array('#type' => 'value', '#value' => $weight),
+ );
+ if ($contexts_selector == 'basic') {
+ $form[$name]['label'] = array(
+ '#type' => 'select',
+ '#options' => $label_options,
+ '#default_value' => isset($defaults['label']) ? $defaults['label'] : 'above',
+ );
+ }
+ foreach ($contexts as $key => $title) {
+ $form[$name][$key]['format'] = array(
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => isset($defaults[$key]['format']) ? $defaults[$key]['format'] : 'fieldset',
+ );
+ // exclude in $content
+ $form[$name][$key]['exclude'] = array(
+ '#type' => 'checkbox',
+ '#options' => array(0 => t('Include'), 1 => t('Exclude')),
+ '#default_value' => isset($defaults[$key]['exclude']) ? $defaults[$key]['exclude'] : 0,
+ );
+ }
+ foreach ($group['fields'] as $field_name => $field) {
+ $form[$field_name]['parent']['#value'] = $name;
+ }
+ }
+
+ $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
+ return $form;
+}
+
+/**
+ * Submit handler for the display overview form.
+ */
+function content_display_overview_form_submit($form, &$form_state) {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $form_values = $form_state['values'];
+ foreach ($form_values as $key => $values) {
+ // Groups are handled in fieldgroup_display_overview_form_submit().
+ if (in_array($key, $form['#fields'])) {
+ $field = content_fields($key, $form['#type_name']);
+ // We have some numeric keys here, so we can't use array_merge.
+ $field['display_settings'] = $values + $field['display_settings'];
+ content_field_instance_update($field, FALSE);
+ }
+ }
+
+ // Clear caches and rebuild menu.
+ content_clear_type_cache(TRUE);
+ menu_rebuild();
+
+ drupal_set_message(t('Your settings have been saved.'));
+}
+
+/**
+ * Return an array of field_type options.
+ */
+function content_field_type_options() {
+ static $options;
+
+ if (!isset($options)) {
+ $options = array();
+ $field_types = _content_field_types();
+ $field_type_options = array();
+ foreach ($field_types as $field_type_name => $field_type) {
+ // skip field types which have no widget types.
+ if (content_widget_type_options($field_type_name)) {
+ $options[$field_type_name] = t($field_type['label']);
+ }
+ }
+ asort($options);
+ }
+ return $options;
+}
+
+/**
+ * Return an array of widget type options for a field type.
+ *
+ * If no field type is provided, returns a nested array of
+ * all widget types, keyed by field type human name
+ */
+function content_widget_type_options($field_type = NULL, $by_label = FALSE) {
+ static $options;
+
+ if (!isset($options)) {
+ $options = array();
+ foreach (_content_widget_types() as $widget_type_name => $widget_type) {
+ foreach ($widget_type['field types'] as $widget_field_type) {
+ $options[$widget_field_type][$widget_type_name] = t($widget_type['label']);
+ }
+ }
+ }
+
+ if ($field_type) {
+ return !empty($options[$field_type]) ? $options[$field_type] : array();
+ }
+ elseif ($by_label) {
+ $field_types = _content_field_types();
+ $options_by_label = array();
+ foreach ($options as $field_type => $widgets) {
+ $options_by_label[t($field_types[$field_type]['label'])] = $widgets;
+ }
+ return $options_by_label;
+ }
+ else {
+ return $options;
+ }
+}
+
+/**
+ * Return an array of existing field to be added to a node type.
+ */
+function content_existing_field_options($type_name) {
+ $type = content_types($type_name);
+ $fields = content_fields();
+ $field_types = _content_field_types();
+
+ $options = array();
+ foreach ($fields as $field) {
+ if (!isset($type['fields'][$field['field_name']]) && !$field['locked']) {
+ $field_type = $field_types[$field['type']];
+ $text = t('@type: @field (@label)', array('@type' => t($field_type['label']), '@label' => t($field['widget']['label']), '@field' => $field['field_name']));
+ $options[$field['field_name']] = (drupal_strlen($text) > 80) ? truncate_utf8($text, 77) . '...' : $text;
+ }
+ }
+ // Sort the list by type, then by field name, then by label.
+ asort($options);
+
+ return $options;
+}
+
+/**
+ * A form element for selecting field, widget, and label.
+ */
+function content_field_basic_form(&$form_state, $form_values) {
+ module_load_include('inc', 'content', 'includes/content.crud');
+
+ $type_name = $form_values['type_name'];
+ $type = content_types($form_values['type_name']);
+ $field_name = $form_values['field_name'];
+ $field_type = $form_values['type'];
+ $label = $form_values['label'];
+
+ $form = array();
+
+ $form['basic'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Edit basic information'),
+ );
+ $form['basic']['field_name'] = array(
+ '#title' => t('Field name'),
+ '#type' => 'textfield',
+ '#value' => $field_name,
+ '#description' => t("The machine-readable name of the field. This name cannot be changed."),
+ '#disabled' => TRUE,
+ );
+ $form['basic']['label'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Label'),
+ '#default_value' => $label,
+ '#required' => TRUE,
+ '#description' => t('A human-readable name to be used as the label for this field in the %type content type.', array('%type' => $type['name'])),
+ );
+ $form['basic']['type'] = array(
+ '#type' => 'select',
+ '#title' => t('Field type'),
+ '#options' => content_field_type_options(),
+ '#default_value' => $field_type,
+ '#description' => t('The type of data you would like to store in the database with this field. This option cannot be changed.'),
+ '#disabled' => TRUE,
+ );
+ $form['basic']['widget_type'] = array(
+ '#type' => 'select',
+ '#title' => t('Widget type'),
+ '#required' => TRUE,
+ '#options' => content_widget_type_options($field_type),
+ '#default_value' => $form_values['widget_type'],
+ '#description' => t('The type of form element you would like to present to the user when creating this field in the %type content type.', array('%type' => $type['name'])),
+ );
+
+ $form['type_name'] = array(
+ '#type' => 'value',
+ '#value' => $type_name,
+ );
+
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Continue'),
+ );
+
+ $form['#validate'] = array();
+ $form['#submit'] = array('content_field_basic_form_submit');
+
+ return $form;
+}
+
+/**
+ * Create a new field for a content type.
+ */
+function content_field_basic_form_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+
+ $label = $form_values['label'];
+
+ // Set the right module information
+ $field_types = _content_field_types();
+ $widget_types = _content_widget_types();
+ $form_values['module'] = $field_types[$form_values['type']]['module'];
+ $form_values['widget_module'] = $widget_types[$form_values['widget_type']]['module'];
+
+ // Make sure we retain previous values and only over-write changed values.
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $instances = content_field_instance_read(array('field_name' => $form_values['field_name'], 'type_name' => $form_values['type_name']));
+ $field = array_merge(content_field_instance_collapse($instances[0]), $form_values);
+ if (content_field_instance_update($field)) {
+ drupal_set_message(t('Updated basic settings for field %label.', array(
+ '%label' => $label)));
+ }
+ else {
+ drupal_set_message(t('There was a problem updating the basic settings for field %label.', array(
+ '%label' => $label)));
+ }
+
+ $type = content_types($form_values['type_name']);
+ $form_state['redirect'] = 'admin/content/node-type/'. $type['url_str'] .'/fields/'. $form_values['field_name'];
+ $form_state['rebuild'] = FALSE;
+}
+
+/**
+ * Menu callback; present a form for removing a field from a content type.
+ */
+function content_field_remove_form(&$form_state, $type_name, $field_name) {
+ $type = content_types($type_name);
+ $field = $type['fields'][$field_name];
+
+ $form = array();
+ $form['type_name'] = array(
+ '#type' => 'value',
+ '#value' => $type_name,
+ );
+ $form['field_name'] = array(
+ '#type' => 'value',
+ '#value' => $field_name,
+ );
+
+ $output = confirm_form($form,
+ t('Are you sure you want to remove the field %field?', array('%field' => $field['widget']['label'])),
+ 'admin/content/node-type/'. $type['url_str'] .'/fields',
+ t('If you have any content left in this field, it will be lost. This action cannot be undone.'),
+ t('Remove'), t('Cancel'),
+ 'confirm'
+ );
+
+ if ($field['locked']) {
+ unset($output['actions']['submit']);
+ $output['description']['#value'] = t('This field is locked and cannot be removed.');
+ }
+
+ return $output;
+}
+
+/**
+ * Remove a field from a content type.
+ */
+function content_field_remove_form_submit($form, &$form_state) {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $form_values = $form_state['values'];
+
+ $type = content_types($form_values['type_name']);
+ $field = $type['fields'][$form_values['field_name']];
+ if ($field['locked']) {
+ return;
+ }
+
+ if ($type && $field && $form_values['confirm']) {
+ if (content_field_instance_delete($form_values['field_name'], $form_values['type_name'])) {
+ drupal_set_message(t('Removed field %field from %type.', array(
+ '%field' => $field['widget']['label'],
+ '%type' => $type['name'])));
+ }
+ else {
+ drupal_set_message(t('There was a problem deleting %field from %type.', array(
+ '%field' => $field['widget']['label'],
+ '%type' => $type['name'])));
+ }
+ $form_state['redirect'] = 'admin/content/node-type/'. $type['url_str'] .'/fields';
+ }
+}
+
+/**
+ * Menu callback; presents the field editing page.
+ */
+function content_field_edit_form(&$form_state, $type_name, $field_name) {
+ $output = '';
+ $type = content_types($type_name);
+ $field = $type['fields'][$field_name];
+
+ if ($field['locked']) {
+ $output = array();
+ $output['locked'] = array(
+ '#value' => t('The field %field is locked and cannot be edited.', array('%field' => $field['widget']['label'])),
+ );
+ return $output;
+ }
+
+ $field_types = _content_field_types();
+ $field_type = $field_types[$field['type']];
+ $widget_types = _content_widget_types();
+ $widget_type = $widget_types[$field['widget']['type']];
+
+ $title = isset($field['widget']['label']) ? $field['widget']['label'] : $field['field_name'];
+ drupal_set_title(check_plain($title));
+
+ // See if we need to change the widget type or label.
+ if (isset($form_state['change_basic'])) {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $field_values = content_field_instance_collapse($field);
+ return content_field_basic_form($form_state, $field_values);
+ }
+
+ $add_new_sequence = isset($_REQUEST['destinations']);
+
+ // Remove menu tabs when we are in an 'add new' sequence.
+ if ($add_new_sequence) {
+ menu_set_item(NULL, menu_get_item('node'));
+ }
+
+ $form = array();
+ $form['#field'] = $field;
+ $form['#type'] = $type;
+
+ // Basic iformation : hide when we are in an 'add new' sequence.
+ $form['basic'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('%type basic information', array('%type' => $type['name'])),
+ '#access' => !$add_new_sequence,
+ );
+ $form['basic']['label'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Label'),
+ '#value' => $field['widget']['label'],
+ '#disabled' => TRUE,
+ );
+ $form['basic']['field_name'] = array(
+ '#type' => 'hidden',
+ '#title' => t('Field name'),
+ '#value' => $field['field_name'],
+ '#disabled' => TRUE,
+ );
+ $form['basic']['type'] = array(
+ '#type' => 'hidden',
+ '#title' => t('Field type'),
+ '#value' => $field['type'],
+ '#disabled' => TRUE,
+ );
+ $widget_options = content_widget_type_options($field['type']);
+ $form['basic']['widget_type'] = array(
+ '#type' => 'select',
+ '#title' => t('Widget type'),
+ '#options' => $widget_options,
+ '#default_value' => $field['widget']['type'] ? $field['widget']['type'] : key($widget_options),
+ '#disabled' => TRUE,
+ );
+ $form['basic']['change'] = array(
+ '#type' => 'submit',
+ '#value' => t('Change basic information'),
+ '#submit' => array('content_field_edit_form_submit_update_basic'),
+ );
+
+ $form['widget'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('%type settings', array('%type' => $type['name'])),
+ '#description' => t('These settings apply only to the %field field as it appears in the %type content type.', array(
+ '%field' => $field['widget']['label'],
+ '%type' => $type['name'])),
+ );
+ $form['widget']['weight'] = array(
+ '#type' => 'hidden',
+ '#default_value' => $field['widget']['weight'],
+ );
+
+ $additions = (array) module_invoke($widget_type['module'], 'widget_settings', 'form', $field['widget']);
+ drupal_alter('widget_settings', $additions, 'form', $field['widget']);
+ $form['widget'] = array_merge($form['widget'], $additions);
+
+ $form['widget']['description'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Help text'),
+ '#default_value' => $field['widget']['description'],
+ '#rows' => 5,
+ '#description' => t('Instructions to present to the user below this field on the editing form. Allowed HTML tags: @tags', array('@tags' => _content_filter_xss_display_allowed_tags())),
+ '#required' => FALSE,
+ );
+
+ // Add handling for default value if not provided by field.
+ if (content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) {
+
+ // Store the original default value for use in programmed forms.
+ // Set '#default_value' instead of '#value' so programmed values
+ // can override whatever we set here.
+ $default_value = isset($field['widget']['default_value']) ? $field['widget']['default_value'] : array();
+ $default_value_php = isset($field['widget']['default_value_php']) ? $field['widget']['default_value_php'] : '';
+ $form['widget']['default_value'] = array(
+ '#type' => 'value',
+ '#default_value' => $default_value,
+ );
+ $form['widget']['default_value_php'] = array(
+ '#type' => 'value',
+ '#default_value' => $default_value_php,
+ );
+
+ // We can't tell at the time we build the form if this is a programmed
+ // form or not, so we always end up adding the default value widget
+ // even if we won't use it.
+ $form['widget']['default_value_fieldset'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Default value'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ );
+
+ // Default value widget.
+ $widget_form = array('#node' => (object) array('type' => $type_name));
+ $widget_form_state = array('values' => array($field['field_name'] => $default_value));
+ // Make sure the default value is not a required field.
+ $widget_field = $field;
+ $widget_field['required'] = FALSE;
+ module_load_include('inc', 'content', 'includes/content.node_form');
+ $form_element = content_field_form($widget_form, $widget_form_state, $widget_field, 0);
+ $form['widget']['default_value_fieldset']['default_value_widget'] = $form_element;
+ $form['widget']['default_value_fieldset']['default_value_widget']['#tree'] = TRUE;
+ // Set up form info that the default value widget will need to find in the form.
+ $form['#field_info'] = array($widget_field['field_name'] => $widget_field);
+
+ // Advanced: PHP code.
+ $form['widget']['default_value_fieldset']['advanced_options'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('PHP code'),
+ '#collapsible' => TRUE,
+ '#collapsed' => empty($field['widget']['default_value_php']),
+ );
+
+ if (user_access('Use PHP input for field settings (dangerous - grant with care)')) {
+ $db_info = content_database_info($field);
+ $columns = array_keys($db_info['columns']);
+ foreach ($columns as $key => $column) {
+ $columns[$key] = t("'@column' => value for @column", array('@column' => $column));
+ }
+ $sample = t("return array(\n 0 => array(@columns),\n // You'll usually want to stop here. Provide more values\n // if you want your 'default value' to be multi-valued:\n 1 => array(@columns),\n 2 => ...\n);", array('@columns' => implode(', ', $columns)));
+
+ $form['widget']['default_value_fieldset']['advanced_options']['default_value_php'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Code'),
+ '#default_value' => isset($field['widget']['default_value_php']) ? $field['widget']['default_value_php'] : '',
+ '#rows' => 6,
+ '#tree' => TRUE,
+ '#description' => t('Advanced usage only: PHP code that returns a default value. Should not include <?php ?> delimiters. If this field is filled out, the value returned by this code will override any value specified above. Expected format:
!sample
To figure out the expected format, you can use the devel load tab provided by devel module on a %type content page.', array(
+ '!sample' => $sample,
+ '@link_devel' => 'http://www.drupal.org/project/devel',
+ '%type' => $type_name)),
+ );
+ }
+ else {
+ $form['widget']['default_value_fieldset']['advanced_options']['markup_default_value_php'] = array(
+ '#type' => 'item',
+ '#title' => t('Code'),
+ '#value' => !empty($field['widget']['default_value_php']) ? ''. check_plain($field['widget']['default_value_php']) .'' : t('<none>'),
+ '#description' => empty($field['widget']['default_value_php']) ? t("You're not allowed to input PHP code.") : t('This PHP code was set by an administrator and will override any value specified above.'),
+ );
+ }
+ }
+
+ $form['field'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Global settings'),
+ '#description' => t('These settings apply to the %field field in every content type in which it appears.', array('%field' => $field['widget']['label'])),
+ );
+ $form['field']['required'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Required'),
+ '#default_value' => $field['required'],
+ );
+ $description = t('Maximum number of values users can enter for this field.');
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
+ $description .= ' '. t("'Unlimited' will provide an 'Add more' button so the users can add as many values as they like.");
+ }
+ $description .= ' '. t('Warning! Changing this setting after data has been created could result in the loss of data!') .'';
+ $form['field']['multiple'] = array(
+ '#type' => 'select',
+ '#title' => t('Number of values'),
+ '#options' => array(1 => t('Unlimited'), 0 => 1) + drupal_map_assoc(range(2, 10)),
+ '#default_value' => $field['multiple'],
+ '#description' => $description,
+ );
+
+ $form['field']['previous_field'] = array(
+ '#type' => 'hidden',
+ '#value' => serialize($field),
+ );
+
+ $additions = (array) module_invoke($field_type['module'], 'field_settings', 'form', $field);
+ drupal_alter('field_settings', $additions, 'form', $field);
+ $form['field'] = array_merge($form['field'], $additions);
+
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save field settings'),
+ );
+ $form['type_name'] = array(
+ '#type' => 'value',
+ '#value' => $type_name,
+ );
+ $form['field_name'] = array(
+ '#type' => 'value',
+ '#value' => $field_name,
+ );
+ $form['type'] = array(
+ '#type' => 'value',
+ '#value' => $field['type'],
+ );
+ $form['module'] = array(
+ '#type' => 'value',
+ '#value' => $field['module'],
+ );
+ $form['widget']['label'] = array(
+ '#type' => 'value',
+ '#value' => $field['widget']['label'],
+ );
+ $form['widget_module'] = array(
+ '#type' => 'value',
+ '#value' => $field['widget']['module'],
+ );
+ $form['columns'] = array(
+ '#type' => 'value',
+ '#value' => $field['columns'],
+ );
+ return $form;
+}
+
+/**
+ * Validate a field's settings.
+ */
+function content_field_edit_form_validate($form, &$form_state) {
+ $form_values = $form_state['values'];
+ if (isset($form_state['change_basic']) || $form_values['op'] == t('Change basic information')) {
+ return;
+ }
+
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $previous_field = unserialize($form_values['previous_field']);
+ $field = content_field_instance_expand($form_values);
+ $field['db_storage'] = content_storage_type($field);
+
+ $field_types = _content_field_types();
+ $field_type = $field_types[$field['type']];
+ $widget_types = _content_widget_types();
+ $widget_type = $widget_types[$field['widget']['type']];
+
+ if ($dropped_data = content_alter_db_analyze($previous_field, $field)) {
+ // @TODO
+ // This is a change that might result in loss of data.
+ // Add a confirmation form here.
+ // dsm($dropped_data);
+ }
+
+ module_invoke($widget_type['module'], 'widget_settings', 'validate', array_merge($field, $form_values));
+ module_invoke($field_type['module'], 'field_settings', 'validate', array_merge($field, $form_values));
+
+ // If content.module is handling the default value,
+ // validate the result using the field validation.
+ if (content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) {
+
+ // If this is a programmed form, get rid of the default value widget,
+ // we have the default values already.
+ if ($form['#programmed']) {
+ form_set_value(array('#parents' => array('default_value_widget')), NULL, $form_state);
+ return;
+ }
+
+ if (isset($form_values['default_value_php']) &&
+ ($php = trim($form_values['default_value_php']))) {
+ $error = FALSE;
+ ob_start();
+ $return = eval($php);
+ ob_end_clean();
+ if (!is_array($return)) {
+ $error = TRUE;
+ }
+ else {
+ foreach ($return as $item) {
+ if (!is_array($item)) {
+ $error = TRUE;
+ break;
+ }
+ }
+ }
+ if ($error) {
+ $db_info = content_database_info($field);
+ $columns = array_keys($db_info['columns']);
+ foreach ($columns as $key => $column) {
+ $columns[$key] = t("'@column' => value for @column", array('@column' => $column));
+ }
+ $sample = t("return array(\n 0 => array(@columns),\n // You'll usually want to stop here. Provide more values\n // if you want your 'default value' to be multi-valued:\n 1 => array(@columns),\n 2 => ...\n);", array('@columns' => implode(', ', $columns)));
+
+ form_set_error('default_value_php', t('The default value PHP code returned an incorrect value. Expected format:
!sample
Returned value: @value', array(
+ '!sample' => $sample,
+ '@value' => print_r($return, TRUE))));
+ return;
+ }
+ else {
+ $default_value = $return;
+ $is_code = TRUE;
+ form_set_value(array('#parents' => array('default_value_php')), $php, $form_state);
+ form_set_value(array('#parents' => array('default_value')), array(), $form_state);
+ }
+ }
+ elseif (!empty($form_values['default_value_widget'])) {
+ // Fields that handle their own multiple values may use an expected
+ // value as the top-level key, so just pop off the top element.
+ $key = array_shift(array_keys($form_values['default_value_widget']));
+ $default_value = $form_values['default_value_widget'][$key];
+ $is_code = FALSE;
+ form_set_value(array('#parents' => array('default_value_php')), '', $form_state);
+ form_set_value(array('#parents' => array('default_value')), $default_value, $form_state);
+ }
+ if (isset($default_value)) {
+ $node = array();
+ $node[$form_values['field_name']] = $default_value;
+ $field['required'] = FALSE;
+ $field_function = $field_type['module'] .'_field';
+
+ $errors_before = form_get_errors();
+
+ // Widget now does its own validation, should be no need
+ // to add anything for widget validation here.
+ if (function_exists($field_function)) {
+ $field_function('validate', $node, $field, $default_value, $form, NULL);
+ }
+ // The field validation routine won't set an error on the right field,
+ // so set it here.
+ $errors_after = form_get_errors();
+ if (count($errors_after) > count($errors_before)) {
+ if (trim($form_values['default_value_php'])) {
+ form_set_error('default_value_php', t("The PHP code for 'default value' returned @value, which is invalid.", array(
+ '@value' => print_r($default_value, TRUE))));
+ }
+ else {
+ form_set_error('default_value', t('The default value is invalid.'));
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Button submit handler.
+ */
+function content_field_edit_form_submit_update_basic($form, &$form_state) {
+ $form_state['change_basic'] = TRUE;
+ $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * Save a field's settings after editing.
+ */
+function content_field_edit_form_submit($form, &$form_state) {
+ module_load_include('inc', 'content', 'includes/content.crud');
+ $form_values = $form_state['values'];
+ content_field_instance_update($form_values);
+
+ $destinations = !empty($_REQUEST['destinations']) ? $_REQUEST['destinations'] : array();
+ // Remove any external URLs.
+ $destinations = array_diff($destinations, array_filter($destinations, 'menu_path_is_external'));
+ if ($destinations) {
+ drupal_set_message(t('Added field %label.', array('%label' => $form_values['label'])));
+ $form_state['redirect'] = content_get_destinations($destinations);
+ }
+ else {
+ drupal_set_message(t('Saved field %label.', array('%label' => $form_values['label'])));
+ $type = content_types($form_values['type_name']);
+ $form_state['redirect'] = 'admin/content/node-type/'. $type['url_str'] .'/fields';
+ }
+}
+
+/**
+ * Helper function to handle multipage redirects.
+ */
+function content_get_destinations($destinations) {
+ $query = array();
+ $path = array_shift($destinations);
+ if ($destinations) {
+ $query['destinations'] = $destinations;
+ }
+ return array($path, $query);
+}
+
+/**
+ * Content Schema Alter
+ *
+ * Alter the database schema.
+ *
+ * TODO figure out an API-safe way to use batching to update the nodes that
+ * will be affected by this change so the node_save() hooks will fire.
+ *
+ */
+function content_alter_schema($previous_field, $new_field) {
+ content_alter_db($previous_field, $new_field);
+}
+
+/**
+ * Schema Alter Analyze
+ *
+ * Analyze if changes will remove columns or delta values, thus losing data.
+ * Do this so we can delete the data and fire the necessary hooks, before
+ * we actually alter the schema.
+ */
+function content_alter_db_analyze($previous_field, $new_field) {
+ $dropped = array();
+ // There is no loss of data if there was no previous data.
+ if (empty($previous_field)) {
+ return $dropped;
+ }
+
+ // Analyze possible data loss from changes in storage type.
+ if (!empty($previous_field) && !empty($new_field)) {
+ // Changing from multiple to not multiple data, will cause loss of all
+ // values greater than zero.
+ if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD &&
+ $new_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE) {
+ $dropped['delta'] = 0;
+ }
+ // Changing from one multiple value to another will cause loss of all
+ // values for deltas greater than or equal to the new multiple value.
+ elseif (isset($previous_field['multiple']) && isset($new_field['multiple'])) {
+ if ($previous_field['multiple'] > $new_field['multiple'] &&
+ $new_field['multiple'] > 1) {
+ $dropped['delta'] = $new_field['multiple'];
+ }
+ }
+ }
+
+ // Analyze possible data loss from changes in field columns.
+ $previous_schema = !empty($previous_field) ? content_table_schema($previous_field) : array('fields' => array());
+ $new_schema = !empty($new_field) ? content_table_schema($new_field) : array('fields' => array());
+ $dropped_columns = array_diff(array_keys($previous_schema['fields']), array_keys($new_schema['fields']));
+ if ($dropped_columns) {
+ $dropped['columns'] = $dropped_columns;
+ }
+// if (empty($new_schema['fields'])) {
+// // No new columns, will lose all columns for a field.
+// foreach ($previous_schema['fields'] as $column => $attributes) {
+// $dropped['columns'][] = $column;
+// }
+// }
+// else {
+// // Check both old and new columns to see if we are deleting some columns for a field.
+// foreach ($previous_schema['fields'] as $column => $attributes) {
+// if (!isset($new_schema['fields'][$column])) {
+// $dropped['columns'][] = $column;
+// }
+// }
+// }
+
+ return $dropped;
+}
+
+/**
+ * Perform adds, alters, and drops as needed to synchronize the database with
+ * new field definitions.
+ */
+function content_alter_db($previous_field, $new_field) {
+ $ret = array();
+
+ // One or the other of these must be valid.
+ if (empty($previous_field) && empty($new_field)) {
+ return $ret;
+ }
+
+ // Gather relevant information : schema, table name...
+ $previous_schema = !empty($previous_field) ? content_table_schema($previous_field) : array();
+ $new_schema = !empty($new_field) ? content_table_schema($new_field) : array();
+ if (!empty($previous_field)) {
+ $previous_db_info = content_database_info($previous_field);
+ $previous_table = $previous_db_info['table'];
+ }
+ if (!empty($new_field)) {
+ $new_db_info = content_database_info($new_field);
+ $new_table = $new_db_info['table'];
+ }
+
+ // Deletion of a field instance: drop relevant columns and tables and return.
+ if (empty($new_field)) {
+ if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
+ db_drop_table($ret, $previous_table);
+ }
+ else {
+ foreach ($previous_schema['fields'] as $column => $attributes) {
+ if (!in_array($column, array('nid', 'vid', 'delta'))) {
+ db_drop_field($ret, $previous_table, $column);
+ }
+ }
+ }
+ content_alter_db_cleanup();
+ return $ret;
+ }
+
+ // Check that content types that have fields do have a per-type table.
+ if (!empty($new_field)) {
+ $base_tablename = _content_tablename($new_field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ if (!db_table_exists($base_tablename)) {
+ db_create_table($ret, $base_tablename, content_table_schema());
+ }
+ }
+
+ // Create new table and columns, if not already created.
+ if (!db_table_exists($new_table)) {
+ db_create_table($ret, $new_table, $new_schema);
+ }
+ else {
+ // Or add fields and/or indexes to an existing table.
+ foreach ($new_schema['fields'] as $column => $attributes) {
+ if (!in_array($column, array('nid', 'vid', 'delta'))) {
+ // Create the column if it does not exist.
+ if (!db_column_exists($new_table, $column)) {
+ db_add_field($ret, $new_table, $column, $attributes);
+ }
+ // Create the index if requested to, and it does not exist.
+ if (isset($new_schema['indexes'][$column]) && !content_db_index_exists($new_table, $column)) {
+ db_add_index($ret, $new_table, $column, $new_schema['indexes'][$column]);
+ }
+ }
+ }
+ }
+
+ // If this is a new field, we're done.
+ if (empty($previous_field)) {
+ content_alter_db_cleanup();
+ return $ret;
+ }
+
+ // If the previous table doesn't exist, we're done.
+ // Could happen if someone tries to run a schema update from an
+ // content.install update function more than once.
+ if (!db_table_exists($previous_table)) {
+ content_alter_db_cleanup();
+ return $ret;
+ }
+
+ // If changing data from one schema to another, see if changes require that
+ // we drop multiple values or migrate data from one storage type to another.
+ $migrate_columns = array_intersect_assoc($new_schema['fields'], $previous_schema['fields']);
+ unset($migrate_columns['nid'], $migrate_columns['vid'], $migrate_columns['delta']);
+
+ // If we're going from one multiple value a smaller one or to single,
+ // drop all delta values higher than the new maximum delta value.
+ // Not needed if the new multiple is unlimited or if the new table is the content table.
+ if ($new_table != $base_tablename && $new_field['multiple'] < $previous_field['multiple'] && $new_field['multiple'] != 1) {
+ db_query("DELETE FROM {". $new_table ."} WHERE delta >= ". max(1, $new_field['multiple']));
+ }
+
+ // If going from multiple to non-multiple, make sure the field tables have
+ // the right database structure to accept migrated data.
+ if ($new_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
+ if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD && count($previous_schema['fields'])) {
+ // Already using per-field storage; change multiplicity if needed.
+ if ($previous_field['multiple'] > 0 && $new_field['multiple'] == 0) {
+ db_drop_field($ret, $new_table, 'delta');
+ db_drop_primary_key($ret, $new_table);
+ db_add_primary_key($ret, $new_table, array('vid'));
+ }
+ else if ($previous_field['multiple'] == 0 && $new_field['multiple'] > 0) {
+ db_add_field($ret, $new_table, 'delta', array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0));
+ db_drop_primary_key($ret, $new_table);
+ db_add_primary_key($ret, $new_table, array('vid', 'delta'));
+ }
+ }
+ }
+
+ // Migrate data from per-content-type storage.
+ if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE &&
+ $new_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
+ $columns = array_keys($migrate_columns);
+ if ($new_field['multiple']) {
+ db_query('INSERT INTO {'. $new_table .'} (vid, nid, delta, '. implode(', ', $columns) .') '.
+ ' SELECT vid, nid, 0, '. implode(', ', $columns) .' FROM {'. $previous_table .'}');
+ }
+ else {
+ db_query('INSERT INTO {'. $new_table .'} (vid, nid, '. implode(', ', $columns) .') '.
+ ' SELECT vid, nid, '. implode(', ', $columns) .' FROM {'. $previous_table .'}');
+ }
+ foreach ($columns as $column_name) {
+ db_drop_field($ret, $previous_table, $column_name);
+ }
+ }
+
+ // Migrate data from per-field storage, and drop per-field table.
+ if ($previous_field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD &&
+ $new_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE) {
+ // In order to be able to use drupal_write_record, we need to
+ // rebuild the schema now.
+ content_alter_db_cleanup();
+ if ($previous_field['multiple']) {
+ $result = db_query("SELECT * FROM {". $previous_table ."} c JOIN {node} n ON c.nid = n.nid WHERE delta = 0 AND n.type = '%s'", $new_field['type_name']);
+ }
+ else {
+ $result = db_query("SELECT * FROM {". $previous_table ."} c JOIN {node} n ON c.nid = n.nid WHERE n.type = '%s'", $new_field['type_name']);
+ }
+ $record = array();
+ while ($data = db_fetch_array($result)) {
+ $record['nid'] = $data['nid'];
+ $record['vid'] = $data['vid'];
+ if ($previous_field['multiple']) {
+ $record['delta'] = $data['delta'];
+ }
+ foreach ($migrate_columns as $column => $attributes) {
+ if (is_null($data[$column])) {
+ $record[$column] = NULL;
+ }
+ else {
+ $record[$column] = $data[$column];
+ // Prevent double serializtion in drupal_write_record.
+ if (isset($attributes['serialize']) && $attributes['serialize']) {
+ $record[$column] = unserialize($record[$column]);
+ }
+ }
+ }
+ if (db_result(db_query('SELECT COUNT(*) FROM {'. $new_table .
+ '} WHERE vid = %d AND nid = %d', $data['vid'], $data['nid']))) {
+ $keys = $new_field['multiple'] ? array('vid', 'delta') : array('vid');
+ drupal_write_record($new_table, $record, $keys);
+ }
+ else {
+ drupal_write_record($new_table, $record);
+ }
+ }
+ db_drop_table($ret, $previous_table);
+ }
+
+ // Change modified columns that don't involve storage changes.
+ foreach ($new_schema['fields'] as $column => $attributes) {
+ if (isset($previous_schema['fields'][$column]) &&
+ $previous_field['db_storage'] == $new_field['db_storage']) {
+ if ($attributes != $previous_schema['fields'][$column]) {
+ if (!in_array($column, array('nid', 'vid', 'delta'))) {
+ db_change_field($ret, $new_table, $column, $column, $attributes);
+ }
+ }
+ }
+ }
+
+ // Remove obsolete columns.
+ foreach ($previous_schema['fields'] as $column => $attributes) {
+ if (!isset($new_schema['fields'][$column])) {
+ if (!in_array($column, array('nid', 'vid', 'delta'))) {
+ db_drop_field($ret, $previous_table, $column);
+ }
+ }
+ }
+
+ // TODO: debugging stuff - should be removed
+ if (module_exists('devel')) {
+ //dsm($ret);
+ }
+ return $ret;
+}
+
+/**
+ * Helper function for handling cleanup operations when schema changes are made.
+ */
+function content_alter_db_cleanup() {
+ // Rebuild the whole database schema.
+ // TODO: this could be optimized. We don't need to rebuild in *every case*...
+ // Or do we? This affects the schema and menu and may have unfortunate
+ // delayed effects if we don't clear everything out at this point.
+ content_clear_type_cache(TRUE);
+}
+
+/**
+ * Helper function to order fields and groups when theming (preprocessing)
+ * overview forms.
+ *
+ * The $form is passed by reference because we assign depths as parenting
+ * relationships are sorted out.
+ */
+function _content_overview_order(&$form, $field_rows, $group_rows) {
+ // Put weight and parenting values into a $dummy render structure
+ // and let drupal_render figure out the corresponding row order.
+ $dummy = array();
+ // Group rows: account for weight.
+ if (module_exists('fieldgroup')) {
+ foreach ($group_rows as $name) {
+ $dummy[$name] = array('#weight' => $form[$name]['weight']['#value'], '#value' => $name .' ');
+ }
+ }
+ // Field rows : account for weight and parenting.
+ foreach ($field_rows as $name) {
+ $dummy[$name] = array('#weight' => $form[$name]['weight']['#value'], '#value' => $name .' ');
+ if (module_exists('fieldgroup')) {
+ if ($parent = $form[$name]['parent']['#value']) {
+ $form[$name]['#depth'] = 1;
+ $dummy[$parent][$name] = $dummy[$name];
+ unset($dummy[$name]);
+ }
+ }
+ }
+ return $dummy ? explode(' ', trim(drupal_render($dummy))) : array();
+}
+
+/**
+ * Batching process for changing the field schema,
+ * running each affected node through node_save() first, to
+ * fire all hooks.
+ *
+ * TODO This is just a placeholder for now because batching can't be safely
+ * used with API hooks. Need to come back and figure out how to incorporate
+ * this and get it working properly when the fields are altered via the API.
+ */
+function content_alter_fields($previous_field, $new_field) {
+ // See what values need to be updated in the field data.
+ $mask = content_alter_db_mask($previous_field, $new_field);
+
+ // We use batch processing to prevent timeout when updating a large number
+ // of nodes. If there is no previous data to adjust, we can just go straight
+ // to altering the schema, otherwise use batch processing to update
+ // the database one node at a time, then update the schema.
+ if (empty($mask)) {
+ return content_alter_db($previous_field, $new_field);
+ }
+ $updates = array(
+ 'mask' => $mask['mask'],
+ 'alt_mask' => $mask['alt_mask'],
+ 'delta' => $mask['delta'],
+ );
+ $batch = array(
+ 'operations' => array(
+ array('content_field_batch_update', array($previous_field['field_name'] => $updates)),
+ array('content_alter_db', array($previous_field, $new_field))
+ ),
+ 'finished' => '_content_alter_fields_finished',
+ 'title' => t('Processing'),
+ 'error_message' => t('The update has encountered an error.'),
+ 'file' => './'. drupal_get_path('module', 'content') .'/includes/content.admin.inc',
+ );
+ batch_set($batch);
+ if (!empty($url)) {
+ batch_process($url, $url);
+ }
+}
+
+/**
+ * Content Replace Fields 'finished' callback.
+ */
+function _content_alter_fields_finished($success, $results, $operations) {
+ if ($success) {
+ drupal_set_message(t('The database has been altered and data has been migrated or deleted.'));
+ }
+ else {
+ drupal_set_message(t('An error occurred and database alteration did not complete.'), 'error');
+ $message = format_plural(count($results), '1 item successfully processed:', '@count items successfully processed:');
+ $message .= theme('item_list', $results);
+ drupal_set_message($message);
+ }
+}
+
+/**
+ * Create a mask for the column data that should be deleted in each field.
+ *
+ * This is a bit tricky. We could theoretically have some columns
+ * that should be set to empty and others with valid info that should
+ * not be emptied out. But if delta values > X are to be wiped out, they
+ * need to wipe out even columns that still have values. And the NULL
+ * values in these columns after the alteration may be enough to make
+ * the item 'empty', as defined by hook_content_is_empty(), even if
+ * some columns still have values, so all these things need to be tested.
+ */
+function content_alter_db_mask($previous_field, $new_field) {
+ // Get an array of column values that will be dropped by this
+ // schema change and create a mask to feed to content_batch_update.
+
+ $dropped = content_alter_db_analyze($previous_field, $new_field);
+ if (empty($dropped)) {
+ return array();
+ }
+ $mask = array('mask' => array());
+ foreach (array_keys($previous_field['columns']) as $column_name) {
+ // The basic mask will empty the dropped columns.
+ if (isset($dropped['columns']) && in_array($column_name, $dropped['columns'])) {
+ $mask['mask'][$column_name] = NULL;
+ }
+ // Over the delta we'll empty all columns.
+ if (isset($dropped['delta'])) {
+ $mask['alt_mask'][$column_name] = NULL;
+ }
+ }
+ if (isset($dropped['delta'])) {
+ $mask['delta'] = $dropped['delta'];
+ }
+ return $mask;
+}
+
+/**
+ * Content Field Batch Update Operation
+ *
+ * Find all nodes that contain a field and update their values.
+ *
+ * @param $updates
+ * an array like:
+ * 'field_name' => array(
+ * 'mask' => array()
+ * // Keyed array of column names and replacement values for use
+ * // below delta, or for all values if no delta is supplied.
+ * 'alt_mask' => array()
+ * // Optional, keyed array of column names and replacement values for use
+ * // at or above delta, if a delta is supplied.
+ * 'delta' => #
+ * // Optional, the number to use as the delta value where you switch from
+ * // one mask to the other.
+ * ),
+ */
+function content_field_batch_update($updates, &$context) {
+ if (empty($field)) {
+ $context['finished'] = 1;
+ return;
+ }
+ $field_name = $updates['field_name'];
+ $field = content_fields($field_name);
+
+ if (!isset($context['sandbox']['progress'])) {
+ $db_info = content_database_info($field);
+
+ // Might run into non-existent tables when cleaning up a corrupted
+ // database, like some of the old content storage changes in the
+ // .install files.
+ if (!db_table_exists($db_info['table'])) {
+ return $context['finished'] = 1;
+ }
+ $nodes = array();
+ $result = db_query("SELECT nid FROM {". $db_info['table'] ."}");
+ while ($node = db_fetch_array($result)) {
+ $nodes[] = $node['nid'];
+ }
+ $context['sandbox']['progress'] = 0;
+ $context['sandbox']['max'] = count($nodes);
+ $context['sandbox']['nodes'] = $nodes;
+ }
+
+ // Process nodes by groups of 5.
+ $count = min(5, count($context['sandbox']['nodes']));
+
+ for ($i = 1; $i <= $count; $i++) {
+ // For each nid, load the node, empty the column values
+ // or the whole field, and re-save it.
+ $nid = array_shift($context['sandbox']['nodes']);
+ $node = content_field_replace($nid, array($updates));
+
+ // Store result for post-processing in the finished callback.
+ $context['results'][] = l($node->title, 'node/'. $node->nid);
+
+ // Update our progress information.
+ $context['sandbox']['progress']++;
+ $context['message'] = t('Processing %title', array('%title' => $node->title));
+ }
+
+ // Inform the batch engine that we are not finished,
+ // and provide an estimation of the completion level we reached.
+ if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+ $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+ }
+}
+
+/**
+ * Content Field Replace
+ *
+ * Replace field values in a node from an array of update values.
+ *
+ * Supply an array of one or more fields and masks of field column values
+ * to be replaced into field values, one mask for basic values and an optional
+ * different mask for values in field items equal to or higher than a
+ * specified delta.
+ *
+ * The masks should contain only the column values to be substituted in.
+ * The supplied values will be merged into the existing values to replace
+ * only the values in the mask, leaving all other values unchanged.
+ *
+ * The ability to set different masks starting at a delta allows the
+ * possibility of setting values above a certain delta to NULL prior
+ * to altering the database schema.
+ *
+ * @param $nid
+ * @param $updates
+ * an array like:
+ * 'field_name' => array(
+ * 'mask' => array()
+ * // Keyed array of column names and replacement values for use
+ * // below delta, or for all values if no delta is supplied.
+ * 'alt_mask' => array()
+ * // Optional, keyed array of column names and replacement values for use
+ * // at or above delta, if a delta is supplied.
+ * 'delta' => #
+ * // Optional, the number to use as the delta value where you switch from
+ * // one mask to the other.
+ * ),
+ */
+function content_field_replace($nid, $updates) {
+ $node = node_load($nid, NULL, TRUE);
+ foreach ($updates as $field_name => $update) {
+ $items = isset($node->$field_name) ? $node->$field_name : array();
+ foreach ($items as $delta => $value) {
+ $field_mask = (isset($update['delta']) && isset($update['alt_mask']) && $delta >= $update['delta']) ? $update['alt_mask'] : $mask['mask'];
+ // Merge the mask into the field values to do the replacements.
+ $items[$delta] = array_merge($items[$delta], $field_mask);
+ }
+ // Test if the new values will make items qualify as empty.
+ $items = content_set_empty($field, $items);
+ $node->$field_name = $items;
+ }
+ node_save($node);
+ return $node;
+}
+
+/**
+ * Helper form element validator : integer.
+ */
+function _element_validate_integer($element, &$form_state) {
+ $value = $element['#value'];
+ if ($value !== '' && (!is_numeric($value) || intval($value) != $value)) {
+ form_error($element, t('%name must be an integer.', array('%name' => $element['#title'])));
+ }
+}
+
+/**
+ * Helper form element validator : integer > 0.
+ */
+function _element_validate_integer_positive($element, &$form_state) {
+ $value = $element['#value'];
+ if ($value !== '' && (!is_numeric($value) || intval($value) != $value || $value <= 0)) {
+ form_error($element, t('%name must be a positive integer.', array('%name' => $element['#title'])));
+ }
+}
+
+/**
+ * Helper form element validator : number.
+ */
+function _element_validate_number($element, &$form_state) {
+ $value = $element['#value'];
+ if ($value != '' && !is_numeric($value)) {
+ form_error($element, t('%name must be a number.', array('%name' => $element['#title'])));
+ }
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.crud.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.crud.inc
new file mode 100644
index 00000000000..2942940eaf6
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.crud.inc
@@ -0,0 +1,695 @@
+ widget nested array that is used
+ * by the content module, or in flattened $form_values arrays, by
+ * converting flattened arrays to the nested format.
+ *
+ * A hook_content_fieldapi() is available for each field instance action,
+ * and each hook receives the nested field => widget array as an argument.
+ *
+ * The hook_content_fieldapi() $ops include:
+ *
+ * - create instance
+ * - read instance
+ * - update instance
+ * - delete instance
+ *
+ * Another function, content_module_delete($module) will clean up
+ * after a module that has been deleted by removing all data and
+ * settings information that was created by that module.
+ */
+
+/**
+ * Create an array of default values for a field type.
+ */
+function content_field_default_values($field_type) {
+ $field_types = _content_field_types();
+ $module = $field_types[$field_type]['module'];
+
+ $field = array(
+ 'module' => $module,
+ 'type' => $field_type,
+ 'active' => 0,
+ );
+
+ if (module_exists($module)) {
+ $field['active'] = 1;
+ }
+
+ $field['columns'] = (array) module_invoke($module, 'field_settings', 'database columns', $field);
+ // Ensure columns always default to NULL values.
+ foreach ($field['columns'] as $column_name => $column) {
+ $field['columns'][$column_name]['not null'] = FALSE;
+ }
+
+ $field['required'] = 0;
+ $field['multiple'] = 0;
+ $field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
+
+ // Make sure field settings all have an index in the array.
+ $setting_names = (array) module_invoke($module, 'field_settings', 'save', $field);
+ drupal_alter('field_settings', $setting_names, 'save', $field);
+ foreach ($setting_names as $setting) {
+ $field[$setting] = NULL;
+ }
+ return $field;
+}
+
+/**
+ * Create an array of default values for a field instance.
+ */
+function content_instance_default_values($field_name, $type_name, $widget_type) {
+ $widget_types = _content_widget_types();
+ $module = $widget_types[$widget_type]['module'];
+
+ $widget = array(
+ 'field_name' => $field_name,
+ 'type_name' => $type_name,
+ 'weight' => 0,
+ 'label' => $field_name,
+ 'description' => '',
+ 'widget_type' => $widget_type,
+ 'widget_module' => $module,
+ 'display_settings' => array(),
+ 'widget_settings' => array(),
+ );
+
+ if (module_exists($module)) {
+ $widget['widget_active'] = 1;
+ }
+
+ $settings_names = array_merge(array('label'), array_keys(content_build_modes()));
+ $widget['display_settings'] = array();
+ foreach ($settings_names as $name) {
+ $widget['display_settings'][$name]['format'] = ($name == 'label') ? 'above' : 'default';
+ $widget['display_settings'][$name]['exclude'] = 0;
+ }
+
+ // Make sure widget settings all have an index in the array.
+ $settings_names = (array) module_invoke($module, 'widget_settings', 'save', $widget);
+ drupal_alter('widget_settings', $settings_names, 'save', $widget);
+ $widget['widget_settings'] = array();
+ foreach ($settings_names as $name) {
+ $widget['widget_settings'][$name] = NULL;
+ }
+ return $widget;
+}
+
+/**
+ * Expand field info to create field => widget info.
+ */
+function content_field_instance_expand($field) {
+ if (isset($field['widget'])) {
+ return $field;
+ }
+ $field['widget'] = !empty($field['widget_settings']) ? $field['widget_settings'] : array();
+ $field['widget']['label'] = !empty($field['label']) ? $field['label'] : $field['field_name'];
+ $field['widget']['weight'] = !empty($field['weight']) ? $field['weight'] : 0;
+ $field['widget']['description'] = !empty($field['description']) ? $field['description'] : '';
+
+ if (!empty($field['widget_type'])) {
+ $field['widget']['type'] = $field['widget_type'];
+ $widget_types = _content_widget_types();
+ $field['widget']['module'] = isset($widget_types[$field['widget_type']]['module']) ? $widget_types[$field['widget_type']]['module'] : $field['widget_module'];
+ }
+ elseif (!empty($field['widget_module'])) {
+ $field['widget']['module'] = $field['widget_module'];
+ }
+
+ unset($field['widget_type']);
+ unset($field['weight']);
+ unset($field['label']);
+ unset($field['description']);
+ unset($field['widget_module']);
+ unset($field['widget_settings']);
+
+ // If content.module is handling the default value,
+ // initialize $widget_settings with default values,
+ if (isset($field['default_value']) && isset($field['default_value_php']) &&
+ content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) {
+ $field['widget']['default_value'] = !empty($field['default_value']) ? $field['default_value'] : NULL;
+ $field['widget']['default_value_php'] = !empty($field['default_value_php']) ? $field['default_value_php'] : NULL;
+ unset($field['default_value']);
+ unset($field['default_value_php']);
+ }
+ return $field;
+}
+
+/**
+ * Collapse field info from field => widget to flattened form values.
+ */
+function content_field_instance_collapse($field) {
+ if (!isset($field['widget'])) {
+ return $field;
+ }
+ $field['widget_settings'] = !empty($field['widget']) ? $field['widget'] : array();
+ $field['widget_type'] = !empty($field['widget']['type']) ? $field['widget']['type'] : '';
+ $field['weight'] = !empty($field['widget']['weight']) ? $field['widget']['weight'] : 0;
+ $field['label'] = !empty($field['widget']['label']) ? $field['widget']['label'] : $field['field_name'];
+ $field['description'] = !empty($field['widget']['description']) ? $field['widget']['description'] : '';
+ $field['type_name'] = !empty($field['type_name']) ? $field['type_name'] : '';
+
+ if (!empty($field['widget']['module'])) {
+ $widget_module = $field['widget']['module'];
+ }
+ elseif (!empty($field['widget']['type'])) {
+ $widget_types = _content_widget_types();
+ $widget_module = $widget_types[$field['widget']['type']]['module'];
+ }
+ else {
+ $widget_module = '';
+ }
+ $field['widget_module'] = $widget_module;
+ unset($field['widget_settings']['type']);
+ unset($field['widget_settings']['weight']);
+ unset($field['widget_settings']['label']);
+ unset($field['widget_settings']['description']);
+ unset($field['widget_settings']['module']);
+ unset($field['widget']);
+ return $field;
+}
+
+/**
+ * Create a new field instance.
+ *
+ * @param $field
+ * An array of properties to create the field with, input either in
+ * the field => widget format used by the content module or as an
+ * array of form values.
+ *
+ * Required values:
+ * - field_name, the name of the field to be created
+ * - type_name, the content type of the instance to be created
+ *
+ * If there is no prior instance to create this from, we also need:
+ * - type, the type of field to create
+ * - widget_type, the type of widget to use
+ * @param $rebuild
+ * TRUE to clear content type caches and rebuild menu (default).
+ * FALSE allows the caller to process several fields at a time quickly, but then
+ * the caller is reponsible to clear content type caches and rebuild menu as soon
+ * as all fields have been processed. For example:
+ * @code
+ * // Create several fields at a time.
+ * foreach ($fields as $field) {
+ * content_field_instance_create($field, FALSE);
+ * }
+ * // Clear caches and rebuild menu.
+ * content_clear_type_cache(TRUE);
+ * menu_rebuild();
+ * @endcode
+ * @see content_clear_type_cache()
+ * @see menu_rebuild()
+ */
+function content_field_instance_create($field, $rebuild = TRUE) {
+ include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');
+
+ $form_values = $field;
+ $field = content_field_instance_expand($field);
+
+ // If there are prior instances, fill out missing values from the prior values,
+ // otherwise get missing values from default values.
+ $prior_instances = content_field_instance_read(array('field_name' => $field['field_name']));
+ if (!empty($prior_instances) && is_array($prior_instances)) {
+ $prev_field = content_field_instance_expand($prior_instances[0]);
+
+ // Weight, label, and description may have been forced into the $field
+ // by content_field_instance_expand(). If there is a previous instance to
+ // get these values from and there was no value supplied originally, use
+ // the previous value.
+ $field['widget']['weight'] = isset($form_values['weight']) ? $form_values['weight'] : $prev_field['widget']['weight'];
+ $field['widget']['label'] = isset($form_values['label']) ? $form_values['label'] : $prev_field['widget']['label'];
+ $field['widget']['description'] = isset($form_values['description']) ? $form_values['description'] : $prev_field['widget']['description'];
+ }
+ else {
+ $prev_field = array('widget' => array());
+ }
+
+ // If we have a field type, we can build default values for this field type.
+ $default_values = array('widget' => array());
+ if (isset($field['type'])) {
+ $default_values = content_field_default_values($field['type']);
+ $default_instance_values = content_instance_default_values($field['field_name'], $field['type_name'], $field['widget']['type']);
+ $default_values = content_field_instance_expand(array_merge($default_values, $default_instance_values));
+ }
+
+ // Merge default values, previous values, and current values to create
+ // a complete field array.
+ $widget = array_merge($default_values['widget'], $prev_field['widget'], $field['widget']);
+ $field = array_merge($default_values, $prev_field, $field);
+ $field['widget'] = $widget;
+
+ // Make sure we know what module to invoke for field info.
+ if (empty($field['module']) && !empty($field['type'])) {
+ $field_types = _content_field_types();
+ $field['module'] = $field_types[$field['type']]['module'];
+ }
+
+ // The storage type may need to be updated.
+ $field['db_storage'] = content_storage_type($field);
+
+ // Get a fresh copy of the column information whenever a field is created.
+ $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);
+
+ if (empty($prev_field['widget']) || $prior_instances < 1) {
+ // If this is the first instance, create the field.
+ $field['db_storage'] = $field['multiple'] > 0 ? CONTENT_DB_STORAGE_PER_FIELD : CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
+ _content_field_write($field, 'create');
+ }
+ elseif (!empty($prev_field['widget']) && $prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 0) {
+ // If the database storage has changed, update the field and previous instances.
+ $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+ foreach ($prior_instances as $instance) {
+ $new_instance = $instance;
+ $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+ // Invoke hook_content_fieldapi().
+ module_invoke_all('content_fieldapi', 'update instance', $new_instance);
+
+ content_alter_schema($instance, $new_instance);
+ }
+ }
+
+ // Invoke hook_content_fieldapi().
+ module_invoke_all('content_fieldapi', 'create instance', $field);
+
+ // Update the field and the instance with the latest values.
+ _content_field_write($field, 'update');
+ _content_field_instance_write($field, 'create');
+
+ content_alter_schema(array(), $field);
+
+ if ($rebuild) {
+ content_clear_type_cache(TRUE);
+ menu_rebuild();
+ }
+
+ return $field;
+}
+
+/**
+ * Update an existing field instance.
+ *
+ * @param $field
+ * An array of properties to update the field with, input either in
+ * the field => widget format used by the content module or as an
+ * array of form values.
+ * @param $rebuild
+ * TRUE to clear content type caches and rebuild menu (default).
+ * FALSE allows the caller to process several fields at a time quickly, but then
+ * the caller is reponsible to clear content type caches and rebuild menu as soon
+ * as all fields have been processed. For example:
+ * @code
+ * // Update several fields at a time.
+ * foreach ($fields as $field) {
+ * content_field_instance_update($field, FALSE);
+ * }
+ * // Clear caches and rebuild menu.
+ * content_clear_type_cache(TRUE);
+ * menu_rebuild();
+ * @endcode
+ * @see content_clear_type_cache()
+ * @see menu_rebuild()
+ */
+function content_field_instance_update($field, $rebuild = TRUE) {
+ include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');
+
+ // Ensure the field description is in the 'expanded' form.
+ $field = content_field_instance_expand($field);
+
+ // Get the previous value from the table.
+ $previous = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $field['type_name']));
+ $prev_field = array_pop($previous);
+
+ // Create a complete field array by merging the previous and current values,
+ // letting the current values overwrite the previous ones.
+ $widget = array_merge($prev_field['widget'], $field['widget']);
+ $field = array_merge($prev_field, $field);
+ $field['widget'] = $widget;
+
+ // Make sure we know what module to invoke for field info.
+ if (empty($field['module']) && !empty($field['type'])) {
+ $field_types = _content_field_types();
+ $field['module'] = $field_types[$field['type']]['module'];
+ }
+
+ // The storage type may need to be updated.
+ $field['db_storage'] = content_storage_type($field);
+
+ // Changes in field values may affect columns, or column
+ // information may have changed, get a fresh copy.
+ $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);
+
+ // If the database storage has changed, update the field and previous instances.
+ $prior_instances = content_field_instance_read(array('field_name' => $field['field_name']));
+
+ if ($prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 1) {
+ // Update the field's data storage.
+ $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+ // Update the schema for prior instances to adapt to the change in db storage.
+ foreach ($prior_instances as $instance) {
+ if ($instance['type_name'] != $field['type_name']) {
+ $new_instance = $instance;
+ $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+ // Invoke hook_content_fieldapi().
+ module_invoke_all('content_fieldapi', 'update instance', $new_instance);
+
+ content_alter_schema($instance, $new_instance);
+ }
+ }
+ }
+
+ // Invoke hook_content_fieldapi().
+ module_invoke_all('content_fieldapi', 'update instance', $field);
+
+ // Update the field and the instance with the latest values.
+ _content_field_write($field, 'update');
+ _content_field_instance_write($field, 'update');
+
+ content_alter_schema($prev_field, $field);
+
+ if ($rebuild) {
+ content_clear_type_cache(TRUE);
+
+ // The label is in the menu tree, so we need a menu rebuild
+ // if the label changes.
+ if ($prev_field['widget']['label'] != $field['widget']['label']) {
+ menu_rebuild();
+ }
+ }
+
+ return $field;
+}
+
+/**
+ * Write a field record.
+ *
+ * @param $field
+ * The field array to process.
+ */
+function _content_field_write($field, $op = 'update') {
+ // Rearrange the data to create the global_settings array.
+ $field['global_settings'] = array();
+ $setting_names = (array) module_invoke($field['module'], 'field_settings', 'save', $field);
+ drupal_alter('field_settings', $setting_names, 'save', $field);
+
+ foreach ($setting_names as $setting) {
+ // Unlike _content_field_instance_write() and 'widget_settings', 'global_settings'
+ // is never preexisting, so we take no particular precautions here.
+ $field['global_settings'][$setting] = isset($field[$setting]) ? $field[$setting] : '';
+ unset($field[$setting]);
+ }
+ // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
+ $field['db_columns'] = $field['columns'];
+
+ switch ($op) {
+ case 'create':
+ drupal_write_record(content_field_tablename(), $field);
+ break;
+ case 'update':
+ drupal_write_record(content_field_tablename(), $field, 'field_name');
+ break;
+ }
+ unset($field['db_columns']);
+ return $field;
+}
+
+/**
+ * Write a field instance record.
+ *
+ * @param $field
+ * The field array to process.
+ */
+function _content_field_instance_write($field, $op = 'update') {
+ // Collapse the field => widget format, so that the values to be saved by
+ // drupal_write_record are on top-level.
+ $field = content_field_instance_collapse($field);
+
+ // Rearrange the data to create the widget_settings array.
+ $setting_names = (array) module_invoke($field['widget_module'], 'widget_settings', 'save', $field);
+ drupal_alter('widget_settings', $setting_names, 'save', $field);
+ foreach ($setting_names as $setting) {
+ // In some cases (when the updated $field was originally read from
+ // the db, as opposed to gathered from the values of a form), the values
+ // are already in the right place, we take care to not wipe them.
+ if (isset($field[$setting])) {
+ $field['widget_settings'][$setting] = $field[$setting];
+ unset($field[$setting]);
+ }
+ }
+
+ switch ($op) {
+ case 'create':
+ drupal_write_record(content_instance_tablename(), $field);
+ break;
+ case 'update':
+ drupal_write_record(content_instance_tablename(), $field, array('field_name', 'type_name'));
+ break;
+ }
+ return $field;
+}
+
+/**
+ * Load a field instance.
+ *
+ * @param $param
+ * An array of properties to use in selecting a field instance. Valid keys:
+ * - 'type_name' - The name of the content type in which the instance exists.
+ * - 'field_name' - The name of the field whose instance is to be loaded.
+ * if NULL, all instances will be returned.
+ * @param $include_inactive
+ * TRUE will return field instances that are 'inactive', because their field
+ * module or widget module is currently disabled.
+ * @return
+ * The field arrays.
+ */
+function content_field_instance_read($param = NULL, $include_inactive = FALSE) {
+ $cond = array();
+ $args = array();
+ if (is_array($param)) {
+ // Turn the conditions into a query.
+ foreach ($param as $key => $value) {
+ $cond[] = 'nfi.'. db_escape_string($key) ." = '%s'";
+ $args[] = $value;
+ }
+ }
+ if (!$include_inactive) {
+ $cond[] = 'nf.active = 1';
+ $cond[] = 'nfi.widget_active = 1';
+ }
+ $where = $cond ? ' WHERE '. implode(' AND ', $cond) : '';
+
+ $db_result = db_query("SELECT * FROM {". content_instance_tablename() ."} nfi ".
+ " JOIN {". content_field_tablename() ."} nf ON nfi.field_name = nf.field_name ".
+ "$where ORDER BY nfi.weight ASC, nfi.label ASC", $args);
+
+ $fields = array();
+ while ($instance = db_fetch_array($db_result)) {
+ // Unserialize arrays.
+ foreach (array('widget_settings', 'display_settings', 'global_settings', 'db_columns') as $key) {
+ $instance[$key] = (!empty($instance[$key])) ? (array) unserialize($instance[$key]) : array();
+ }
+ // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
+ $instance['columns'] = $instance['db_columns'];
+ unset($instance['db_columns']);
+
+ // Unfold 'global_settings'.
+ foreach ($instance['global_settings'] as $key => $value) {
+ $instance[$key] = $value;
+ }
+ unset($instance['global_settings']);
+
+ // Put the field in the $field => 'widget' structure that is used
+ // all around content.module.
+ $field = content_field_instance_expand($instance);
+
+ // Invoke hook_content_fieldapi().
+ module_invoke_all('content_fieldapi', 'read instance', $field);
+ $fields[] = $field;
+ }
+ return $fields;
+}
+
+/**
+ * Delete an existing field instance.
+ *
+ * @param $field_name
+ * The field name to delete.
+ * @param $type_name
+ * The content type where the field instance is going to be deleted.
+ * @param $rebuild
+ * TRUE to clear content type caches and rebuild menu (default).
+ * FALSE allows the caller to process several fields at a time quickly, but then
+ * the caller is reponsible to clear content type caches and rebuild menu as soon
+ * as all fields have been processed. For example:
+ * @code
+ * // Delete several fields at a time.
+ * foreach ($fields as $field) {
+ * content_field_instance_delete($field['field_name'], $type_name, FALSE);
+ * }
+ * // Clear caches and rebuild menu.
+ * content_clear_type_cache(TRUE);
+ * menu_rebuild();
+ * @endcode
+ * @see content_clear_type_cache()
+ * @see menu_rebuild()
+ */
+function content_field_instance_delete($field_name, $type_name, $rebuild = TRUE) {
+ include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');
+
+ // Get the previous field value.
+ $field = array_pop(content_field_instance_read(array('field_name' => $field_name, 'type_name' => $type_name)));
+
+ // Invoke hook_content_fieldapi().
+ module_invoke_all('content_fieldapi', 'delete instance', $field);
+
+ db_query("DELETE FROM {". content_instance_tablename() .
+ "} WHERE field_name = '%s' AND type_name = '%s'", $field['field_name'], $field['type_name']);
+
+ // If no instances remain, delete the field entirely.
+ $instances = content_field_instance_read(array('field_name' => $field_name));
+ if (sizeof($instances) < 1) {
+ db_query("DELETE FROM {". content_field_tablename() ."} WHERE field_name = '%s'", $field['field_name']);
+ content_alter_schema($field, array());
+ }
+ // If only one instance remains, we may need to change the database
+ // representation for this field.
+ elseif (sizeof($instances) == 1 && !($field['multiple'])) {
+ // Multiple-valued fields are always stored per-field-type.
+ $instance = $instances[0];
+ $new_instance = $instance;
+ $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
+ _content_field_write($new_instance, 'update');
+
+ content_alter_schema($instance, $new_instance);
+ }
+
+ // If the deleted instance was the last field for the content type,
+ // we drop the per-type table. We also consider possibly inactive fields.
+ if (!content_field_instance_read(array('type_name' => $field['type_name']), TRUE)) {
+ $base_tablename = _content_tablename($field['type_name'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ if (db_table_exists($base_tablename)) {
+ db_drop_table($ret, $base_tablename);
+ }
+ }
+
+ if ($rebuild) {
+ content_clear_type_cache(TRUE);
+ menu_rebuild();
+ }
+
+ return $field;
+}
+
+/**
+ * Delete all data related to a module.
+ *
+ * @param string $module
+ */
+function content_module_delete($module) {
+ // Delete the field data.
+ // If content module has been uninstalled first, all tables
+ // have already been dropped, and running that code will raise errors.
+ if (db_table_exists(content_instance_tablename())) {
+ $results = db_query("SELECT field_name, type_name FROM {". content_instance_tablename() ."} WHERE widget_module = '%s'", $module);
+ while ($field = db_fetch_array($results)) {
+ content_field_instance_delete($field['field_name'], $field['type_name'], FALSE);
+ }
+ // Force the caches and static arrays to update to the new info.
+ content_clear_type_cache(TRUE);
+ menu_rebuild();
+ }
+}
+
+/**
+ * Make changes needed when a content type is created.
+ *
+ * @param $info
+ * value supplied by hook_node_type()
+ *
+ * node_get_types() is still missing the new type at this point due to
+ * a static caching bug. We ask it to rebuild its cache so that
+ * content_clear_type_cache() can do its job properly.
+ */
+function content_type_create($info) {
+ node_get_types(NULL, NULL, TRUE);
+ content_clear_type_cache(TRUE);
+}
+
+/**
+ * Make changes needed when an existing content type is updated.
+ *
+ * @param $info
+ * value supplied by hook_node_type()
+ */
+function content_type_update($info) {
+ if (!empty($info->old_type) && $info->old_type != $info->type) {
+ // Rename the content type in all fields that use changed content type.
+ db_query("UPDATE {". content_instance_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));
+
+ // Rename the content fields table to match new content type name.
+ $old_type = content_types($info->old_type);
+ $old_name = _content_tablename($old_type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ $new_name = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ if (db_table_exists($old_name)) {
+ $ret = array();
+ db_rename_table($ret, $old_name, $new_name);
+ watchdog('content', 'Content fields table %old_name has been renamed to %new_name and field instances have been updated.', array(
+ '%old_name' => $old_name, '%new_name' => $new_name));
+ }
+
+ // Rename the variable storing weights for non-CCK fields.
+ if ($extra = variable_get('content_extra_weights_'. $info->old_type, array())) {
+ variable_set('content_extra_weights_'. $info->type, $extra);
+ variable_del('content_extra_weights_'. $info->old_type);
+ }
+ }
+
+ // Reset all content type info.
+ // Menu needs to be rebuilt as well, but node types need to be rebuilt first.
+ // node_type_form_submit() takes care of this.
+ content_clear_type_cache(TRUE);
+}
+
+/**
+ * Make changes needed when a content type is deleted.
+ *
+ * @param $info
+ * value supplied by hook_node_type()
+ *
+ * TODO should we skip doing this entirely since core leaves the
+ * nodes in the database as orphans and wait until the nodes are
+ * deleted to respond?
+ *
+ */
+function content_type_delete($info) {
+ // Don't delete data for content-types defined by disabled modules.
+ if (!empty($info->disabled)) {
+ return;
+ }
+
+ // TODO : What about inactive fields ?
+ // Currently, content_field_instance_delete doesn't work on those...
+ $fields = content_field_instance_read(array('type_name' => $info->type));
+ foreach ($fields as $field) {
+ content_field_instance_delete($field['field_name'], $info->type, FALSE);
+ }
+ $table = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+ if (db_table_exists($table)) {
+ $ret = array();
+ db_drop_table($ret, $table);
+ watchdog('content', 'The content fields table %name has been deleted.', array('%name' => $table));
+ }
+ // Menu needs to be rebuilt as well, but node types need to be rebuilt first.
+ // node_type_form_submit() takes care of this.
+ content_clear_type_cache(TRUE);
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.devel.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.devel.inc
new file mode 100644
index 00000000000..985813a8030
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.devel.inc
@@ -0,0 +1,218 @@
+type;
+ $type = content_types($type_name);
+ $field_types = _content_field_types();
+
+ if (!empty($type['fields'])) {
+ foreach ($type['fields'] as $field) {
+ $node_field = array();
+ // If module handles own multiples, then only call its hook once.
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) {
+ $max = 0;
+ }
+ else {
+ switch ($field['multiple']) {
+ case 0:
+ $max = 0;
+ break;
+ case 1:
+ $max = rand(0, 3); //just an arbitrary number for 'unlimited'
+ break;
+ default:
+ $max = $field['multiple'];
+ break;
+ }
+ }
+ for ($i = 0; $i <= $max; $i++) {
+ $module = $field_types[$field['type']]['module'];
+ $function = $module .'_content_generate';
+ if (function_exists($function)) {
+ $result = $function($node, $field); // $items, $teaser, $page
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) {
+ // Fields that handle their own multiples will add their own deltas.
+ $node_field = $result;
+ }
+ else {
+ // When multiples are handled by the content module, add a delta for each result.
+ $node_field[$i] = $result;
+ }
+ }
+ }
+ $node->{$field['field_name']} = $node_field;
+ }
+ }
+}
+
+/**
+ * A simple function to return multiple values for fields that use
+ * custom multiple value widgets but don't need any other special multiple
+ * values handling. This will call the field generation function
+ * a random number of times and compile the results into a node array.
+ */
+function content_devel_multiple($function, $node, $field) {
+ $node_field = array();
+ if (function_exists($function)) {
+ switch ($field['multiple']) {
+ case 0:
+ $max = 0;
+ break;
+ case 1:
+ $max = rand(0, 3); //just an arbitrary number for 'unlimited'
+ break;
+ default:
+ $max = $field['multiple'];
+ break;
+ }
+ for ($i = 0; $i <= $max; $i++) {
+ $node_field[$i] = $function($node, $field);
+ }
+ }
+ return $node_field;
+}
+
+if (module_exists('text')) {
+ function text_content_generate($node, $field) {
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) {
+ return content_devel_multiple('_text_content_generate', $node, $field);
+ }
+ else {
+ return _text_content_generate($node, $field);
+ }
+ }
+
+ function _text_content_generate($node, $field) {
+ $node_field = array();
+ if ($field['widget']['type'] == 'text_textarea') {
+ $format = $field['text_processing'] ? rand(0, 3) : 0;
+ $node_field['value'] = devel_create_content($format);
+ $node_field['format'] = $format;
+ }
+ else {
+ $allowed_values = content_allowed_values($field);
+ if (!empty($allowed_values)) {
+ // Just pick one of the specified allowed values.
+ $node_field['value'] = array_rand($allowed_values);
+ }
+ else {
+ // Generate a value that respects max_length.
+ if (empty($field['max_length'])) {
+ $field['max_length'] = 12;
+ }
+ $node_field['value'] = user_password($field['max_length']);
+ }
+ }
+ return $node_field;
+ }
+}
+
+if (module_exists('number')) {
+ function number_content_generate($node, $field) {
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) {
+ return content_devel_multiple('_number_content_generate', $node, $field);
+ }
+ else {
+ return _number_content_generate($node, $field);
+ }
+ }
+
+ function _number_content_generate($node, $field) {
+ $node_field = array();
+ $allowed_values = content_allowed_values($field);
+ if (!empty($allowed_values)) {
+ // Just pick one of the specified allowed values.
+ $node_field['value'] = array_rand($allowed_values);
+ }
+ else {
+ $min = is_numeric($field['min']) ? $field['min'] : 0;
+ switch ($field['type']) {
+ case 'number_integer':
+ $max = is_numeric($field['max']) ? $field['max'] : 10000;
+ $decimal = 0;
+ $scale = 0;
+ break;
+
+ case 'number_decimal':
+ $precision = is_numeric($field['precision']) ? $field['precision'] : 10;
+ $scale = is_numeric($field['scale']) ? $field['scale'] : 2;
+ $max = is_numeric($field['max']) ? $field['max'] : pow(10, ($precision - $scale));
+ $decimal = rand(0, (10 * $scale)) / 100;
+ break;
+
+ case 'number_float':
+ $precision = rand(10, 32);
+ $scale = rand(0, 2);
+ $decimal = rand(0, (10 * $scale)) / 100;
+ $max = is_numeric($field['max']) ? $field['max'] : pow(10, ($precision - $scale));
+ break;
+ }
+ $node_field['value'] = round((rand($min, $max) + $decimal), $scale);
+ }
+ return $node_field;
+ }
+}
+
+if (module_exists('nodereference')) {
+ function nodereference_content_generate($node, $field) {
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) {
+ return content_devel_multiple('_nodereference_content_generate', $node, $field);
+ }
+ else {
+ return _nodereference_content_generate($node, $field);
+ }
+ }
+
+ function _nodereference_content_generate($node, $field) {
+ $node_field = array();
+ $allowed_values = nodereference_allowed_values($field);
+ unset($allowed_values[0]);
+ if (!empty($allowed_values)) {
+ // Just pick one of the specified allowed values.
+ $node_field['nid'] = array_rand($allowed_values);
+ }
+ return $node_field;
+ }
+}
+
+if (module_exists('userreference')) {
+ function userreference_content_generate($node, $field) {
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_MODULE) {
+ return content_devel_multiple('_userreference_content_generate', $node, $field);
+ }
+ else {
+ return _userreference_content_generate($node, $field);
+ }
+ }
+
+ function _userreference_content_generate($node, $field) {
+ $node_field = array();
+ $allowed_values = userreference_allowed_values($field);
+ if (isset($allowed_values['none'])) {
+ unset($allowed_values['none']);
+ }
+ if (!empty($allowed_values)) {
+ // Just pick one of the specified allowed values.
+ $node_field['uid'] = array_rand($allowed_values);
+ }
+ return $node_field;
+ }
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.diff.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.diff.inc
new file mode 100644
index 00000000000..42a3634da86
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.diff.inc
@@ -0,0 +1,128 @@
+type)) {
+ $type = content_types($new_node->type);
+ $field_types = _content_field_types();
+ foreach ($type['fields'] as $field) {
+ // Ignore fields the current user is not allowed to view.
+ if (!content_access('view', $field, NULL, $new_node)) {
+ continue;
+ }
+ $function = $field_types[$field['type']]['module'] . '_content_diff_values';
+ $function = function_exists($function) ? $function : 'content_content_diff_values';
+ $old_values = array();
+ $new_values = array();
+ if (isset($old_node->$field['field_name'])) {
+ $old_values = $function($old_node, $field, $old_node->$field['field_name']);
+ }
+ if (isset($new_node->$field['field_name'])) {
+ $new_values = $function($new_node, $field, $new_node->$field['field_name']);
+ }
+ if ($old_values || $new_values) {
+ $result[$field['field_name']] = array(
+ '#name' => $field['widget']['label'],
+ '#old' => $old_values,
+ '#new' => $new_values,
+ '#weight' => $field['widget']['weight'],
+ '#format' => array(
+ 'show_header' => FALSE,
+ ),
+ );
+ }
+ }
+ }
+ return $result;
+}
+
+/**
+ * Default 'implementation' of hook_content_diff_values.
+ *
+ * Note that diff.module takes care of running check_plain on the output.
+ */
+function content_content_diff_values($node, $field, $items) {
+ $return = array();
+ foreach ($items as $item) {
+ foreach (explode("\n", $item['value']) as $i) {
+ $return[] = $i;
+ }
+ }
+ return $return;
+}
+
+if (module_exists('userreference')) {
+ /**
+ * Implementation of hook_content_diff_values.
+ */
+ function userreference_content_diff_values($node, $field, $items) {
+ static $titles = array();
+ // Gather ids.
+ $ids = array();
+ foreach ($items as $item) {
+ if ($item['uid'] && is_numeric($item['uid'])) {
+ $ids[] = $item['uid'];
+ }
+ }
+ // Fetch titles we don't know yet.
+ $queried_ids = array_diff($ids, array_keys($titles));
+ if ($queried_ids) {
+ $result = db_query('SELECT uid, name FROM {users} WHERE uid IN ('. db_placeholders($queried_ids) .')', $queried_ids);
+ while ($row = db_fetch_array($result)) {
+ $titles[$row['uid']] = $row['name'];
+ }
+ }
+ // Return result.
+ $return = array();
+ foreach ($items as $item) {
+ if ($item['uid'] && isset($titles[$item['uid']])) {
+ $return[] = $titles[$item['uid']];
+ }
+ }
+ return $return;
+ }
+}
+
+if (module_exists('nodereference')) {
+ /**
+ * Implementation of hook_content_diff_values.
+ */
+ function nodereference_content_diff_values($node, $field, $items) {
+ static $titles = array();
+ // Gather ids.
+ $ids = array();
+ foreach ($items as $item) {
+ if ($item['nid'] && is_numeric($item['nid'])) {
+ $ids[] = $item['nid'];
+ }
+ }
+ // Fetch titles we don't know yet.
+ $queried_ids = array_diff($ids, array_keys($titles));
+ if ($queried_ids) {
+ $result = db_query('SELECT nid, title FROM {node} WHERE nid IN ('. db_placeholders($queried_ids) .')', $queried_ids);
+ while ($row = db_fetch_array($result)) {
+ $titles[$row['nid']] = $row['title'];
+ }
+ }
+ // Return result.
+ $return = array();
+ foreach ($items as $item) {
+ if ($item['nid'] && isset($titles[$item['nid']])) {
+ $return[] = $titles[$item['nid']];
+ }
+ }
+ return $return;
+ }
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/content.node_form.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.node_form.inc
new file mode 100644
index 00000000000..681a3401cbc
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/content.node_form.inc
@@ -0,0 +1,380 @@
+ $field) {
+ $form['#field_info'][$field['field_name']] = $field;
+ $form += (array) content_field_form($form, $form_state, $field);
+ }
+ return $form;
+}
+
+/**
+ * Create a separate form element for each field.
+ *
+ * // TODO: $count param ? not used anymore ?
+ * Hook_widget() picks up two new values, $count and $delta, to help
+ * widgets know what information to return since multiple values are
+ * sometimes controlled by the content module.
+ *
+ * @param $form
+ * the form to add this field element to
+ * @param $form_state
+ * the form_state for the above form
+ * @param $field
+ * the field array to use to create the form element
+ * @param $get_delta
+ * use to get only a specific delta value of a multiple value field, otherwise
+ * function will return the entire $field form element.
+ */
+function content_field_form(&$form, &$form_state, $field, $get_delta = NULL) {
+ $form['#cache'] = FALSE;
+ $node = $form['#node'];
+ $addition = array();
+ $form_element = array();
+ $field_name = $field['field_name'];
+
+ $items = array();
+
+ // TODO: is the "if (function_exists($function)) {" needed ?
+ // defining the $function here makes it unclear where it is actually called
+ $function = $field['widget']['module'] .'_widget';
+ if (function_exists($function)) {
+ // Prepare the values to be filled in the widget.
+ // We look in the following places:
+ // - Form submitted values
+ // - Node values (when editing an existing node), or pre-filled values (when
+ // creating a new node translation)
+ // - Default values set for the field (when creating a new node).
+ if (!empty($form_state['values'][$field['field_name']])) {
+ $items = $form_state['values'][$field['field_name']];
+ // If there was an AHAH add more button in this field, don't save it.
+ unset($items[$field['field_name'] .'_add_more']);
+ }
+ elseif (!empty($node->$field['field_name'])) {
+ $items = $node->$field['field_name'];
+ }
+ elseif (empty($node->nid)) {
+ if (content_callback('widget', 'default value', $field) != CONTENT_CALLBACK_NONE) {
+ // If a module wants to insert custom default values here,
+ // it should provide a hook_default_value() function to call,
+ // otherwise the content module's content_default_value() function
+ // will be used.
+ $callback = content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_CUSTOM ? $field['widget']['module'] .'_default_value' : 'content_default_value';
+ if (function_exists($callback)) {
+ $items = $callback($form, $form_state, $field, 0);
+ }
+ }
+ }
+
+ // See if access to this form element is restricted,
+ // if so, skip widget processing and just set the value.
+ $access = content_access('edit', $field, NULL, $node);
+ if (!$access) {
+ $addition[$field_name] = array(
+ '#access' => $access,
+ '#type' => 'value',
+ '#value' => $items,
+ );
+ return $addition;
+ }
+
+ // If content module handles multiple values for this form element,
+ // and not selecting an individual $delta, process the multiple value form.
+ if (!isset($get_delta) && content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
+ $form_element = content_multiple_value_form($form, $form_state, $field, $items);
+ }
+ // If the widget is handling multiple values (e.g optionwidgets),
+ // or selecting an individual element, just get a single form
+ // element and make it the $delta value.
+ else {
+ $delta = isset($get_delta) ? $get_delta : 0;
+ if ($element = $function($form, $form_state, $field, $items, $delta)) {
+ $title = check_plain(t($field['widget']['label']));
+ $description = content_filter_xss(t($field['widget']['description']));
+ $defaults = array(
+ '#required' => $get_delta > 0 ? FALSE : $field['required'],
+ '#columns' => array_keys($field['columns']),
+ '#title' => $title,
+ '#description' => $description,
+ '#delta' => $delta,
+ '#field_name' => $field['field_name'],
+ '#type_name' => $field['type_name'],
+ );
+ // If we're processing a specific delta value for a field where the
+ // content module handles multiples, set the delta in the result.
+ // For fields that handle their own processing, we can't make assumptions
+ // about how the field is structured, just merge in the returned value.
+ if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
+ $form_element[$delta] = array_merge($element, $defaults);
+ }
+ else {
+ $form_element = array_merge($element, $defaults);
+ }
+ }
+ }
+
+ // Field name is needed at top level as well as the individual elements
+ // so the multiple values or other field level theme or processing can find it.
+ if ($form_element) {
+ $defaults = array(
+ '#field_name' => $field['field_name'],
+ '#tree' => TRUE,
+ '#weight' => $field['widget']['weight'],
+ '#access' => $access,
+ // TODO: what's the need for #count ? does not seem to be used anywhere ?
+ '#count' => count($form_element),
+ );
+ $addition[$field['field_name']] = array_merge($form_element, $defaults);
+ }
+ }
+ return $addition;
+}
+
+/**
+ * Special handling to create form elements for multiple values.
+ *
+ * Handles generic features for multiple fields:
+ * - number of widgets
+ * - AHAH-'add more' button
+ * - drag-n-drop value reordering
+ */
+function content_multiple_value_form(&$form, &$form_state, $field, $items) {
+ $field_name = $field['field_name'];
+
+ switch ($field['multiple']) {
+ case 0:
+ $max = 0;
+ break;
+ case 1:
+ $filled_items = content_set_empty($field, $items);
+ $current_item_count = isset($form_state['item_count'][$field_name])
+ ? $form_state['item_count'][$field_name]
+ : count($items);
+ // We always want at least one empty icon for the user to fill in.
+ $max = ($current_item_count > count($filled_items))
+ ? $current_item_count - 1
+ : $current_item_count;
+
+ break;
+ default:
+ $max = $field['multiple'] - 1;
+ break;
+ }
+
+ $title = check_plain(t($field['widget']['label']));
+ $description = content_filter_xss(t($field['widget']['description']));
+
+ $form_element = array(
+ '#theme' => 'content_multiple_values',
+ '#title' => $title,
+ '#required' => $field['required'],
+ '#description' => $description,
+ );
+ $function = $field['widget']['module'] .'_widget';
+
+ for ($delta = 0; $delta <= $max; $delta++) {
+ if ($element = $function($form, $form_state, $field, $items, $delta)) {
+ $defaults = array(
+ '#title' => ($field['multiple'] >= 1) ? '' : $title,
+ '#description' => ($field['multiple'] >= 1) ? '' : $description,
+ '#required' => $delta == 0 && $field['required'],
+ '#weight' => $delta,
+ '#delta' => $delta,
+ '#columns' => array_keys($field['columns']),
+ '#field_name' => $field_name,
+ '#type_name' => $field['type_name'],
+ );
+
+ // Add an input field for the delta (drag-n-drop reordering), which will
+ // be hidden by tabledrag js behavior.
+ if ($field['multiple'] >= 1) {
+ // We name the element '_weight' to avoid clashing with column names
+ // defined by field modules.
+ $element['_weight'] = array(
+ '#type' => 'weight',
+ '#delta' => $max, // this 'delta' is the 'weight' element's property
+ '#default_value' => isset($items[$delta]['_weight']) ? $items[$delta]['_weight'] : $delta,
+ '#weight' => 100,
+ );
+ }
+
+ $form_element[$delta] = array_merge($element, $defaults);
+ }
+ }
+
+ // Add AHAH add more button, if not working with a programmed form.
+ if ($field['multiple'] == 1 && empty($form['#programmed'])) {
+ // Make sure the form is cached so ahah can work.
+ $form['#cache'] = TRUE;
+ $content_type = content_types($field['type_name']);
+ $field_name_css = str_replace('_', '-', $field_name);
+
+ $form_element[$field_name .'_add_more'] = array(
+ '#type' => 'submit',
+ '#name' => $field_name .'_add_more',
+ '#value' => t('Add another item'),
+ '#weight' => $field['widget']['weight'] + $max + 1,
+ // Submit callback for disabled JavaScript. drupal_get_form() might get
+ // the form from the cache, so we can't rely on content_form_alter()
+ // including this file. Therefore, call a proxy function to do this.
+ '#submit' => array('content_add_more_submit_proxy'),
+ '#ahah' => array(
+ 'path' => 'content/js_add_more/'. $content_type['url_str'] .'/'. $field_name,
+ 'wrapper' => $field_name_css .'-items',
+ 'method' => 'replace',
+ 'effect' => 'fade',
+ ),
+ // When JS is disabled, the content_add_more_submit handler will find
+ // the relevant field using these entries.
+ '#field_name' => $field_name,
+ '#type_name' => $field['type_name'],
+ );
+
+ // Add wrappers for the fields and 'more' button.
+ $form_element['#prefix'] = '
';
+ }
+ return $form_element;
+}
+
+/**
+ * Submit handler to add more choices to a content form. This handler is used when
+ * JavaScript is not available. It makes changes to the form state and the
+ * entire form is rebuilt during the page reload.
+ */
+function content_add_more_submit($form, &$form_state) {
+ // Set the form to rebuild and run submit handlers.
+ node_form_submit_build_node($form, $form_state);
+ $field_name = $form_state['clicked_button']['#field_name'];
+ $type_name = $form_state['clicked_button']['#type_name'];
+
+ // Make the changes we want to the form state.
+ if ($form_state['values'][$field_name][$field_name .'_add_more']) {
+ $form_state['item_count'][$field_name] = count($form_state['values'][$field_name]);
+ }
+}
+
+/**
+ * Menu callback for AHAH addition of new empty widgets.
+ */
+function content_add_more_js($type_name_url, $field_name) {
+ $type = content_types($type_name_url);
+ $field = content_fields($field_name, $type['type']);
+
+ if (($field['multiple'] != 1) || empty($_POST['form_build_id'])) {
+ // Invalid request.
+ drupal_json(array('data' => ''));
+ exit;
+ }
+
+ // Retrieve the cached form.
+ $form_state = array('submitted' => FALSE);
+ $form_build_id = $_POST['form_build_id'];
+ $form = form_get_cache($form_build_id, $form_state);
+ if (!$form) {
+ // Invalid form_build_id.
+ drupal_json(array('data' => ''));
+ exit;
+ }
+
+ // We don't simply return a new empty widget to append to existing ones, because
+ // - ahah.js won't simply let us add a new row to a table
+ // - attaching the 'draggable' behavior won't be easy
+ // So we resort to rebuilding the whole table of widgets including the existing ones,
+ // which makes us jump through a few hoops.
+
+ // The form that we get from the cache is unbuilt. We need to build it so that
+ // _value callbacks can be executed and $form_state['values'] populated.
+ // We only want to affect $form_state['values'], not the $form itself
+ // (built forms aren't supposed to enter the cache) nor the rest of $form_data,
+ // so we use copies of $form and $form_data.
+ $form_copy = $form;
+ $form_state_copy = $form_state;
+ $form_copy['#post'] = array();
+ form_builder($_POST['form_id'], $form_copy, $form_state_copy);
+ // Just grab the data we need.
+ $form_state['values'] = $form_state_copy['values'];
+ // Reset cached ids, so that they don't affect the actual form we output.
+ form_clean_id(NULL, TRUE);
+
+ // Sort the $form_state['values'] we just built *and* the incoming $_POST data
+ // according to d-n-d reordering.
+ unset($form_state['values'][$field_name][$field['field_name'] .'_add_more']);
+ foreach ($_POST[$field_name] as $delta => $item) {
+ $form_state['values'][$field_name][$delta]['_weight'] = $item['_weight'];
+ }
+ $form_state['values'][$field_name] = _content_sort_items($field, $form_state['values'][$field_name]);
+ $_POST[$field_name] = _content_sort_items($field, $_POST[$field_name]);
+
+ // Build our new form element for the whole field, asking for one more element.
+ $form_state['item_count'] = array($field_name => count($_POST[$field_name]) + 1);
+ $form_element = content_field_form($form, $form_state, $field);
+ // Let other modules alter it.
+ // We pass an empty array as hook_form_alter's usual 'form_state' parameter,
+ // instead of $form_state (for reasons we may never remember).
+ // However, this argument is still expected to be passed by-reference
+ // (and PHP5.3 will throw an error if it isn't.) This leads to:
+ $data = &$form_element;
+ $empty_form_state = array();
+ $data['__drupal_alter_by_ref'] = array(&$empty_form_state);
+ drupal_alter('form', $data, 'content_add_more_js');
+
+ // Add the new element at the right place in the (original, unbuilt) form.
+ if (module_exists('fieldgroup') && ($group_name = _fieldgroup_field_get_group($type['type'], $field_name))) {
+ $form[$group_name][$field_name] = $form_element[$field_name];
+ }
+ else {
+ $form[$field_name] = $form_element[$field_name];
+ }
+
+ // Save the new definition of the form.
+ $form_state['values'] = array();
+ form_set_cache($form_build_id, $form, $form_state);
+
+ // Build the new form against the incoming $_POST values so that we can
+ // render the new element.
+ $delta = max(array_keys($_POST[$field_name])) + 1;
+ $_POST[$field_name][$delta]['_weight'] = $delta;
+ $form_state = array('submitted' => FALSE);
+ $form += array(
+ '#post' => $_POST,
+ '#programmed' => FALSE,
+ );
+ $form = form_builder($_POST['form_id'], $form, $form_state);
+
+ // Render the new output.
+ $field_form = (!empty($group_name)) ? $form[$group_name][$field_name] : $form[$field_name];
+ // We add a div around the new content to receive the ahah effect.
+ $field_form[$delta]['#prefix'] = '
',
+ '#process' => array('views_process_dependency'),
+ '#dependency' => array('edit-options-multiple-group' => array(TRUE)),
+ '#description' => t('(start from last values)'),
+ );
+ }
+
+ /**
+ * Determine if this field is click sortable.
+ */
+ function click_sortable() {
+ $field = $this->content_field;
+ $options = $this->options;
+
+ // Grouped fields are not click-sortable.
+ return !empty($this->definition['click sortable']) && !$this->defer_query;
+ }
+
+ function query() {
+ // If this is not a grouped field, use the generic query().
+ if (!$this->defer_query) {
+ return parent::query();
+ }
+
+ // Grouped field: do NOT call ensure_my_table, only add additional fields.
+ $this->add_additional_fields();
+ $this->field_alias = $this->aliases['vid'];
+ }
+
+ function pre_render(&$values) {
+ // If there are no values to render (displaying a summary, or query returned no results),
+ // or if this is not a grouped field, do nothing specific.
+ if (isset($this->view->build_info['summary']) || empty($values) || !$this->defer_query) {
+ return parent::pre_render($values);
+ }
+
+ $field = $this->content_field;
+ $db_info = content_database_info($field);
+ $options = $this->options;
+
+ // Build the list of vids to retrieve.
+ // TODO: try fetching from cache_content first ??
+ $vids = array();
+ $this->field_values = array();
+ foreach ($values as $result) {
+ if (isset($result->{$this->field_alias})) {
+ $vids[] = $result->{$this->field_alias};
+ }
+ }
+
+ // It may happend that the multiple values field is related to a non
+ // required relation for which no node data related to the field being
+ // processed here is available.
+ if (empty($vids)) {
+ return parent::pre_render($values);
+ }
+
+ // List columns to retrieve.
+ $alias = content_views_tablename($field);
+ // Prefix aliases with '_' to avoid clashing with field columns names.
+ $query_columns = array(
+ 'vid AS _vid',
+ "delta as _delta",
+ // nid is needed to generate the links for 'link to node' option.
+ 'nid AS _nid',
+ );
+ // The actual field columns.
+ foreach ($db_info['columns'] as $column => $attributes) {
+ $query_columns[] = "$attributes[column] AS $column";
+ }
+ $query = 'SELECT '. implode(', ', $query_columns) .
+ ' FROM {'. $db_info['table'] ."}".
+ " WHERE vid IN (". implode(',', $vids) .')'.
+ " ORDER BY _nid ASC, _delta ". ($options['multiple']['multiple_reversed'] ? 'DESC' : 'ASC');
+ $result = db_query($query);
+
+ while ($item = db_fetch_array($result)) {
+ // Clean up the $item from vid and delta. We keep nid for now.
+ $vid = $item['_vid'];
+ unset($item['_vid']);
+ $delta = !empty($item['_delta']) ? $item['_delta'] : 0;
+ $item['#delta'] = $item['_delta'];
+ unset($item['_delta']);
+ $this->field_values[$vid][$delta] = $item;
+ }
+ }
+
+ /**
+ * Return DIV or SPAN based upon the field's element type.
+ *
+ * Fields rendered with the 'group multiple' option use
markers,
+ * and thus shouldn't be wrapped in a .
+ */
+ function element_type($none_supported = FALSE, $default_empty = FALSE) {
+ // If this is not a grouped field, use the parent method.
+ if (!$this->defer_query) {
+ return parent::element_type($none_supported, $default_empty);
+ }
+
+ // The 'element_type' property denotes Views 3.x ('semantic views'
+ // functionnality). If the property is set, and not set to '' ("default"),
+ // let the generic method handle the output.
+ if (isset($this->options['element_type']) && $this->options['element_type'] !== '') {
+ return parent::element_type($none_supported, $default_empty);
+ }
+
+ if ($default_empty) {
+ return '';
+ }
+
+ if (isset($this->definition['element type'])) {
+ return $this->definition['element type'];
+ }
+
+ return 'div';
+ }
+
+ function render($values) {
+ // If this is not a grouped field, use content_handler_field::render().
+ if (!$this->defer_query) {
+ return parent::render($values);
+ }
+
+ // We're down to a single node here, so we can retrieve the actual field
+ // definition for the node type being considered.
+ $field = content_fields($this->content_field['field_name'], $values->{$this->aliases['type']});
+
+ // If the field does not appear in the node type, then we have no value
+ // to display, and can just return.
+ if (empty($field)) {
+ return '';
+ }
+
+ $options = $this->options;
+
+ $vid = $values->{$this->field_alias};
+ if (isset($this->field_values[$vid])) {
+ // Gather items, respecting the 'Display n values starting from m' settings.
+ $count_skipped = 0;
+ $items = array();
+ foreach ($this->field_values[$vid] as $item) {
+ if (empty($options['multiple']['multiple_from']) || ($count_skipped >= $options['multiple']['multiple_from'])) {
+ if (empty($options['multiple']['multiple_number']) || (count($items) < $options['multiple']['multiple_number'])) {
+ // Grab the nid - needed for render_link().
+ $nid = $item['_nid'];
+ unset($item['_nid']);
+ $items[] = $item;
+ }
+ else {
+ break;
+ }
+ }
+ $count_skipped++;
+ }
+
+ // Build a pseudo-node from the retrieved values.
+ $node = drupal_clone($values);
+ // content_format and formatters will need a 'type'.
+ $node->type = $values->{$this->aliases['type']};
+ $node->nid = $values->{$this->aliases['nid']};
+ $node->vid = $values->{$this->aliases['vid']};
+
+ // Some formatters need to behave differently depending on the build_mode
+ // (for instance: preview), so we provide one.
+ $node->build_mode = NODE_BUILD_NORMAL;
+
+ // Render items.
+ $formatter_name = $options['format'];
+ if ($items && ($formatter = _content_get_formatter($formatter_name, $field['type']))) {
+ $rendered = array();
+ if (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE) {
+ // Single-value formatter.
+ foreach ($items as $item) {
+ $output = content_format($field, $item, $formatter_name, $node);
+ if (!empty($output)) {
+ $rendered[] = $this->render_link($output, (object) array('nid' => $nid));
+ }
+ }
+ }
+ else {
+ // Multiple values formatter.
+ $output = content_format($field, $items, $formatter_name, $values);
+ if (!empty($output)) {
+ $rendered[] = $this->render_link($output, (object) array('nid' => $nid));
+ }
+ }
+
+ if (count($rendered) > 1) {
+ // TODO: could we use generic field display ?
+ return theme('content_view_multiple_field', $rendered, $field, $values);
+ }
+ elseif ($rendered) {
+ return $rendered[0];
+ }
+ }
+ }
+
+ return '';
+ }
+
+ function render_link($data, $values) {
+ if (!$this->defer_query) {
+ return parent::render_link($data, $values);
+ }
+
+ if (!empty($this->options['link_to_node']) && $data !== NULL && $data !== '') {
+ if (method_exists('render_as_link', 'views_handler_field')) {
+ // Views 2.3+
+ $this->options['alter']['make_link'] = TRUE;
+ $this->options['alter']['path'] = "node/" . $values->{$this->aliases['nid']};
+ }
+ else {
+ // Views up to 2.2
+ return l($data, "node/" . $values->nid, array('html' => TRUE));
+ }
+ }
+ else {
+ return $data;
+ }
+ }
+
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_float.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_float.inc
new file mode 100644
index 00000000000..bf9f3c4f79d
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_float.inc
@@ -0,0 +1,26 @@
+content_field = content_fields($this->definition['content_field_name']);
+ $this->additional_fields = $this->definition['additional fields'];
+ }
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_many_to_one.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_many_to_one.inc
new file mode 100644
index 00000000000..74b5348d033
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_many_to_one.inc
@@ -0,0 +1,42 @@
+content_field = content_fields($this->definition['content_field_name']);
+ $this->additional_fields = $this->definition['additional fields'];
+ $field = $this->content_field;
+ $this->value_title = $field['widget']['label'];
+ }
+
+ function get_value_options() {
+ $this->value_options = $this->allowed_values();
+ }
+
+ // Get allowed values from hook_allowed_values(), if any,
+ // or from content_allowed_values();
+ function allowed_values() {
+ $field = $this->content_field;
+ $function = $field['module'] .'_allowed_values';
+ if ($this->value_form_type == 'select') {
+ // Select elements accept multidimensional arrays to support optgroups.
+ $options = function_exists($function) ? $function($field) : content_allowed_values($field, FALSE);
+ // For selects, HTML should be filtered out and entities left unencoded.
+ // See content_allowed_values / content_filter_xss / filter_xss.
+ content_allowed_values_filter_html($options);
+ }
+ else {
+ $options = function_exists($function) ? $function($field) : content_allowed_values($field);
+ }
+ return (array) $options;
+ }
+
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_numeric.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_numeric.inc
new file mode 100644
index 00000000000..1c4a23a67a6
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_numeric.inc
@@ -0,0 +1,17 @@
+content_field = content_fields($this->definition['content_field_name']);
+ $this->additional_fields = $this->definition['additional fields'];
+ }
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_string.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_string.inc
new file mode 100644
index 00000000000..9901e91e2bc
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_filter_string.inc
@@ -0,0 +1,17 @@
+content_field = content_fields($this->definition['content_field_name']);
+ $this->additional_fields = $this->definition['additional fields'];
+ }
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_relationship.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_relationship.inc
new file mode 100644
index 00000000000..136e193f84b
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_relationship.inc
@@ -0,0 +1,73 @@
+content_field = content_fields($this->definition['content_field_name']);
+ }
+
+ function option_definition() {
+ $options = parent::option_definition();
+ $options['delta'] = array('default' => -1);
+
+ return $options;
+ }
+
+ /**
+ * Add a delta selector for multiple fields.
+ */
+ function options_form(&$form, &$form_state) {
+ $field = $this->content_field;
+ parent::options_form($form, $form_state);
+
+ // Only add the form gadget if the field is multiple.
+ if ($field['multiple']) {
+ $max_delta = $field['multiple'];
+ // 1 means unlimited.
+ if ($max_delta == 1) {
+ $max_delta = 10;
+ }
+
+ $options = array('-1' => t('All'));
+ for ($i = 0; $i < $max_delta; $i++) {
+ $options[$i] = $i + 1;
+ }
+ $form['delta'] = array(
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => $this->options['delta'],
+ '#title' => t('Delta'),
+ '#description' => t('The delta allows you to select which item in a multiple value field to key the relationship off of. Select "1" to use the first item, "2" for the second item, and so on. If you select "All", each item in the field will create a new row, which may appear to cause duplicates.'),
+ );
+ }
+ }
+
+ function ensure_my_table() {
+ if (!isset($this->table_alias)) {
+ $join = $this->get_join();
+ if (!isset($join->extra)) {
+ $join->extra = array();
+ }
+ $delta = isset($this->options['delta']) ? $this->options['delta'] : -1;
+ if ($delta != -1) {
+ $join->extra[] = array(
+ 'field' => 'delta',
+ 'value' => $delta,
+ 'numeric' => TRUE,
+ );
+ }
+
+ $this->table_alias = $this->query->add_table($this->table, $this->relationship, $join);
+ }
+ return $this->table_alias;
+ }
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_sort.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_sort.inc
new file mode 100644
index 00000000000..1a3ad7cbacd
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_handler_sort.inc
@@ -0,0 +1,74 @@
+content_field = content_fields($this->definition['content_field_name']);
+ $this->additional_fields = $this->definition['additional fields'];
+ }
+
+ function option_definition() {
+ $options = parent::option_definition();
+ $options['delta'] = array('default' => -1);
+
+ return $options;
+ }
+
+ /**
+ * Add a delta selector for multiple fields.
+ */
+ function options_form(&$form, &$form_state) {
+ $field = $this->content_field;
+ parent::options_form($form, $form_state);
+
+ // Only add the form gadget if the field is multiple.
+ if ($field['multiple']) {
+ $max_delta = $field['multiple'];
+ // 1 means unlimited.
+ if ($max_delta == 1) {
+ $max_delta = 10;
+ }
+
+ $options = array('-1' => t('All'));
+ for ($i = 0; $i < $max_delta; $i++) {
+ $options[$i] = $i + 1;
+ }
+ $form['delta'] = array(
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => $this->options['delta'],
+ '#title' => t('Delta'),
+ '#description' => t('The delta allows you to select which item in a multiple value field will be used for sorting. Select "1" to use the first item, "2" for the second item, and so on. If you select "All", each item in the field will create a new row, which may appear to cause duplicates.'),
+ );
+ }
+ }
+
+ function ensure_my_table() {
+ if (!isset($this->table_alias)) {
+ $join = $this->get_join();
+ if (!isset($join->extra)) {
+ $join->extra = array();
+ }
+ $delta = isset($this->options['delta']) ? $this->options['delta'] : -1;
+ if ($delta != -1) {
+ $join->extra[] = array(
+ 'field' => 'delta',
+ 'value' => $delta,
+ 'numeric' => TRUE,
+ );
+ }
+
+ $this->table_alias = $this->query->ensure_table($this->table, $this->relationship, $join);
+ }
+ return $this->table_alias;
+ }
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_display_simple.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_display_simple.inc
new file mode 100644
index 00000000000..e82531657e7
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_display_simple.inc
@@ -0,0 +1,43 @@
+view->render($this->display->id);
+ }
+
+ function render() {
+ return !empty($this->view->result) || !empty($this->view->style_plugin->definition['even empty']) ? $this->view->style_plugin->render($this->view->result) : '';
+ }
+
+ function uses_exposed() {
+ return FALSE;
+ }
+}
+
+class content_plugin_display_references extends content_plugin_display_simple {
+ function query() {
+ $options = $this->get_option('content_options');
+
+ if ($options['string'] !== '') {
+ $like = $GLOBALS["db_type"] == 'pgsql' ? "ILIKE" : "LIKE";
+ $match_clauses = array(
+ 'contains' => "$like '%%%s%%'",
+ 'equals' => "= '%s'",
+ 'starts_with' => "$like '%s%%'",
+ );
+ $clause = isset($match_clauses[$options['match']]) ? $match_clauses[$options['match']] : $match_clauses['contains'];
+ $alias = $this->view->query->ensure_table($options['table']);
+ $this->view->query->add_where(NULL, "$alias.$options[field_string] $clause", $options['string']);
+ }
+ elseif ($options['ids']) {
+ $alias = $this->view->query->ensure_table($options['table']);
+ $this->view->query->add_where(NULL, "$alias.$options[field_id] IN (" . db_placeholders($options['ids']) . ')', $options['ids']);
+ }
+ }
+}
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_style_php_array_ac.inc b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_style_php_array_ac.inc
new file mode 100644
index 00000000000..abff82d4f08
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/includes/views/handlers/content_plugin_style_php_array_ac.inc
@@ -0,0 +1,34 @@
+render_grouping($this->view->result, $this->options['grouping']);
+
+ $base_field = $this->view->base_field;
+ $title_field = $this->display->display_options['content_title_field'];
+ $title_field_alias = $this->view->field[$title_field]->field_alias;
+
+ // TODO : We don't display grouping info for now.
+ // Could be useful for select widget, though.
+ $this->view->row_index = 0;
+ foreach ($sets as $title => $records) {
+ foreach ($records as $label => $row) {
+ $results[$row->{$base_field}] = array(
+ 'title' => $row->{$title_field_alias},
+ 'rendered' => $this->row_plugin->render($row),
+ );
+ $this->view->row_index++;
+ }
+ }
+ unset($this->view->row_index);
+ return $results;
+ }
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.info
new file mode 100644
index 00000000000..693101c2935
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.info
@@ -0,0 +1,12 @@
+; $Id$
+name = Content Copy
+description = Enables ability to import/export field definitions.
+dependencies[] = content
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.module
new file mode 100644
index 00000000000..d0154705cca
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy.module
@@ -0,0 +1,649 @@
+ 'Export',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('content_copy_export_form'),
+ 'access arguments' => array('administer content types'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 3,
+ );
+ $items['admin/content/types/import'] = array(
+ 'title' => 'Import',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('content_copy_import_form'),
+ 'access arguments' => array('administer content types'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 4,
+ );
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function content_copy_theme() {
+ return array(
+ 'content_copy_export_form' => array(
+ 'template' => 'content_copy_export_form',
+ 'arguments' => array('form' => NULL),
+ ),
+ );
+}
+
+/**
+ * A form to export field definitions.
+ */
+function content_copy_export_form(&$form_state) {
+ include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');
+ include_once('./'. drupal_get_path('module', 'node') .'/content_types.inc');
+
+ $form_values = isset($form_state['values']) ? $form_state['values'] : array();
+ $step = isset($form_state['storage']['step']) ? $form_state['storage']['step'] + 1 : 1;
+
+ $exportable_fields = array();
+ $groups = array();
+
+ $type_name = isset($form_values['type_name']) ? $form_values['type_name'] : '';
+ if ($type_name) {
+ $type = content_types($type_name);
+ $exportable_fields = content_copy_fields($type_name);
+ if (module_exists('fieldgroup')) {
+ $groups = fieldgroup_groups($type_name);
+ }
+ }
+
+ // If a content type has been selected and there are no fields or groups to select,
+ // jump straight to export.
+ if ($step == 2 && !($groups) && !($exportable_fields)) {
+ $step = 3;
+ }
+
+ $form['#step'] = $step;
+ $form['#prefix'] = t('This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to an existing content type or create a new content type that includes the selected fields.');
+
+ switch ($step) {
+ case 1: // Select a content type.
+ $types = content_copy_types();
+ $form['type_name'] = array(
+ '#title' => t('Types'),
+ '#type' => 'radios',
+ '#options' => $types,
+ '#description' => t('Select the content type to export.'),
+ );
+ break;
+
+ case 2: // Select groups and fields.
+ $form['type_name'] = array(
+ '#type' => 'hidden',
+ '#value' => $type_name,
+ );
+
+ $form += array(
+ '#fields' => $exportable_fields,
+ '#groups' => array_keys($groups),
+ );
+
+ $fields_options = $groups_options = array();
+
+ // Fields.
+ foreach ($exportable_fields as $field_name) {
+ $field = content_fields($field_name, $type_name);
+ $fields_options[$field_name] = '';
+ $weight = $field['widget']['weight'];
+ $form[$field_name] = array(
+ 'human_name' => array('#value' => check_plain($field['widget']['label'])),
+ 'field_name' => array('#value' => $field['field_name']),
+ 'type' => array('#value' => $field['type']),
+ 'weight' => array('#type' => 'value', '#value' => $weight),
+ 'parent' => array('#type' => 'value', '#value' => ''),
+ '#row_type' => 'field',
+ );
+ }
+ $form['fields'] = array(
+ '#type' => 'checkboxes',
+ '#options' => $fields_options,
+ '#default_value' => array_keys($fields_options),
+ );
+
+ // Groups.
+ foreach ($groups as $name => $group) {
+ $groups_options[$name] = '';
+ $weight = $group['weight'];
+ $form[$name] = array(
+ 'human_name' => array('#value' => check_plain($group['label'])),
+ 'group_name' => array('#value' => $group['group_name']),
+ 'weight' => array('#type' => 'value', '#value' => $weight),
+ '#row_type' => 'group',
+ );
+ foreach ($group['fields'] as $field_name => $field) {
+ // Do nothing for non-exportable (inactive) fields.
+ if (isset($form[$field_name])) {
+ $form[$field_name]['parent']['#value'] = $name;
+ }
+ }
+ }
+ if ($groups) {
+ $form['groups'] = array(
+ '#type' => 'checkboxes',
+ '#options' => $groups_options,
+ '#default_value' => array_keys($groups_options),
+ );
+ }
+ break;
+
+ case 3: // Display the export macro.
+ $GLOBALS['content_copy']['count'] = 0;
+ $form['export'] = array(
+ '#title' => t('Export data'),
+ '#type' => 'textarea',
+ '#cols' => 60,
+ '#value' => content_copy_export($form_values),
+ '#rows' => max(40, $GLOBALS['content_copy']['count']),
+ '#description' => t('Copy the export text and paste it into another content type using the import function.'),
+ );
+ // The calls to drupal_execute('content_field_edit_form') in
+ // content_copy_export() affect the page title,
+ drupal_set_title(t('Content types'));
+ break;
+ }
+
+ if ($step < 3) { // Omit submit button on the textarea block to display the export data.
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Export'),
+ );
+ }
+
+ $form['step'] = array(
+ '#type' => 'value',
+ '#value' => $step,
+ );
+
+ return $form;
+}
+
+function content_copy_export_form_submit($form, &$form_state) {
+ $form_state['rebuild'] = TRUE;
+ $form_state['storage']['step'] = $form_state['values']['step'];
+}
+
+
+/**
+ * Process the export, get field admin forms for all requested fields
+ * and save the form values as formatted text.
+ */
+function content_copy_export($form_values) {
+ // Set a global variable to tell when to intervene with form_alter().
+ $GLOBALS['content_copy']['status'] = 'export';
+
+ // Get the content type info by submitting the content type form.
+ $node_state = array('values' => array('type_name' => $form_values['type_name']));
+ module_load_include('inc', 'node', 'content_types');
+ drupal_execute('node_type_form', $node_state, node_get_types('type', $form_values['type_name']));
+
+ module_load_include('inc', 'content', 'includes/content.admin');
+ module_load_include('inc', 'content', 'includes/content.crud');
+
+ // Get an array of groups to export.
+ // Record a macro for each group by submitting the group edit form.
+ $groups = array();
+ if (!empty($form_values['groups']) && module_exists('fieldgroup')) {
+ $groups = array_filter($form_values['groups']);
+ foreach ($groups as $group) {
+ $group_state = array('values' => array('group_name' => $group));
+ drupal_execute('fieldgroup_group_edit_form', $group_state, $form_values['type_name'], $group, 'edit');
+ }
+ }
+
+ // Get an array of fields to export
+ // Record a macro for each field by submitting the field settings form.
+ // Omit fields from the export if their module is not currently installed
+ // otherwise the system will generate errors when the macro tries to execute their forms.
+ if (!empty($form_values['fields'])) {
+ $type = content_types($form_values['type_name']);
+ $fields = array_filter($form_values['fields']);
+ foreach ($fields as $field_name) {
+ $field = $type['fields'][$field_name];
+ $field_types = _content_field_types();
+ $field_module = $field_types[$field['type']]['module'];
+ $widget_types = _content_widget_types();
+ $widget_module = $widget_types[$field['widget']['type']]['module'];
+ if (!empty($field_module) && module_exists($field_module) && !empty($widget_module) && module_exists($widget_module)) {
+ $field_state = array('values' => content_field_instance_collapse($field));
+ $field_state['values']['op'] = t('Save field settings');
+ if (module_exists('fieldgroup')) {
+ // Avoid undefined index error by always creating this.
+ $field_state['values']['group'] = '';
+ $group_name = fieldgroup_get_group($form_values['type_name'], $field_name);
+ if (in_array($group_name, $groups)) {
+ $field_state['values']['group'] = $group_name;
+ }
+ }
+ drupal_execute('content_field_edit_form', $field_state, $form_values['type_name'], $field_name);
+ }
+ }
+ }
+
+ // Convert the macro array into formatted text.
+ $output = content_copy_get_macro();
+
+ // Add weights of non-CCK fields.
+ if ($extra = variable_get('content_extra_weights_'. $form_values['type_name'], array())) {
+ $output .= "\$content['extra'] = ". var_export((array) $extra, TRUE) .";\n";
+ }
+
+ return $output;
+}
+
+/**
+ * A form to import formatted text created with export.
+ *
+ * The macro can be filled from a file, if provided.
+ * Provide a type_name to force the fields to be added to a specific
+ * type, or leave out type_name to create a new content type.
+ *
+ * Example:
+ * // If Content Copy is enabled, offer an import link.
+ * if (module_exists('content_copy')) {
+ * $form['macro'] = array(
+ * '#type' => 'fieldset',
+ * '#title' => t('Create a content type'),
+ * '#description' => t('Follow this link to create automatically a content type and import preconfigured fields.'),
+ * '#collapsible' => TRUE,
+ * '#collapsed' => FALSE,
+ * );
+ * $form['macro']['link'] = array(
+ * '#type' => 'markup',
+ * '#value' => l(t('import'), 'admin/content/types/import', array(), 'type_name=event¯o_file='. drupal_get_path('module', 'my_module') .'/my_content_type.txt'),
+ * );
+ * }
+ */
+function content_copy_import_form(&$form_state, $type_name = '') {
+ include_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');
+ include_once('./'. drupal_get_path('module', 'node') .'/content_types.inc');
+
+ $form['#prefix'] = t('This form will import field definitions exported from another content type or another database. Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type.');
+ $form['type_name'] = array(
+ '#type' => 'select',
+ '#options' => array('' => t('')) + content_copy_types(),
+ '#default_value' => $type_name,
+ '#title' => t('Content type'),
+ '#description' => t('Select the content type to import these fields into. Select <Create> to create a new content type to contain the fields.'),
+ );
+ $form['macro'] = array(
+ '#type' => 'textarea',
+ '#rows' => 40,
+ '#title' => t('Import data'),
+ '#required' => TRUE,
+ '#description' => t('Paste the text created by a content export into this field.'),
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Import'),
+ );
+ // Read in a file if there is one and set it as the default macro value.
+ if (isset($_REQUEST['macro_file']) && $file = file_get_contents($_REQUEST['macro_file'])) {
+ $form['macro']['#default_value'] = $file;
+ if (isset($_REQUEST['type_name'])) {
+ $form['type_name']['#default_value'] = $_REQUEST['type_name'];
+ }
+ $form['#prefix'] .= '
'. t('A file has been pre-loaded for import.') .'
';
+ }
+ return $form;
+}
+
+/**
+ * Submit handler for import form.
+ * For each submitted field:
+ * 1) add new field to the database
+ * 2) execute the imported field macro to update the settings to the imported values
+ */
+function content_copy_import_form_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+
+ // Get the content type we are importing into.
+ $type_name = $form_values['type_name'];
+ $type_label = node_get_types('name', $type_name);
+
+ $content = NULL;
+ // Convert the import formatted text back into a $content array.
+ // Return if errors generated or not an array.
+ // Use '@' to suppress errors about undefined constants in the macro.
+ @eval($form_values['macro']);
+
+ // Preliminary error trapping, must have valid arrays to work with.
+ if (!isset($content) || !isset($content['type']) || !is_array($content) || !is_array($content['type'])) {
+ form_set_error('macro', t('The import data is not valid import text.'));
+ return;
+ }
+
+ module_load_include('inc', 'content', 'includes/content.crud');
+
+ // Get all type and field info for this database.
+ $content_info = _content_type_info();
+
+ $imported_type = $content['type'];
+ $imported_type_name = $imported_type['type'];
+ $imported_type_label = $imported_type['name'];
+
+ // It is allowed to import a type with no fields,
+ // so the fields array could be empty and must be cast as an array.
+ $imported_fields = isset($content['fields']) ? $content['fields'] : array();
+
+ // Perform more pre-import error trapping.
+ // If there are potential problems, exit without doing the import.
+ $not_enabled = array();
+
+ // The groups array could be empty and still valid, make sure to cast it as an array.
+ // If there are groups in the import, make sure the fieldgroup module is enabled.
+ $imported_groups = array();
+ if (isset($content['groups']) && module_exists('fieldgroup')) {
+ $imported_groups = (array) $content['groups'];
+ }
+ elseif (isset($content['groups']) && is_array($content['groups'])) {
+ $not_enabled[] = 'fieldgroup';
+ }
+
+ // Make sure that all the field and widget modules in the import are enabled in this database.
+ foreach ($imported_fields as $import) {
+ $field = content_field_instance_collapse($import);
+ if (empty($field['module']) || empty($field['widget_module'])) {
+ $not_enabled[] = $field['field_name'];
+ }
+ else {
+ if (!module_exists($field['module'])) {
+ $not_enabled[] = $field['module'];
+ }
+ if (!module_exists($field['widget_module'])) {
+ $not_enabled[] = $field['widget_module'];
+ }
+ }
+ }
+
+ // If any required module is not enabled, set an error message and exit.
+ if ($not_enabled) {
+ form_set_error('macro', t('The following modules must be enabled for this import to work: %modules.', array(
+ '%modules' => implode(', ', array_unique($not_enabled))
+ )));
+ }
+
+ // Make sure the imported content type doesn't already exist in the database.
+ if ($form_values['type_name'] == '') {
+ if (in_array($imported_type_name, array_keys($content_info['content types']))) {
+ form_set_error('macro', t('The content type %type already exists in this database.', array(
+ '%type' => $imported_type_name
+ )));
+ }
+ }
+
+ if (form_get_errors()) {
+ drupal_set_message(t('Exiting. No import performed.'), 'error');
+ return;
+ }
+
+ // Create the content type, if requested.
+ if ($form_values['type_name'] == '') {
+
+ $type = (object) $imported_type;
+ $values = $imported_type;
+ // Prevent a warning in node/content_types.inc
+ $type->has_title = TRUE;
+ $type_form_state = array('values' => $values);
+
+ // There's no API for creating node types, we still have to use drupal_execute().
+ drupal_execute('node_type_form', $type_form_state, $type);
+
+ // Reset type and database values once new type has been added.
+ $type_name = $imported_type_name;
+ $type_label = node_get_types('name', $type_name);
+ content_clear_type_cache();
+ $content_info = _content_type_info();
+
+ if (form_get_errors() || !isset($content_info['content types']) || !is_array($content_info['content types'][$type_name])) {
+ drupal_set_message(t('An error has occurred adding the content type %type. Please check the errors displayed for more details.', array(
+ '%type' => $imported_type_name
+ )));
+ return;
+ }
+ }
+
+ // Create the groups for this type, if they don't already exist.
+ if (module_exists('fieldgroup') && $imported_groups) {
+ foreach ($imported_groups as $group) {
+ $group_name = $group['group_name'];
+ fieldgroup_save_group($type_name, $group);
+ }
+ // Reset the static variable in fieldgroup_groups() with new data.
+ fieldgroup_groups('', FALSE, TRUE);
+ }
+
+ // Iterate through the field forms in the import and execute each.
+ $rebuild = FALSE;
+ foreach ($imported_fields as $field) {
+
+ // Make sure the field doesn't already exist in the type.
+ // If so, do nothing, fields can't be duplicated within a content type.
+ $field_name = $field['field_name'];
+
+ // Might need to overwrite the content type name if a new type was created.
+ $field['type_name'] = $type_name;
+
+ if (!empty($field['field_name']) && isset($content_info['content types'][$type_name]['fields'][$field_name])) {
+ drupal_set_message(t('The imported field %field_label (%field_name) was not added to %type because that field already exists in %type.', array(
+ '%field_label' => $field['label'], '%field_name' => $field_name, '%type' => $type_label)));
+ }
+ else {
+ $field = content_field_instance_create($field, FALSE);
+ $rebuild = TRUE;
+ drupal_set_message(t('The field %field_label (%field_name) was added to the content type %type.', array(
+ '%field_label' => $field['widget']['label'], '%field_name' => $field_name, '%type' => $type_label)));
+ }
+
+ // Fieldgroup module erases all group related data when a module that
+ // provides a content type is disabled, but CCK does not remove the fields.
+ // In this case, we should ensure group data related to fields is properly
+ // restored. Hence, we need to update field group data for newly imported
+ // field, but also for fields that already exist.
+ if (module_exists('fieldgroup') && isset($imported_groups)) {
+ fieldgroup_update_fields($field);
+ }
+ }
+
+ // Clear caches and rebuild menu only if any field has been created.
+ if ($rebuild) {
+ content_clear_type_cache(TRUE);
+ menu_rebuild();
+ }
+
+ // Import weights of non-CCK fields.
+ if (isset($content['extra'])) {
+ variable_set('content_extra_weights_'. $type_name, $content['extra']);
+ }
+}
+
+/**
+ * Implementation of hook_form_alter().
+ * Intervene to run form through macro when doing export
+ */
+function content_copy_form_alter(&$form, $form_state, $form_id) {
+ $alter_forms = array('node_type_form', 'content_field_edit_form', 'fieldgroup_group_edit_form');
+ if (isset($GLOBALS['content_copy']) && isset($GLOBALS['content_copy']['status']) && $GLOBALS['content_copy']['status'] == 'export' && in_array($form_id, $alter_forms)) {
+ $form['#submit'][] = 'content_copy_record_macro';
+ }
+}
+
+/**
+ * Get all the *active* fields for a content type.
+ */
+function content_copy_fields($type_name) {
+ $fields = array();
+ if (!$type_name) {
+ return $fields;
+ }
+ $content_info = _content_type_info();
+ foreach ($content_info['content types'][$type_name]['fields'] as $field_name => $field) {
+ // Omit fields from the export if their module is not currently installed
+ // otherwise the system will generate errors when the macro tries to execute their forms.
+ $field_types = _content_field_types();
+ $field_module = $field_types[$field['type']]['module'];
+ $widget_types = _content_widget_types();
+ $widget_module = $widget_types[$field['widget']['type']]['module'];
+
+ if (!$field['locked'] && !empty($field_module) && module_exists($field_module) && !empty($widget_module) && module_exists($widget_module)) {
+ $fields[] = $field_name;
+ }
+ }
+ return $fields;
+}
+
+/**
+ * Get all content types.
+ */
+function content_copy_types() {
+ $types = array();
+ $content_info = _content_type_info();
+ foreach ($content_info['content types'] as $type_name => $val) {
+ $types[$type_name] = check_plain($val['name']) .' ('. $type_name .')';
+ }
+ return $types;
+}
+
+/**
+ * A handler that stores the form submissions into a $GLOBALS array
+ */
+function content_copy_record_macro($form, &$form_state) {
+ $edit = $form_state['values'];
+ $subs = isset($GLOBALS['content_copy']['submissions']) ? $GLOBALS['content_copy']['submissions'] : array();
+
+ // Get the form values and store them in a $GLOBALS['content_copy']['submissions'] array.
+ // Update $GLOBALS['content_copy']['count'] with an approximation of the number of rows in this item.
+ // Count is used to approximate necessary size of textarea in form.
+
+ $form_id = $form_state['values']['form_id'];
+ if (isset($edit['type_name']) || isset($edit['submit']) || isset($edit['delete']) || isset($edit['form_id'])) {
+ unset($edit['type_name'], $edit['submit'], $edit['delete'], $edit['form_id'], $edit['previous_field']);
+ }
+ switch ($form_id) {
+ case 'node_type_form':
+ $subs['type'] = $edit;
+ $GLOBALS['content_copy']['count'] += sizeof($edit) + 5;
+ break;
+
+ case 'fieldgroup_group_edit_form':
+ $subs['groups'][] = $edit;
+ $GLOBALS['content_copy']['count'] += sizeof($edit) + 5;
+ break;
+
+ default:
+ if (isset($edit['field_widget_type'])) {
+ $tmp = explode('-', $edit['field_widget_type']);
+ $field_name = $tmp[0];
+ }
+ else {
+ $field_name = isset($edit['field_name']) ? $edit['field_name'] : '';
+ }
+
+ // The display settings are being fetched directly from the DB. During import,
+ // we'll re-insert the data directly as well.
+ //
+ $query = 'SELECT display_settings FROM {'. content_instance_tablename() .'} WHERE field_name = \'%s\'';
+ $row_info = db_fetch_array(db_query($query, $field_name));
+
+ // If an error occurs, notify the user.
+ if ($db_err = db_error()) {
+ drupal_set_message(t("An error occurred when exporting the 'display settings' data for the field %field_name. The db error is: '%db_err'.", array(
+ '%field_name' => $field_name,
+ '%db_err' => $db_err
+ )));
+ }
+ else {
+ // The db fetch occurred successfully, unserialize the data blob and
+ // insert it into a new "display_settings" field of the data.
+ if ($display_settings = unserialize($row_info['display_settings'])) {
+ $edit['display_settings'] = $display_settings;
+ }
+ }
+ $subs['fields'][] = $edit;
+ $GLOBALS['content_copy']['count'] += sizeof($edit) + 5;
+ break;
+ }
+
+ $GLOBALS['content_copy']['submissions'] = $subs;
+}
+
+/**
+ * @return a code representation of the recorded macro.
+ */
+function content_copy_get_macro() {
+ // Define the indexes for the evaluated code.
+ $string = "";
+ if (array_key_exists('submissions', $GLOBALS['content_copy'])) {
+ foreach ($GLOBALS['content_copy']['submissions'] as $form_type => $form) {
+ $string .= "\$content['$form_type'] = ". var_export((array) $form, TRUE) .";\n";
+ }
+ return $string;
+ }
+}
+
+function template_preprocess_content_copy_export_form($vars) {
+ $form = &$vars['form'];
+
+ if ($form['#step'] == 2) {
+ $order = _content_overview_order($form, $form['#fields'], $form['#groups']);
+
+ $rows = array();
+ foreach ($order as $key) {
+ $element = &$form[$key];
+ $row = new stdClass();
+
+ $row->row_type = $element['#row_type'];
+ $checkbox_key = $element['#row_type'] == 'field' ? 'fields' : 'groups';
+ $row->checkbox = drupal_render($form[$checkbox_key][$key]);
+ foreach (element_children($element) as $child) {
+ $row->{$child} = drupal_render($element[$child]);
+ }
+ $row->label_class = in_array($key, $form['#groups']) ? 'label-group' : 'label-field';
+ $row->indentation = theme('indentation', isset($element['#depth']) ? $element['#depth'] : 0);
+
+ $rows[] = $row;
+ }
+ $vars['rows'] = $rows;
+ }
+
+ $vars['submit'] = drupal_render($form);
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy_export_form.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy_export_form.tpl.php
new file mode 100644
index 00000000000..54b0de6c619
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/content_copy_export_form.tpl.php
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ row_type):
+ case 'field': ?>
+
checkbox; ?>
+
indentation; ?>human_name; ?>
+
field_name; ?>
+
type; ?>
+
+
checkbox; ?>
+
indentation; ?>human_name; ?>
+
group_name; ?>
+
+
+
+
+
+
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.de.po
new file mode 100644
index 00000000000..fd1917e8817
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.de.po
@@ -0,0 +1,137 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2008-11-05 12:54+0100\n"
+"PO-Revision-Date: 2008-11-05 13:17+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/content_copy/content_copy_export_form.tpl.php:9
+#: modules/content_copy/content_copy.module:187;38
+msgid "Export"
+msgstr "Exportieren"
+
+#: modules/content_copy/content_copy.module:97
+msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields."
+msgstr "Dieses Formular verarbeitet einen Inhaltstyp, ein oder mehrere Felder von diesem Typ und exportiert die Einstellungen. Der von diesem Prozess erstellte Export kann kopiert und als Import in die Aktuelle oder jede andere Datenbank eingefügt werden. Der Import wird die Felder zu einem vorhandenen Inhaltstyp hinzufügen oder einen neuen Inhaltstyp mit den ausgewählten Feldern erstellen."
+
+#: modules/content_copy/content_copy.module:103
+msgid "Types"
+msgstr "Typen"
+
+#: modules/content_copy/content_copy.module:107
+msgid "Select the content type to export."
+msgstr "Wählen Sie einen Inhaltstyp für den Export."
+
+#: modules/content_copy/content_copy.module:171
+msgid "Export data"
+msgstr "Daten exportieren"
+
+#: modules/content_copy/content_copy.module:176
+msgid "Copy the export text and paste it into another content type using the import function."
+msgstr "Kopieren Sie den exportierten Text und fügen Sie ihn mit der Importfunktion in einen anderen Inhaltstyp ein."
+
+#: modules/content_copy/content_copy.module:180
+msgid "Content types"
+msgstr "Inhaltstypen"
+
+#: modules/content_copy/content_copy.module:299
+msgid "This form will import field definitions exported from another content type or another database. Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type."
+msgstr "Dieses Formular wird Felddefinitionen importieren, die von einem anderen Inhaltstyp oder anderen Datenbank exportiert wurden. Dabei ist zu beachten, dass die Felder nicht innerhalb des gleichen Inhalttyps dupliziert werden können, deshalb werden importierte Felder nur hinzugefügt, wenn diese im ausgewählten Typ noch nicht vorhanden sind."
+
+#: modules/content_copy/content_copy.module:302
+msgid ""
+msgstr ""
+
+#: modules/content_copy/content_copy.module:304
+msgid "Content type"
+msgstr "Inhaltstyp"
+
+#: modules/content_copy/content_copy.module:305
+msgid "Select the content type to import these fields into. Select <Create> to create a new content type to contain the fields."
+msgstr "Wählen Sie den Inhaltstyp zum Aufnehmen der importierten Felder aus. Wählen Sie <Erstellen> zum Erstellen eines neuen Inhaltstyps für die zu importierenden Felder."
+
+#: modules/content_copy/content_copy.module:310
+msgid "Import data"
+msgstr "Daten importieren"
+
+#: modules/content_copy/content_copy.module:312
+msgid "Paste the text created by a content export into this field."
+msgstr "Fügen Sie den Text aus einem Inhaltsexport in dieses Feld ein."
+
+#: modules/content_copy/content_copy.module:316;46
+msgid "Import"
+msgstr "Importieren"
+
+# "vorgeladen" sounds strange
+#: modules/content_copy/content_copy.module:324
+#, fuzzy
+msgid "A file has been pre-loaded for import."
+msgstr "Eine Datei wurde für den Import vorgeladen."
+
+#: modules/content_copy/content_copy.module:350
+msgid "The import data is not valid import text."
+msgstr "Die importierten Daten sind kein gültiger Importtext."
+
+#: modules/content_copy/content_copy.module:399
+msgid "The following modules must be enabled for this import to work: %modules."
+msgstr "Die folgenden Module müssen eingeschaltet sein, damit dieser Import erfolgreich durchgeführt werden kann: %modules."
+
+#: modules/content_copy/content_copy.module:407
+msgid "The content type %type already exists in this database."
+msgstr "Der Inhaltstyp %type existiert bereits in dieser Datenbank."
+
+#: modules/content_copy/content_copy.module:414
+msgid "Exiting. No import performed."
+msgstr "Abbruch. Kein Import durchgeführt."
+
+#: modules/content_copy/content_copy.module:438
+msgid "An error has occurred adding the content type %type. Please check the errors displayed for more details."
+msgstr "Beim Hinzufügen des Inhaltstyps %type trat ein Fehler auf. Bitte überprüfen Sie die angezeigten Fehler für weitere Details."
+
+#: modules/content_copy/content_copy.module:463
+msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type."
+msgstr "Das importierte Feld %field_label (%field_name) wurde nicht zu %type hinzugefügt, weil dieses Feld bereits in %type existiert."
+
+#: modules/content_copy/content_copy.module:472
+msgid "The field %field_label (%field_name) was added to the content type %type."
+msgstr "Das Feld %field_label (%field_name) wurde zu dem Inhaltstyp %type hinzugefügt."
+
+#: modules/content_copy/content_copy.module:553
+msgid "An error occurred when exporting the 'display settings' data for the field %field_name. The db error is: '%db_err'."
+msgstr "Beim Exportieren der ‚Anzeige-Einstellungs‘-Daten für das Feld %field_name ist ein Fehler aufgetreten. Der DB-Fehler ist: ‚%db_err‘."
+
+#: modules/content_copy/content_copy.module:0
+msgid "content_copy"
+msgstr "Inhaltskopie"
+
+#: modules/content_copy/content_copy.info:0
+msgid "Content Copy"
+msgstr "Inhaltskopie"
+
+#: modules/content_copy/content_copy.info:0
+msgid "Enables ability to import/export field definitions."
+msgstr "Aktiviert die Möglichkeit zum Importieren und Exportieren von Felddefinitionen."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.fr.po
new file mode 100644
index 00000000000..6c54ab5d2dc
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.fr.po
@@ -0,0 +1,177 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-07-03 13:52+0100\n"
+"Last-Translator: Damien Tournoud \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: modules/content_copy/content_copy.module:80
+msgid ""
+"This form will process a content type and one or more fields from that type "
+"and export the settings. The export created by this process can be copied "
+"and pasted as an import into the current or any other database. The import "
+"will add the fields to into an existing content type or create a new content "
+"type that includes the selected fields."
+msgstr ""
+"Ce formulaire traitera un type de contenu et un ou plusieurs champs de ce "
+"type, pour en exporter les paramètres. Le code d'export ainsi généré peut "
+"être copié et collé dans la page d'import, vers la base de données courante "
+"ou vers une autre base de données. L'opération d'import ajoutera les champs "
+"à un type de contenu existant ou créera un nouveau type de contenu intégrant "
+"les champs sélectionnés."
+
+#: modules/content_copy/content_copy.module:86
+msgid "Types"
+msgstr "Types"
+
+#: modules/content_copy/content_copy.module:90
+msgid "Select the content type to export."
+msgstr "Sélectionner le type de contenu à exporter."
+
+#: modules/content_copy/content_copy.module:115
+msgid "Groups"
+msgstr "Groupes"
+
+#: modules/content_copy/content_copy.module:119
+msgid "Select the group definitions to export from %type."
+msgstr "Sélectionnez les définitions de groupes à exporter depuis '%type'."
+
+#: modules/content_copy/content_copy.module:129
+msgid "Select the field definitions to export from %type."
+msgstr "Sélectionnez les définitions de champs à exporter depuis '%type'."
+
+#: modules/content_copy/content_copy.module:139
+msgid "Export data"
+msgstr "Données exportée"
+
+#: modules/content_copy/content_copy.module:144
+msgid ""
+"Copy the export text and paste it into another content type using the import "
+"function."
+msgstr ""
+"Copiez le texte exporté et collez-le dans le type de contenu de votre choix, "
+"à l'aide de la fonction d'import."
+
+#: modules/content_copy/content_copy.module:154;38
+msgid "Export"
+msgstr "Exporter"
+
+#: modules/content_copy/content_copy.module:227
+msgid ""
+"This form will import field definitions exported from another content type "
+"or another database. Note that fields cannot be duplicated within the "
+"same content type, so imported fields will be added only if they do not "
+"already exist in the selected type."
+msgstr ""
+"Ce formulaire permet d'importer les définitions de champs exportées depuis "
+"un autre type de contenu ou depuis une autre base de données. Notez que "
+"les champs ne peuvent être dupliqués au sein d'un même type de contenu : les "
+"champs importés ne peuvent donc être ajoutés que s'ils n'existent pas encore "
+"dans le type sélectionné."
+
+#: modules/content_copy/content_copy.module:230
+msgid ""
+msgstr ""
+
+#: modules/content_copy/content_copy.module:232
+msgid "Content type"
+msgstr "Type de contenu"
+
+#: modules/content_copy/content_copy.module:233
+msgid ""
+"Select the content type to import these fields into. Select <"
+"Create> to create a new content type to contain the fields."
+msgstr ""
+"Choisissez le type de contenu vers lequel vous voulez importer ces champs."
+" Sélectionnez <Create> pour créer un nouveau type de contenu "
+"comportant ces champs."
+
+#: modules/content_copy/content_copy.module:238
+msgid "Import data"
+msgstr "Données à importer"
+
+#: modules/content_copy/content_copy.module:240
+msgid "Paste the text created by a content export into this field."
+msgstr "Collez dans ce champ le texte créé par un export de contenu."
+
+#: modules/content_copy/content_copy.module:244;46
+msgid "Import"
+msgstr "Importer"
+
+#: modules/content_copy/content_copy.module:270
+msgid "The import data is not valid import text."
+msgstr "Les données d'import ne sont valides."
+
+#: modules/content_copy/content_copy.module:318
+msgid ""
+"The following modules must be enabled for this import to work: %modules."
+msgstr ""
+"Les modules suivants doivent être activés pour que l'import fonctionne : '%"
+"modules'."
+
+#: modules/content_copy/content_copy.module:324;338
+msgid ""
+msgstr ""
+
+#: modules/content_copy/content_copy.module:326
+msgid "The content type %type already exists in this database."
+msgstr "Le type de contenu '%type' existe déjà dans cette base de données."
+
+#: modules/content_copy/content_copy.module:333
+msgid "Exiting. No import performed."
+msgstr "Abandon. L'import n'a pas été réalisé."
+
+#: modules/content_copy/content_copy.module:355
+msgid ""
+"An error has occurred adding the content type %type. Please check the "
+"errors displayed for more details."
+msgstr ""
+"Une erreur s'est produite à l'ajout du type de contenu '%type'. Consultez les erreurs affichées à l'écran pour plus de détails."
+
+#: modules/content_copy/content_copy.module:380
+msgid ""
+"The imported field %field_label (%field_name) was not added to %type because "
+"that field already exists in %type."
+msgstr ""
+"Le champ importé '%field_label' (%field_name) n'a pas été ajouté à '%type' "
+"car ce champ existe déjà."
+
+#: modules/content_copy/content_copy.module:389
+msgid ""
+"The field %field_label (%field_name) was added to the content type %type."
+msgstr ""
+"Le champ importé '%field_label' (%field_name) a été ajouté au type de "
+"contenu '%type'."
+
+#: modules/content_copy/content_copy.module:503
+msgid ""
+"An error occurred when exporting the 'display settings' data for the field %"
+"field_name. The db error is: '%db_err'."
+msgstr ""
+"Une erreur s'est produite à l'export des données 'paramètres d'affichage' "
+"pour le champ '%field_name'. L'erreur renvoyée par la base de données "
+"est : '%db_err'."
+
+#: modules/content_copy/content_copy.module:0
+msgid "content_copy"
+msgstr "content_copy"
+
+#: modules/content_copy/content_copy.info:0
+msgid "Content Copy"
+msgstr "Content Copy"
+
+#: modules/content_copy/content_copy.info:0
+msgid "Enables ability to import/export field definitions."
+msgstr "Permet d'importer et d'exporter des définitions de champs."
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.hu.po
new file mode 100644
index 00000000000..12c9d4acba9
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.hu.po
@@ -0,0 +1,193 @@
+# Hungarian translation of cck (6.x-2.0-rc10)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# content_copy.module,v 1.27.2.13 2008/10/08 12:55:54 karens
+# content_copy.info,v 1.6 2008/04/23 18:01:48 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cck (6.x-2.0-rc10)\n"
+"POT-Creation-Date: 2008-10-31 12:16-0500\n"
+"PO-Revision-Date: 2008-10-26 11:48-0500\n"
+"Last-Translator: Balogh Zoltán\n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: modules/content_copy/content_copy.module:262,46
+msgid "Import"
+msgstr "Import"
+
+#: modules/content_copy/content_copy.module:139,38
+msgid "Export"
+msgstr "Export"
+
+#: modules/content_copy/content_copy.module:132
+msgid "Content types"
+msgstr "Tartalom típusok"
+
+#: modules/content_copy/content_copy.module:100
+msgid "Groups"
+msgstr "Csoportok"
+
+#: modules/content_copy/content_copy.module:250
+msgid "Content type"
+msgstr "Tartalomtípus"
+
+#: modules/content_copy/content_copy.module:85
+msgid "Types"
+msgstr "Típusok"
+
+#: modules/content_copy/content_copy.module:80
+msgid ""
+"This form will process a content type and one or more fields from that "
+"type and export the settings. The export created by this process can "
+"be copied and pasted as an import into the current or any other "
+"database. The import will add the fields to into an existing content "
+"type or create a new content type that includes the selected fields."
+msgstr ""
+"Ez az űrlap készíti el a tartalomtípus és a típusból egy vagy "
+"több mező beállításainak exportálását. A folyamat által "
+"készített exportot lehet lemásolni és mint importot beilleszteni "
+"az aktuális, vagy bármely más adatbázisba. Az import hozzá fogja "
+"adni a mezőket egy létező tartalom típushoz, vagy létre fog hozni "
+"egy új tartalomtípust, mely tartalmazni fogja a kiválasztott "
+"mezőket."
+
+#: modules/content_copy/content_copy.module:89
+msgid "Select the content type to export."
+msgstr "Tartalomtípus kiválasztása az exporthoz."
+
+#: modules/content_copy/content_copy.module:104
+msgid "Select the group definitions to export from %type."
+msgstr ""
+"Csoport meghatározások kiválasztása az exporthoz a következő "
+"tartalomtípusból: %type."
+
+#: modules/content_copy/content_copy.module:114
+msgid "Select the field definitions to export from %type."
+msgstr ""
+"Mező meghatározások kiválasztása az exporthoz a következő "
+"tartalom típusból: %type."
+
+#: modules/content_copy/content_copy.module:123
+msgid "Export data"
+msgstr "Adatok exportálása"
+
+#: modules/content_copy/content_copy.module:128
+msgid ""
+"Copy the export text and paste it into another content type using the "
+"import function."
+msgstr ""
+"Az export által előállított szöveget át lehet másolni egy "
+"másik tartalomtípusba az import művelet segítségével."
+
+#: modules/content_copy/content_copy.module:245
+msgid ""
+"This form will import field definitions exported from another content "
+"type or another database. Note that fields cannot be duplicated "
+"within the same content type, so imported fields will be added only if "
+"they do not already exist in the selected type."
+msgstr ""
+"Ez az űrlap importálja a mező meghatározásokat, melyek egy másik "
+"tartalom típusból, vagy egy másik adatbázisból lettek "
+"exportálva. Megjegyzés: Egy tartalom típuson belül a mezőket "
+"nem lehet többszörözni, így csak azok a mezők lesznek hozzáadva, "
+"melyek még nem szerepelnek a kiválasztott tartalom típusban."
+
+#: modules/content_copy/content_copy.module:248
+msgid ""
+msgstr ""
+
+#: modules/content_copy/content_copy.module:251
+msgid ""
+"Select the content type to import these fields into. Select "
+"<Create> to create a new content type to contain the fields."
+msgstr ""
+"Tartalom típus kiválasztása a mezők importálásához. A "
+"<Létrehozás> segítségével új tartalom típus jön létre, "
+"mely tartalmazni fogja a mezőket."
+
+#: modules/content_copy/content_copy.module:256
+msgid "Import data"
+msgstr "Adatok importálása"
+
+#: modules/content_copy/content_copy.module:258
+msgid "Paste the text created by a content export into this field."
+msgstr ""
+"A tartalom exportnál keletkezett szöveget kell ebbe a mezőbe "
+"illeszteni."
+
+#: modules/content_copy/content_copy.module:270
+msgid "A file has been pre-loaded for import."
+msgstr "A fájl előzetesen be lett töltve az importhoz."
+
+#: modules/content_copy/content_copy.module:296
+msgid "The import data is not valid import text."
+msgstr "Az adat nem értelmezhető import szövegként."
+
+#: modules/content_copy/content_copy.module:344
+msgid ""
+"The following modules must be enabled for this import to work: "
+"%modules."
+msgstr ""
+"A következő modulokat engedélyezni kell, hogy ez az import "
+"működjön: %modules."
+
+#: modules/content_copy/content_copy.module:352
+msgid "The content type %type already exists in this database."
+msgstr "%type tartalomtípus már szerepel az adatbázisban."
+
+#: modules/content_copy/content_copy.module:359
+msgid "Exiting. No import performed."
+msgstr "Kilépés. Az importálás nem lett végrehajtva."
+
+#: modules/content_copy/content_copy.module:383
+msgid ""
+"An error has occurred adding the content type %type. Please check "
+"the errors displayed for more details."
+msgstr ""
+"Hiba történt a következő tartalomtípus hozzáadása közben: "
+"%type. További részletek a megjelenített hibaüzenetekben."
+
+#: modules/content_copy/content_copy.module:409
+msgid ""
+"The imported field %field_label (%field_name) was not added to %type "
+"because that field already exists in %type."
+msgstr ""
+"%field_label (%field_name) mező már létezik, ezért az import "
+"során nem lett hozzáadva a következő tartalomtípushoz: %type."
+
+#: modules/content_copy/content_copy.module:418
+msgid ""
+"The field %field_label (%field_name) was added to the content type "
+"%type."
+msgstr ""
+"%field_label (%field_name) mező hozzá lett adva a következő "
+"tartalomtípushoz: %type."
+
+#: modules/content_copy/content_copy.module:532
+msgid ""
+"An error occurred when exporting the 'display settings' data for the "
+"field %field_name. The db error is: '%db_err'."
+msgstr ""
+"%field_name mező „Megjelenítési beállítás” adatainak "
+"exportálása közben egy hiba keletkezett. Az adatbázis hiba: "
+"„%db_err”."
+
+#: modules/content_copy/content_copy.module:0
+msgid "content_copy"
+msgstr "content_copy"
+
+#: modules/content_copy/content_copy.info:0
+msgid "Content Copy"
+msgstr "Content Copy"
+
+#: modules/content_copy/content_copy.info:0
+msgid "Enables ability to import/export field definitions."
+msgstr ""
+"Lehetővé teszi a meződefiníciók importálását és "
+"exportálását."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.nl.po
new file mode 100644
index 00000000000..4ae43085f77
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.nl.po
@@ -0,0 +1,146 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched
+# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched
+# content_copy.info,v 1.6 2008/04/23 18:01:48 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:25+0200\n"
+"PO-Revision-Date: 2009-06-03 14:27+0100\n"
+"Last-Translator: L.B. Cohn \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: content_copy_export_form.tpl.php:9
+#: content_copy.module:191;38
+msgid "Export"
+msgstr "Exporteren"
+
+#: content_copy_export_form.tpl.php:10
+msgid "Label"
+msgstr "Label"
+
+#: content_copy_export_form.tpl.php:11
+msgid "Name"
+msgstr "Naam"
+
+#: content_copy_export_form.tpl.php:12
+msgid "Type"
+msgstr "Type"
+
+#: content_copy.module:97
+msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields."
+msgstr "Dit formulier zal een inhoudstype en één of meerdere velden van dat type exporteren. Dit kan worden gekopieerd en geplakt in deze of een andere database. Importeren zal deze velden aan een bestanden inhoudstype toevoegen of een nieuw inhoudstype maken met de geselecteerde velden."
+
+#: content_copy.module:103
+msgid "Types"
+msgstr "Typen"
+
+#: content_copy.module:107
+msgid "Select the content type to export."
+msgstr "Selecteer de inhoudstypes om te exporteren"
+
+#: content_copy.module:175
+msgid "Export data"
+msgstr "Exporteer data"
+
+#: content_copy.module:180
+msgid "Copy the export text and paste it into another content type using the import function."
+msgstr "Kopieer de geexporteerde tekst en plak het in een ander inhoudstype of gebruik de importeerfunctie."
+
+#: content_copy.module:184
+msgid "Content types"
+msgstr "Inhoudstypen"
+
+#: content_copy.module:251
+msgid "Save field settings"
+msgstr "Veldinstellingen indienen"
+
+#: content_copy.module:303
+msgid "This form will import field definitions exported from another content type or another database. Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type."
+msgstr "Dit formulier zal veldinformatie importeren die zijn geexporteerd uit een ander inhoudstype of database. Merk op dat velden niet kunnen worden gedupliceerd in hetzelfde inhoudstype, dus geimporteerde velden zullen alleen worden toegevoegd als ze nog niet bestaan in het geselecteerde inhoudstype."
+
+#: content_copy.module:306
+msgid ""
+msgstr ""
+
+#: content_copy.module:308
+msgid "Content type"
+msgstr "Inhoudstype"
+
+#: content_copy.module:309
+msgid "Select the content type to import these fields into. Select <Create> to create a new content type to contain the fields."
+msgstr "Selecteer het inhoudstype waarin deze velden moeten worden geimporteerd. Selecteer <Maak> om een nieuw inhoudstype te maken waarin de velden komen."
+
+#: content_copy.module:314
+msgid "Import data"
+msgstr "Importeer data"
+
+#: content_copy.module:316
+msgid "Paste the text created by a content export into this field."
+msgstr "Plak de tekst die is geexporteerd in dit veld."
+
+#: content_copy.module:320;46
+msgid "Import"
+msgstr "Importeren"
+
+#: content_copy.module:328
+msgid "A file has been pre-loaded for import."
+msgstr "Een bestand is voorgeladen voor het importeren."
+
+#: content_copy.module:354
+msgid "The import data is not valid import text."
+msgstr "De geimporteerde data is geen valide importeertekst."
+
+#: content_copy.module:403
+msgid "The following modules must be enabled for this import to work: %modules."
+msgstr "De volgende modules moeten worden aangezet om te kunnen importeren: %modules."
+
+#: content_copy.module:411
+msgid "The content type %type already exists in this database."
+msgstr "Het inhoudstype %type bestaat al in de database."
+
+#: content_copy.module:418
+msgid "Exiting. No import performed."
+msgstr "Gestopt, er is niks geimporteerd."
+
+#: content_copy.module:442
+msgid "An error has occurred adding the content type %type. Please check the errors displayed for more details."
+msgstr "Er is een fout opgetreden tijden het toevoegen van het inhoudstype %type. Bekijk de foutmeldingen voor meer informatie."
+
+#: content_copy.module:467
+msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type."
+msgstr "Het geimporteerde veld %field_label (%field_name) is niet toegevoegd aan %type omdat het veld al bestaat in %type."
+
+#: content_copy.module:476
+msgid "The field %field_label (%field_name) was added to the content type %type."
+msgstr "Het veld %field_label (%field_name) is toegevoegd aan het inhoudstype %type."
+
+#: content_copy.module:581
+msgid "An error occurred when exporting the 'display settings' data for the field %field_name. The db error is: '%db_err'."
+msgstr "Er is een fout opgetreden tijdens het exporteren van de weergaveinstellingendata voor het veld %field_name. De databasefoutmelding is: '%db_err'."
+
+#: content_copy.module:0
+msgid "content_copy"
+msgstr "content_copy"
+
+#: content_copy.info:0
+msgid "Content Copy"
+msgstr "Kopieer inhoud"
+
+#: content_copy.info:0
+msgid "Enables ability to import/export field definitions."
+msgstr "Laat velddefinities geimporteerd en geexporteerd worden."
+
+#: content_copy.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.pot
new file mode 100644
index 00000000000..c1c4192b03d
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.pot
@@ -0,0 +1,126 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-content_copy)
+# Copyright YEAR NAME
+# Generated from files:
+# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched
+# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched
+# content_copy.info,v 1.6 2008/04/23 18:01:48 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/content_copy/content_copy_export_form.tpl.php:9 modules/content_copy/content_copy.module:191;38
+msgid "Export"
+msgstr ""
+
+#: modules/content_copy/content_copy.module:97
+msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:103
+msgid "Types"
+msgstr ""
+
+#: modules/content_copy/content_copy.module:107
+msgid "Select the content type to export."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:175
+msgid "Export data"
+msgstr ""
+
+#: modules/content_copy/content_copy.module:180
+msgid "Copy the export text and paste it into another content type using the import function."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:184
+msgid "Content types"
+msgstr ""
+
+#: modules/content_copy/content_copy.module:303
+msgid "This form will import field definitions exported from another content type or another database. Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:306
+msgid ""
+msgstr ""
+
+#: modules/content_copy/content_copy.module:308
+msgid "Content type"
+msgstr ""
+
+#: modules/content_copy/content_copy.module:309
+msgid "Select the content type to import these fields into. Select <Create> to create a new content type to contain the fields."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:314
+msgid "Import data"
+msgstr ""
+
+#: modules/content_copy/content_copy.module:316
+msgid "Paste the text created by a content export into this field."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:320;46
+msgid "Import"
+msgstr ""
+
+#: modules/content_copy/content_copy.module:328
+msgid "A file has been pre-loaded for import."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:354
+msgid "The import data is not valid import text."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:403
+msgid "The following modules must be enabled for this import to work: %modules."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:411
+msgid "The content type %type already exists in this database."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:418
+msgid "Exiting. No import performed."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:442
+msgid "An error has occurred adding the content type %type. Please check the errors displayed for more details."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:467
+msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:476
+msgid "The field %field_label (%field_name) was added to the content type %type."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:581
+msgid "An error occurred when exporting the 'display settings' data for the field %field_name. The db error is: '%db_err'."
+msgstr ""
+
+#: modules/content_copy/content_copy.module:0
+msgid "content_copy"
+msgstr ""
+
+#: modules/content_copy/content_copy.info:0
+msgid "Content Copy"
+msgstr ""
+
+#: modules/content_copy/content_copy.info:0
+msgid "Enables ability to import/export field definitions."
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.sv.po
new file mode 100644
index 00000000000..cddae942dc4
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_copy/translations/modules-content_copy.sv.po
@@ -0,0 +1,148 @@
+# $Id$
+#
+# Swedish translation of Drupal (content_copy)
+# Generated from files:
+# content_copy_export_form.tpl.php,v 1.1.2.2 2008/10/28 02:11:49 yched
+# content_copy.module,v 1.27.2.21 2009/02/26 23:15:54 yched
+# content_copy.info,v 1.6 2008/04/23 18:01:48 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CCK - Content Copy 6.x\n"
+"POT-Creation-Date: 2009-05-27 12:42+0200\n"
+"PO-Revision-Date: 2009-05-27 13:04+0100\n"
+"Last-Translator: Magnus Gunnarsson \n"
+"Language-Team: drupalsverige.se\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: Swedish\n"
+"X-Poedit-Country: SWEDEN\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: content_copy_export_form.tpl.php:9
+#: content_copy.module:191;38
+msgid "Export"
+msgstr "Exportera"
+
+#: content_copy_export_form.tpl.php:10
+msgid "Label"
+msgstr "Etikett"
+
+#: content_copy_export_form.tpl.php:11
+msgid "Name"
+msgstr "Namn"
+
+#: content_copy_export_form.tpl.php:12
+msgid "Type"
+msgstr "Typ"
+
+#: content_copy.module:97
+msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields."
+msgstr "Detta formulär kommer att bearbeta en innehållstyp och ett eller flera fält från den typen och exportera inställningarna. Exporten skapad av denna bearbetning kan kopieras och klistras in som en import till den nuvarande, eller annan databas. Importen kommer att lägga till fält till den existerande innehållstypen eller skapa en ny innehållstyp som inkluderade valda fält."
+
+#: content_copy.module:103
+msgid "Types"
+msgstr "Typer"
+
+#: content_copy.module:107
+msgid "Select the content type to export."
+msgstr "Välj innehållstyp att exportera."
+
+#: content_copy.module:175
+msgid "Export data"
+msgstr "Exportera data"
+
+#: content_copy.module:180
+msgid "Copy the export text and paste it into another content type using the import function."
+msgstr "Kopiera den exporterade texten och klistra in den till en annan innehållstyp genom att använda funktionen för import."
+
+#: content_copy.module:184
+msgid "Content types"
+msgstr "Innehållstyper"
+
+#: content_copy.module:251
+msgid "Save field settings"
+msgstr "Spara inställningar för fält"
+
+#: content_copy.module:303
+msgid "This form will import field definitions exported from another content type or another database. Note that fields cannot be duplicated within the same content type, so imported fields will be added only if they do not already exist in the selected type."
+msgstr "Detta formulär kommer att importera definitioner på fält exporterade från annan innehållstyp eller annan databas. Observera att detta fält inte kan vara en dublett inom samma innehållstp, så importerade fält kommer enbart att läggas till om de inte redan existerar i den valda typen."
+
+#: content_copy.module:306
+msgid ""
+msgstr ""
+
+#: content_copy.module:308
+msgid "Content type"
+msgstr "Innehållstyp"
+
+#: content_copy.module:309
+msgid "Select the content type to import these fields into. Select <Create> to create a new content type to contain the fields."
+msgstr "Välj innehållstyp att importera dessa fält till. Välj <Skapa> för att skapa en ny innehållstyp som skall innehålla fälten."
+
+#: content_copy.module:314
+msgid "Import data"
+msgstr "Importera data"
+
+#: content_copy.module:316
+msgid "Paste the text created by a content export into this field."
+msgstr "Klistra in texten skapad av en export av innehåll till detta fält."
+
+#: content_copy.module:320;46
+msgid "Import"
+msgstr "Importera"
+
+#: content_copy.module:328
+msgid "A file has been pre-loaded for import."
+msgstr "En fil har förladdats för import."
+
+#: content_copy.module:354
+msgid "The import data is not valid import text."
+msgstr "Det importerade datat är inte giltig text för import."
+
+#: content_copy.module:403
+msgid "The following modules must be enabled for this import to work: %modules."
+msgstr "Följande moduler måste aktiveras för att denna import skall fungera: %modules."
+
+#: content_copy.module:411
+msgid "The content type %type already exists in this database."
+msgstr "Innehållstypen %type finns redan i databasen."
+
+#: content_copy.module:418
+msgid "Exiting. No import performed."
+msgstr "Avslutar. Ingen import genomförd."
+
+#: content_copy.module:442
+msgid "An error has occurred adding the content type %type. Please check the errors displayed for more details."
+msgstr "Ett fel inträffade när innehållstypen %type lades till. Var vänlig se de visade felmeddelandena för mer detaljer."
+
+#: content_copy.module:467
+msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type."
+msgstr "Det importerade fältet %field_label (%field_name) lades inte till %type eftersom det fältet redan existerar i %type."
+
+#: content_copy.module:476
+msgid "The field %field_label (%field_name) was added to the content type %type."
+msgstr "Fältet %field_label (%field_name) lades till innehållstypen %type."
+
+#: content_copy.module:581
+msgid "An error occurred when exporting the 'display settings' data for the field %field_name. The db error is: '%db_err'."
+msgstr "Ett fel inträffade "
+
+#: content_copy.module:0
+msgid "content_copy"
+msgstr "content_copy"
+
+#: content_copy.info:0
+msgid "Content Copy"
+msgstr "Kopiera innehåll"
+
+#: content_copy.info:0
+msgid "Enables ability to import/export field definitions."
+msgstr "Aktiverar förmågan att importera/exportera definitioner av fält."
+
+#: content_copy.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_multigroup/README.txt b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_multigroup/README.txt
new file mode 100644
index 00000000000..1b15aaddeeb
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_multigroup/README.txt
@@ -0,0 +1,4 @@
+; $Id$
+
+Ongoing work on the multigroup module has moved to the experimental
+CCK 3.0 branch.
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.info
new file mode 100644
index 00000000000..3c0e4d4fea1
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.info
@@ -0,0 +1,12 @@
+; $Id$
+name = Content Permissions
+description = Set field-level permissions for CCK fields.
+package = CCK
+core = 6.x
+dependencies[] = content
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.install
new file mode 100644
index 00000000000..a499833c6f2
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.install
@@ -0,0 +1,10 @@
+configure your field permissions immediately. All fields are inaccessible by default.', array('!url' => url('admin/user/permissions', array('fragment' => 'content_permissions')))));
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.module
new file mode 100644
index 00000000000..7c81d5d53a2
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/content_permissions.module
@@ -0,0 +1,28 @@
+
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2008-11-05 12:54+0100\n"
+"PO-Revision-Date: 2008-11-05 13:18+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854
+#: modules/content_permissions/content_permissions.module:9
+msgid "edit "
+msgstr ""
+
+# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854
+#: modules/content_permissions/content_permissions.module:9;10
+msgid "field_name"
+msgstr ""
+
+# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854
+#: modules/content_permissions/content_permissions.module:10
+msgid "view "
+msgstr ""
+
+#: modules/content_permissions/content_permissions.module:0
+msgid "content_permissions"
+msgstr "Inhaltsberechtigungen"
+
+#: modules/content_permissions/content_permissions.install:9
+msgid "Please configure your field permissions immediately. All fields are inaccessible by default."
+msgstr "Bitte umgehend die Feldberechtigungen konfigurieren. Alle Felder sind standardmäßig gesperrt."
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Content Permissions"
+msgstr "Inhaltsberechtigungen"
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Set field-level permissions for CCK fields."
+msgstr "Konfiguriert Berechtigungen für CCK-Felder auf Feldebene."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.fr.po
new file mode 100644
index 00000000000..7db1655a019
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.fr.po
@@ -0,0 +1,49 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-10-19 18:01+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854
+#: modules/content_permissions/content_permissions.module:9
+msgid "edit "
+msgstr ""
+
+# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854
+#: modules/content_permissions/content_permissions.module:9;10
+msgid "field_name"
+msgstr ""
+
+# Dynamic permission names are not yet translatable in Drupal. http://drupal.org/node/250854
+#: modules/content_permissions/content_permissions.module:10
+msgid "view "
+msgstr ""
+
+#: modules/content_permissions/content_permissions.module:0
+msgid "content_permissions"
+msgstr "content_permissions"
+
+#: modules/content_permissions/content_permissions.install:7
+msgid "Please configure your field permissions immediately. All fields are inaccessible by default."
+msgstr "Merci de configurer vos droits relatifs aux champs immédiatement. Par défaut, tous les champs sont inaccessibles."
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Content Permissions"
+msgstr "Droits sur le contenu"
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Set field-level permissions for CCK fields."
+msgstr "Configurer les droits d'accès au niveau des champs pour les champs CCK."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.hu.po
new file mode 100644
index 00000000000..35e1496aa88
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.hu.po
@@ -0,0 +1,52 @@
+# Hungarian translation of cck (6.x-2.0-rc10)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# content_permissions.module,v 1.5.2.2 2008/10/06 15:11:39 karens
+# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens
+# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cck (6.x-2.0-rc10)\n"
+"POT-Creation-Date: 2008-10-31 12:16-0500\n"
+"PO-Revision-Date: 2008-10-26 11:49-0500\n"
+"Last-Translator: Balogh Zoltán\n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: modules/content_permissions/content_permissions.module:9
+msgid "edit "
+msgstr "szerkesztés "
+
+#: modules/content_permissions/content_permissions.module:9,10
+msgid "field_name"
+msgstr "field_name"
+
+#: modules/content_permissions/content_permissions.module:10
+msgid "view "
+msgstr "nézet "
+
+#: modules/content_permissions/content_permissions.module:0
+msgid "content_permissions"
+msgstr "content_permissions"
+
+#: modules/content_permissions/content_permissions.install:9
+msgid ""
+"Please configure your field permissions "
+"immediately. All fields are inaccessible by default."
+msgstr ""
+"Érdemes azonnal beállítani a mezők "
+"jogosultságait. Alapértelmezés szerint egyik mező sem érhető "
+"el."
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Content Permissions"
+msgstr "Tartalom Jogosultságok"
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Set field-level permissions for CCK fields."
+msgstr "Mezőszintű jogosultságok beállítása."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.nl.po
new file mode 100644
index 00000000000..d1023df9d9f
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.nl.po
@@ -0,0 +1,56 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# content_permissions.module,v 1.5.2.5 2008/12/27 22:22:55 yched
+# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens
+# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:25+0200\n"
+"PO-Revision-Date: 2009-06-03 14:25+0200\n"
+"Last-Translator: NAME \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: content_permissions.module:10
+msgid "edit "
+msgstr "bewerk"
+
+#: content_permissions.module:10;11
+msgid "field_name"
+msgstr "field_name"
+
+#: content_permissions.module:11
+msgid "view "
+msgstr "bekijk"
+
+#: content_permissions.module:0
+msgid "content_permissions"
+msgstr "content_permissions"
+
+#: content_permissions.install:9
+msgid "Please configure your field permissions immediately. All fields are inaccessible by default."
+msgstr ""
+"Stel je veldpermissies direct in. Alle velden "
+"zijn standaard niet te bekijken."
+
+#: content_permissions.info:0
+msgid "Content Permissions"
+msgstr "Inhoudpermissies"
+
+#: content_permissions.info:0
+msgid "Set field-level permissions for CCK fields."
+msgstr "Stel veldpermissies in voor CCK-velden."
+
+#: content_permissions.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.pot
new file mode 100644
index 00000000000..1cdfa63e147
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.pot
@@ -0,0 +1,50 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-content_permissions)
+# Copyright YEAR NAME
+# Generated from files:
+# content_permissions.module,v 1.5.2.5 2008/12/27 22:22:55 yched
+# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens
+# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/content_permissions/content_permissions.module:10
+msgid "edit "
+msgstr ""
+
+#: modules/content_permissions/content_permissions.module:10;11
+msgid "field_name"
+msgstr ""
+
+#: modules/content_permissions/content_permissions.module:11
+msgid "view "
+msgstr ""
+
+#: modules/content_permissions/content_permissions.module:0
+msgid "content_permissions"
+msgstr ""
+
+#: modules/content_permissions/content_permissions.install:9
+msgid "Please configure your field permissions immediately. All fields are inaccessible by default."
+msgstr ""
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Content Permissions"
+msgstr ""
+
+#: modules/content_permissions/content_permissions.info:0
+msgid "Set field-level permissions for CCK fields."
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.sv.po
new file mode 100644
index 00000000000..4c2371bed92
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/content_permissions/translations/modules-content_permissions.sv.po
@@ -0,0 +1,55 @@
+# $Id$
+#
+# Swedish translation of Drupal (content_permissions)
+# Generated from files:
+# content_permissions.module,v 1.5.2.5 2008/12/27 22:22:55 yched
+# content_permissions.install,v 1.1.2.2 2008/10/04 13:14:22 karens
+# content_permissions.info,v 1.2 2008/04/23 18:01:52 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CCK - Content Permissions 6.x\n"
+"POT-Creation-Date: 2009-05-27 13:07+0200\n"
+"PO-Revision-Date: 2009-05-27 13:15+0100\n"
+"Last-Translator: Magnus Gunnarsson \n"
+"Language-Team: drupalsverige.se\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: Swedish\n"
+"X-Poedit-Country: SWEDEN\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: content_permissions.module:10
+msgid "edit "
+msgstr "redigera"
+
+#: content_permissions.module:10;11
+msgid "field_name"
+msgstr "fält_namn"
+
+#: content_permissions.module:11
+msgid "view "
+msgstr "visa"
+
+#: content_permissions.module:0
+msgid "content_permissions"
+msgstr "content_permissions"
+
+#: content_permissions.install:9
+msgid "Please configure your field permissions immediately. All fields are inaccessible by default."
+msgstr "Var vänlig konfigurera dina rättigheter för fält omedelbart. Alla fält är som standard ej tillgängliga."
+
+#: content_permissions.info:0
+msgid "Content Permissions"
+msgstr "Rättigheter för innehåll"
+
+#: content_permissions.info:0
+msgid "Set field-level permissions for CCK fields."
+msgstr "Ange rättigheter per fältnivå för fält av typen CCK."
+
+#: content_permissions.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-rtl.css b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-rtl.css
new file mode 100644
index 00000000000..0953e796cf8
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-rtl.css
@@ -0,0 +1,6 @@
+/* $Id$ */
+
+div.fieldgroup .content {
+ padding-left:0;
+ padding-right:1em;
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-simple.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-simple.tpl.php
new file mode 100644
index 00000000000..bf24fc37c4c
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup-simple.tpl.php
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.css b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.css
new file mode 100644
index 00000000000..bc86173e6f3
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.css
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+div.fieldgroup {
+ margin:.5em 0 1em 0;
+}
+div.fieldgroup .content {
+ padding-left:1em;/*LTR*/
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.info
new file mode 100644
index 00000000000..260520b661c
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.info
@@ -0,0 +1,12 @@
+; $Id$
+name = Fieldgroup
+description = Create display groups for CCK fields.
+dependencies[] = content
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.install
new file mode 100644
index 00000000000..da4b71ff183
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.install
@@ -0,0 +1,316 @@
+ array(
+ 'group_type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => 'standard'),
+ 'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'group_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'label' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+ 'settings' => array('type' => 'text', 'size' => 'medium', 'not null' => TRUE),
+ 'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+ ),
+ 'primary key' => array('type_name', 'group_name'),
+ );
+
+ $schema['content_group_fields'] = array(
+ 'fields' => array(
+ 'type_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'group_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ 'field_name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
+ ),
+ 'primary key' => array('type_name', 'group_name', 'field_name'),
+ );
+
+ return $schema;
+}
+
+/**
+ * rename groups form "group-*" to "group_*"
+ */
+function fieldgroup_update_1() {
+ $ret = array();
+ if (!db_table_exists('node_group')) {
+ return $ret;
+ }
+ switch ($GLOBALS['db_type']) {
+ case 'pgsql':
+ $ret[] = update_sql("UPDATE {node_group} SET group_name = 'group_'||SUBSTRING(group_name FROM 7)");
+ $ret[] = update_sql("UPDATE {node_group_fields} SET group_name = 'group_'||SUBSTRING(group_name FROM 7)");
+ break;
+
+ case 'mysql':
+ case 'mysqli':
+ $ret[] = update_sql("UPDATE {node_group} SET group_name = CONCAT('group_', SUBSTRING(group_name FROM 7))");
+ $ret[] = update_sql("UPDATE {node_group_fields} SET group_name = CONCAT('group_', SUBSTRING(group_name FROM 7))");
+ break;
+ }
+ return $ret;
+}
+
+/**
+ * add display settings for the group
+ */
+function fieldgroup_update_2() {
+ $ret = array();
+ if (!db_table_exists('node_group')) {
+ return $ret;
+ }
+
+ // set settings column to accept larger values
+ switch ($GLOBALS['db_type']) {
+ case 'mysql':
+ case 'mysqli':
+ $ret[] = update_sql('ALTER TABLE {node_group} CHANGE settings settings mediumtext NOT NULL');
+ break;
+
+ case 'pgsql':
+ db_change_column($ret, 'node_group', 'settings', 'settings', 'text', array('not null' => TRUE));
+ break;
+ }
+
+ // move description into the settings array, and add new settings
+ $result = db_query("SELECT * FROM {node_group}");
+ while ($group = db_fetch_array($result)) {
+ $settings = array();
+ $settings['form'] = unserialize($group['settings']);
+ $settings['form']['description'] = $group['description'];
+ $settings['display'] = array('collapsible' => 0, 'collapsed' => 0, 'description' => '');
+ $ret[] = update_sql("UPDATE {node_group} SET settings = '". db_escape_string(serialize($settings)) ."', description = '' WHERE group_name = '". $group['group_name'] ."'");
+ }
+
+ // drop description column
+ switch ($GLOBALS['db_type']) {
+ case 'mysql':
+ case 'mysqli':
+ $ret[] = update_sql('ALTER TABLE {node_group} DROP description');
+ break;
+
+ case 'pgsql':
+ // Postgres only supports dropping of columns since 7.4
+ break;
+ }
+
+ return $ret;
+}
+
+
+/**
+ * converts group settings collapsible/collapsed => style
+ */
+function fieldgroup_update_3() {
+ $ret = array();
+ if (!db_table_exists('node_group')) {
+ return $ret;
+ }
+ $result = db_query("SELECT * FROM {node_group}");
+ while ($group = db_fetch_array($result)) {
+ $group['settings'] = unserialize($group['settings']);
+
+ if (!isset($group['settings']['form']['style'])) {
+ foreach (array('form', 'display') as $context) {
+ if (isset($group['settings'][$context]['collapsible']) && $group['settings'][$context]['collapsible']) {
+ if (isset($group['settings'][$context]['collapsed']) && $group['settings'][$context]['collapsed']) {
+ $group['settings'][$context]['style'] = 'fieldset_collapsed';
+ }
+ else {
+ $group['settings'][$context]['style'] = 'fieldset_collapsible';
+ }
+ }
+ else {
+ $group['settings'][$context]['style'] = 'fieldset';
+ }
+ }
+
+ $ret[] = update_sql("UPDATE {node_group} SET settings = '". db_escape_string(serialize($group['settings'])) ."' WHERE group_name = '". $group['group_name'] ."'");
+ }
+ }
+
+ return $ret;
+}
+
+/*
+ * Increases module weight, so that other modules can form_alter() cck forms before the fields
+ * are moved in groups
+ */
+function fieldgroup_update_4() {
+ $ret = array();
+ $ret[] = update_sql("UPDATE {system} SET weight = 9 WHERE name = 'fieldgroup'");
+ return $ret;
+}
+
+
+/**
+ * Start D6 upgrades
+ */
+
+/**
+ * Move fieldgroup tables to the content_* namespace.
+ */
+function fieldgroup_update_6000() {
+ if ($abort = content_check_update('fieldgroup')) {
+ return $abort;
+ }
+
+ $ret = array();
+
+ db_rename_table($ret, 'node_group', 'content_group');
+ db_rename_table($ret, 'node_group_fields', 'content_group_fields');
+ variable_set('fieldgroup_schema_version', 6000);
+ return $ret;
+}
+
+/*
+ * Increases module weight, so that other modules can form_alter() cck forms before the fields
+ * are moved in groups.
+ *
+ * Sites upgraded from D5 should have this already set.
+ * New D6 installs earlier than RC5 need this, as it was missing in fieldgroup_install.
+ */
+function fieldgroup_update_6001() {
+ if ($abort = content_check_update('fieldgroup')) {
+ return $abort;
+ }
+
+ $ret = array();
+ $ret[] = update_sql("UPDATE {system} SET weight = 9 WHERE name = 'fieldgroup'");
+ return $ret;
+}
+
+/**
+ * Same as 6000 : Move fieldgroup tables to the content_* namespace.
+ * This was missing in D6 releases earlier than RC5. Ensure we don't run this twice.
+ */
+function fieldgroup_update_6002() {
+ if ($abort = content_check_update('fieldgroup')) {
+ return $abort;
+ }
+
+ $ret = array();
+ if (db_table_exists('node_group')) {
+ db_rename_table($ret, 'node_group', 'content_group');
+ db_rename_table($ret, 'node_group_fields', 'content_group_fields');
+ variable_set('fieldgroup_schema_version', 6000);
+ }
+ return $ret;
+}
+
+/**
+ * Remove tinyint (127) limitation on group weights.
+ */
+function fieldgroup_update_6003() {
+ if ($abort = content_check_update('fieldgroup')) {
+ return $abort;
+ }
+
+ $ret = array();
+ db_change_field($ret, 'content_group', 'weight', 'weight', array('type' => 'int', 'not null' => TRUE, 'default' => 0));
+ return $ret;
+}
+
+/**
+ * Add 'type' property for fieldgroups.
+ */
+function fieldgroup_update_6004() {
+ if ($abort = content_check_update('fieldgroup')) {
+ return $abort;
+ }
+
+ $ret = array();
+ db_add_field($ret, 'content_group', 'group_type', array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => 'standard'));
+ $ret[] = update_sql("DELETE FROM {cache_content} WHERE cid='fieldgroup_data'");
+ return $ret;
+}
+
+/**
+ * Add the 'exclude from $content' display setting to all existing groups.
+ */
+function fieldgroup_update_6005() {
+ $ret = array();
+ $result = db_query("SELECT * FROM {content_group}");
+ while ($type = db_fetch_array($result)) {
+ $new_settings = array();
+ $settings = unserialize($type['settings']);
+ $new_settings = $settings;
+ $display_settings = !empty($settings['display']) ? $settings['display'] : array();
+ if (!empty($display_settings)) {
+ foreach ($display_settings as $key => $val) {
+ $new_settings['display'][$key] = $val;
+ if ($key !== 'label' && is_array($val)) {
+ $new_settings['display'][$key]['exclude'] = 0;
+ }
+ }
+ }
+ else {
+ $new_settings['display'] = array(
+ 'label' => array('format' => 'above'),
+ 'full' => array('format' => 'default', 'exclude' => 0),
+ 'teaser' => array('format' => 'default', 'exclude' => 0),
+ );
+ }
+ db_query("UPDATE {content_group} SET settings='%s' WHERE group_name='%s' AND type_name='%s'", serialize($new_settings), $type['group_name'], $type['type_name']);
+ }
+ return $ret;
+}
+
+/**
+ * Removed a previous version of "Remove orphaned fields" (6007), broken for db prefixes.
+ */
+function fieldgroup_update_6006() {
+ return array();
+}
+
+/**
+ * Remove orphaned fields (see http://drupal.org/node/339537).
+ */
+function fieldgroup_update_6007() {
+ $ret = array();
+ $ret[] = update_sql("DELETE FROM {content_group_fields} WHERE (field_name, type_name) NOT IN (SELECT field_name, type_name FROM {content_node_field_instance})");
+ return $ret;
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.module
new file mode 100644
index 00000000000..3e0fdec7edc
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/fieldgroup.module
@@ -0,0 +1,913 @@
+content.
+ * - hook_fieldgroup_form: Alter the group portion of the node form.
+ * - hook_fieldgroup_types: Add additional fieldgroup group_types.
+ * - hook_fieldgroup_default_settings: Add additional fieldgroup default settings.
+ * - hook_fieldgroup_save: Do additional processing when a fieldgroup is saved.
+ */
+/**
+ * Implementation of hook_init().
+ */
+function fieldgroup_init() {
+ drupal_add_css(drupal_get_path('module', 'fieldgroup') .'/fieldgroup.css');
+}
+
+/**
+ * Implementation of hook_ctools_plugin_directory().
+ */
+function fieldgroup_ctools_plugin_directory($module, $plugin) {
+ if ($module == 'ctools' && $plugin == 'content_types') {
+ return 'panels/' . $plugin;
+ }
+}
+
+/**
+ * Implementation of hook_menu().
+ */
+function fieldgroup_menu() {
+ $items = array();
+
+ // Make sure this doesn't fire until content_types is working,
+ // needed to avoid errors on initial installation.
+ if (!defined('MAINTENANCE_MODE')) {
+ foreach (node_get_types() as $type) {
+ $type_name = $type->type;
+ $content_type = content_types($type_name);
+ $type_url_str = $content_type['url_str'];
+ $items['admin/content/node-type/'. $type_url_str .'/groups/%'] = array(
+ 'title' => 'Edit group',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('fieldgroup_group_edit_form', $type_name, 5),
+ 'access arguments' => array('administer content types'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/content/node-type/'. $type_url_str .'/groups/%/remove'] = array(
+ 'title' => 'Edit group',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('fieldgroup_remove_group', $type_name, 5),
+ 'access arguments' => array('administer content types'),
+ 'type' => MENU_CALLBACK,
+ );
+ }
+ }
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function fieldgroup_theme() {
+ return array(
+ 'fieldgroup_simple' => array(
+ 'template' => 'fieldgroup-simple',
+ 'arguments' => array('element' => NULL),
+ ),
+ 'fieldgroup_fieldset' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'fieldgroup_display_overview_form' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_elements().
+ */
+function fieldgroup_elements() {
+ return array(
+ 'fieldgroup_simple' => array(),
+ 'fieldgroup_fieldset' => array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL,),
+ );
+}
+
+/**
+ * Implementation of hook_fieldapi().
+ */
+function fieldgroup_content_fieldapi($op, $field) {
+ switch ($op) {
+ case 'delete instance':
+ db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE field_name = '%s' AND type_name = '%s'", $field['field_name'], $field['type_name']);
+ cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
+ break;
+ }
+}
+
+function fieldgroup_group_edit_form(&$form_state, $type_name, $group_name) {
+ $content_type = content_types($type_name);
+ $groups = fieldgroup_groups($content_type['type']);
+
+ if (!$group = $groups[$group_name]) {
+ drupal_not_found();
+ exit;
+ }
+
+ $form['label'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Label'),
+ '#default_value' => $group['label'],
+ '#required' => TRUE,
+ );
+
+ // Set a default value for group type early in the form so it
+ // can be overridden by subsequent form elements added by other modules.
+ $group_type = !empty($group['group_type']) ? $group['group_type'] : 'standard';
+ $form['group_type'] = array('#type' => 'hidden', '#default_value' => $group_type);
+
+ $form['settings']['#tree'] = TRUE;
+ $form['settings']['form'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Form settings'),
+ '#description' => t('These settings apply to the group in the node editing form.'),
+ );
+ $form['settings']['form']['style'] = array(
+ '#type' => 'radios',
+ '#title' => t('Style'),
+ '#default_value' => $group['settings']['form']['style'],
+ '#options' => array(
+ 'fieldset' => t('always open'),
+ 'fieldset_collapsible' => t('collapsible'),
+ 'fieldset_collapsed' => t('collapsed'),
+ )
+ );
+ $form['settings']['form']['description'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Help text'),
+ '#default_value' => $group['settings']['form']['description'],
+ '#rows' => 5,
+ '#description' => t('Instructions to present to the user on the editing form.'),
+ '#required' => FALSE,
+ );
+ $form['settings']['display'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Display settings'),
+ '#description' => t('These settings apply to the group on node display.'),
+ );
+ $form['settings']['display']['description'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Description'),
+ '#default_value' => $group['settings']['display']['description'],
+ '#rows' => 5,
+ '#description' => t('A description of the group.'),
+ '#required' => FALSE,
+ );
+
+ foreach (array_keys(content_build_modes()) as $key) {
+ $form['settings']['display'][$key]['format'] = array('#type' => 'value', '#value' => isset($group['settings']['display'][$key]['format']) ? $group['settings']['display'][$key]['format'] : 'fieldset');
+ $form['settings']['display'][$key]['exclude'] = array('#type' => 'value', '#value' => isset($group['settings']['display'][$key]['exclude']) ? $group['settings']['display'][$key]['exclude'] : 0);
+ }
+ $form['settings']['display']['label'] = array('#type' => 'value', '#value' => $group['settings']['display']['label']);
+ $form['weight'] = array('#type' => 'hidden', '#default_value' => $group['weight']);
+ $form['group_name'] = array('#type' => 'hidden', '#default_value' => $group_name);
+
+ $form['#content_type'] = $content_type;
+
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ '#weight' => 10,
+ );
+
+ return $form;
+}
+
+function fieldgroup_group_edit_form_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+ $content_type = $form['#content_type'];
+ fieldgroup_save_group($content_type['type'], $form_values);
+ $form_state['redirect'] = 'admin/content/node-type/'. $content_type['url_str'] .'/fields';
+}
+
+function fieldgroup_remove_group(&$form_state, $type_name, $group_name) {
+ $content_type = content_types($type_name);
+ $groups = fieldgroup_groups($content_type['type']);
+ $group = isset($groups[$group_name]) ? $groups[$group_name] : '';
+
+ if (empty($group)) {
+ drupal_not_found();
+ exit;
+ }
+
+ $form['#submit'][] = 'fieldgroup_remove_group_submit';
+ $form['#content_type'] = $content_type;
+ $form['#group_name'] = $group_name;
+
+ return confirm_form($form,
+ t('Are you sure you want to remove the group %label?',
+ array('%label' => t($group['label']))),
+ 'admin/content/node-type/'. $content_type['url_str'] .'/fields', t('This action cannot be undone.'),
+ t('Remove'), t('Cancel'));
+}
+
+function fieldgroup_remove_group_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+ $content_type = $form['#content_type'];
+ $group_name = $form['#group_name'];
+ fieldgroup_delete($content_type['type'], $group_name);
+ drupal_set_message(t('The group %group_name has been removed.', array('%group_name' => $group_name)));
+ $form_state['redirect'] = 'admin/content/node-type/'. $content_type['url_str'] .'/fields';
+}
+
+/**
+ * Returns all groups for a content type
+ */
+function fieldgroup_groups($content_type = '', $sorted = FALSE, $reset = FALSE) {
+ global $language;
+ static $groups, $groups_sorted;
+ if (!isset($groups) || $reset) {
+ if ($cached = cache_get('fieldgroup_data:'. $language->language, content_cache_tablename())) {
+ $data = $cached->data;
+ $groups = $data['groups'];
+ $groups_sorted = $data['groups_sorted'];
+ }
+ else {
+ $result = db_query("SELECT * FROM {". fieldgroup_tablename() ."} ORDER BY weight, group_name");
+ $groups = array();
+ $groups_sorted = array();
+ while ($group = db_fetch_array($result)) {
+ $group['settings'] = unserialize($group['settings']);
+ $group['fields'] = array();
+
+ // Allow external modules to translate field group strings.
+ $group_strings = array(
+ 'label' => $group['label'],
+ 'form_description' => $group['settings']['form']['description'],
+ 'display_description' => $group['settings']['display']['description'],
+ );
+ drupal_alter('content_fieldgroup_strings', $group_strings, $group['type_name'], $group['group_name']);
+ $group['label'] = $group_strings['label'];
+ $group['settings']['form']['description'] = $group_strings['form_description'];
+ $group['settings']['display']['description'] = $group_strings['display_description'];
+
+ $groups[$group['type_name']][$group['group_name']] = $group;
+ $groups_sorted[$group['type_name']][] = &$groups[$group['type_name']][$group['group_name']];
+ }
+ //load fields
+ $result = db_query("SELECT nfi.*, ng.group_name FROM {". fieldgroup_tablename() ."} ng ".
+ "INNER JOIN {". fieldgroup_fields_tablename() ."} ngf ON ngf.type_name = ng.type_name AND ngf.group_name = ng.group_name ".
+ "INNER JOIN {". content_instance_tablename() ."} nfi ON nfi.field_name = ngf.field_name AND nfi.type_name = ngf.type_name ".
+ "WHERE nfi.widget_active = 1 ORDER BY nfi.weight");
+ while ($field = db_fetch_array($result)) {
+ // Allow external modules to translate field strings.
+ $field_strings = array(
+ 'widget_label' => $field['label'],
+ 'widget_description' => $field['description'],
+ );
+ drupal_alter('content_field_strings', $field_strings, $field['type_name'], $field['field_name']);
+ $field['label'] = $field_strings['widget_label'];
+ $field['description'] = $field_strings['widget_description'];
+
+ $groups[$field['type_name']][$field['group_name']]['fields'][$field['field_name']] = $field;
+ }
+ cache_set('fieldgroup_data:'. $language->language, array('groups' => $groups, 'groups_sorted' => $groups_sorted), content_cache_tablename());
+ }
+ }
+ if (empty($content_type)) {
+ return $groups;
+ }
+ elseif (empty($groups) || empty($groups[$content_type])) {
+ return array();
+ }
+ return $sorted ? $groups_sorted[$content_type] : $groups[$content_type];
+}
+
+
+function _fieldgroup_groups_label($content_type) {
+ $groups = fieldgroup_groups($content_type);
+
+ $labels[''] = '<'. t('none') .'>';
+ foreach ($groups as $group_name => $group) {
+ $labels[$group_name] = t($group['label']);
+ }
+ return $labels;
+}
+
+function _fieldgroup_field_get_group($content_type, $field_name) {
+ return db_result(db_query("SELECT group_name FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $content_type, $field_name));
+}
+
+/**
+ * Implementation of hook_form_alter()
+ */
+function fieldgroup_form_alter(&$form, $form_state, $form_id) {
+ if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
+ foreach (fieldgroup_groups($form['type']['#value']) as $group_name => $group) {
+ $form[$group_name] = array(
+ '#type' => 'fieldset',
+ '#title' => check_plain(t($group['label'])),
+ '#collapsed' => $group['settings']['form']['style'] == 'fieldset_collapsed',
+ '#collapsible' => in_array($group['settings']['form']['style'], array('fieldset_collapsed', 'fieldset_collapsible')),
+ '#weight' => $group['weight'],
+ '#description' => content_filter_xss(t($group['settings']['form']['description'])),
+ '#attributes' => array('class' => strtr($group['group_name'], '_', '-')),
+ );
+
+ $has_accessible_field = FALSE;
+ foreach ($group['fields'] as $field_name => $field) {
+ if (isset($form[$field_name])) {
+ $form[$group_name][$field_name] = $form[$field_name];
+ // Track whether this group has any accessible fields within it.
+ if (!isset($form[$field_name]['#access']) || $form[$field_name]['#access'] !== FALSE) {
+ $has_accessible_field = TRUE;
+ }
+ unset($form[$field_name]);
+ }
+ }
+ if (!empty($group['fields']) && !element_children($form[$group_name])) {
+ //hide the fieldgroup, because the fields are hidden too
+ unset($form[$group_name]);
+ }
+
+ if (!$has_accessible_field) {
+ // Hide the fieldgroup, because the fields are inaccessible.
+ $form[$group_name]['#access'] = FALSE;
+ }
+
+ // Allow other modules to alter the form.
+ // Can't use module_invoke_all because we want
+ // to be able to use a reference to $form and $form_state.
+ foreach (module_implements('fieldgroup_form') as $module) {
+ $function = $module .'_fieldgroup_form';
+ $function($form, $form_state, $form_id, $group);
+ }
+
+ }
+
+ }
+ // The group is only added here so it will appear in the export
+ // when using Content Copy.
+ elseif ($form_id == 'content_field_edit_form' && isset($form['widget'])) {
+ $content_type = content_types($form['type_name']['#value']);
+ $form['widget']['group'] = array(
+ '#type' => 'value',
+ '#value' => _fieldgroup_field_get_group($content_type['type'], $form['field_name']['#value']),
+ );
+ }
+ elseif ($form_id == 'content_field_overview_form') {
+ $form['#validate'][] = 'fieldgroup_field_overview_form_validate';
+ $form['#submit'][] = 'fieldgroup_field_overview_form_submit';
+ }
+ elseif ($form_id == 'content_display_overview_form' && !empty($form['#groups'])) {
+ $form['#submit'][] = 'fieldgroup_display_overview_form_submit';
+ if (!isset($form['submit'])) {
+ $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 10);
+ }
+ }
+ elseif ($form_id == 'content_field_remove_form') {
+ $form['#submit'][] = 'fieldgroup_field_remove_form_submit';
+ }
+}
+
+/**
+ * API for group name validation.
+ *
+ * Pulled into separate function to be re-usable.
+ */
+function fieldgroup_validate_name($group, $type_name) {
+ $errors = array();
+
+ // No label.
+ if (!$group['label']) {
+ $errors['label'][] = t('You need to provide a label.');
+ }
+
+ // No group name.
+ if (!$group['group_name']) {
+ $errors['group_name'][] = t('You need to provide a group name.');
+ }
+ // Group name validation.
+ else {
+ $group_name = $group['group_name'];
+ $group['group_type'] = !empty($group['group_type']) ? $group['group_type'] : 'standard';
+
+ // Add the 'group_' prefix.
+ if (substr($group_name, 0, 6) != 'group_') {
+ $group_name = 'group_'. $group_name;
+ }
+
+ // Invalid field name.
+ if (!preg_match('!^group_[a-z0-9_]+$!', $group_name)) {
+ $errors['group_name'][] = t('The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores.', array('%group_name' => $group_name));
+ }
+ if (strlen($group_name) > 32) {
+ $errors['group_name'][] = t('The group name %group_name is too long. The name is limited to 32 characters, including the \'group_\' prefix.', array('%group_name' => $group_name));
+ }
+
+ // Group name already exists.
+ $groups = fieldgroup_groups($type_name);
+ if (isset($groups[$group_name])) {
+ $errors['group_name'][] = t('The group name %group_name already exists.', array('%group_name' => $group_name));
+ }
+ if (empty($errors['group_name'])) {
+ $group['group_name'] = $group_name;
+ }
+ }
+ return array('group_name' => $group['group_name'], 'errors' => $errors);
+}
+
+function fieldgroup_field_overview_form_validate($form, &$form_state) {
+ $form_values = $form_state['values'];
+ $group = $form_values['_add_new_group'];
+
+ if (array_filter(array($group['label'], $group['group_name']))) {
+ $validation = fieldgroup_validate_name($group, $form['#type_name']);
+ if (!empty($validation['errors'])) {
+ foreach ($validation['errors'] as $type => $messages) {
+ foreach ($messages as $message) {
+ if ($type == 'label') {
+ form_set_error('_add_new_group][label', t('Add new group:') .' '. $message);
+ }
+ else {
+ form_set_error('_add_new_group][group_name', t('Add new group:') .' '. $message);
+ }
+ }
+ }
+ }
+ $group_name = $validation['group_name'];
+ form_set_value($form['_add_new_group']['group_name'], $group_name, $form_state);
+ }
+ else {
+ // Fail validation if attempt to nest fields under a new group without the
+ // proper information. Not raising an error would cause the nested fields
+ // to get weights the user doesn't expect.
+
+ foreach ($form_values as $key => $values) {
+ if ($values['parent'] == '_add_new_group') {
+ form_set_error('_add_new_group][label', t('Add new group: you need to provide a label.'));
+ form_set_error('_add_new_group][group_name', t('Add new group: you need to provide a group name.'));
+ break;
+ }
+ }
+ }
+}
+
+function fieldgroup_field_overview_form_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+ $type_name = $form['#type_name'];
+
+ // Create new group if needed.
+ if (!empty($form_values['_add_new_group']['label'])) {
+ $group = $form_values['_add_new_group'];
+ $group['settings'] = field_group_default_settings($group['group_type']);
+ fieldgroup_save_group($type_name, $group);
+ $new_group_name = $group['group_name'];
+ }
+
+ // Parse incoming rows.
+ $add_field_rows = array('_add_new_field', '_add_existing_field');
+ $field_rows = array_merge($form['#fields'], $add_field_rows);
+ foreach ($form_values as $key => $values) {
+ // If 'field' row: update field parenting.
+ if (in_array($key, $field_rows)) {
+ // If newly added fields were added to a group:
+ if (in_array($key, $add_field_rows)) {
+ // We replace the '_add_*_field' key with the actual name of
+ // the field that got added.
+ // content_field_overview_form_submit() placed those
+ // in $form_state['fields_added'] for us.
+ if (isset($form_state['fields_added'][$key])) {
+ $key = $form_state['fields_added'][$key];
+ }
+ else {
+ // No field was actually created : skip to next row.
+ continue;
+ }
+ }
+ // If the field was added to the newly created group, replace the
+ // '_add_new_group' value with the actual name of the group.
+ $parent = ($values['parent'] == '_add_new_group' && isset($new_group_name)) ? $new_group_name : $values['parent'];
+ // TODO: check the parent group does exist ?
+ fieldgroup_update_fields(array('field_name' => $key, 'group' => $parent, 'type_name' => $type_name));
+ }
+
+ // If 'group' row: update groups weights
+ // (possible newly created group has already been taken care of).
+ elseif (in_array($key, $form['#groups'])) {
+ db_query("UPDATE {". fieldgroup_tablename() ."} SET weight = %d WHERE type_name = '%s' AND group_name = '%s'",
+ $values['weight'], $type_name, $key);
+ }
+ }
+
+ cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
+}
+
+function field_group_default_settings($group_type) {
+ $settings = array(
+ 'form' => array('style' => 'fieldset', 'description' => ''),
+ 'display' => array('description' => '', 'label' => 'above'),
+ );
+ module_load_include('inc', 'content', 'includes/content.admin');
+ foreach (array_keys(content_build_modes()) as $key) {
+ $settings['display'][$key]['format'] = 'fieldset';
+ $settings['display'][$key]['exclude'] = 0;
+ }
+ // Allow other modules to add new default settings.
+ $settings = array_merge($settings, module_invoke_all('fieldgroup_default_settings', $group_type));
+ return $settings;
+}
+
+function fieldgroup_display_overview_form_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+ $groups = fieldgroup_groups($form['#type_name']);
+ foreach ($form_values as $key => $values) {
+ if (in_array($key, $form['#groups'])) {
+ $group = $groups[$key];
+ // We have some numeric keys here, so we can't use array_merge.
+ $group['settings']['display'] = $values + $group['settings']['display'];
+ fieldgroup_save_group($form['#type_name'], $group);
+ }
+ }
+}
+
+function fieldgroup_field_remove_form_submit($form, &$form_state) {
+ $form_values = $form_state['values'];
+ // TODO:
+ // - when a (non last) field is removed from a group, a 'ghost row' remains in the fields overview
+ // - when the last field is removed, the group disappears
+ // seems to be fixed when emptying the cache.
+ db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']);
+}
+
+/**
+ * Implementation of hook_nodeapi().
+ */
+function fieldgroup_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
+ switch ($op) {
+ case 'view':
+ // Prevent against invalid 'nodes' built by broken 3rd party code.
+ if (isset($node->type)) {
+ // Build the node content element needed to render each fieldgroup.
+ foreach (fieldgroup_groups($node->type) as $group) {
+ fieldgroup_build_content($group, $node, $teaser, $page);
+ }
+ }
+ break;
+ }
+}
+
+/**
+ * Build the node content element needed to render a fieldgroup.
+ *
+ * @param $group
+ * The field group definition.
+ * @param $node
+ * The node containing the field group to display. Can be a 'pseudo-node',
+ * containing at least 'type', 'nid', 'vid', and the content for fields
+ * required for the group.
+ * @param $teaser
+ * @param $page
+ * Similar to hook_nodeapi('view').
+ *
+ * @see fieldgroup_nodeapi()
+ * @see fieldgroup_view_group()
+ */
+function fieldgroup_build_content($group, &$node, $teaser, $page) {
+ // NODE_BUILD_NORMAL is 0, and ('whatever' == 0) is TRUE, so we need a ===.
+ if ($node->build_mode === NODE_BUILD_NORMAL || $node->build_mode == NODE_BUILD_PREVIEW) {
+ $context = $teaser ? 'teaser' : 'full';
+ }
+ else {
+ $context = $node->build_mode;
+ }
+
+ $group_name = $group['group_name'];
+
+ // Do not include group labels when indexing content.
+ if ($context == NODE_BUILD_SEARCH_INDEX) {
+ $group['settings']['display']['label'] = 'hidden';
+ }
+ $label = $group['settings']['display']['label'] == 'above';
+ $element = array(
+ '#title' => $label ? check_plain(t($group['label'])) : '',
+ '#description' => $label ? content_filter_xss(t($group['settings']['display']['description'])) : '',
+ );
+ $format = isset($group['settings']['display'][$context]['format']) ? $group['settings']['display'][$context]['format'] : 'fieldset';
+
+ switch ($format) {
+ case 'simple':
+ $element['#type'] = 'fieldgroup_simple';
+ $element['#group_name'] = $group_name;
+ $element['#node'] = $node;
+ break;
+ case 'hidden':
+ $element['#access'] = FALSE;
+ break;
+ case 'fieldset_collapsed':
+ $element['#collapsed'] = TRUE;
+ case 'fieldset_collapsible':
+ $element['#collapsible'] = TRUE;
+ case 'fieldset':
+ $element['#type'] = 'fieldgroup_fieldset';
+ $element['#attributes'] = array('class' => 'fieldgroup '. strtr($group['group_name'], '_', '-'));
+ break;
+ }
+ foreach ($group['fields'] as $field_name => $field) {
+ if (isset($node->content[$field_name])) {
+ $element[$field_name] = $node->content[$field_name];
+ }
+ }
+
+ // Allow other modules to alter the group view.
+ // Can't use module_invoke_all because we want
+ // to be able to use a reference to $node and $element.
+ foreach (module_implements('fieldgroup_view') as $module) {
+ $function = $module .'_fieldgroup_view';
+ $function($node, $element, $group, $context);
+ }
+
+ // Unset the original field values now that we've moved them.
+ foreach ($group['fields'] as $field_name => $field) {
+ if (isset($node->content[$field_name])) {
+ unset($node->content[$field_name]);
+ }
+ }
+
+ // The wrapper lets us get the themed output for the group
+ // to populate the $GROUP_NAME_rendered variable for node templates,
+ // and hide it from the $content variable if needed.
+ // See fieldgroup_preprocess_node(), theme_fieldgroup_wrapper().
+ $wrapper = array(
+ 'group' => $element,
+ '#weight' => $group['weight'],
+ '#post_render' => array('fieldgroup_wrapper_post_render'),
+ '#group_name' => $group_name,
+ '#type_name' => $node->type,
+ '#context' => $context,
+ );
+
+ $node->content[$group_name] = $wrapper;
+}
+
+/**
+ * Render a single field group, fully themed with label.
+ *
+ * To be used by third-party code (Panels, ...) that needs to output an
+ * isolated field group. Do *not* use inside node templates, use the
+ * $GROUP_NAME_rendered variables instead. You can also use the 'simple'
+ * style format and override the template fieldgroup-simple.tpl.php.
+ *
+ * By default, the field group is displayed using the settings defined for the
+ * 'full node' or 'teaser' contexts (depending on the value of the $teaser param).
+ * Set $node->build_mode to a different value to use a different context.
+ *
+ * Different settings can be specified by adjusting $group['settings']['display'].
+ *
+ * @param $group
+ * The field group definition.
+ * @param $node
+ * The node containing the field group to display. Can be a 'pseudo-node',
+ * containing at least 'type', 'nid', 'vid', and the field data required
+ * for the group.
+ * @param $teaser
+ * @param $page
+ * Similar to hook_nodeapi('view').
+ * @return
+ * The themed output for the field group.
+ *
+ * @see content_view_field()
+ */
+function fieldgroup_view_group($group, &$node, $teaser = FALSE, $page = FALSE) {
+ $group_name = $group['group_name'];
+ $field_types = _content_field_types();
+
+ // Clone the node to prevent from altering the original.
+ $node_copy = drupal_clone($node);
+
+ // Use 'full'/'teaser' if not specified otherwise.
+ $node_copy->build_mode = isset($node_copy->build_mode) ? $node_copy->build_mode : NODE_BUILD_NORMAL;
+
+ // Build the content element for individual fields in the field group.
+ if (!isset($node_copy->content)) {
+ $node_copy->content = array();
+ }
+ foreach (array_keys($group['fields']) as $field_name) {
+ $field = content_fields($field_name, $node_copy->type);
+
+ if (isset($node_copy->{$field_name})) {
+ $items = $node_copy->{$field_name};
+
+ // One-field equivalent to _content_field_invoke('sanitize').
+ $module = $field_types[$field['type']]['module'];
+ $function = $module .'_field';
+ if (function_exists($function)) {
+ $function('sanitize', $node_copy, $field, $items, $teaser, $page);
+ $node_copy->{$field_name} = $items;
+ }
+
+ $field_view = content_field('view', $node_copy, $field, $items, $teaser, $page);
+ // content_field('view') adds a wrapper to handle variables and 'excluded'
+ // fields for node templates. We bypass it and get the actual field.
+ $node_copy->content[$field_name] = $field_view[$field_name];
+ }
+ }
+
+ // Build the content element of the field group itself.
+ fieldgroup_build_content($group, $node_copy, $teaser, $page);
+
+ // fieldgroup_build_content() adds a wrapper to handle variables and 'excluded'
+ // groups for node templates. We bypass it and render the actual field group.
+ $output = drupal_render($node_copy->content[$group_name]['group']);
+
+ return $output;
+}
+
+/**
+ * Hide specified fields from the $content variable in node templates.
+ */
+function fieldgroup_wrapper_post_render($content, $element) {
+ $groups = fieldgroup_groups($element['#type_name']);
+ $group = $groups[$element['#group_name']];
+
+ // The display settings are not in quite the same place in the
+ // group and the field, so create the value the theme will expect.
+ $group['display_settings'] = $group['settings']['display'];
+ if (theme('content_exclude', $content, $group, $element['#context'])) {
+ return '';
+ }
+ return $content;
+}
+
+/*
+ * Get the group name for a field.
+ * If the field isn't in a group, FALSE will be returned.
+ * @return The name of the group, or FALSE.
+ */
+function fieldgroup_get_group($content_type, $field_name) {
+ foreach (fieldgroup_groups($content_type) as $group_name => $group) {
+ if (in_array($field_name, array_keys($group['fields']))) {
+ return $group_name;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of hook_node_type()
+ * React to change in node types
+ */
+function fieldgroup_node_type($op, $info) {
+ if ($op == 'update' && !empty($info->old_type) && $info->type != $info->old_type) {
+ // update the tables
+ db_query("UPDATE {". fieldgroup_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));
+ db_query("UPDATE {". fieldgroup_fields_tablename() ."} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));
+ cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
+ }
+ elseif ($op == 'delete') {
+ db_query("DELETE FROM {". fieldgroup_tablename() ."} WHERE type_name = '%s'", $info->type);
+ db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s'", $info->type);
+ }
+}
+
+function fieldgroup_types() {
+ $types = array('standard' => t('Standard group'));
+ // Allow other modules to add new group_types.
+ $types = array_merge($types, module_invoke_all('fieldgroup_types'));
+ return $types;
+}
+
+function fieldgroup_tablename($version = NULL) {
+ if (is_null($version)) {
+ $version = variable_get('fieldgroup_schema_version', 0);
+ }
+ return $version < 6000 ? 'node_group' : 'content_group';
+}
+
+function fieldgroup_fields_tablename($version = NULL) {
+ if (is_null($version)) {
+ $version = variable_get('fieldgroup_schema_version', 0);
+ }
+ return $version < 6000 ? 'node_group_fields' : 'content_group_fields';
+}
+
+/**
+ * CRUD API for fieldgroup module.
+ *
+ * @todo
+ * Make this into more of a real API for groups.
+ */
+/*
+ * Saves the given group for this content-type
+ */
+function fieldgroup_save_group($type_name, $group) {
+ $groups = fieldgroup_groups($type_name);
+
+ // Allow other modules to intervene when the group is saved.
+ foreach (module_implements('fieldgroup_save_group') as $module) {
+ $function = $module .'_fieldgroup_save_group';
+ $function($group);
+ }
+
+ if (!isset($groups[$group['group_name']])) {
+ // Accept group name from programmed submissions if valid.
+ db_query("INSERT INTO {". fieldgroup_tablename() ."} (group_type, type_name, group_name, label, settings, weight)".
+ " VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $group['group_type'], $type_name, $group['group_name'], $group['label'], serialize($group['settings']), $group['weight']);
+ cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
+ return SAVED_NEW;
+ }
+ else {
+ db_query("UPDATE {". fieldgroup_tablename() ."} SET group_type = '%s', label = '%s', settings = '%s', weight = %d ".
+ "WHERE type_name = '%s' AND group_name = '%s'",
+ $group['group_type'], $group['label'], serialize($group['settings']), $group['weight'], $type_name, $group['group_name']);
+ cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
+ return SAVED_UPDATED;
+ }
+}
+
+function fieldgroup_update_fields($form_values) {
+ $default = _fieldgroup_field_get_group($form_values['type_name'], $form_values['field_name']);
+
+ if ($default != $form_values['group']) {
+ if ($form_values['group'] && !$default) {
+ db_query("INSERT INTO {". fieldgroup_fields_tablename() ."} (type_name, group_name, field_name) VALUES ('%s', '%s', '%s')", $form_values['type_name'], $form_values['group'], $form_values['field_name']);
+ }
+ elseif ($form_values['group']) {
+ db_query("UPDATE {". fieldgroup_fields_tablename() ."} SET group_name = '%s' WHERE type_name = '%s' AND field_name = '%s'", $form_values['group'], $form_values['type_name'], $form_values['field_name']);
+ }
+ else {
+ db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND field_name = '%s'", $form_values['type_name'], $form_values['field_name']);
+ }
+ cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
+ }
+}
+
+function fieldgroup_delete($content_type, $group_name) {
+ db_query("DELETE FROM {". fieldgroup_tablename() ."} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name);
+ db_query("DELETE FROM {". fieldgroup_fields_tablename() ."} WHERE type_name = '%s' AND group_name = '%s'", $content_type, $group_name);
+ cache_clear_all('fieldgroup_data:', content_cache_tablename(), TRUE);
+}
+
+/**
+ * Format a fieldgroup using a 'fieldset'.
+ *
+ * Derived from core's theme_fieldset, with no output if the content is empty.
+ */
+function theme_fieldgroup_fieldset($element) {
+ if (empty($element['#children']) && empty($element['#value'])) {
+ return '';
+ }
+
+ if ($element['#collapsible']) {
+ drupal_add_js('misc/collapse.js');
+
+ if (!isset($element['#attributes']['class'])) {
+ $element['#attributes']['class'] = '';
+ }
+
+ $element['#attributes']['class'] .= ' collapsible';
+ if ($element['#collapsed']) {
+ $element['#attributes']['class'] .= ' collapsed';
+ }
+ }
+ return '\n";
+}
+
+
+/**
+ * Process variables for fieldgroup.tpl.php.
+ *
+ * The $variables array contains the following arguments:
+ * - $group_name
+ * - $group_name_css
+ * - $label
+ * - $description
+ * - $content
+ *
+ * @see fieldgroup-simple.tpl.php
+ */
+function template_preprocess_fieldgroup_simple(&$vars) {
+ $element = $vars['element'];
+
+ $vars['group_name'] = $element['#group_name'];
+ $vars['group_name_css'] = strtr($element['#group_name'], '_', '-');
+ $vars['label'] = isset($element['#title']) ? $element['#title'] : '';;
+ $vars['description'] = isset($element['#description']) ? $element['#description'] : '';;
+ $vars['content'] = isset($element['#children']) ? $element['#children'] : '';
+ $vars['template_files'] = array(
+ 'fieldgroup-simple-',
+ 'fieldgroup-simple-'. $element['#group_name'],
+ 'fieldgroup-simple-'. $element['#node']->type,
+ 'fieldgroup-simple-'. $element['#group_name'] .'-'. $element['#node']->type,
+ );
+}
+
+/**
+ * Theme preprocess function for node.
+ *
+ * Adds $GROUP_NAME_rendered variables,
+ * containing the themed output for the whole group.
+ */
+function fieldgroup_preprocess_node(&$vars) {
+ $node = $vars['node'];
+
+ foreach (fieldgroup_groups($node->type) as $group_name => $group) {
+ // '#chilren' might not be set if the group is empty.
+ $vars[$group_name .'_rendered'] = isset($node->content[$group_name]['#children']) ? $node->content[$group_name]['#children'] : '';
+ }
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/content_fieldgroup.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/content_fieldgroup.inc
new file mode 100644
index 00000000000..dc462c586e1
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/content_fieldgroup.inc
@@ -0,0 +1,164 @@
+ t('Content fieldgroup'),
+ 'defaults' => array('label' => 'hidden', 'format' => 'simple', 'empty' => ''),
+ );
+}
+
+/**
+ * Return all fieldgroup content types available.
+ */
+function fieldgroup_content_fieldgroup_content_type_content_types() {
+ // This will hold all the individual fieldgroup content types.
+ $types = array();
+
+ // The outer loop goes through each node type with groups.
+ foreach (fieldgroup_groups() as $node_type_groups) {
+ // The inner loop gives us each fieldgroup on each node type with groups.
+ foreach ($node_type_groups as $group) {
+ // Skip field groups that are not of standard type.
+ if ($group['group_type'] != 'standard') {
+ continue;
+ }
+
+ // Name the content type a combination of fieldgroup and node type names.
+ $content_type_name = $group['type_name'] . ':' . $group['group_name'];
+
+ // Assemble the information about the content type.
+ $info = array(
+ 'category' => t('Node'),
+ 'icon' => 'icon_cck_field_group.png',
+ 'title' => t('Field group: @group in @type', array(
+ '@group' => t($group['label']),
+ '@type' => node_get_types('name', $group['type_name']),
+ )),
+ 'description' => t('All fields from this field group on the referenced node.'),
+ 'required context' => new ctools_context_required(t('Node'), 'node', array('type' => array($group['type_name']))),
+ );
+
+ $types[$content_type_name] = $info;
+ }
+ }
+
+ return $types;
+}
+
+/**
+ * Output function for the 'fieldgroup' content type.
+ */
+function fieldgroup_content_fieldgroup_content_type_render($subtype, $conf, $panel_args, $context) {
+ if (!isset($context->data)) {
+ return;
+ }
+ $node = drupal_clone($context->data);
+
+ // Make sure old data doesn't cause problems:
+ if (empty($conf['label'])) {
+ $conf['label'] = 'hidden';
+ }
+ if (empty($conf['format'])) {
+ $conf['format'] = 'simple';
+ }
+
+ // Extract the node type and fieldgroup name from the subtype.
+ list($node_type, $group_name) = explode(':', $subtype, 2);
+
+ // Get a list of all fieldgroups for this node type.
+ $groups = fieldgroup_groups($node_type);
+
+ if (!isset($groups[$group_name])) {
+ return;
+ }
+ $group = $groups[$group_name];
+
+ // Render the field group.
+ $node->build_mode = NODE_BUILD_NORMAL;
+ $group['settings']['display']['label'] = $conf['label'] == 'normal' || !empty($conf['override_title']) ? 'hidden' : $conf['label'];
+ $group['settings']['display']['full']['format'] = $conf['format'];
+ $group['settings']['display']['full']['exclude'] = 0;
+ $output = fieldgroup_view_group($group, $node);
+
+ $block = new stdClass();
+ if ($conf['label'] == 'normal') {
+ $block->title = t($group['label']);
+ }
+ $block->content = !empty($output) ? $output : $conf['empty'];
+ return $block;
+}
+
+/**
+ * Returns a settings form for the custom type.
+ */
+function fieldgroup_content_fieldgroup_content_type_edit_form(&$form, &$form_state) {
+ $conf = $form_state['conf'];
+
+ $label_options = array(
+ 'normal' => t('Block title'),
+ 'above' => t('Above'),
+ );
+ $form['label'] = array(
+ '#type' => 'select',
+ '#title' => t('Field group label'),
+ '#default_value' => !empty($conf['label']) && isset($label_options[$conf['label']]) ? $conf['label'] : 'hidden',
+ '#options' => $label_options,
+ '#description' => t('Configure how the field group label is going to be displayed. This option takes no effect when "Override title" option is enabled, the specified block title is displayed instead.'),
+ );
+
+ $format_options = array(
+ 'simple' => t('Simple'),
+ 'fieldset' => t('Fieldset'),
+ 'fieldset_collapsible' => t('Fieldset - Collapsible'),
+ 'fieldset_collapsed' => t('Fieldset - Collapsed'),
+ );
+ $form['format'] = array(
+ '#type' => 'select',
+ '#title' => t('Field group format'),
+ '#default_value' => !empty($conf['format']) && isset($format_options[$conf['format']]) ? $conf['format'] : 'simple',
+ '#options' => $format_options,
+ '#description' => t('This option allows you to configure the field group format.'),
+ );
+
+ $form['empty'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Empty text'),
+ '#description' => t('Text to display if group has no data. Note that title will not display unless overridden.'),
+ '#rows' => 5,
+ '#default_value' => $conf['empty'],
+ );
+}
+
+function fieldgroup_content_fieldgroup_content_type_edit_form_submit(&$form, &$form_state) {
+ // Copy everything from our defaults.
+ foreach (array_keys($form_state['plugin']['defaults']) as $key) {
+ $form_state['conf'][$key] = $form_state['values'][$key];
+ }
+}
+
+/**
+ * Admin title for fieldgroup content type.
+ */
+function fieldgroup_content_fieldgroup_content_type_admin_title($subtype, $conf, $context) {
+ // Extract the node type and fieldgroup name from the subtype.
+ list($node_type, $group_name) = explode(':', $subtype, 2);
+
+ // Get information about this field group for this node type.
+ $groups = fieldgroup_groups($node_type);
+ $group = $groups[$group_name];
+
+ return t('"@s" field group: @group in @type', array(
+ '@s' => $context->identifier,
+ '@group' => t($group['label']),
+ '@type' => node_get_types('name', $node_type),
+ ));
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/icon_cck_field_group.png b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/icon_cck_field_group.png
new file mode 100644
index 00000000000..84594431b70
Binary files /dev/null and b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/panels/content_types/icon_cck_field_group.png differ
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.de.po
new file mode 100644
index 00000000000..3f6a582b634
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.de.po
@@ -0,0 +1,42 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: 2009-06-16 19:08+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:39
+msgid "@type: (fieldgroup) @fieldgroup"
+msgstr "@type: (Feldgruppe) @fieldgroup"
+
+#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:42
+msgid "All fields from this fieldgroup on the referenced node."
+msgstr "Alle Felder einer Feldgruppe auf dem referenzierten Beitrag."
+
+#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:119
+msgid "\"@s\" fieldgroup (@name)"
+msgstr "„@s“ Feldgruppe (@name)"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.pot
new file mode 100644
index 00000000000..d97357a1451
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup-panels-content_types.pot
@@ -0,0 +1,31 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-fieldgroup-panels-content_types)
+# Copyright YEAR NAME
+# Generated from file: content_fieldgroup.inc,v 1.1.2.1 2009/04/29 18:34:46 karens
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:39
+msgid "@type: (fieldgroup) @fieldgroup"
+msgstr ""
+
+#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:42
+msgid "All fields from this fieldgroup on the referenced node."
+msgstr ""
+
+#: modules/fieldgroup/panels/content_types/content_fieldgroup.inc:119
+msgid "\"@s\" fieldgroup (@name)"
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.de.po
new file mode 100644
index 00000000000..b9af7104d2d
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.de.po
@@ -0,0 +1,151 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: 2009-06-16 19:06+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:30
+msgid "All fields from a fieldgroup on the referenced node."
+msgstr "Alle Felder einer Feldgruppe auf dem referenzierten Beitrag."
+
+#: modules/fieldgroup/fieldgroup.panels.inc:32
+msgid "Node context"
+msgstr "Beitragskontext"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:91
+msgid "@group_label (@group_type_name)"
+msgstr "@group_label (@group_type_name)"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:102
+#: modules/fieldgroup/fieldgroup.info:0
+msgid "Fieldgroup"
+msgstr "Feldgruppe"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:128
+msgid "\"@s\" fieldgroup @name"
+msgstr "„@s“ Feldgruppe @name"
+
+#: modules/fieldgroup/fieldgroup.module:130
+msgid "Form settings"
+msgstr "Formulareinstellungen"
+
+#: modules/fieldgroup/fieldgroup.module:131
+msgid "These settings apply to the group in the node editing form."
+msgstr "Diese Einstellungen gelten für die Gruppe im Bearbeitungsformular des Beitrages."
+
+#: modules/fieldgroup/fieldgroup.module:135
+msgid "Style"
+msgstr "Darstellung"
+
+#: modules/fieldgroup/fieldgroup.module:138
+msgid "always open"
+msgstr "Immer geöffnet"
+
+#: modules/fieldgroup/fieldgroup.module:139
+msgid "collapsible"
+msgstr "Zusammenklappbar"
+
+#: modules/fieldgroup/fieldgroup.module:140
+msgid "collapsed"
+msgstr "Zusammengeklappt"
+
+#: modules/fieldgroup/fieldgroup.module:148
+msgid "Instructions to present to the user on the editing form."
+msgstr "Eine Hilfestellung, die dem Benutzer im Bearbeitungsformular angezeigt wird."
+
+#: modules/fieldgroup/fieldgroup.module:153
+msgid "Display settings"
+msgstr "Anzeigeeinstellungen"
+
+#: modules/fieldgroup/fieldgroup.module:154
+msgid "These settings apply to the group on node display."
+msgstr "Diese Einstellungen gelten bei der Beitragsanzeige für die Gruppe."
+
+#: modules/fieldgroup/fieldgroup.module:161
+msgid "A description of the group."
+msgstr "Eine Beschreibung der Gruppe."
+
+#: modules/fieldgroup/fieldgroup.module:206
+msgid "Are you sure you want to remove the group %label?"
+msgstr "Soll die Gruppe %label wirklich gelöscht werden?"
+
+#: modules/fieldgroup/fieldgroup.module:208
+msgid "This action cannot be undone."
+msgstr "Dieser Vorgang kann nicht rückgängig gemacht werden."
+
+#: modules/fieldgroup/fieldgroup.module:217
+msgid "The group %group_name has been removed."
+msgstr "Die Gruppe %group_name wurde gelöscht."
+
+#: modules/fieldgroup/fieldgroup.module:359
+msgid "You need to provide a label."
+msgstr "Eine Bezeichnung muss angegeben werden."
+
+#: modules/fieldgroup/fieldgroup.module:364
+msgid "You need to provide a group name."
+msgstr "Ein Gruppenname muss angegeben werden."
+
+#: modules/fieldgroup/fieldgroup.module:378
+msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores."
+msgstr "Der Gruppenname %group_name ist ungültig. Der Name darf nur nicht-akzentuierte Kleinbuchstaben, Zahlen und Unterstriche enthalten."
+
+#: modules/fieldgroup/fieldgroup.module:381
+msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix."
+msgstr "Der Gruppenname %group_name ist zu lang. Der Name ist inklusive dem Präfix ‚group_‘ auf 32 Zeichen begrenzt."
+
+#: modules/fieldgroup/fieldgroup.module:387
+msgid "The group name %group_name already exists."
+msgstr "Der Gruppenname %group_name ist schon vorhanden."
+
+#: modules/fieldgroup/fieldgroup.module:406;409
+msgid "Add new group:"
+msgstr "Neue Gruppe hinzufügen:"
+
+#: modules/fieldgroup/fieldgroup.module:424
+msgid "Add new group: you need to provide a label."
+msgstr "Neue Gruppe hinzufügen: Eine Bezeichnung muss angegeben werden."
+
+#: modules/fieldgroup/fieldgroup.module:425
+msgid "Add new group: you need to provide a group name."
+msgstr "Neue Gruppe hinzufügen: Ein Gruppenname muss angegeben werden."
+
+#: modules/fieldgroup/fieldgroup.module:654
+msgid "Standard group"
+msgstr "Standard-Gruppe"
+
+#: modules/fieldgroup/fieldgroup.module:45;52
+msgid "Edit group"
+msgstr "Gruppe bearbeiten"
+
+#: modules/fieldgroup/fieldgroup.module:0
+msgid "fieldgroup"
+msgstr "Feldgruppe"
+
+#: modules/fieldgroup/fieldgroup.info:0
+msgid "Create display groups for CCK fields."
+msgstr "Anzeigegruppen für CCK-Felder erstellen."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.fr.po
new file mode 100644
index 00000000000..04ad703115f
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.fr.po
@@ -0,0 +1,110 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-07-03 19:20+0100\n"
+"Last-Translator: Damien Tournoud \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: modules/fieldgroup/fieldgroup.module:103
+msgid "Add"
+msgstr "Ajouter"
+
+#: modules/fieldgroup/fieldgroup.module:128
+msgid "Form settings"
+msgstr "Paramètres du formulaire"
+
+#: modules/fieldgroup/fieldgroup.module:129
+msgid "These settings apply to the group in the node editing form."
+msgstr "Ces paramètres s'appliquent au groupe dans le formulaire d'édition de nœud."
+
+#: modules/fieldgroup/fieldgroup.module:133
+msgid "Style"
+msgstr "Style"
+
+#: modules/fieldgroup/fieldgroup.module:136
+msgid "always open"
+msgstr "toujours déplié"
+
+#: modules/fieldgroup/fieldgroup.module:137
+msgid "collapsible"
+msgstr "repliable"
+
+#: modules/fieldgroup/fieldgroup.module:138
+msgid "collapsed"
+msgstr "replié"
+
+#: modules/fieldgroup/fieldgroup.module:146
+msgid "Instructions to present to the user on the editing form."
+msgstr "Instructions à présenter à l'utilisateur dans le formulaire d'édition."
+
+#: modules/fieldgroup/fieldgroup.module:151
+msgid "Display settings"
+msgstr "Paramètres d'affichage"
+
+#: modules/fieldgroup/fieldgroup.module:152
+msgid "These settings apply to the group on node display."
+msgstr "Ces paramètres s'appliquent au groupe à l'affichage du nœud."
+
+#: modules/fieldgroup/fieldgroup.module:159
+msgid "A description of the group."
+msgstr "Description du groupe."
+
+#: modules/fieldgroup/fieldgroup.module:194
+msgid "The group name %name already exists."
+msgstr "Le nom de groupe '%name' existe déjà."
+
+#: modules/fieldgroup/fieldgroup.module:198
+msgid "The group name %name is invalid."
+msgstr "Le nom de groupe '%name' est invalide."
+
+#: modules/fieldgroup/fieldgroup.module:233
+msgid "Are you sure you want to remove the group %label?"
+msgstr "Êtes-vous sûr(e) de vouloir supprimer le groupe '%label' ?"
+
+#: modules/fieldgroup/fieldgroup.module:235
+msgid "This action cannot be undone."
+msgstr "Cette action est irréversible."
+
+#: modules/fieldgroup/fieldgroup.module:244
+msgid "The group %group_name has been removed."
+msgstr "Le groupe '%group_name' a été supprimé."
+
+#: modules/fieldgroup/fieldgroup.module:347
+msgid "Display in group"
+msgstr "Afficher dans le groupe"
+
+#: modules/fieldgroup/fieldgroup.module:350
+msgid "Select a group, in which the field will be displayed on the editing form."
+msgstr "Choisissez un groupe dans lequel apparaîtra le champ dans le formulaire d'édition."
+
+#: modules/fieldgroup/fieldgroup.module:29
+msgid "Add group"
+msgstr "Ajouter un groupe"
+
+#: modules/fieldgroup/fieldgroup.module:37;44
+msgid "Edit group"
+msgstr "Éditer le groupe"
+
+#: modules/fieldgroup/fieldgroup.module:0
+msgid "fieldgroup"
+msgstr "fieldgroup"
+
+#: modules/fieldgroup/fieldgroup.info:0
+msgid "Fieldgroup"
+msgstr "Fieldgroup"
+
+#: modules/fieldgroup/fieldgroup.info:0
+msgid "Create field groups for CCK fields."
+msgstr "Créer des groupes de champs pour des champs CCK."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.hu.po
new file mode 100644
index 00000000000..551dfbc0b60
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.hu.po
@@ -0,0 +1,163 @@
+# Hungarian translation of cck (6.x-2.0-rc10)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# fieldgroup.module,v 1.79.2.34 2008/10/06 15:11:39 karens
+# fieldgroup.panels.inc,v 1.1.2.4 2008/10/06 17:21:51 karens
+# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cck (6.x-2.0-rc10)\n"
+"POT-Creation-Date: 2008-10-31 12:16-0500\n"
+"PO-Revision-Date: 2008-10-26 16:40-0500\n"
+"Last-Translator: Balogh Zoltán\n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: modules/fieldgroup/fieldgroup.module:196
+msgid "This action cannot be undone."
+msgstr "Ez a művelet nem visszavonható."
+
+#: modules/fieldgroup/fieldgroup.module:254
+msgid "none"
+msgstr "nincs"
+
+#: modules/fieldgroup/fieldgroup.module:126
+msgid "Style"
+msgstr "Stílus"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:10,66
+msgid "Content fieldgroup"
+msgstr "Tartalom mezőcsoport"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:47
+msgid "Content fieldgroup content goes here."
+msgstr "Tartalom mezőcsoport tartalma jön ide."
+
+#: modules/fieldgroup/fieldgroup.panels.inc:69
+msgid "All fields from a fieldgroup on the referenced node."
+msgstr "Minden mező a mezőcsoportból a hivatkozott tartalmon."
+
+#: modules/fieldgroup/fieldgroup.panels.inc:90
+msgid "@group_label (@group_type_name)"
+msgstr "@group_label (@group_type_name)"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:108
+msgid ""
+"Text to display if group has no data. Note that title will not display "
+"unless overridden."
+msgstr ""
+"Megjelenítendő szöveg, ha a csoportnak nincs adata. A cím nem "
+"jelenik meg, ha nincs felülírva."
+
+#: modules/fieldgroup/fieldgroup.panels.inc:123
+msgid "\"@s\" fieldgroup @name"
+msgstr "„@s” mezőcsoport @name"
+
+#: modules/fieldgroup/fieldgroup.module:121
+msgid "Form settings"
+msgstr "Űrlap beállításai"
+
+#: modules/fieldgroup/fieldgroup.module:122
+msgid "These settings apply to the group in the node editing form."
+msgstr ""
+"Ezek a beállítások lesznek értelmezve a csoportra a "
+"tartalomszerkesztő űrlapon."
+
+#: modules/fieldgroup/fieldgroup.module:129
+msgid "always open"
+msgstr "mindig nyitott"
+
+#: modules/fieldgroup/fieldgroup.module:130
+msgid "collapsible"
+msgstr "összecsukható"
+
+#: modules/fieldgroup/fieldgroup.module:131
+msgid "collapsed"
+msgstr "összecsukott"
+
+#: modules/fieldgroup/fieldgroup.module:139
+msgid "Instructions to present to the user on the editing form."
+msgstr "Az űrlap szerkesztésekor megjelenő útmutató."
+
+#: modules/fieldgroup/fieldgroup.module:144
+msgid "Display settings"
+msgstr "Megjelenítési beállítások"
+
+#: modules/fieldgroup/fieldgroup.module:145
+msgid "These settings apply to the group on node display."
+msgstr ""
+"Ezek a beállítások lesznek értelmezve a csoportra a tartalom "
+"megjelenítésekor."
+
+#: modules/fieldgroup/fieldgroup.module:152
+msgid "A description of the group."
+msgstr "A csoport leírása."
+
+#: modules/fieldgroup/fieldgroup.module:194
+msgid "Are you sure you want to remove the group %label?"
+msgstr "%label csoport biztosan törölhető?"
+
+#: modules/fieldgroup/fieldgroup.module:205
+msgid "The group %group_name has been removed."
+msgstr "%group_name csoport törölve lett."
+
+#: modules/fieldgroup/fieldgroup.module:347
+msgid "You need to provide a label."
+msgstr "Meg kell adni egy címkét."
+
+#: modules/fieldgroup/fieldgroup.module:352
+msgid "You need to provide a group name."
+msgstr "Meg kell adni a csoport nevét."
+
+#: modules/fieldgroup/fieldgroup.module:366
+msgid ""
+"The group name %group_name is invalid. The name must include only "
+"lowercase unaccentuated letters, numbers, and underscores."
+msgstr ""
+"%group_name csoportnév érvénytelen. A név csak ékezet nélküli "
+"kisbetűket, számokat és aláhúzásjeleket tartalmazhat."
+
+#: modules/fieldgroup/fieldgroup.module:369
+msgid ""
+"The group name %group_name is too long. The name is limited to 32 "
+"characters, including the 'group_' prefix."
+msgstr ""
+"%group_name csoportnév túl hosszú. A név csak 32 karakter hosszú "
+"lehet, beleértve a „group_” előtagot is."
+
+#: modules/fieldgroup/fieldgroup.module:381
+msgid "The group name %group_name already exists."
+msgstr "%group_name nevű csoport már létezik."
+
+#: modules/fieldgroup/fieldgroup.module:400,403
+msgid "Add new group:"
+msgstr "Új csoport hozzáadása:"
+
+#: modules/fieldgroup/fieldgroup.module:418
+msgid "Add new group: you need to provide a label."
+msgstr "Új csoport hozzáadása: meg kell adni egy címkét."
+
+#: modules/fieldgroup/fieldgroup.module:419
+msgid "Add new group: you need to provide a group name."
+msgstr "Új csoport hozzáadása: meg kell adni a csoport nevét."
+
+#: modules/fieldgroup/fieldgroup.module:622
+msgid "Standard group"
+msgstr "Alapvető csoport"
+
+#: modules/fieldgroup/fieldgroup.module:39,46
+msgid "Edit group"
+msgstr "Csoport szerkesztése"
+
+#: modules/fieldgroup/fieldgroup.module:0
+msgid "fieldgroup"
+msgstr "mezőcsoport"
+
+#: modules/fieldgroup/fieldgroup.info:0
+msgid "Create display groups for CCK fields."
+msgstr "Csoportokat hoz létre a CCK mezők számára."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.nl.po
new file mode 100644
index 00000000000..51f892d58fa
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.nl.po
@@ -0,0 +1,192 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched
+# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens
+# fieldgroup.module,v 1.79.2.45 2009/02/28 23:56:17 yched
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:25+0200\n"
+"PO-Revision-Date: 2009-06-03 14:25+0200\n"
+"Last-Translator: NAME \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: fieldgroup.panels.inc:10;27
+msgid "Content fieldgroup"
+msgstr "Inhoudveldgroep"
+
+#: fieldgroup.panels.inc:30
+msgid "All fields from a fieldgroup on the referenced node."
+msgstr "Alle velden van een veldgroep op de gerefereerde node."
+
+#: fieldgroup.panels.inc:31
+msgid "Node"
+msgstr "Node"
+
+#: fieldgroup.panels.inc:32
+msgid "Node context"
+msgstr "Node context"
+
+#: fieldgroup.panels.inc:91
+msgid "@group_label (@group_type_name)"
+msgstr "@group_label (@group_type_name)"
+
+#: fieldgroup.panels.inc:102 fieldgroup.info:0
+msgid "Fieldgroup"
+msgstr "Veldgroep"
+
+#: fieldgroup.panels.inc:112
+msgid "Text to display if group has no data. Note that title will not display unless overridden."
+msgstr ""
+"Tekst om weer te geven als de groep geen data heeft. Merk op dat de "
+"titel niet zal worden getoond tenzij anders ingesteld."
+
+#: fieldgroup.panels.inc:128
+msgid "\"@s\" fieldgroup @name"
+msgstr "\"@s\" veldgroep @name"
+
+#: fieldgroup.module:111
+msgid "Label"
+msgstr "Label"
+
+#: fieldgroup.module:124
+msgid "Form settings"
+msgstr "Formulierinstellingen"
+
+#: fieldgroup.module:125
+msgid "These settings apply to the group in the node editing form."
+msgstr "Deze instellingen zijn voor de groep in het node-bewerkformulier."
+
+#: fieldgroup.module:129
+msgid "Style"
+msgstr "Stijl"
+
+#: fieldgroup.module:132
+msgid "always open"
+msgstr "altijd open"
+
+#: fieldgroup.module:133
+msgid "collapsible"
+msgstr "uitklapbaar"
+
+#: fieldgroup.module:134
+msgid "collapsed"
+msgstr "uitgeklapt"
+
+#: fieldgroup.module:139
+msgid "Help text"
+msgstr "Helptekst"
+
+#: fieldgroup.module:142
+msgid "Instructions to present to the user on the editing form."
+msgstr "Instructies om aan de gebruiker te tonen bij het bewerkformulier."
+
+#: fieldgroup.module:147
+msgid "Display settings"
+msgstr "Weergaveinstellingen"
+
+#: fieldgroup.module:148
+msgid "These settings apply to the group on node display."
+msgstr "Deze instellingen zijn voor de groep van de node-weergave."
+
+#: fieldgroup.module:152
+msgid "Description"
+msgstr "Beschrijving"
+
+#: fieldgroup.module:155
+msgid "A description of the group."
+msgstr "Een beschrijving van de groep"
+
+#: fieldgroup.module:171;335
+msgid "Save"
+msgstr "Opslaan"
+
+#: fieldgroup.module:200
+msgid "Are you sure you want to remove the group %label?"
+msgstr "Weet je zeker dat je de groep %label wilt verwijderen?"
+
+#: fieldgroup.module:202
+msgid "This action cannot be undone."
+msgstr "Deze actie kan niet ongedaan worden gemaakt."
+
+#: fieldgroup.module:203
+msgid "Remove"
+msgstr "Verwijderen"
+
+#: fieldgroup.module:203
+msgid "Cancel"
+msgstr "Annuleren"
+
+#: fieldgroup.module:211
+msgid "The group %group_name has been removed."
+msgstr "De groep %group is verwijderd."
+
+#: fieldgroup.module:260
+msgid "none"
+msgstr "geen"
+
+#: fieldgroup.module:353
+msgid "You need to provide a label."
+msgstr "Je moet een label opgeven."
+
+#: fieldgroup.module:358
+msgid "You need to provide a group name."
+msgstr "Je moet een groepnaam opgeven."
+
+#: fieldgroup.module:372
+msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores."
+msgstr ""
+"De groepnaam %group_name in niet toegestaan. De naam mag alleen kleine "
+"alfanumerieke karakters en underscores bevatten."
+
+#: fieldgroup.module:375
+msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix."
+msgstr ""
+"De groepnaam %group_name is te lang. De naam mag niet langer zijn dan "
+"32 karakters inclusief 'group_'-voorvoegsel."
+
+#: fieldgroup.module:381
+msgid "The group name %group_name already exists."
+msgstr "De groepnaam %group_name bestaat al."
+
+#: fieldgroup.module:400;403
+msgid "Add new group:"
+msgstr "Voeg nieuwe groep toe:"
+
+#: fieldgroup.module:418
+msgid "Add new group: you need to provide a label."
+msgstr "Voeg een nieuwe groep toe: je moet een label opgeven."
+
+#: fieldgroup.module:419
+msgid "Add new group: you need to provide a group name."
+msgstr "Voeg nieuwe groep toe: je moet een groepnaam opgeven."
+
+#: fieldgroup.module:648
+msgid "Standard group"
+msgstr "Standaardgroep"
+
+#: fieldgroup.module:39;46
+msgid "Edit group"
+msgstr "Bewerk groep"
+
+#: fieldgroup.module:0
+msgid "fieldgroup"
+msgstr "veldgroep"
+
+#: fieldgroup.info:0
+msgid "Create display groups for CCK fields."
+msgstr "Maak weergavegroepen voor CCK-velden."
+
+#: fieldgroup.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.pot
new file mode 100644
index 00000000000..167a0ed869a
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.pot
@@ -0,0 +1,142 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-fieldgroup)
+# Copyright YEAR NAME
+# Generated from files:
+# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched
+# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens
+# fieldgroup.module,v 1.79.2.48 2009/04/29 20:51:52 karens
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/fieldgroup/fieldgroup.panels.inc:30
+msgid "All fields from a fieldgroup on the referenced node."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.panels.inc:32
+msgid "Node context"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.panels.inc:91
+msgid "@group_label (@group_type_name)"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.panels.inc:102 modules/fieldgroup/fieldgroup.info:0
+msgid "Fieldgroup"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.panels.inc:128
+msgid "\"@s\" fieldgroup @name"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:130
+msgid "Form settings"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:131
+msgid "These settings apply to the group in the node editing form."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:135
+msgid "Style"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:138
+msgid "always open"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:139
+msgid "collapsible"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:140
+msgid "collapsed"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:148
+msgid "Instructions to present to the user on the editing form."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:153
+msgid "Display settings"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:154
+msgid "These settings apply to the group on node display."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:161
+msgid "A description of the group."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:206
+msgid "Are you sure you want to remove the group %label?"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:208
+msgid "This action cannot be undone."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:217
+msgid "The group %group_name has been removed."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:359
+msgid "You need to provide a label."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:364
+msgid "You need to provide a group name."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:378
+msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:381
+msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:387
+msgid "The group name %group_name already exists."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:406;409
+msgid "Add new group:"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:424
+msgid "Add new group: you need to provide a label."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:425
+msgid "Add new group: you need to provide a group name."
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:654
+msgid "Standard group"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:45;52
+msgid "Edit group"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.module:0
+msgid "fieldgroup"
+msgstr ""
+
+#: modules/fieldgroup/fieldgroup.info:0
+msgid "Create display groups for CCK fields."
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.sv.po
new file mode 100644
index 00000000000..c2fb9c3ea4f
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/fieldgroup/translations/modules-fieldgroup.sv.po
@@ -0,0 +1,204 @@
+# $Id$
+#
+# Swedish translation of Drupal (fieldgroup)
+# Generated from files:
+# fieldgroup.panels.inc,v 1.1.2.5 2009/01/10 22:47:06 yched
+# content_fieldgroup.inc,v 1.1.2.1 2009/04/29 18:34:46 karens
+# fieldgroup.info,v 1.6.2.1 2008/09/22 18:25:21 karens
+# fieldgroup.module,v 1.79.2.48 2009/04/29 20:51:52 karens
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CCK - Fieldgroup 6.x\n"
+"POT-Creation-Date: 2009-05-27 13:16+0200\n"
+"PO-Revision-Date: 2009-05-27 13:39+0100\n"
+"Last-Translator: Magnus Gunnarsson \n"
+"Language-Team: drupalsverige.se\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: Swedish\n"
+"X-Poedit-Country: SWEDEN\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: fieldgroup.panels.inc:10;27
+#: panels/content_types/content_fieldgroup.inc:14
+msgid "Content fieldgroup"
+msgstr "Fältgrupp för innehåll"
+
+#: fieldgroup.panels.inc:30
+msgid "All fields from a fieldgroup on the referenced node."
+msgstr "Alla fält från en fältgrupp på den hänvisade noden."
+
+#: fieldgroup.panels.inc:31
+#: panels/content_types/content_fieldgroup.inc:43
+msgid "Node"
+msgstr "Nod"
+
+#: fieldgroup.panels.inc:32
+msgid "Node context"
+msgstr "Sammanhang för nod"
+
+#: fieldgroup.panels.inc:91
+msgid "@group_label (@group_type_name)"
+msgstr "@group_label (@group_type_name)"
+
+#: fieldgroup.panels.inc:102
+#: fieldgroup.info:0
+msgid "Fieldgroup"
+msgstr "Fältgrupp"
+
+#: fieldgroup.panels.inc:112
+#: panels/content_types/content_fieldgroup.inc:102
+msgid "Text to display if group has no data. Note that title will not display unless overridden."
+msgstr "Text att visa om gruppen inte har något innehåll. Observera att titel inte kommer att visas om det inte åsidosätts."
+
+#: fieldgroup.panels.inc:128
+msgid "\"@s\" fieldgroup @name"
+msgstr "\"@s\" fältgrupp @name"
+
+#: fieldgroup.module:117
+msgid "Label"
+msgstr "Etikett"
+
+#: fieldgroup.module:130
+msgid "Form settings"
+msgstr "Inställningar för formulär"
+
+#: fieldgroup.module:131
+msgid "These settings apply to the group in the node editing form."
+msgstr "Dessa inställningar gäller för gruppen i redigeringsformuläret för noden."
+
+#: fieldgroup.module:135
+msgid "Style"
+msgstr "Stil"
+
+#: fieldgroup.module:138
+msgid "always open"
+msgstr "alltid utfälld"
+
+#: fieldgroup.module:139
+msgid "collapsible"
+msgstr "hopfällbar"
+
+#: fieldgroup.module:140
+msgid "collapsed"
+msgstr "hopfälld"
+
+#: fieldgroup.module:145
+msgid "Help text"
+msgstr "Hjälptext"
+
+#: fieldgroup.module:148
+msgid "Instructions to present to the user on the editing form."
+msgstr "Instruktioner som visas för användaren på redigeringsformuläret."
+
+#: fieldgroup.module:153
+msgid "Display settings"
+msgstr "Inställningar för visning"
+
+#: fieldgroup.module:154
+msgid "These settings apply to the group on node display."
+msgstr "Dessa inställningar gäller för gruppen på visningen av noden."
+
+#: fieldgroup.module:158
+msgid "Description"
+msgstr "Beskrivning"
+
+#: fieldgroup.module:161
+msgid "A description of the group."
+msgstr "En beskrivning av gruppen."
+
+#: fieldgroup.module:177;341
+msgid "Save"
+msgstr "Spara"
+
+#: fieldgroup.module:206
+msgid "Are you sure you want to remove the group %label?"
+msgstr "Är du säker på att du vill ta bort gruppen %label?"
+
+#: fieldgroup.module:208
+msgid "This action cannot be undone."
+msgstr "Denna åtgärd kan inte ångras."
+
+#: fieldgroup.module:209
+msgid "Remove"
+msgstr "Ta bort"
+
+#: fieldgroup.module:209
+msgid "Cancel"
+msgstr "Avbryt"
+
+#: fieldgroup.module:217
+msgid "The group %group_name has been removed."
+msgstr "Gruppen %group_name har tagits bort."
+
+#: fieldgroup.module:266
+msgid "none"
+msgstr "ingen"
+
+#: fieldgroup.module:359
+msgid "You need to provide a label."
+msgstr "Du måste ange en etikett."
+
+#: fieldgroup.module:364
+msgid "You need to provide a group name."
+msgstr "Du måste ange ett gruppnamn."
+
+#: fieldgroup.module:378
+msgid "The group name %group_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores."
+msgstr "Gruppnamnet %group_name är inte giltigt. Namnet får enbart bestå av små bokstäver som inte är accentuerade, siffor och understreck."
+
+#: fieldgroup.module:381
+msgid "The group name %group_name is too long. The name is limited to 32 characters, including the 'group_' prefix."
+msgstr "Gruppnamnet %group_name är för långt. Namnet får bestå av max 32 tecken, inklusive prefixet 'group_'."
+
+#: fieldgroup.module:387
+msgid "The group name %group_name already exists."
+msgstr "Gruppnamnet %group_name existerar redan."
+
+#: fieldgroup.module:406;409
+msgid "Add new group:"
+msgstr "Lägg till ny grupp:"
+
+#: fieldgroup.module:424
+msgid "Add new group: you need to provide a label."
+msgstr "Lägg till ny grupp: du måste ange en etikett."
+
+#: fieldgroup.module:425
+msgid "Add new group: you need to provide a group name."
+msgstr "Lägg till ny grupp: du måste ange ett gruppnamn."
+
+#: fieldgroup.module:654
+msgid "Standard group"
+msgstr "Standardgrupp"
+
+#: fieldgroup.module:45;52
+msgid "Edit group"
+msgstr "Redigera grupp"
+
+#: fieldgroup.module:0
+msgid "fieldgroup"
+msgstr "fältgrupp"
+
+#: fieldgroup.info:0
+msgid "Create display groups for CCK fields."
+msgstr "Skapa visningsgrupper för fält av typen CCK."
+
+#: fieldgroup.info:0
+msgid "CCK"
+msgstr "CCK"
+
+#: panels/content_types/content_fieldgroup.inc:39
+msgid "@type: (fieldgroup) @fieldgroup"
+msgstr "@type: (fältgrupp) @fieldgroup"
+
+#: panels/content_types/content_fieldgroup.inc:42
+msgid "All fields from this fieldgroup on the referenced node."
+msgstr "Alla fält från denna fältgrup på den hänvisade noden."
+
+#: panels/content_types/content_fieldgroup.inc:119
+msgid "\"@s\" fieldgroup (@name)"
+msgstr "\"@s\" fältgrupp (@name)"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.help.ini
new file mode 100644
index 00000000000..fae42f8d589
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.help.ini
@@ -0,0 +1,8 @@
+; $Id$
+
+[advanced help settings]
+hide = TRUE
+
+[nodereference]
+title = Nodereference field
+parent = content%fields
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.html
new file mode 100644
index 00000000000..a62e8855027
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/help/nodereference.html
@@ -0,0 +1,3 @@
+
The Nodereference field stores the nid of a related node. The title of the related node is usually displayed as the value of this field.
+
The Nodereference field can use an autocomplete widget, or, when used with Optionwidgets, the available values can be presented to the end user in a drop-down select list, checkboxes, or radios.
+
A Nodereference field can be used in Views to create a Relationship to another node, to allow you to use any field, argument, or filter from the related node in your view.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.info
new file mode 100644
index 00000000000..fa38e36af4e
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.info
@@ -0,0 +1,14 @@
+; $Id$
+name = Node Reference
+description = Defines a field type for referencing one node from another.
+dependencies[] = content
+dependencies[] = text
+dependencies[] = optionwidgets
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.install
new file mode 100644
index 00000000000..aad591ccece
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.install
@@ -0,0 +1,165 @@
+ $fields) {
+ foreach ($fields as $field) {
+ if ($field['type'] == 'nodereference') {
+ $sandbox['fields'][] = $field;
+ }
+ }
+ }
+
+ if (empty($sandbox['fields'])) {
+ return $ret;
+ }
+
+ $sandbox['progress'] = 0;
+ $sandbox['visited'] = array();
+ }
+
+ $field = $sandbox['fields'][$sandbox['progress']];
+
+ // We only want to process a field once -- if we hit it a second time,
+ // that means it's its own table and it should have already been updated.
+ if (!in_array($field['field_name'], $sandbox['visited'])) {
+ $db_info = content_database_info($field);
+ $table = $db_info['table'];
+ $attributes = $db_info['columns']['nid'];
+ $column = $attributes['column'];
+ $attributes['not null'] = FALSE;
+ db_change_field($ret, $table, $column, $column, array('type' => 'int', 'not null' => FALSE));
+ db_field_set_no_default($ret, $db_info['table'], $column);
+ $ret[] = update_sql("UPDATE {". $db_info['table'] ."} SET ". $column ." = NULL WHERE ". $column ." = 0");
+
+ $sandbox['visited'][] = $field['field_name'];
+ }
+
+ $sandbox['progress']++;
+ $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']);
+
+ return $ret;
+}
+
+/**
+ * Create an index by node reference column for all fields.
+ */
+function nodereference_update_6001(&$sandbox) {
+ include_once('./'. drupal_get_path('module', 'content') .'/content.install');
+ drupal_load('module', 'content');
+
+ $ret = array();
+
+ if (!isset($sandbox['progress'])) {
+ if ($abort = content_check_update('nodereference')) {
+ return $abort;
+ }
+
+ // Get the latest cache values and schema.
+ content_clear_type_cache(TRUE, TRUE);
+ $types = content_types_install();
+
+ if (empty($types)) {
+ return $ret;
+ }
+
+ $sandbox['fields'] = array();
+ foreach ($types as $type_name => $fields) {
+ foreach ($fields as $field) {
+ if ($field['type'] == 'nodereference') {
+ $sandbox['fields'][] = $field;
+ }
+ }
+ }
+
+ if (empty($sandbox['fields'])) {
+ return $ret;
+ }
+
+ $sandbox['progress'] = 0;
+ $sandbox['visited'] = array();
+ }
+
+ $field = $sandbox['fields'][$sandbox['progress']];
+
+ // We only want to process a field once -- if we hit it a second time,
+ // that means it's its own table and it should have already been updated.
+ if (!in_array($field['field_name'], $sandbox['visited'])) {
+ $db_info = content_database_info($field);
+ $table = $db_info['table'];
+ $attributes = $db_info['columns']['nid'];
+ $column = $attributes['column'];
+ if (!content_db_index_exists($table, $column)) {
+ db_add_index($ret, $table, $column, array($column));
+ }
+ $sandbox['visited'][] = $field['field_name'];
+ }
+
+ $sandbox['progress']++;
+ $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']);
+
+ return $ret;
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.module
new file mode 100644
index 00000000000..1deda511af9
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.module
@@ -0,0 +1,1054 @@
+ 'Nodereference autocomplete',
+ 'page callback' => 'nodereference_autocomplete',
+ 'access callback' => 'nodereference_autocomplete_access',
+ 'access arguments' => array(2),
+ 'type' => MENU_CALLBACK
+ );
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function nodereference_theme() {
+ return array(
+ 'nodereference_select' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'nodereference_buttons' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'nodereference_autocomplete' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'nodereference_formatter_default' => array(
+ 'arguments' => array('element'),
+ ),
+ 'nodereference_formatter_plain' => array(
+ 'arguments' => array('element'),
+ ),
+ 'nodereference_formatter_full' => array(
+ 'arguments' => array('element'),
+ 'function' => 'theme_nodereference_formatter_full_teaser',
+ ),
+ 'nodereference_formatter_teaser' => array(
+ 'arguments' => array('element'),
+ 'function' => 'theme_nodereference_formatter_full_teaser',
+ ),
+ );
+}
+
+/**
+ * Implementaion of hook_ctools_plugin_directory().
+ */
+function nodereference_ctools_plugin_directory($module, $plugin) {
+ if ($module == 'ctools' && $plugin == 'relationships') {
+ return 'panels/' . $plugin;
+ }
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function nodereference_field_info() {
+ return array(
+ 'nodereference' => array(
+ 'label' => t('Node reference'),
+ 'description' => t('Store the ID of a related node as an integer value.'),
+// 'content_icon' => 'icon_content_noderef.png',
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_field_settings().
+ */
+function nodereference_field_settings($op, $field) {
+ switch ($op) {
+ case 'form':
+ $form = array();
+ $form['referenceable_types'] = array(
+ '#type' => 'checkboxes',
+ '#title' => t('Content types that can be referenced'),
+ '#multiple' => TRUE,
+ '#default_value' => is_array($field['referenceable_types']) ? $field['referenceable_types'] : array(),
+ '#options' => array_map('check_plain', node_get_types('names')),
+ );
+ if (module_exists('views')) {
+ $views = array('--' => '--');
+ $all_views = views_get_all_views();
+ foreach ($all_views as $view) {
+ // Only 'node' views that have fields will work for our purpose.
+ if ($view->base_table == 'node' && !empty($view->display['default']->display_options['fields'])) {
+ if ($view->type == 'Default') {
+ $views[t('Default Views')][$view->name] = $view->name;
+ }
+ else {
+ $views[t('Existing Views')][$view->name] = $view->name;
+ }
+ }
+ }
+
+ $form['advanced'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Advanced - Nodes that can be referenced (View)'),
+ '#collapsible' => TRUE,
+ '#collapsed' => !isset($field['advanced_view']) || $field['advanced_view'] == '--',
+ );
+ if (count($views) > 1) {
+ $form['advanced']['advanced_view'] = array(
+ '#type' => 'select',
+ '#title' => t('View used to select the nodes'),
+ '#options' => $views,
+ '#default_value' => isset($field['advanced_view']) ? $field['advanced_view'] : '--',
+ '#description' => t('
Choose the "Views module" view that selects the nodes that can be referenced. Note:
') .
+ t('
Only views that have fields will work for this purpose.
This will discard the "Content types" settings above. Use the view\'s "filters" section instead.
Use the view\'s "fields" section to display additional informations about candidate nodes on node creation/edition form.
Use the view\'s "sort criteria" section to determine the order in which candidate nodes will be displayed.
'),
+ );
+ $form['advanced']['advanced_view_args'] = array(
+ '#type' => 'textfield',
+ '#title' => t('View arguments'),
+ '#default_value' => isset($field['advanced_view_args']) ? $field['advanced_view_args'] : '',
+ '#required' => FALSE,
+ '#description' => t('Provide a comma separated list of arguments to pass to the view.'),
+ );
+ }
+ else {
+ $form['advanced']['no_view_help'] = array(
+ '#value' => t('
The list of nodes that can be referenced can be based on a "Views module" view but no appropriate views were found. Note:
') .
+ t('
Only views that have fields will work for this purpose.
This will discard the "Content types" settings above. Use the view\'s "filters" section instead.
Use the view\'s "fields" section to display additional informations about candidate nodes on node creation/edition form.
Use the view\'s "sort criteria" section to determine the order in which candidate nodes will be displayed.
'),
+ );
+ }
+ }
+ return $form;
+
+ case 'save':
+ $settings = array('referenceable_types');
+ if (module_exists('views')) {
+ $settings[] = 'advanced_view';
+ $settings[] = 'advanced_view_args';
+ }
+ return $settings;
+
+ case 'database columns':
+ $columns = array(
+ 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'index' => TRUE),
+ );
+ return $columns;
+
+ case 'views data':
+ $data = content_views_field_views_data($field);
+ $db_info = content_database_info($field);
+ $table_alias = content_views_tablename($field);
+
+ // Filter: swap the handler to the 'in' operator.
+ $data[$table_alias][$field['field_name'] .'_nid']['filter']['handler'] = 'content_handler_filter_many_to_one';
+ // Argument: use node.title for summaries.
+ $data["node_$table_alias"]['table']['join']['node'] = array(
+ 'table' => 'node',
+ 'field' => 'nid',
+ 'left_table' => $table_alias,
+ 'left_field' => $field['field_name'] .'_nid',
+ );
+ $data[$table_alias][$field['field_name'] .'_nid']['argument']['handler'] = 'content_handler_argument_reference';
+ $data[$table_alias][$field['field_name'] .'_nid']['argument']['name table'] = "node_$table_alias";
+ $data[$table_alias][$field['field_name'] .'_nid']['argument']['name field'] = 'title';
+ // Relationship: add a relationship for related node.
+ $data[$table_alias][$field['field_name'] .'_nid']['relationship'] = array(
+ 'base' => 'node',
+ 'field' => $db_info['columns']['nid']['column'],
+ 'handler' => 'content_handler_relationship',
+ 'label' => t($field['widget']['label']),
+ 'content_field_name' => $field['field_name'],
+ );
+ return $data;
+ }
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function nodereference_field($op, &$node, $field, &$items, $teaser, $page) {
+ static $sanitized_nodes = array();
+
+ switch ($op) {
+ // When preparing a translation, load any translations of existing references.
+ case 'prepare translation':
+ $addition = array();
+ $addition[$field['field_name']] = array();
+ if (isset($node->translation_source->$field['field_name']) && is_array($node->translation_source->$field['field_name'])) {
+ foreach ($node->translation_source->$field['field_name'] as $key => $reference) {
+ $reference_node = node_load($reference['nid']);
+ // Test if the referenced node type is translatable and, if so,
+ // load translations if the reference is not for the current language.
+ // We can assume the translation module is present because it invokes 'prepare translation'.
+ if (translation_supported_type($reference_node->type) && !empty($reference_node->language) && $reference_node->language != $node->language && $translations = translation_node_get_translations($reference_node->tnid)) {
+ // If there is a translation for the current language, use it.
+ $addition[$field['field_name']][] = array(
+ 'nid' => isset($translations[$node->language]) ? $translations[$node->language]->nid : $reference['nid'],
+ );
+ }
+ }
+ }
+ return $addition;
+
+ case 'validate':
+ // Extract nids to check.
+ $ids = array();
+ foreach ($items as $delta => $item) {
+ if (is_array($item) && !empty($item['nid'])) {
+ if (is_numeric($item['nid'])) {
+ $ids[] = $item['nid'];
+ }
+ else {
+ $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
+ if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']);
+ form_set_error($error_element, t("%name: invalid input.", array('%name' => t($field['widget']['label']))));
+ }
+ }
+ }
+ // Prevent performance hog if there are no ids to check.
+ if ($ids) {
+ $refs = _nodereference_potential_references($field, '', NULL, $ids);
+ foreach ($items as $delta => $item) {
+ if (is_array($item)) {
+ $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
+ if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']);
+ if (!empty($item['nid']) && !isset($refs[$item['nid']])) {
+ form_set_error($error_element, t("%name: this post can't be referenced.", array('%name' => t($field['widget']['label']))));
+ }
+ }
+ }
+ }
+ return $items;
+
+ case 'sanitize':
+ // We can't just check the node is 'referenceable', because Views-mode
+ // could rely on 'current user' (at edit time).
+
+ // Extract nids to check.
+ $ids = array();
+ foreach ($items as $delta => $item) {
+ if (is_array($item)) {
+ // Default to 'non accessible'.
+ $items[$delta]['safe'] = array();
+ if (!empty($item['nid']) && is_numeric($item['nid'])) {
+ $ids[] = $item['nid'];
+ }
+ }
+ }
+ if ($ids) {
+ // Load information about nids that we haven't already loaded during
+ // this page request.
+ $missing_ids = array_diff($ids, array_keys($sanitized_nodes));
+ if (!empty($missing_ids)) {
+ $where = array('n.nid in ('. db_placeholders($missing_ids) . ')');
+ if (!user_access('administer nodes')) {
+ $where[] = 'n.status = 1';
+ }
+ $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status FROM {node} n WHERE '. implode(' AND ', $where)), $missing_ids);
+ while ($row = db_fetch_array($result)) {
+ $sanitized_nodes[$row['nid']] = $row;
+ }
+ }
+ foreach ($items as $delta => $item) {
+ if (is_array($item) && !empty($item['nid']) && isset($sanitized_nodes[$item['nid']])) {
+ $items[$delta]['safe'] = $sanitized_nodes[$item['nid']];
+ }
+ }
+ }
+ return $items;
+ }
+}
+
+/**
+ * Implementation of hook_content_is_empty().
+ */
+function nodereference_content_is_empty($item, $field) {
+ if (empty($item['nid'])) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of hook_field_formatter_info().
+ */
+function nodereference_field_formatter_info() {
+ return array(
+ 'default' => array(
+ 'label' => t('Title (link)'),
+ 'field types' => array('nodereference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ 'plain' => array(
+ 'label' => t('Title (no link)'),
+ 'field types' => array('nodereference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ 'full' => array(
+ 'label' => t('Full node'),
+ 'field types' => array('nodereference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ 'teaser' => array(
+ 'label' => t('Teaser'),
+ 'field types' => array('nodereference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ );
+}
+
+/**
+ * Theme function for 'default' nodereference field formatter.
+ */
+function theme_nodereference_formatter_default($element) {
+ $output = '';
+ if (!empty($element['#item']['safe']['nid'])) {
+ $output = l($element['#item']['safe']['title'], 'node/'. $element['#item']['safe']['nid']);
+ if (!$element['#item']['safe']['status']) {
+ $output = ' '. t('(Unpublished)') ." $output";
+ }
+ }
+ return $output;
+}
+
+/**
+ * Theme function for 'plain' nodereference field formatter.
+ */
+function theme_nodereference_formatter_plain($element) {
+ $output = '';
+ if (!empty($element['#item']['safe']['nid'])) {
+ $output = check_plain($element['#item']['safe']['title']);
+ if (!$element['#item']['safe']['status']) {
+ $output = ' '. t('(Unpublished)') ." $output";
+ }
+ }
+ return $output;
+}
+
+/**
+ * Proxy theme function for 'full' and 'teaser' nodereference field formatters.
+ */
+function theme_nodereference_formatter_full_teaser($element) {
+ static $recursion_queue = array();
+ $output = '';
+ if (!empty($element['#item']['safe']['nid'])) {
+ $nid = $element['#item']['safe']['nid'];
+ $node = $element['#node'];
+ $field = content_fields($element['#field_name'], $element['#type_name']);
+ // If no 'referencing node' is set, we are starting a new 'reference thread'
+ if (!isset($node->referencing_node)) {
+ $recursion_queue = array();
+ }
+ $recursion_queue[] = $node->nid;
+ if (in_array($nid, $recursion_queue)) {
+ // Prevent infinite recursion caused by reference cycles:
+ // if the node has already been rendered earlier in this 'thread',
+ // we fall back to 'default' (node title) formatter.
+ return theme('nodereference_formatter_default', $element);
+ }
+ if ($referenced_node = node_load($nid)) {
+ $referenced_node->referencing_node = $node;
+ $referenced_node->referencing_field = $field;
+ $output = node_view($referenced_node, $element['#formatter'] == 'teaser');
+ }
+ }
+ return $output;
+}
+
+/**
+ * Helper function for formatters.
+ *
+ * Store node titles collected in the curent request.
+ */
+function _nodereference_titles($nid, $known_title = NULL) {
+ static $titles = array();
+ if (!isset($titles[$nid])) {
+ $title = $known_title ? $known_title : db_result(db_query(db_rewrite_sql("SELECT n.title FROM {node} n WHERE n.nid=%d"), $nid));
+ $titles[$nid] = $title ? $title : '';
+ }
+ return $titles[$nid];
+}
+
+/**
+ * Implementation of hook_widget_info().
+ *
+ * We need custom handling of multiple values for the nodereference_select
+ * widget because we need to combine them into a options list rather
+ * than display multiple elements.
+ *
+ * We will use the content module's default handling for default value.
+ *
+ * Callbacks can be omitted if default handing is used.
+ * They're included here just so this module can be used
+ * as an example for custom modules that might do things
+ * differently.
+ */
+function nodereference_widget_info() {
+ return array(
+ 'nodereference_select' => array(
+ 'label' => t('Select list'),
+ 'field types' => array('nodereference'),
+ 'multiple values' => CONTENT_HANDLE_MODULE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ 'nodereference_buttons' => array(
+ 'label' => t('Check boxes/radio buttons'),
+ 'field types' => array('nodereference'),
+ 'multiple values' => CONTENT_HANDLE_MODULE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ 'nodereference_autocomplete' => array(
+ 'label' => t('Autocomplete text field'),
+ 'field types' => array('nodereference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ );
+}
+
+/**
+ * Implementation of FAPI hook_elements().
+ *
+ * Any FAPI callbacks needed for individual widgets can be declared here,
+ * and the element will be passed to those callbacks for processing.
+ *
+ * Drupal will automatically theme the element using a theme with
+ * the same name as the hook_elements key.
+ *
+ * Autocomplete_path is not used by text_widget but other widgets can use it
+ * (see nodereference and userreference).
+ */
+function nodereference_elements() {
+ return array(
+ 'nodereference_select' => array(
+ '#input' => TRUE,
+ '#columns' => array('uid'), '#delta' => 0,
+ '#process' => array('nodereference_select_process'),
+ ),
+ 'nodereference_buttons' => array(
+ '#input' => TRUE,
+ '#columns' => array('uid'), '#delta' => 0,
+ '#process' => array('nodereference_buttons_process'),
+ ),
+ 'nodereference_autocomplete' => array(
+ '#input' => TRUE,
+ '#columns' => array('name'), '#delta' => 0,
+ '#process' => array('nodereference_autocomplete_process'),
+ '#autocomplete_path' => FALSE,
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_widget_settings().
+ */
+function nodereference_widget_settings($op, $widget) {
+ switch ($op) {
+ case 'form':
+ $form = array();
+ $match = isset($widget['autocomplete_match']) ? $widget['autocomplete_match'] : 'contains';
+ $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60;
+ if ($widget['type'] == 'nodereference_autocomplete') {
+ $form['autocomplete_match'] = array(
+ '#type' => 'select',
+ '#title' => t('Autocomplete matching'),
+ '#default_value' => $match,
+ '#options' => array(
+ 'starts_with' => t('Starts with'),
+ 'contains' => t('Contains'),
+ ),
+ '#description' => t('Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of nodes.'),
+ );
+ $form['size'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Size of textfield'),
+ '#default_value' => $size,
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#required' => TRUE,
+ );
+ }
+ else {
+ $form['autocomplete_match'] = array('#type' => 'hidden', '#value' => $match);
+ $form['size'] = array('#type' => 'hidden', '#value' => $size);
+ }
+ return $form;
+
+ case 'save':
+ return array('autocomplete_match', 'size');
+ }
+}
+
+/**
+ * Implementation of hook_widget().
+ *
+ * Attach a single form element to the form. It will be built out and
+ * validated in the callback(s) listed in hook_elements. We build it
+ * out in the callbacks rather than here in hook_widget so it can be
+ * plugged into any module that can provide it with valid
+ * $field information.
+ *
+ * Content module will set the weight, field name and delta values
+ * for each form element. This is a change from earlier CCK versions
+ * where the widget managed its own multiple values.
+ *
+ * If there are multiple values for this field, the content module will
+ * call this function as many times as needed.
+ *
+ * @param $form
+ * the entire form array, $form['#node'] holds node information
+ * @param $form_state
+ * the form_state, $form_state['values'][$field['field_name']]
+ * holds the field's form values.
+ * @param $field
+ * the field array
+ * @param $items
+ * array of default values for this field
+ * @param $delta
+ * the order of this item in the array of subelements (0, 1, 2, etc)
+ *
+ * @return
+ * the form item for a single element for this field
+ */
+function nodereference_widget(&$form, &$form_state, $field, $items, $delta = 0) {
+ switch ($field['widget']['type']) {
+ case 'nodereference_select':
+ $element = array(
+ '#type' => 'nodereference_select',
+ '#default_value' => $items,
+ );
+ break;
+
+ case 'nodereference_buttons':
+ $element = array(
+ '#type' => 'nodereference_buttons',
+ '#default_value' => $items,
+ );
+ break;
+
+ case 'nodereference_autocomplete':
+ $element = array(
+ '#type' => 'nodereference_autocomplete',
+ '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL,
+ '#value_callback' => 'nodereference_autocomplete_value',
+ );
+ break;
+ }
+ return $element;
+}
+
+/**
+ * Value for a nodereference autocomplete element.
+ *
+ * Substitute in the node title for the node nid.
+ */
+function nodereference_autocomplete_value($element, $edit = FALSE) {
+ $field_key = $element['#columns'][0];
+ if (!empty($element['#default_value'][$field_key])) {
+ $nid = $element['#default_value'][$field_key];
+ $value = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $nid));
+ $value .= ' [nid:'. $nid .']';
+ return array($field_key => $value);
+ }
+ return array($field_key => NULL);
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function nodereference_select_process($element, $edit, $form_state, $form) {
+ // The nodereference_select widget doesn't need to create its own
+ // element, it can wrap around the optionwidgets_select element.
+ // This will create a new, nested instance of the field.
+ // Add a validation step where the value can be unwrapped.
+ $field_key = $element['#columns'][0];
+ $element[$field_key] = array(
+ '#type' => 'optionwidgets_select',
+ '#default_value' => isset($element['#value']) ? $element['#value'] : '',
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#required' => $element['#required'],
+ '#description' => $element['#description'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+ if (empty($element[$field_key]['#element_validate'])) {
+ $element[$field_key]['#element_validate'] = array();
+ }
+ array_unshift($element[$field_key]['#element_validate'], 'nodereference_optionwidgets_validate');
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function nodereference_buttons_process($element, $edit, $form_state, $form) {
+ // The nodereference_select widget doesn't need to create its own
+ // element, it can wrap around the optionwidgets_select element.
+ // This will create a new, nested instance of the field.
+ // Add a validation step where the value can be unwrapped.
+ $field_key = $element['#columns'][0];
+ $element[$field_key] = array(
+ '#type' => 'optionwidgets_buttons',
+ '#default_value' => isset($element['#value']) ? $element['#value'] : '',
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#required' => $element['#required'],
+ '#description' => $element['#description'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+ if (empty($element[$field_key]['#element_validate'])) {
+ $element[$field_key]['#element_validate'] = array();
+ }
+ array_unshift($element[$field_key]['#element_validate'], 'nodereference_optionwidgets_validate');
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ */
+function nodereference_autocomplete_process($element, $edit, $form_state, $form) {
+
+ // The nodereference autocomplete widget doesn't need to create its own
+ // element, it can wrap around the text_textfield element and add an autocomplete
+ // path and some extra processing to it.
+ // Add a validation step where the value can be unwrapped.
+ $field_key = $element['#columns'][0];
+
+ $element[$field_key] = array(
+ '#type' => 'text_textfield',
+ '#default_value' => isset($element['#value']) ? $element['#value'] : '',
+ '#autocomplete_path' => 'nodereference/autocomplete/'. $element['#field_name'],
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#required' => $element['#required'],
+ '#description' => $element['#description'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+ if (empty($element[$field_key]['#element_validate'])) {
+ $element[$field_key]['#element_validate'] = array();
+ }
+ array_unshift($element[$field_key]['#element_validate'], 'nodereference_autocomplete_validate');
+
+ // Used so that hook_field('validate') knows where to flag an error.
+ $element['_error_element'] = array(
+ '#type' => 'value',
+ // Wrapping the element around a text_textfield element creates a
+ // nested element, so the final id will look like 'field-name-0-nid-nid'.
+ '#value' => implode('][', array_merge($element['#parents'], array($field_key, $field_key))),
+ );
+ return $element;
+}
+
+/**
+ * Validate a select/buttons element.
+ *
+ * Remove the wrapper layer and set the right element's value.
+ * We don't know exactly where this element is, so we drill down
+ * through the element until we get to our key.
+ *
+ * We use $form_state['values'] instead of $element['#value']
+ * to be sure we have the most accurate value when other modules
+ * like optionwidgets are using #element_validate to alter the value.
+ */
+function nodereference_optionwidgets_validate($element, &$form_state) {
+ $field_key = $element['#columns'][0];
+
+ $value = $form_state['values'];
+ $new_parents = array();
+ foreach ($element['#parents'] as $parent) {
+ $value = $value[$parent];
+ // Use === to be sure we get right results if parent is a zero (delta) value.
+ if ($parent === $field_key) {
+ $element['#parents'] = $new_parents;
+ form_set_value($element, $value, $form_state);
+ break;
+ }
+ $new_parents[] = $parent;
+ }
+}
+
+/**
+ * Validate an autocomplete element.
+ *
+ * Remove the wrapper layer and set the right element's value.
+ * This will move the nested value at 'field-name-0-nid-nid'
+ * back to its original location, 'field-name-0-nid'.
+ */
+function nodereference_autocomplete_validate($element, &$form_state) {
+ $field_name = $element['#field_name'];
+ $type_name = $element['#type_name'];
+ $field = content_fields($field_name, $type_name);
+ $field_key = $element['#columns'][0];
+ $delta = $element['#delta'];
+ $value = $element['#value'][$field_key];
+ $nid = NULL;
+ if (!empty($value)) {
+ preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $value, $matches);
+ if (!empty($matches)) {
+ // Explicit [nid:n].
+ list(, $title, $nid) = $matches;
+ if (!empty($title) && ($n = node_load($nid)) && trim($title) != trim($n->title)) {
+ form_error($element[$field_key], t('%name: title mismatch. Please check your selection.', array('%name' => t($field['widget']['label']))));
+ }
+ }
+ else {
+ // No explicit nid.
+ $reference = _nodereference_potential_references($field, $value, 'equals', NULL, 1);
+ if (empty($reference)) {
+ form_error($element[$field_key], t('%name: found no valid post with that title.', array('%name' => t($field['widget']['label']))));
+ }
+ else {
+ // TODO:
+ // the best thing would be to present the user with an additional form,
+ // allowing the user to choose between valid candidates with the same title
+ // ATM, we pick the first matching candidate...
+ $nid = key($reference);
+ }
+ }
+ }
+ form_set_value($element, $nid, $form_state);
+}
+
+/**
+ * Implementation of hook_allowed_values().
+ */
+function nodereference_allowed_values($field) {
+ $references = _nodereference_potential_references($field);
+
+ $options = array();
+ foreach ($references as $key => $value) {
+ $options[$key] = $value['rendered'];
+ }
+
+ return $options;
+}
+
+/**
+ * Fetch an array of all candidate referenced nodes.
+ *
+ * This info is used in various places (allowed values, autocomplete results,
+ * input validation...). Some of them only need the nids, others nid + titles,
+ * others yet nid + titles + rendered row (for display in widgets).
+ * The array we return contains all the potentially needed information, and lets
+ * consumers use the parts they actually need.
+ *
+ * @param $field
+ * The field description.
+ * @param $string
+ * Optional string to filter titles on (used by autocomplete).
+ * @param $match
+ * Operator to match filtered name against, can be any of:
+ * 'contains', 'equals', 'starts_with'
+ * @param $ids
+ * Optional node ids to lookup (the $string and $match arguments will be
+ * ignored).
+ * @param $limit
+ * If non-zero, limit the size of the result set.
+ *
+ * @return
+ * An array of valid nodes in the form:
+ * array(
+ * nid => array(
+ * 'title' => The node title,
+ * 'rendered' => The text to display in widgets (can be HTML)
+ * ),
+ * ...
+ * )
+ */
+function _nodereference_potential_references($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) {
+ static $results = array();
+
+ // Create unique id for static cache.
+ $cid = $field['field_name'] .':'. $match .':'. ($string !== '' ? $string : implode('-', $ids)) .':'. $limit;
+ if (!isset($results[$cid])) {
+ $references = FALSE;
+ if (module_exists('views') && !empty($field['advanced_view']) && $field['advanced_view'] != '--') {
+ $references = _nodereference_potential_references_views($field, $string, $match, $ids, $limit);
+ }
+ // If the view doesn't exist, we got FALSE, and fallback to the regular 'standard mode'.
+
+ if ($references === FALSE) {
+ $references = _nodereference_potential_references_standard($field, $string, $match, $ids, $limit);
+ }
+
+ // Store the results.
+ $results[$cid] = !empty($references) ? $references : array();
+ }
+
+ return $results[$cid];
+}
+
+/**
+ * Helper function for _nodereference_potential_references():
+ * case of Views-defined referenceable nodes.
+ */
+function _nodereference_potential_references_views($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) {
+ $view_name = $field['advanced_view'];
+
+ if ($view = views_get_view($view_name)) {
+ // We add a display, and let it derive from the 'default' display.
+ // TODO: We should let the user pick a display in the fields settings - sort of requires AHAH...
+ $display = $view->add_display('content_references');
+ $view->set_display($display);
+
+ // TODO from merlinofchaos on IRC : arguments using summary view can defeat the style setting.
+ // We might also need to check if there's an argument, and set *its* style_plugin as well.
+ $view->display_handler->set_option('style_plugin', 'content_php_array_autocomplete');
+ $view->display_handler->set_option('row_plugin', 'fields');
+ // Used in content_plugin_style_php_array::render(), to get
+ // the 'field' to be used as title.
+ $view->display_handler->set_option('content_title_field', 'title');
+
+ // Additional options to let content_plugin_display_references::query()
+ // narrow the results.
+ $options = array(
+ 'table' => 'node',
+ 'field_string' => 'title',
+ 'string' => $string,
+ 'match' => $match,
+ 'field_id' => 'nid',
+ 'ids' => $ids,
+ );
+ $view->display_handler->set_option('content_options', $options);
+
+ // TODO : for consistency, a fair amount of what's below
+ // should be moved to content_plugin_display_references
+
+ // Limit result set size.
+ $limit = isset($limit) ? $limit : 0;
+ $view->display_handler->set_option('items_per_page', $limit);
+
+ // Get arguments for the view.
+ if (!empty($field['advanced_view_args'])) {
+ // TODO: Support Tokens using token.module ?
+ $view_args = array_map('trim', explode(',', $field['advanced_view_args']));
+ }
+ else {
+ $view_args = array();
+ }
+
+ // We do need title field, so add it if not present (unlikely, but...)
+ $fields = $view->get_items('field', $display);
+ if (!isset($fields['title'])) {
+ $view->add_item($display, 'field', 'node', 'title');
+ }
+
+ // If not set, make all fields inline and define a separator.
+ $options = $view->display_handler->get_option('row_options');
+ if (empty($options['inline'])) {
+ $options['inline'] = drupal_map_assoc(array_keys($view->get_items('field', $display)));
+ }
+ if (empty($options['separator'])) {
+ $options['separator'] = '-';
+ }
+ $view->display_handler->set_option('row_options', $options);
+
+ // Make sure the query is not cached
+ $view->is_cacheable = FALSE;
+
+ // Get the results.
+ $result = $view->execute_display($display, $view_args);
+ }
+ else {
+ $result = FALSE;
+ }
+
+ return $result;
+}
+
+/**
+ * Helper function for _nodereference_potential_references():
+ * referenceable nodes defined by content types.
+ */
+function _nodereference_potential_references_standard($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) {
+ $related_types = array();
+ $where = array();
+ $args = array();
+
+ if (is_array($field['referenceable_types'])) {
+ foreach (array_filter($field['referenceable_types']) as $related_type) {
+ $related_types[] = "n.type = '%s'";
+ $args[] = $related_type;
+ }
+ }
+
+ $where[] = implode(' OR ', $related_types);
+
+ if (!count($related_types)) {
+ return array();
+ }
+
+ if ($string !== '') {
+ $like = $GLOBALS["db_type"] == 'pgsql' ? "ILIKE" : "LIKE";
+ $match_clauses = array(
+ 'contains' => "$like '%%%s%%'",
+ 'equals' => "= '%s'",
+ 'starts_with' => "$like '%s%%'",
+ );
+ $where[] = 'n.title '. (isset($match_clauses[$match]) ? $match_clauses[$match] : $match_clauses['contains']);
+ $args[] = $string;
+ }
+ elseif ($ids) {
+ $where[] = 'n.nid IN (' . db_placeholders($ids) . ')';
+ $args = array_merge($args, $ids);
+ }
+
+ $where_clause = $where ? 'WHERE ('. implode(') AND (', $where) .')' : '';
+ $sql = db_rewrite_sql("SELECT n.nid, n.title AS node_title, n.type AS node_type FROM {node} n $where_clause ORDER BY n.title, n.type");
+ $result = $limit ? db_query_range($sql, $args, 0, $limit) : db_query($sql, $args);
+ $references = array();
+ while ($node = db_fetch_object($result)) {
+ $references[$node->nid] = array(
+ 'title' => $node->node_title,
+ 'rendered' => check_plain($node->node_title),
+ );
+ }
+
+ return $references;
+}
+
+/**
+ * Check access to the menu callback of the autocomplete widget.
+ *
+ * Check for both 'edit' and 'view' access in the unlikely event
+ * a user has edit but not view access.
+ */
+function nodereference_autocomplete_access($field_name) {
+ return user_access('access content') && ($field = content_fields($field_name)) && isset($field['field_name']) && content_access('view', $field) && content_access('edit', $field);
+}
+
+/**
+ * Menu callback; Retrieve a pipe delimited string of autocomplete suggestions for existing users
+ */
+function nodereference_autocomplete($field_name, $string = '') {
+ $fields = content_fields();
+ $field = $fields[$field_name];
+ $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains';
+ $matches = array();
+
+ $references = _nodereference_potential_references($field, $string, $match, array(), 10);
+ foreach ($references as $id => $row) {
+ // Add a class wrapper for a few required CSS overrides.
+ $matches[$row['title'] ." [nid:$id]"] = '
'. $row['rendered'] . '
';
+ }
+ drupal_json($matches);
+}
+
+/**
+ * Implementation of hook_node_types.
+ */
+function nodereference_node_type($op, $info) {
+ switch ($op) {
+ case 'update':
+ // Reflect type name changes to the 'referenceable types' settings.
+ if (!empty($info->old_type) && $info->old_type != $info->type) {
+ // content.module's implementaion of hook_node_type() has already
+ // refreshed _content_type_info().
+ $fields = content_fields();
+ $rebuild = FALSE;
+ foreach ($fields as $field_name => $field) {
+ if ($field['type'] == 'nodereference' && isset($field['referenceable_types'][$info->old_type])) {
+ $field['referenceable_types'][$info->type] = empty($field['referenceable_types'][$info->old_type]) ? 0 : $info->type;
+ unset($field['referenceable_types'][$info->old_type]);
+ content_field_instance_update($field, FALSE);
+ $rebuild = TRUE;
+ }
+ }
+
+ // Clear caches and rebuild menu only if any field has been updated.
+ if ($rebuild) {
+ content_clear_type_cache(TRUE);
+ menu_rebuild();
+ }
+ }
+ break;
+ }
+}
+
+/**
+ * Theme preprocess function.
+ *
+ * Allows specific node templates for nodes displayed as values of a
+ * nodereference field with the 'full node' / 'teaser' formatters.
+ */
+function nodereference_preprocess_node(&$vars) {
+ // The 'referencing_field' attribute of the node is added by the 'teaser'
+ // and 'full node' formatters.
+ if (!empty($vars['node']->referencing_field)) {
+ $node = $vars['node'];
+ $field = $node->referencing_field;
+ $vars['template_files'][] = 'node-nodereference';
+ $vars['template_files'][] = 'node-nodereference-'. $field['field_name'];
+ $vars['template_files'][] = 'node-nodereference-'. $node->type;
+ $vars['template_files'][] = 'node-nodereference-'. $field['field_name'] .'-'. $node->type;
+ }
+}
+
+/**
+ * FAPI theme for an individual elements.
+ *
+ * The textfield or select is already rendered by the
+ * textfield or select themes and the html output
+ * lives in $element['#children']. Override this theme to
+ * make custom changes to the output.
+ *
+ * $element['#field_name'] contains the field name
+ * $element['#delta] is the position of this element in the group
+ */
+function theme_nodereference_select($element) {
+ return $element['#children'];
+}
+
+function theme_nodereference_buttons($element) {
+ return $element['#children'];
+}
+
+function theme_nodereference_autocomplete($element) {
+ return $element['#children'];
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.rules.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.rules.inc
new file mode 100644
index 00000000000..7a9d4d537ac
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/nodereference.rules.inc
@@ -0,0 +1,60 @@
+ t('Load a referenced node'),
+ 'arguments' => array(
+ 'node' => array(
+ 'type' => 'node',
+ 'label' => t('Content containing the node reference field'),
+ ),
+ ),
+ 'new variables' => array(
+ 'referenced_node' => array(
+ 'type' => 'node',
+ 'label' => t('Referenced content'),
+ ),
+ ),
+ 'module' => 'CCK',
+ 'help' => t('Note that if the field has multiple values, only the first content node will be loaded.'),
+ );
+ return $info;
+}
+
+function nodereference_rules_action_load($node, $settings) {
+ if ($nid = $node->{$settings['field']}[0]['nid']) {
+ return array('referenced_node' => node_load(array('nid' => $nid)));
+ }
+}
+
+function nodereference_rules_action_load_form($settings, &$form) {
+ $settings += array('field' => '');
+ $options = content_rules_get_field_names_by_type('nodereference');
+ $form['settings']['field'] = array(
+ '#type' => 'select',
+ '#title' => t('Field'),
+ '#default_value' => $settings['field'],
+ '#options' => $options,
+ '#required' => TRUE,
+ '#disabled' => empty($options),
+ '#description' => empty($options) ? t('There are no nodereference fields defined.') : '',
+ );
+}
+
+/**
+ * Helps upgrading from the workflow-ng action
+ * "workflow_ng_action_load_referenced_node" to the equivalent rules action.
+ */
+function workflow_ng_action_load_referenced_node_upgrade(&$element) {
+ $element['#name'] = 'nodereference_rules_action_load';
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/panels/relationships/node_from_noderef.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/panels/relationships/node_from_noderef.inc
new file mode 100644
index 00000000000..74d47f57772
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/panels/relationships/node_from_noderef.inc
@@ -0,0 +1,76 @@
+ t('Node from reference'),
+ 'keyword' => 'nodereference',
+ 'description' => t('Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only.'),
+ 'required context' => new ctools_context_required(t('Node'), 'node'),
+ 'context' => 'nodereference_node_from_noderef_context',
+ 'settings form' => 'nodereference_node_from_noderef_settings_form',
+ 'settings form validate' => 'nodereference_node_from_noderef_settings_form_validate',
+ );
+}
+
+/**
+ * Return a new ctools context based on an existing context.
+ */
+function nodereference_node_from_noderef_context($context, $conf) {
+ $field = content_fields($conf['field_name']);
+
+ // If unset it wants a generic, unfilled context, which is just NULL.
+ if (empty($context->data)) {
+ $new_context = ctools_context_create_empty('node', NULL);
+ }
+ else if (isset($context->data->{$conf['field_name']}[0]['nid']) && ($nid = $context->data->{$conf['field_name']}[0]['nid'])) {
+ if ($node = node_load($nid)) {
+ $new_context = ctools_context_create('node', $node);
+ }
+ }
+
+ if (!empty($new_context)) {
+ // Have nodereference relationships limit CCK field availability as well.
+ $restrictions = array_keys(array_filter($field['referenceable_types']));
+ if ($restrictions) {
+ if (isset($new_context->restrictions['type'])) {
+ $new_context->restrictions['type'] = array_unique(array_merge($new_context->restrictions['type'], $restrictions));
+ }
+ else {
+ $new_context->restrictions['type'] = $restrictions;
+ }
+ }
+
+ return $new_context;
+ }
+}
+
+/**
+ * Settings form for the ctools relationship.
+ */
+function nodereference_node_from_noderef_settings_form($conf) {
+ $options = array();
+ foreach (content_fields() as $field) {
+ if ($field['type'] == 'nodereference') {
+ $options[$field['field_name']] = t($field['widget']['label']);
+ }
+ }
+ $form['field_name'] = array(
+ '#title' => t('Node reference field'),
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => isset($conf['field_name']) ? $conf['field_name'] : '',
+ '#prefix' => '
',
+ '#suffix' => '
',
+ );
+
+ return $form;
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.de.po
new file mode 100644
index 00000000000..310bd8c77ba
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.de.po
@@ -0,0 +1,42 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: 2009-06-16 19:10+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/nodereference/panels/relationships/node_from_noderef.inc:14
+msgid "Node from reference"
+msgstr "Beitrag der Referenz"
+
+#: modules/nodereference/panels/relationships/node_from_noderef.inc:16
+msgid "Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only."
+msgstr ""
+
+#: modules/nodereference/panels/relationships/node_from_noderef.inc:50
+msgid "Node reference field"
+msgstr "Beitragsreferenzfeld"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.pot
new file mode 100644
index 00000000000..123269570fc
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference-panels-relationships.pot
@@ -0,0 +1,31 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-nodereference-panels-relationships)
+# Copyright YEAR NAME
+# Generated from file: node_from_noderef.inc,v 1.1.2.1 2009/06/02 12:24:03 yched
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/nodereference/panels/relationships/node_from_noderef.inc:14
+msgid "Node from reference"
+msgstr ""
+
+#: modules/nodereference/panels/relationships/node_from_noderef.inc:16
+msgid "Adds a node from a node reference in a node context; if multiple nodes are referenced, this will get the first referenced node only."
+msgstr ""
+
+#: modules/nodereference/panels/relationships/node_from_noderef.inc:50
+msgid "Node reference field"
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.de.po
new file mode 100644
index 00000000000..c8df9d5471b
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.de.po
@@ -0,0 +1,124 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2009-03-09 22:08+0100\n"
+"PO-Revision-Date: 2009-03-09 22:59+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/nodereference/nodereference.rules.inc:15
+msgid "Load a referenced node"
+msgstr "Referenzierten Beitrag laden"
+
+#: modules/nodereference/nodereference.rules.inc:19
+msgid "Content containing the node reference field"
+msgstr "Der Inhalt der das Beitragsreferenzfeld enthält"
+
+#: modules/nodereference/nodereference.rules.inc:25
+msgid "Referenced content"
+msgstr "Referenzierter Inhalt"
+
+#: modules/nodereference/nodereference.rules.inc:29
+msgid "Note that if the field has multiple values, only the first content node will be loaded."
+msgstr "Sollte ein Feld mehrere Werte enthalten, wird nur der erste Beitrag geladen."
+
+#: modules/nodereference/nodereference.rules.inc:50
+msgid "There are no nodereference fields defined."
+msgstr "Es sind keine Beitragsreferenzfelder vorhanden."
+
+#: modules/nodereference/nodereference.module:60
+msgid "Node reference"
+msgstr "Beitragsreferenz"
+
+#: modules/nodereference/nodereference.module:61
+msgid "Store the ID of a related node as an integer value."
+msgstr "Speichert die ID des zugehörigen Beitrages als ganzzahligen Wert."
+
+#: modules/nodereference/nodereference.module:75
+msgid "Content types that can be referenced"
+msgstr "Inhaltstypen, auf die referenziert werden kann"
+
+#: modules/nodereference/nodereference.module:97
+msgid "Advanced - Nodes that can be referenced (View)"
+msgstr "Erweitert - Beiträge, auf die referenziert werden kann (Ansicht)"
+
+#: modules/nodereference/nodereference.module:104
+msgid "View used to select the nodes"
+msgstr "Die zur Auswahl von Beiträgen verwendete Ansicht"
+
+#: modules/nodereference/nodereference.module:107
+#, fuzzy
+msgid "
Choose the \"Views module\" view that selects the nodes that can be referenced. Note:
"
+msgstr "
Wähle die „Views-Modul“-Ansicht das die Beiträge auswählt, die Referenziert werden können. Hinweis:
The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. Note:
"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:217
+msgid "%name: this post can't be referenced."
+msgstr "%name: Dieser Beitrag kann nicht referenziert werden."
+
+#: modules/nodereference/nodereference.module:242
+msgid "Title (link)"
+msgstr "Titel (Link)"
+
+#: modules/nodereference/nodereference.module:247
+msgid "Title (no link)"
+msgstr "Titel (kein Link)"
+
+#: modules/nodereference/nodereference.module:423
+msgid "Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of nodes."
+msgstr "Die Methode zur Sammlung von Autovervollständigungsvorschlägen auswählen. Dabei ist zu beachten, dass Enthält auf Websites mit tausenden von Beiträgen große Performanceprobleme verursachen kann."
+
+#: modules/nodereference/nodereference.module:671
+msgid "%name: title mismatch. Please check your selection."
+msgstr "%name: Der Titel ist ungültig. Bitte die Auswahl überprüfen."
+
+#: modules/nodereference/nodereference.module:678
+msgid "%name: found no valid post with that title."
+msgstr "%name: Kein gültiger Beitrag mit diesem Titel gefunden."
+
+#: modules/nodereference/nodereference.module:15
+msgid "Nodereference autocomplete"
+msgstr "Autovervollständigung der Beitragsreferenz"
+
+#: modules/nodereference/nodereference.module:0
+msgid "nodereference"
+msgstr "Beitragsreferenz"
+
+#: modules/nodereference/nodereference.info:0
+msgid "Node Reference"
+msgstr "Beitragsreferenz"
+
+#: modules/nodereference/nodereference.info:0
+msgid "Defines a field type for referencing one node from another."
+msgstr "Definiert einen Feldtyp, um einen Beitrag von einem anderen zu referenzieren."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.fr.po
new file mode 100644
index 00000000000..8afec3675a5
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.fr.po
@@ -0,0 +1,86 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-07-03 18:05+0100\n"
+"Last-Translator: Damien Tournoud \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: modules/nodereference/nodereference.module:71
+msgid "Node reference"
+msgstr "Référence de nœud"
+
+#: modules/nodereference/nodereference.module:72
+msgid "Store the ID of a related node as an integer value."
+msgstr "Enregistre l'identifiant d'un nœud associé, sous la forme d'une valeur entière."
+
+#: modules/nodereference/nodereference.module:90
+msgid "Content types that can be referenced"
+msgstr "Types de contenu pouvant être référencés"
+
+#: modules/nodereference/nodereference.module:101
+msgid "Existing Views"
+msgstr "Vues existantes"
+
+#: modules/nodereference/nodereference.module:108
+msgid "Advanced - Nodes that can be referenced (View)"
+msgstr "Avancé - Nœuds pouvant être référencés (Vue)"
+
+#: modules/nodereference/nodereference.module:114
+msgid "View used to select the nodes"
+msgstr "Vue utilisée pour choisir les nœuds"
+
+#: modules/nodereference/nodereference.module:117
+msgid "Choose the \"Views module\" view that selects the nodes that can be referenced. Note:
Only views that have fields will work for this purpose.
This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.
Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.
Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.
"
+msgstr "Choisissez la vue du module Views qui sélectionne les nœuds pouvant être référencés. Notez que :
seules les vues présentant des champs fonctionneront dans ce cadre
ceci effacera les paramètres de \"Types de contenus\" figurant ci-dessus. Utilisez à la place la section \"filtres\" de la vue ;
utilisez la section \"champs\" de la vue pour afficher des informations supplémentaires sur les nœuds candidats dans le formulaire de création/édition de nœud ;
utilisez la section \"critère de tri\" de la vue pour déterminer l'ordre d'affichage des nœuds candidats.
"
+
+#: modules/nodereference/nodereference.module:121
+msgid "View arguments"
+msgstr "Arguments de la vue"
+
+#: modules/nodereference/nodereference.module:124
+msgid "Provide a comma separated list of arguments to pass to the view."
+msgstr "Fournit une liste d'arguments, séparés par des virgules, à transmettre à la vue."
+
+#: modules/nodereference/nodereference.module:175
+msgid "%name: This post can't be referenced."
+msgstr "Champ '%name' : cette publication ne peut être référencée."
+
+#: modules/nodereference/nodereference.module:200
+msgid "Title (link)"
+msgstr "Titre (avec lien)"
+
+#: modules/nodereference/nodereference.module:205
+msgid "Title (no link)"
+msgstr "Titre (sans lien)"
+
+#: modules/nodereference/nodereference.module:518
+msgid "%name: Title mismatch. Please check your selection."
+msgstr "Champ '%name' : incohérence au niveau du titre. Merci de vérifier votre sélection."
+
+#: modules/nodereference/nodereference.module:15
+msgid "Nodereference autocomplete"
+msgstr "Auto-complètement de la référence de nœud"
+
+#: modules/nodereference/nodereference.module:0
+msgid "nodereference"
+msgstr "nodereference"
+
+#: modules/nodereference/nodereference.info:0
+msgid "Node Reference"
+msgstr "Node Reference"
+
+#: modules/nodereference/nodereference.info:0
+msgid "Defines a field type for referencing one node from another."
+msgstr "Définit un type de champ qui permet d'établir des liens entre les nœuds."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.hu.po
new file mode 100644
index 00000000000..17625b2569b
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.hu.po
@@ -0,0 +1,123 @@
+# Hungarian translation of cck (6.x-2.0-rc10)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens
+# nodereference.module,v 1.138.2.38 2008/10/06 15:11:39 karens
+# nodereference.info,v 1.8 2008/04/23 18:02:07 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cck (6.x-2.0-rc10)\n"
+"POT-Creation-Date: 2008-10-31 12:16-0500\n"
+"PO-Revision-Date: 2008-10-26 16:40-0500\n"
+"Last-Translator: Balogh Zoltán\n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: modules/nodereference/nodereference.rules.inc:15
+msgid "Load a referenced node"
+msgstr "Egy hivatkozott tartalom betöltése"
+
+#: modules/nodereference/nodereference.rules.inc:19
+msgid "Content containing the node reference field"
+msgstr "A tartalom, amely a hivatkozó mezőt tartalmazza"
+
+#: modules/nodereference/nodereference.rules.inc:25
+msgid "Referenced content"
+msgstr "Hivatkozott tartalom"
+
+#: modules/nodereference/nodereference.rules.inc:29
+msgid ""
+"Note that if the field has multiple values, only the first content "
+"node will be loaded."
+msgstr ""
+"Megjegyzés: Ha a mezőnek több értéke is lehet, akkor csak az "
+"első tartalom fog betöltődni."
+
+#: modules/nodereference/nodereference.rules.inc:50
+msgid "There are no nodereference fields defined."
+msgstr "Nincsenek tartalomra hivatkozó mezők meghatározva."
+
+#: modules/nodereference/nodereference.module:68
+msgid "Node reference"
+msgstr "Tartalomra hivatkozás"
+
+#: modules/nodereference/nodereference.module:69
+msgid "Store the ID of a related node as an integer value."
+msgstr "A hivatkozott tartalom azonosítójának tárolása egész számként."
+
+#: modules/nodereference/nodereference.module:87
+msgid "Content types that can be referenced"
+msgstr "Tartalomtípusok, melyekre hivatkozni lehet"
+
+#: modules/nodereference/nodereference.module:110
+msgid "Advanced - Nodes that can be referenced (View)"
+msgstr "Haladó - tartalmak, melyekre hivatkozni lehet (Nézet)"
+
+#: modules/nodereference/nodereference.module:116
+msgid "View used to select the nodes"
+msgstr "Nézet használata a tartalmak kiválasztásához"
+
+#: modules/nodereference/nodereference.module:119
+msgid ""
+"Choose the \"Views module\" view that selects the nodes that can be "
+"referenced. Note:
Only views that have fields will work "
+"for this purpose.
This will discard the \"Content types\" "
+"settings above. Use the view's \"filters\" section "
+"instead.
Use the view's \"fields\" section to display "
+"additional informations about candidate nodes on node creation/edition "
+"form.
Use the view's \"sort criteria\" section to determine "
+"the order in which candidate nodes will be displayed.
"
+msgstr ""
+"A „Nézet modul” egyik nézetének kiválasztása, mely azokat a "
+"tartalmakat mutatja, melyekre hivatkozni "
+"lehet. Megjegyzés:
Itt csak olyan nézet működik, melynek "
+"vannak mezői.
Ez felülírja a fenti „Tartalomtípusok” "
+"beállítást. A nézet „szűrő” feltétele használható e "
+"helyett.
A nézet „mezők” része használható arra, hogy "
+"bővebb információkat jelenítsen meg a lehetséges tartalmakról a "
+"szerkesztő űrlapon.
A nézet „sorrend” része "
+"befolyásolja a lehetséges tartalmak megjelenítési "
+"sorrendjét.
"
+
+#: modules/nodereference/nodereference.module:199
+msgid "%name: this post can't be referenced."
+msgstr "%name: erre a tartalomra nem lehet hivatkozni."
+
+#: modules/nodereference/nodereference.module:224
+msgid "Title (link)"
+msgstr "Cím (hivatkozással)"
+
+#: modules/nodereference/nodereference.module:229
+msgid "Title (no link)"
+msgstr "Cím (hivatkozás nélkül)"
+
+#: modules/nodereference/nodereference.module:624
+msgid "%name: title mismatch. Please check your selection."
+msgstr "%name: a cím nem egyezik."
+
+#: modules/nodereference/nodereference.module:631
+msgid "%name: found no valid post with that title."
+msgstr "%name: nincs érvényes tartalom ezzel a címmel."
+
+#: modules/nodereference/nodereference.module:15
+msgid "Nodereference autocomplete"
+msgstr "Automatikusan kiegészülő tartalomhivatkozás"
+
+#: modules/nodereference/nodereference.module:0
+msgid "nodereference"
+msgstr "tartalomhivatozás"
+
+#: modules/nodereference/nodereference.info:0
+msgid "Node Reference"
+msgstr "Tartalomra hivatkozás"
+
+#: modules/nodereference/nodereference.info:0
+msgid "Defines a field type for referencing one node from another."
+msgstr ""
+"Olyan mezőtípust ad, amely a tartalomban egy másik tartalomra "
+"hivatkozik."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.nl.po
new file mode 100644
index 00000000000..514ff86fa5e
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.nl.po
@@ -0,0 +1,193 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens
+# nodereference.module,v 1.138.2.50 2009/03/18 21:00:58 yched
+# nodereference.info,v 1.8 2008/04/23 18:02:07 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:25+0200\n"
+"PO-Revision-Date: 2009-06-03 14:25+0200\n"
+"Last-Translator: NAME \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: nodereference.rules.inc:15
+msgid "Load a referenced node"
+msgstr "Laad een gerefereerde node"
+
+#: nodereference.rules.inc:19
+msgid "Content containing the node reference field"
+msgstr "Inhoud met het nodereferentieveld"
+
+#: nodereference.rules.inc:25
+msgid "Referenced content"
+msgstr "Gerefereerde inhoud"
+
+#: nodereference.rules.inc:29
+msgid "Note that if the field has multiple values, only the first content node will be loaded."
+msgstr ""
+"Merk op dat als het veld meerdere waardes heeft, alleen de eerste "
+"inhoudnode zal worden geladen."
+
+#: nodereference.rules.inc:45
+msgid "Field"
+msgstr "Veld"
+
+#: nodereference.rules.inc:50
+msgid "There are no nodereference fields defined."
+msgstr "Er zijn geen nodereferentie velden."
+
+#: nodereference.module:60
+msgid "Node reference"
+msgstr "Nodereferentie"
+
+#: nodereference.module:61
+msgid "Store the ID of a related node as an integer value."
+msgstr "Bewaar de ID van een gerelateerde node als een integer-waarde."
+
+#: nodereference.module:75
+msgid "Content types that can be referenced"
+msgstr "Inhoudstypes waarnaar een referentie geplaatst kan worden"
+
+#: nodereference.module:87
+msgid "Default Views"
+msgstr "Standaard views"
+
+#: nodereference.module:90
+msgid "Existing Views"
+msgstr "Bestaande Views"
+
+#: nodereference.module:97
+msgid "Advanced - Nodes that can be referenced (View)"
+msgstr "Geavanceerd - Nodes die kunnen worden gerefereerd (View)"
+
+#: nodereference.module:104
+msgid "View used to select the nodes"
+msgstr "View die gebruikt wordt voor het selecteren van nodes"
+
+#: nodereference.module:107
+msgid "
Choose the \"Views module\" view that selects the nodes that can be referenced. Note:
"
+msgstr ""
+"
Kies de \"Views module\"-view die selecteert welke nodes kunnen "
+"worden gerefereerd. Merk op:
"
+
+#: nodereference.module:108;121
+msgid "
Only views that have fields will work for this purpose.
This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.
Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.
Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.
"
+msgstr ""
+"
Alleen Views met velden zullen werken voor dit "
+"doel.
Dit zal de \"Inhoudstypes-\"-instellingen boven "
+"negeren. Gebruik anders de view z'n \"filters\" "
+"sectie.
Gebruik de view z'n \"velden\"-sectie om extra "
+"informatie over gebruikers op het bewerkformulier weer te "
+"geven.
Gebruik de view z'n \"sorteercriteria\"-sectie om de "
+"volgorde te bepalen waarin gebruikers worden weergegeven.
"
+
+#: nodereference.module:112
+msgid "View arguments"
+msgstr "Bekijk argumenten"
+
+#: nodereference.module:115
+msgid "Provide a comma separated list of arguments to pass to the view."
+msgstr ""
+"Geef een door komma's gescheiden lijst met argumenten op om naar de "
+"view te sturen."
+
+#: nodereference.module:120
+msgid "
The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. Note:
"
+msgstr ""
+"
De lijst met nodes die kunnen worden gerefereerd, gebaseerd op een "
+"\"Views module\"-view, maar geen passende views gevonden. Merk "
+"op:
"
+
+#: nodereference.module:205
+msgid "%name: invalid input."
+msgstr "%name: geen toegestane waarde."
+
+#: nodereference.module:217
+msgid "%name: this post can't be referenced."
+msgstr "%name: dit bericht kan niet worden gerefereerd."
+
+#: nodereference.module:242
+msgid "Title (link)"
+msgstr "Titel (link)"
+
+#: nodereference.module:247
+msgid "Title (no link)"
+msgstr "Titel (geen link)"
+
+#: nodereference.module:252
+msgid "Full node"
+msgstr "Volledige node"
+
+#: nodereference.module:257
+msgid "Teaser"
+msgstr "Voorbeeldweergave"
+
+#: nodereference.module:347
+msgid "Select list"
+msgstr "Selectielijst"
+
+#: nodereference.module:355
+msgid "Check boxes/radio buttons"
+msgstr "Vinkje/radio buttons"
+
+#: nodereference.module:363
+msgid "Autocomplete text field"
+msgstr "Automatisch aanvullend tekstveld"
+
+#: nodereference.module:417
+msgid "Autocomplete matching"
+msgstr "Automatisch aanvullende overeenkomst"
+
+#: nodereference.module:420
+msgid "Starts with"
+msgstr "Begint met"
+
+#: nodereference.module:421
+msgid "Contains"
+msgstr "Bevat"
+
+#: nodereference.module:423
+msgid "Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of nodes."
+msgstr ""
+"Selecteer de methode die wordt gebruikt om automatisch aangevulde "
+"suggesties te geven. Merk op Bevat prestatieproblemen kan "
+"veroorzaken op sites met vele duizenden gebruikers."
+
+#: nodereference.module:671
+msgid "%name: title mismatch. Please check your selection."
+msgstr "%name: titel niet gevonden. Controleer je selectie."
+
+#: nodereference.module:678
+msgid "%name: found no valid post with that title."
+msgstr "%name: geen bericht gevonden met die titel."
+
+#: nodereference.module:15
+msgid "Nodereference autocomplete"
+msgstr "Nodereferentie automatisch aanvullen"
+
+#: nodereference.module:0
+msgid "nodereference"
+msgstr "nodereferentie"
+
+#: nodereference.info:0
+msgid "Node Reference"
+msgstr "Nodereferentie"
+
+#: nodereference.info:0
+msgid "Defines a field type for referencing one node from another."
+msgstr "Levert een veldtype for het refereren van een node naar een ander."
+
+#: nodereference.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.pot
new file mode 100644
index 00000000000..cc8eeb93230
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.pot
@@ -0,0 +1,114 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-nodereference)
+# Copyright YEAR NAME
+# Generated from files:
+# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens
+# nodereference.module,v 1.138.2.55 2009/06/02 12:24:04 yched
+# nodereference.info,v 1.8 2008/04/23 18:02:07 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/nodereference/nodereference.rules.inc:15
+msgid "Load a referenced node"
+msgstr ""
+
+#: modules/nodereference/nodereference.rules.inc:19
+msgid "Content containing the node reference field"
+msgstr ""
+
+#: modules/nodereference/nodereference.rules.inc:25
+msgid "Referenced content"
+msgstr ""
+
+#: modules/nodereference/nodereference.rules.inc:29
+msgid "Note that if the field has multiple values, only the first content node will be loaded."
+msgstr ""
+
+#: modules/nodereference/nodereference.rules.inc:50
+msgid "There are no nodereference fields defined."
+msgstr ""
+
+#: modules/nodereference/nodereference.module:69
+msgid "Node reference"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:70
+msgid "Store the ID of a related node as an integer value."
+msgstr ""
+
+#: modules/nodereference/nodereference.module:85
+msgid "Content types that can be referenced"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:107
+msgid "Advanced - Nodes that can be referenced (View)"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:114
+msgid "View used to select the nodes"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:117
+msgid "
Choose the \"Views module\" view that selects the nodes that can be referenced. Note:
The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. Note:
"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:228
+msgid "%name: this post can't be referenced."
+msgstr ""
+
+#: modules/nodereference/nodereference.module:253
+msgid "Title (link)"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:258
+msgid "Title (no link)"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:435
+msgid "Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of nodes."
+msgstr ""
+
+#: modules/nodereference/nodereference.module:691
+msgid "%name: title mismatch. Please check your selection."
+msgstr ""
+
+#: modules/nodereference/nodereference.module:698
+msgid "%name: found no valid post with that title."
+msgstr ""
+
+#: modules/nodereference/nodereference.module:15
+msgid "Nodereference autocomplete"
+msgstr ""
+
+#: modules/nodereference/nodereference.module:0
+msgid "nodereference"
+msgstr ""
+
+#: modules/nodereference/nodereference.info:0
+msgid "Node Reference"
+msgstr ""
+
+#: modules/nodereference/nodereference.info:0
+msgid "Defines a field type for referencing one node from another."
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.sv.po
new file mode 100644
index 00000000000..53722637f6a
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/nodereference/translations/modules-nodereference.sv.po
@@ -0,0 +1,179 @@
+# $Id$
+#
+# Swedish translation of Drupal (nodereference)
+# Generated from files:
+# nodereference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens
+# nodereference.module,v 1.138.2.54 2009/04/29 20:51:53 karens
+# nodereference.info,v 1.8 2008/04/23 18:02:07 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CCK - Nodereference 6.x\n"
+"POT-Creation-Date: 2009-05-27 13:40+0200\n"
+"PO-Revision-Date: 2009-05-27 14:40+0100\n"
+"Last-Translator: Magnus Gunnarsson \n"
+"Language-Team: drupalsverige.se\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: Swedish\n"
+"X-Poedit-Country: SWEDEN\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: nodereference.rules.inc:15
+msgid "Load a referenced node"
+msgstr "Ladda en hänvisad nod"
+
+#: nodereference.rules.inc:19
+msgid "Content containing the node reference field"
+msgstr "Innehåll som innehåller det hänvisade nodfältet"
+
+#: nodereference.rules.inc:25
+msgid "Referenced content"
+msgstr "Hänvisat innehåll"
+
+#: nodereference.rules.inc:29
+msgid "Note that if the field has multiple values, only the first content node will be loaded."
+msgstr "Observera att om fält har flera värden, så kommer enbart den första innehållsnoden att laddas."
+
+#: nodereference.rules.inc:45
+msgid "Field"
+msgstr "Fält"
+
+#: nodereference.rules.inc:50
+msgid "There are no nodereference fields defined."
+msgstr "Det finns inga hänvisade nodfält definierade."
+
+#: nodereference.module:60
+msgid "Node reference"
+msgstr "Hänvisad nod"
+
+#: nodereference.module:61
+msgid "Store the ID of a related node as an integer value."
+msgstr "Lagra ID för en relaterad nod som ett heltalsvärde."
+
+#: nodereference.module:76
+msgid "Content types that can be referenced"
+msgstr "Innehållstyper som kan hänvisas"
+
+#: nodereference.module:88
+msgid "Default Views"
+msgstr "Förvald vy"
+
+#: nodereference.module:91
+msgid "Existing Views"
+msgstr "Existerande vyer"
+
+#: nodereference.module:98
+msgid "Advanced - Nodes that can be referenced (View)"
+msgstr "Avancerat - Noder som kan hänvisas (Vyer)"
+
+#: nodereference.module:105
+msgid "View used to select the nodes"
+msgstr "Vy som används för att välja noder"
+
+#: nodereference.module:108
+msgid "
Choose the \"Views module\" view that selects the nodes that can be referenced. Note:
"
+msgstr "
Välj \"modulen Views\" vy som väljer noden som kan hänvisas. Observera:
"
+
+#: nodereference.module:109;122
+msgid "
Only views that have fields will work for this purpose.
This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.
Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.
Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.
"
+msgstr "
Enbart vyer som har fält kommer att fungera för detta ändamål.
Detta kommer att bryta mot inställningarna för \"Innehållstyper\" ovan. Använd vyns \"filtrering\" istället.
Använd vyns \"fält\" för att visa ytterligare information om kandiderande noder på formuläret för att skapa/redigera nod
Använd vyns \"sorteringskriterier\" för att bestämma ordningen på vilken de kandiderande noder kommer att visas
"
+
+#: nodereference.module:113
+msgid "View arguments"
+msgstr "Argument för vy"
+
+#: nodereference.module:116
+msgid "Provide a comma separated list of arguments to pass to the view."
+msgstr "Tillhandahåll en kommaseparerad lista av argument att skicka till vyn."
+
+#: nodereference.module:121
+msgid "
The list of nodes that can be referenced can be based on a \"Views module\" view but no appropriate views were found. Note:
"
+msgstr "
Listan av noder som kan hänvisas kan baseras på en vy från \"modulen Views\", men inga lämpliga vyer hittades. Observera
"
+
+#: nodereference.module:207
+msgid "%name: invalid input."
+msgstr "%name: ogiltig inmatning."
+
+#: nodereference.module:219
+msgid "%name: this post can't be referenced."
+msgstr "%name: denna post kan inte hänvisas."
+
+#: nodereference.module:244
+msgid "Title (link)"
+msgstr "Titel (länk)"
+
+#: nodereference.module:249
+msgid "Title (no link)"
+msgstr "Titel (ingen länk)"
+
+#: nodereference.module:254
+msgid "Full node"
+msgstr "Fullständig nod"
+
+#: nodereference.module:259
+msgid "Teaser"
+msgstr "Förhandstitt"
+
+#: nodereference.module:349
+msgid "Select list"
+msgstr "Listval"
+
+#: nodereference.module:357
+msgid "Check boxes/radio buttons"
+msgstr "Kryssrutor/radioknappar"
+
+#: nodereference.module:365
+msgid "Autocomplete text field"
+msgstr "Automatiskt kompletterande textfält"
+
+#: nodereference.module:420
+msgid "Autocomplete matching"
+msgstr "Automatiskt kompletterande som överensstämmer"
+
+#: nodereference.module:423
+msgid "Starts with"
+msgstr "Börjar med"
+
+#: nodereference.module:424
+msgid "Contains"
+msgstr "Innehåller"
+
+#: nodereference.module:426
+msgid "Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of nodes."
+msgstr "Välj metod att använda för att samla in automatiskt kompletterande förslag. Observera att Innehåller kan orsaka prestandaproblem med webbplatser som har tusentals noder."
+
+#: nodereference.module:430
+msgid "Size of textfield"
+msgstr "Storlek på textfält"
+
+#: nodereference.module:682
+msgid "%name: title mismatch. Please check your selection."
+msgstr "%name: titel stämmer inte. Var vänlig kontrollera ditt urval."
+
+#: nodereference.module:689
+msgid "%name: found no valid post with that title."
+msgstr "%name: hittade ingen giltig post med denna titel."
+
+#: nodereference.module:15
+msgid "Nodereference autocomplete"
+msgstr "Automatiskt kompletterande nodhänvisning"
+
+#: nodereference.module:0
+msgid "nodereference"
+msgstr "nodereference"
+
+#: nodereference.info:0
+msgid "Node Reference"
+msgstr "Hänvisning av nod"
+
+#: nodereference.info:0
+msgid "Defines a field type for referencing one node from another."
+msgstr "Definierar en fälttyp för att hänvisa en nod till en annan."
+
+#: nodereference.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.help.ini
new file mode 100644
index 00000000000..205c2259cc1
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.help.ini
@@ -0,0 +1,8 @@
+; $Id$
+
+[advanced help settings]
+hide = TRUE
+
+[number]
+title = Number field
+parent = content%fields
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.html
new file mode 100644
index 00000000000..8725d75b442
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/help/number.html
@@ -0,0 +1,2 @@
+
The Number field stores numeric data in the database. It can either be an integer value, a decimal value, or a float value.
+
The Number field provides a place for the administrator to create a list of 'Allowed values' for the field. When used with Optionwidgets, the allowed values are presented to the end user in a drop-down select list, checkboxes, or radios.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.info
new file mode 100644
index 00000000000..4b00d32cb6e
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.info
@@ -0,0 +1,12 @@
+; $Id$
+name = Number
+description = Defines numeric field types.
+dependencies[] = content
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.install
new file mode 100644
index 00000000000..f9e794ec26b
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/number.install
@@ -0,0 +1,60 @@
+ array('arguments' => array('element' => NULL)),
+ 'number_formatter_default' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_us_0' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_us_1' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_us_2' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_be_0' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_be_1' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_be_2' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_fr_0' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_fr_1' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_fr_2' => array('arguments' => array('element' => NULL), 'function' => 'theme_number_formatter_generic'),
+ 'number_formatter_unformatted' => array('arguments' => array('element' => NULL)),
+ );
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function number_field_info() {
+ return array(
+ 'number_integer' => array(
+ 'label' => t('Integer'),
+ 'description' => t('Store a number in the database as an integer.'),
+// 'content_icon' => 'icon_content_number.png',
+ ),
+ 'number_decimal' => array(
+ 'label' => t('Decimal'),
+ 'description' => t('Store a number in the database in a fixed decimal format.'),
+// 'content_icon' => 'icon_content_number.png',
+ ),
+ 'number_float' => array(
+ 'label' => t('Float'),
+ 'description' => t('Store a number in the database in a floating point format.'),
+// 'content_icon' => 'icon_content_number.png',
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_field_settings().
+ */
+function number_field_settings($op, $field) {
+ switch ($op) {
+ case 'form':
+ $form = array();
+ $form['min'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Minimum'),
+ '#element_validate' => array('_element_validate_number'),
+ '#default_value' => is_numeric($field['min']) ? $field['min'] : '',
+ );
+ $form['max'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Maximum'),
+ '#element_validate' => array('_element_validate_number'),
+ '#default_value' => is_numeric($field['max']) ? $field['max'] : '',
+ );
+ if ($field['type'] == 'number_decimal') {
+ $form['precision'] = array(
+ '#type' => 'select',
+ '#options' => drupal_map_assoc(range(10, 32)),
+ '#title' => t('Precision'),
+ '#description' => t('The total number of digits to store in the database, including those to the right of the decimal.'),
+ '#default_value' => is_numeric($field['precision']) ? $field['precision'] : 10,
+ );
+ $form['scale'] = array(
+ '#type' => 'select',
+ '#options' => drupal_map_assoc(range(0, 10)),
+ '#title' => t('Scale'),
+ '#description' => t('The number of digits to the right of the decimal.'),
+ '#default_value' => is_numeric($field['scale']) ? $field['scale'] : 2,
+ );
+ $form['decimal'] = array(
+ '#type' => 'select',
+ '#options' => array('.' => 'decimal point', ',' => 'comma', ' ' => 'space'),
+ '#title' => t('Decimal marker'),
+ '#description' => t('The character users will input to mark the decimal point in forms.'),
+ '#default_value' => !empty($field['decimal']) ? $field['decimal'] : '.',
+ );
+ }
+ $form['append']['prefix'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Prefix'),
+ '#size' => 60,
+ '#default_value' => !empty($field['prefix']) ? $field['prefix'] : '',
+ '#description' => t('Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds).'),
+ );
+ $form['append']['suffix'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Suffix'),
+ '#size' => 60,
+ '#default_value' => !empty($field['suffix']) ? $field['suffix'] : '',
+ '#description' => t('Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds).'),
+ );
+ $form['allowed_values_fieldset'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Allowed values'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ );
+ $form['allowed_values_fieldset']['allowed_values'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Allowed values list'),
+ '#default_value' => !empty($field['allowed_values']) ? $field['allowed_values'] : '',
+ '#required' => FALSE,
+ '#rows' => 10,
+ '#description' => t('The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified. Allowed HTML tags: @tags', array('%type' => $field['type'], '@tags' => _content_filter_xss_display_allowed_tags())),
+ );
+ $form['allowed_values_fieldset']['advanced_options'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('PHP code'),
+ '#collapsible' => TRUE,
+ '#collapsed' => empty($field['allowed_values_php']),
+ );
+ if (user_access('Use PHP input for field settings (dangerous - grant with care)')) {
+ $form['allowed_values_fieldset']['advanced_options']['allowed_values_php'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Code'),
+ '#default_value' => !empty($field['allowed_values_php']) ? $field['allowed_values_php'] : '',
+ '#rows' => 6,
+ '#description' => t('Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above.'),
+ );
+ }
+ else {
+ $form['allowed_values_fieldset']['advanced_options']['markup_allowed_values_php'] = array(
+ '#type' => 'item',
+ '#title' => t('Code'),
+ '#value' => !empty($field['allowed_values_php']) ? ''. check_plain($field['allowed_values_php']) .'' : t('<none>'),
+ '#description' => empty($field['allowed_values_php']) ? t("You're not allowed to input PHP code.") : t('This PHP code was set by an administrator and will override the allowed values list above.'),
+ );
+ }
+ return $form;
+
+ case 'save':
+ $values = array('prefix', 'suffix', 'min', 'max', 'allowed_values', 'allowed_values_php');
+ if ($field['type'] == 'number_decimal') {
+ $values = array_merge($values, array('precision', 'scale', 'decimal'));
+ }
+ return $values;
+
+ case 'database columns':
+ if ($field['type'] == 'number_integer') {
+ return array(
+ 'value' => array('type' => 'int', 'not null' => FALSE, 'sortable' => TRUE),
+ );
+ }
+ if ($field['type'] == 'number_float') {
+ return array(
+ 'value' => array('type' => 'float', 'not null' => FALSE, 'sortable' => TRUE),
+ );
+ }
+ if ($field['type'] == 'number_decimal') {
+ $precision = isset($field['precision']) ? $field['precision'] : 10;
+ $scale = isset($field['scale']) ? $field['scale'] : 2;
+ return array(
+ 'value' => array('type' => 'numeric', 'precision' => $precision, 'scale' => $scale, 'not null' => FALSE, 'sortable' => TRUE),
+ );
+ }
+
+ case 'views data':
+ $allowed_values = content_allowed_values($field);
+ if (count($allowed_values)) {
+ $data = content_views_field_views_data($field);
+ $db_info = content_database_info($field);
+ $table_alias = content_views_tablename($field);
+
+ // Filter: Add a 'many to one' filter.
+ $copy = $data[$table_alias][$field['field_name'] .'_value'];
+ $copy['title'] = t('@label (!name) - Allowed values', array('@label' => t($field['widget']['label']), '!name' => $field['field_name']));
+ $copy['filter']['handler'] = 'content_handler_filter_many_to_one';
+ $copy['filter']['numeric'] = TRUE;
+ unset($copy['field'], $copy['argument'], $copy['sort']);
+ $data[$table_alias][$field['field_name'] .'_value_many_to_one'] = $copy;
+ // Argument: swap the handler to the 'many to one' operator
+ $data[$table_alias][$field['field_name'] .'_value']['argument']['handler'] = 'content_handler_argument_many_to_one';
+ $data[$table_alias][$field['field_name'] .'_value']['argument']['numeric'] = TRUE;
+ return $data;
+ }
+ break;
+ }
+}
+
+function _number_widget_settings_min_validate($element, &$form_state) {
+ $value = $form_state['values']['min'];
+ if ($value && !is_numeric($value)) {
+ form_set_error('min', t('"Minimum" must be a number.'));
+ }
+}
+
+function _number_widget_settings_max_validate($element, &$form_state) {
+ $value = $form_state['values']['max'];
+ if ($value && !is_numeric($value)) {
+ form_set_error('max', t('"Maximum" must be a number.'));
+ }
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function number_field($op, &$node, $field, &$items, $teaser, $page) {
+ switch ($op) {
+ case 'validate':
+ $allowed_values = content_allowed_values($field);
+ if (is_array($items)) {
+ foreach ($items as $delta => $item) {
+ $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
+ if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']);
+ if ($item['value'] != '') {
+ if (is_numeric($field['min']) && $item['value'] < $field['min']) {
+ form_set_error($error_element, t('%name: the value may be no smaller than %min.', array('%name' => t($field['widget']['label']), '%min' => $field['min'])));
+ }
+ if (is_numeric($field['max']) && $item['value'] > $field['max']) {
+ form_set_error($error_element, t('%name: the value may be no larger than %max.', array('%name' => t($field['widget']['label']), '%max' => $field['max'])));
+ }
+ if (count($allowed_values)) {
+ // We cannot use array_key_exists() because allowed values are
+ // stored as strings, and we need to compare numeric equality.
+ $valid = FALSE;
+ foreach ($allowed_values as $kay => $value) {
+ if ((float) $item['value'] == (float) $kay) {
+ $valid = TRUE;
+ break;
+ }
+ }
+ if (!$valid) {
+ form_set_error($error_element, t('%name: illegal value.', array('%name' => t($field['widget']['label']))));
+ }
+ }
+ }
+ }
+ }
+ return $items;
+ }
+}
+
+/**
+ * Implementation of hook_content_is_empty().
+ */
+function number_content_is_empty($item, $field) {
+ if (empty($item['value']) && (string)$item['value'] !== '0') {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of hook_field_formatter_info().
+ */
+function number_field_formatter_info() {
+ return array(
+ 'default' => array('label' => '9999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')),
+ 'us_0' => array('label' => '9,999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')),
+ 'us_1' => array('label' => '9,999.9', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')),
+ 'us_2' => array('label' => '9,999.99', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')),
+ 'be_0' => array('label' => '9.999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')),
+ 'be_1' => array('label' => '9.999,9', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')),
+ 'be_2' => array('label' => '9.999,99', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')),
+ 'fr_0' => array('label' => '9 999', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')),
+ 'fr_1' => array('label' => '9 999, 9', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')),
+ 'fr_2' => array('label' => '9 999, 99', 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_decimal', 'number_float')),
+ 'unformatted' => array('label' => t('unformatted'), 'multiple values' => CONTENT_HANDLE_CORE, 'field types' => array('number_integer', 'number_decimal', 'number_float')),
+ );
+}
+
+/**
+ * Proxy theme function for 'unformatted' number field formatter.
+ */
+function theme_number_formatter_unformatted($element) {
+ return $element['#item']['value'];
+}
+
+/**
+ * Proxy theme function for number field formatters.
+ */
+function theme_number_formatter_generic($element) {
+ $field = content_fields($element['#field_name'], $element['#type_name']);
+ $value = $element['#item']['value'];
+
+ if (($allowed_values = content_allowed_values($field))) {
+ if (isset($allowed_values[$value]) && $allowed_values[$value] != $value) {
+ return $allowed_values[$value];
+ }
+ }
+
+ if (empty($value) && $value !== '0') {
+ return '';
+ }
+
+ switch ($element['#formatter']) {
+ case 'us_0':
+ $output = number_format($value, 0, '.', ',');
+ break;
+ case 'us_1':
+ $output = number_format($value, 1, '.', ',');
+ break;
+ case 'us_2':
+ $output = number_format($value, 2, '.', ',');
+ break;
+ case 'be_0':
+ $output = number_format($value, 0, ',', '.');
+ break;
+ case 'be_1':
+ $output = number_format($value, 1, ',', '.');
+ break;
+ case 'be_2':
+ $output = number_format($value, 2, ',', '.');
+ break;
+ case 'fr_0':
+ $output = number_format($value, 0, ', ', ' ');
+ break;
+ case 'fr_1':
+ $output = number_format($value, 1, ', ', ' ');
+ break;
+ case 'fr_2':
+ $output = number_format($value, 2, ', ', ' ');
+ break;
+ default:
+ $output = $value;
+ break;
+ }
+
+ $prefixes = isset($field['prefix']) ? array_map('content_filter_xss', explode('|', $field['prefix'])) : array('');
+ $suffixes = isset($field['suffix']) ? array_map('content_filter_xss', explode('|', $field['suffix'])) : array('');
+ $prefix = (count($prefixes) > 1) ? format_plural($value, $prefixes[0], $prefixes[1]) : $prefixes[0];
+ $suffix = (count($suffixes) > 1) ? format_plural($value, $suffixes[0], $suffixes[1]) : $suffixes[0];
+
+ return $prefix . $output . $suffix;
+}
+
+/**
+ * Implementation of hook_widget_info().
+ *
+ * Here we indicate that the content module will handle
+ * the default value and multiple values for these widgets.
+ *
+ * Callbacks can be omitted if default handing is used.
+ * They're included here just so this module can be used
+ * as an example for custom modules that might do things
+ * differently.
+ */
+function number_widget_info() {
+ return array(
+ 'number' => array(
+ 'label' => t('Text field'),
+ 'field types' => array('number_integer', 'number_decimal', 'number_float'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ );
+}
+
+/**
+ * Implementation of FAPI hook_elements().
+ *
+ * Any FAPI callbacks needed for individual widgets can be declared here,
+ * and the element will be passed to those callbacks for processing.
+ *
+ * Drupal will automatically theme the element using a theme with
+ * the same name as the hook_elements key.
+ *
+ * Includes a regex to check for valid values as an additional parameter
+ * the validator can use. The regex can be overridden if necessary.
+ */
+function number_elements() {
+ return array(
+ 'number' => array(
+ '#input' => TRUE,
+ '#columns' => array('value'), '#delta' => 0,
+ '#process' => array('number_process'),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_widget().
+ *
+ * Attach a single form element to the form. It will be built out and
+ * validated in the callback(s) listed in hook_elements. We build it
+ * out in the callbacks rather than here in hook_widget so it can be
+ * plugged into any module that can provide it with valid
+ * $field information.
+ *
+ * Content module will set the weight, field name and delta values
+ * for each form element. This is a change from earlier CCK versions
+ * where the widget managed its own multiple values.
+ *
+ * If there are multiple values for this field, the content module will
+ * call this function as many times as needed.
+ *
+ * @param $form
+ * the entire form array, $form['#node'] holds node information
+ * @param $form_state
+ * the form_state, $form_state['values'][$field['field_name']]
+ * holds the field's form values.
+ * @param $field
+ * the field array
+ * @param $items
+ * array of default values for this field
+ * @param $delta
+ * the order of this item in the array of subelements (0, 1, 2, etc)
+ *
+ * @return
+ * the form item for a single element for this field
+ */
+function number_widget(&$form, &$form_state, $field, $items, $delta = 0) {
+ $element = array(
+ '#type' => $field['widget']['type'],
+ '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL,
+ );
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function number_process($element, $edit, $form_state, $form) {
+ $field_name = $element['#field_name'];
+ $field = $form['#field_info'][$field_name];
+ $field_key = $element['#columns'][0];
+
+ $value = isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : '';
+ $value = isset($field['decimal']) ? str_replace('.', $field['decimal'], $value) : $value;
+ $element[$field_key] = array(
+ '#type' => 'textfield',
+ '#default_value' => $value,
+ // Need to allow a slightly larger size that the field length to allow
+ // for some configurations where all characters won't fit in input field.
+ '#size' => isset($field['precision']) ? $field['precision'] + 2 : 12,
+ '#maxlength' => isset($field['precision']) ? $field['precision'] : 10,
+ '#attributes' => array('class' => 'number'),
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#description' => $element['#description'],
+ '#required' => $element['#required'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+
+ $prefixes = array();
+ $suffixes = array();
+
+ // Make sure we don't wipe out element validation added elsewhere.
+ if (empty($element['#element_validate'])) {
+ $element['#element_validate'] = array();
+ }
+ if (!empty($field['prefix'])) {
+ $prefixes = explode('|', $field['prefix']);
+ $element[$field_key]['#field_prefix'] = content_filter_xss(array_pop($prefixes));
+ }
+ if (!empty($field['suffix'])) {
+ $suffixes = explode('|', $field['suffix']);
+ $element[$field_key]['#field_suffix'] = content_filter_xss(array_pop($suffixes));
+ }
+ switch ($field['type']) {
+ case 'number_float':
+ $element['#element_validate'][] = 'number_float_validate';
+ break;
+ case 'number_integer':
+ $element['#element_validate'][] = 'number_integer_validate';
+ break;
+ case 'number_decimal':
+ $element['#element_validate'][] = 'number_decimal_validate';
+ $element['#decimal'] = isset($field['decimal']) ? $field['decimal'] : '.';
+ $element['#precision'] = isset($field['precision']) ? $field['precision'] : 10;
+ $element['#scale'] = isset($field['scale']) ? $field['scale'] : 2;
+ break;
+ }
+
+ // Used so that hook_field('validate') knows where to flag an error.
+ $element['_error_element'] = array(
+ '#type' => 'value',
+ '#value' => implode('][', array_merge($element['#parents'], array($field_key))),
+ );
+
+ return $element;
+}
+
+/**
+ * FAPI validation of an individual float element.
+ */
+function number_float_validate($element, &$form_state) {
+ $field_name = $element['#field_name'];
+ $type_name = $element['#type_name'];
+ $field = content_fields($field_name, $type_name);
+ $field_key = $element['#columns'][0];
+ $value = $element['#value'][$field_key];
+
+ if (($element[$field_key]['#required'] || !empty($value))) {
+ $start = $value;
+ $value = preg_replace('@[^-0-9\.]@', '', $value);
+ if ($start != $value) {
+ $error_field = implode('][', $element['#parents']) .']['. $field_key;
+ form_set_error($error_field, t('Only numbers and decimals are allowed in %field.', array('%field' => t($field['widget']['label']))));
+ }
+ else {
+ form_set_value($element[$field_key], $value, $form_state);
+ }
+ }
+}
+
+/**
+ * FAPI validation of an individual integer element.
+ */
+function number_integer_validate($element, &$form_state) {
+ $field_name = $element['#field_name'];
+ $type_name = $element['#type_name'];
+ $field = content_fields($field_name, $type_name);
+ $field_key = $element['#columns'][0];
+ $value = $element['#value'][$field_key];
+
+ if (($element[$field_key]['#required'] || !empty($value))) {
+ $start = $value;
+ $value = preg_replace('@[^-0-9]@', '', $value);
+ if ($start != $value) {
+ $error_field = implode('][', $element['#parents']) .']['. $field_key;
+ form_set_error($error_field, t('Only numbers are allowed in %field.', array('%field' => t($field['widget']['label']))));
+ }
+ else {
+ form_set_value($element[$field_key], $value, $form_state);
+ }
+ }
+}
+
+/**
+ * FAPI validation of an individual decimal element.
+ */
+function number_decimal_validate($element, &$form_state) {
+ $field_name = $element['#field_name'];
+ $type_name = $element['#type_name'];
+ $field = content_fields($field_name, $type_name);
+ $field_key = $element['#columns'][0];
+ $value = $element['#value'][$field_key];
+
+ if (($element[$field_key]['#required'] || !empty($value))) {
+ $decimal = $element['#decimal'] ? $element['#decimal'] : '.';
+ $start = $value;
+ $value = preg_replace('@[^-0-9\\'. $decimal .']@', '', $value);
+ if ($start != $value) {
+ $error_field = implode('][', $element['#parents']) .']['. $field_key;
+ form_set_error($error_field, t('Only numbers and the decimal character (%decimal) are allowed in %field.', array('%decimal' => $element['#decimal'], '%field' => t($field['widget']['label']))));
+ }
+ else {
+ $value = str_replace($element['#decimal'], '.', $value);
+ $value = round($value, $element['#scale']);
+ form_set_value($element[$field_key], $value, $form_state);
+ }
+ }
+}
+
+/**
+ * FAPI theme for an individual number element.
+ *
+ * The textfield is already rendered by the textfield
+ * theme and the HTML output lives in $element['#children'].
+ * Override this theme to make custom changes to the output.
+ *
+ * $element['#field_name'] contains the field name
+ * $element['#delta] is the position of this element in the group
+ */
+function theme_number($element) {
+ return $element['#children'];
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.de.po
new file mode 100644
index 00000000000..b9ed3f525c0
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.de.po
@@ -0,0 +1,152 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2008-11-05 12:54+0100\n"
+"PO-Revision-Date: 2008-11-05 13:18+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/number/number.module:34
+msgid "Integer"
+msgstr "Ganzzahl"
+
+#: modules/number/number.module:35
+msgid "Store a number in the database as an integer."
+msgstr "Speichert die Zahl in der Datenbank als Ganzzahl."
+
+#: modules/number/number.module:38
+msgid "Decimal"
+msgstr "Dezimalzahl"
+
+#: modules/number/number.module:39
+msgid "Store a number in the database in a fixed decimal format."
+msgstr "Speichert die Zahl in der Datenbank in einem festen Dezimalformat."
+
+#: modules/number/number.module:42
+msgid "Float"
+msgstr "Fließkommazahl"
+
+#: modules/number/number.module:43
+msgid "Store a number in the database in a floating point format."
+msgstr "Speichert die Zahl in der Datenbank in einem Fließkommaformat."
+
+#: modules/number/number.module:57
+msgid "Minimum"
+msgstr "Minimum"
+
+#: modules/number/number.module:63
+msgid "Maximum"
+msgstr "Maximum"
+
+#: modules/number/number.module:71
+msgid "Precision"
+msgstr "Präzision"
+
+#: modules/number/number.module:72
+msgid "The total number of digits to store in the database, including those to the right of the decimal."
+msgstr "Die gesamte Anzahl der in der Datenbank zu speichernden Stellen, inclusive der rechts vom Dezimaltrennzeichen angegebenen."
+
+#: modules/number/number.module:78
+msgid "Scale"
+msgstr "Skalierung"
+
+#: modules/number/number.module:79
+msgid "The number of digits to the right of the decimal."
+msgstr "Die Anzahl der rechts vom Dezimaltrennzeichen angegebenen Stellen."
+
+#: modules/number/number.module:85
+msgid "Decimal marker"
+msgstr "Dezimalzeichen"
+
+#: modules/number/number.module:86
+msgid "The character users will input to mark the decimal point in forms."
+msgstr "Das von Benutzern in Formularen als Dezimalzeichen zu verwendende Symbol."
+
+#: modules/number/number.module:92
+msgid "Prefix"
+msgstr "Präfix"
+
+#: modules/number/number.module:95
+msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr "Eine Zeichenkette angeben, welche dem Wert vorrangestellt werden soll, z.b. $ oder €. Ansonsten freilassen. Werte für Einzahl und Mehrzahl mit einer Pipe trennen (Pfund|Pfunde)."
+
+#: modules/number/number.module:99
+msgid "Suffix"
+msgstr "Suffix"
+
+#: modules/number/number.module:102
+msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr "Eine Zeichenkette angeben, welche dem Wert angehängt werden soll, z.b. m², m/s², kb/s. Ansonsten freilassen. Werte für Einzahl und Mehrzahl mit einer Pipe trennen (Pfund|Pfunde)."
+
+#: modules/number/number.module:195
+msgid "\"Minimum\" must be a number."
+msgstr "„Minimum“ muss eine Zahl sein."
+
+#: modules/number/number.module:202
+msgid "\"Maximum\" must be a number."
+msgstr "„Maximum“ muss eine Zahl sein."
+
+#: modules/number/number.module:219
+msgid "%name: the value may be no smaller than %min."
+msgstr "%name: Der Wert darf nicht kleiner als %min sein."
+
+#: modules/number/number.module:222
+msgid "%name: the value may be no larger than %max."
+msgstr "%name: Der Wert darf nicht grösser als %max sein."
+
+#: modules/number/number.module:270
+msgid "unformatted"
+msgstr "unformatiert"
+
+# Float validation: English needs work
+#: modules/number/number.module:509
+#, fuzzy
+msgid "Only numbers and decimals are allowed in %field."
+msgstr "Im Feld %field sind nur Ganzzahlen und Fließkommazahlen zulässig."
+
+# Integer validation: English needs work
+#: modules/number/number.module:532
+#, fuzzy
+msgid "Only numbers are allowed in %field."
+msgstr "Im Feld %field sind nur Ganzzahlen zulässig."
+
+# Decimal validation with decimal character: English needs work
+#: modules/number/number.module:556
+#, fuzzy
+msgid "Only numbers and the decimal character (%decimal) are allowed in %field."
+msgstr "Im Feld %field sind nur Dezimalzahlen und das Dezimaltrennzeichen (%decimal) zulässig."
+
+#: modules/number/number.module:0
+msgid "number"
+msgstr "Zahl"
+
+#: modules/number/number.info:0
+msgid "Number"
+msgstr "Zahl"
+
+#: modules/number/number.info:0
+msgid "Defines numeric field types."
+msgstr "Definiert einen numerischen Feldtyp."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.fr.po
new file mode 100644
index 00000000000..b1b913f5474
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.fr.po
@@ -0,0 +1,163 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-07-03 13:24+0100\n"
+"Last-Translator: Damien Tournoud \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: modules/number/number.module:41
+msgid "Integer"
+msgstr "Entier"
+
+#: modules/number/number.module:42
+msgid "Store a number in the database as an integer."
+msgstr "Enregistre un nombre dans la base de données en tant qu'entier."
+
+#: modules/number/number.module:49
+msgid "Decimal"
+msgstr "Décimal"
+
+#: modules/number/number.module:50
+msgid "Store a number in the database in a fixed decimal format."
+msgstr "Enregistre un nombre dans la base de données en format décimal fixe."
+
+#: modules/number/number.module:57
+msgid "Float"
+msgstr "Réel à virgule flottante"
+
+#: modules/number/number.module:58
+msgid "Store a number in the database in a floating point format."
+msgstr ""
+"Enregistre un nombre dans la base de données en format réel à virgule "
+"flottante."
+
+#: modules/number/number.module:76
+msgid "Minimum"
+msgstr "Minimum"
+
+#: modules/number/number.module:81
+msgid "Maximum"
+msgstr "Maximum"
+
+#: modules/number/number.module:88
+msgid "Precision"
+msgstr "Précision"
+
+#: modules/number/number.module:89
+msgid ""
+"The total number of digits to store in the database, including those to the "
+"right of the decimal."
+msgstr ""
+"Nombre total de chiffres à enregistrer dans la base de données, y compris "
+"ceux à droite du marqueur décimal."
+
+#: modules/number/number.module:95
+msgid "Scale"
+msgstr "Échelle"
+
+#: modules/number/number.module:96
+msgid "The number of digits to the right of the decimal."
+msgstr "Nombre de chiffres à la droite du marqueur décimal."
+
+#: modules/number/number.module:102
+msgid "Decimal marker"
+msgstr "Marqueur décimal"
+
+#: modules/number/number.module:103
+msgid "The character users will input to mark the decimal point in forms."
+msgstr ""
+"Caractère employé par les utilisateurs dans les formulaires pour signaler la "
+"partie décimale des nombres."
+
+#: modules/number/number.module:109
+msgid "Prefix"
+msgstr "Préfixe"
+
+#: modules/number/number.module:112
+msgid ""
+"Define a string that should be prefixed to the value, like $ or €. Leave "
+"blank for none. Separate singular and plural values with a pipe (pound|"
+"pounds)."
+msgstr ""
+"Définissez une chaîne de caractères à utiliser pour préfixer la valeur, par "
+"exemple $ ou €. Laissez vide pour ne rien afficher de plus. Séparez les "
+"valeurs singulier et pluriel par une barre verticale (euro|euros)."
+
+#: modules/number/number.module:116
+msgid "Suffix"
+msgstr "Suffixe"
+
+#: modules/number/number.module:119
+msgid ""
+"Define a string that should suffixed to the value, like m², m/s², kb/s. "
+"Leave blank for none. Separate singular and plural values with a pipe (pound|"
+"pounds)."
+msgstr ""
+"Définissez une chaîne de caractères à utiliser pour suffixerla valeur, par "
+"exemple m², m/s², ko/s. Laissez vide pour ne rien afficher de plus. Séparez "
+"les valeurs singulier et pluriel par une barre verticale (euro|euros)."
+
+#: modules/number/number.module:162
+msgid "\"Minimum\" must be a number."
+msgstr "'Minimum' doit être un nombre."
+
+#: modules/number/number.module:165
+msgid "\"Maximum\" must be a number."
+msgstr "'Maximum' doit être un nombre."
+
+#: modules/number/number.module:222
+msgid "The value of %name may be no smaller than %min."
+msgstr "La valeur de '%name 'ne peut être plus petite que %min."
+
+#: modules/number/number.module:225
+msgid "The value of %name may be no larger than %max."
+msgstr "La valeur de '%name' ne peut pas être plus grande que %max."
+
+#: modules/number/number.module:263
+msgid "unformatted"
+msgstr "non mis en forme"
+
+#: modules/number/number.module:476
+msgid ""
+"Only numbers and decimals are allowed in %field. %start was changed to %"
+"value."
+msgstr ""
+"Seuls des nombres et des décimaux sont autorisés dans '%field'. La valeur "
+"saisie, '%start', a été modifié en '%value'."
+
+#: modules/number/number.module:494
+msgid "Only numbers are allowed in %field. %start was changed to %value."
+msgstr ""
+"Seuls des nombres sont autorisés dans '%field'. La valeur saisie, '%start', "
+"a été modifié en '%value'."
+
+#: modules/number/number.module:513
+msgid ""
+"Only numbers and the decimal character (%decimal) are allowed in %field. %"
+"start was changed to %value."
+msgstr ""
+"Seuls des nombres et le marqueur décimal (%decimal) sont autorisés dans '%"
+"field'. La valeur saisie, '%start', a été modifié en '%value'."
+
+#: modules/number/number.module:0
+msgid "number"
+msgstr "number"
+
+#: modules/number/number.info:0
+msgid "Number"
+msgstr "Number"
+
+#: modules/number/number.info:0
+msgid "Defines numeric field types."
+msgstr "Permet de définir des champs numériques"
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.hu.po
new file mode 100644
index 00000000000..8e818387313
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.hu.po
@@ -0,0 +1,228 @@
+# Hungarian translation of number (all releases)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# number.module,v 1.91.2.23 2008/10/06 15:11:39 karens
+# number.info,v 1.7 2008/04/23 18:02:16 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: number (all releases)\n"
+"POT-Creation-Date: 2008-10-26 11:25-0500\n"
+"PO-Revision-Date: 2008-10-26 09:39-0500\n"
+"Last-Translator: Fehér János \n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: number.module:147,156
+msgid "Code"
+msgstr "Kód"
+
+#: number.info:0
+msgid "Number"
+msgstr "Szám"
+
+#: number.module:91
+msgid "Precision"
+msgstr "Helyiértékek"
+
+#: number.module:112
+msgid "Prefix"
+msgstr "Előtag"
+
+#: number.module:119
+msgid "Suffix"
+msgstr "Toldalék"
+
+#: number.info:0
+msgid "CCK"
+msgstr "CCK"
+
+#: number.module:140
+msgid "PHP code"
+msgstr "PHP kód"
+
+#: number.module:157
+msgid "<none>"
+msgstr "<nincs>"
+
+#: number.module:158
+msgid "You're not allowed to input PHP code."
+msgstr "Nem engedélyezett a PHP kód bevitele."
+
+#: number.module:42
+msgid "Integer"
+msgstr "Egész szám"
+
+#: number.module:43
+msgid "Store a number in the database as an integer."
+msgstr "Egészként tárol számot az adatbázisban."
+
+#: number.module:50
+msgid "Decimal"
+msgstr "Decimális"
+
+#: number.module:51
+msgid "Store a number in the database in a fixed decimal format."
+msgstr "Rögzített tízes számot tárol az adatbázisban"
+
+#: number.module:58
+msgid "Float"
+msgstr "Lebegőpontos"
+
+#: number.module:59
+msgid "Store a number in the database in a floating point format."
+msgstr "Lebegőpontos számot tárol az adatbázisban."
+
+#: number.module:77
+msgid "Minimum"
+msgstr "Minimum"
+
+#: number.module:83
+msgid "Maximum"
+msgstr "Maximum"
+
+#: number.module:92
+msgid ""
+"The total number of digits to store in the database, including those "
+"to the right of the decimal."
+msgstr ""
+"Az adatbázisban tárolt számjegyek teljes száma, beleértve a "
+"tizedesponttól jobbra lévő számjegyeket is."
+
+#: number.module:98
+msgid "Scale"
+msgstr "Felbontás"
+
+#: number.module:99
+msgid "The number of digits to the right of the decimal."
+msgstr "A számjegyek száma."
+
+#: number.module:105
+msgid "Decimal marker"
+msgstr "Decimális jelölő"
+
+#: number.module:106
+msgid "The character users will input to mark the decimal point in forms."
+msgstr "Az űrlapokon a tizedespont jelölésére használt karakter."
+
+#: number.module:115
+msgid ""
+"Define a string that should be prefixed to the value, like $ or €. "
+"Leave blank for none. Separate singular and plural values with a pipe "
+"(pound|pounds)."
+msgstr ""
+"Egy karaktersorozat, ami az érték előtagja lehet, mint például a "
+"$ vagy az €. Ha nincs előtag, akkor üresen kell hagyni. "
+"Függőleges vonallal lehet elválasztani egymástól az egyes és a "
+"többes számú alakot (font|fontok)."
+
+#: number.module:122
+msgid ""
+"Define a string that should suffixed to the value, like m², m/s², "
+"kb/s. Leave blank for none. Separate singular and plural values with a "
+"pipe (pound|pounds)."
+msgstr ""
+"Egy karaktersorozat, ami az érték toldaléka lehet, mint például "
+"m², m/s², kb/s. Ha nincs toldalék, akkor üresen kell hagyni. "
+"Függőleges vonallal lehet elválasztani egymástól az egyes és a "
+"többes számú alakot (font|fontok)."
+
+#: number.module:126
+msgid "Allowed values"
+msgstr "Megengedett értékek"
+
+#: number.module:132
+msgid "Allowed values list"
+msgstr "Megengedett értékek"
+
+#: number.module:136
+msgid ""
+"The possible values this field can contain. Enter one value per line, "
+"in the format key|label. The key is the value that will be stored in "
+"the database, and it must match the field storage type (%type). The "
+"label is optional, and the key will be used as the label if no label "
+"is specified. Allowed HTML tags: @tags"
+msgstr ""
+"A mező lehetséges értékei. Egy sorban egy értéket lehet megadni "
+"kulcs|címke formában. A kulcs értéke kerül az adatbázisba, és "
+"ennek meg kell felelnie az adatbázisban tárolt típussal (%type). A "
+"címke nem kötelező, ha nincs megadva, akkor a kulcs kerül "
+"felhasználásra, mint címke. Engedélyezett HTML elemek: @tags"
+
+#: number.module:150
+msgid ""
+"Advanced usage only: PHP code that returns a keyed array of allowed "
+"values. Should not include <?php ?> delimiters. If this field is "
+"filled out, the array returned by this code will override the allowed "
+"values list above."
+msgstr ""
+"Csak haladóknak: PHP kód, ami visszaadja a megengedett értékek "
+"tömbjét. Nem szükséges <?php ?> elemek közé zárni. Ha ez "
+"a mező ki van töltve, a kód által visszaadott tömb felülír "
+"minden fentebb megadott értéket."
+
+#: number.module:158
+msgid ""
+"This PHP code was set by an administrator and will override the "
+"allowed values list above."
+msgstr ""
+"Ezt a PHP kódot egy adminisztrátor állította be, és felül fogja "
+"írni a fentebb megadott elfogadható értékek listáját."
+
+#: number.module:210
+msgid "\"Minimum\" must be a number."
+msgstr "„Minimum”-nak számot kell megadni."
+
+#: number.module:217
+msgid "\"Maximum\" must be a number."
+msgstr "„Maximum”-nak számot kell megadni."
+
+#: number.module:234
+msgid "%name: the value may be no smaller than %min."
+msgstr "%name: az érték nem lehet kisebb ennél: %min."
+
+#: number.module:237
+msgid "%name: the value may be no larger than %max."
+msgstr "%name: az érték nem lehet nagyobb ennél: %max."
+
+#: number.module:250
+msgid "%name: illegal value."
+msgstr "%name: érvénytelen érték."
+
+#: number.module:285
+msgid "unformatted"
+msgstr "formázatlan"
+
+#: number.module:368
+msgid "Text field"
+msgstr "Szöveg mező"
+
+#: number.module:524
+msgid ""
+"Only numbers and decimals are allowed in %field. %start was changed to "
+"%value."
+msgstr ""
+"%field: csak számok és tizedesek bevitele megengedett. %start új "
+"értéke: %value."
+
+#: number.module:546
+msgid "Only numbers are allowed in %field. %start was changed to %value."
+msgstr ""
+"%field: csak számok bevitele megengedett. %start új értéke: "
+"%value."
+
+#: number.module:569
+msgid ""
+"Only numbers and the decimal character (%decimal) are allowed in "
+"%field. %start was changed to %value."
+msgstr ""
+"%field: csak számok és a tizedespont (%decimal) bevitele "
+"megengedett. %start új értéke: %value."
+
+#: number.module:0
+msgid "number"
+msgstr "szám"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.nl.po
new file mode 100644
index 00000000000..c44a4e8ba67
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.nl.po
@@ -0,0 +1,214 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# number.module,v 1.91.2.33 2009/03/16 22:04:07 yched
+# number.info,v 1.7 2008/04/23 18:02:16 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:26+0200\n"
+"PO-Revision-Date: 2009-06-03 14:26+0200\n"
+"Last-Translator: NAME \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: number.module:34
+msgid "Integer"
+msgstr "Integer"
+
+#: number.module:35
+msgid "Store a number in the database as an integer."
+msgstr "Sla een waarde in de database op als integer."
+
+#: number.module:38
+msgid "Decimal"
+msgstr "Decimaal"
+
+#: number.module:39
+msgid "Store a number in the database in a fixed decimal format."
+msgstr "Sla een waarde in de database op in een decimaal formaat."
+
+#: number.module:42
+msgid "Float"
+msgstr "Float"
+
+#: number.module:43
+msgid "Store a number in the database in a floating point format."
+msgstr "Sla een waarde in de database op als floating point getal."
+
+#: number.module:57
+msgid "Minimum"
+msgstr "Minimum"
+
+#: number.module:63
+msgid "Maximum"
+msgstr "Maximum"
+
+#: number.module:71
+msgid "Precision"
+msgstr "Precisie"
+
+#: number.module:72
+msgid "The total number of digits to store in the database, including those to the right of the decimal."
+msgstr ""
+"Het totale aantal cijfers om op te slaan in de database, inclusief de "
+"waardes achter de komma."
+
+#: number.module:78
+msgid "Scale"
+msgstr "Schaal"
+
+#: number.module:79
+msgid "The number of digits to the right of the decimal."
+msgstr "Het aantal waardes achter de komma."
+
+#: number.module:85
+msgid "Decimal marker"
+msgstr "Decimaal scheidingsteken"
+
+#: number.module:86
+msgid "The character users will input to mark the decimal point in forms."
+msgstr ""
+"Het karakter dat gebruikers zullen gebruiken om de waardes achter de "
+"komma aan te geven in formulieren."
+
+#: number.module:92
+msgid "Prefix"
+msgstr "Voorvoegsel"
+
+#: number.module:95
+msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr ""
+"Geef op wat als voorvoegsel moet worden gebruikt zoals: $ of €. Laat "
+"leeg als er geen voorvoegsel moet worden gebruikt. Maak onderscheid "
+"tussen enkelvoud en meervoud met een pipe, bijvoorbeeld: euro|euro's."
+
+#: number.module:99
+msgid "Suffix"
+msgstr "Achtervoegsel"
+
+#: number.module:102
+msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr ""
+"Geef op wat als achtervoegsel moet worden gebruikt zoals: m², m/s², "
+"kb/s. Laat leeg als er geen achtervoegsel moet worden gebruikt. Maak "
+"onderscheid tussen enkelvoud en meervoud met een pipe, bijvoorbeeld: "
+"kilo|kilo's."
+
+#: number.module:106
+msgid "Allowed values"
+msgstr "Toegestane waardes"
+
+#: number.module:112
+msgid "Allowed values list"
+msgstr "Lijst met toegestane waardes"
+
+#: number.module:116
+msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified. Allowed HTML tags: @tags"
+msgstr ""
+"De mogelijke waardes die in dit veld kunnen staan. Voer één waarde "
+"per regel in, in het formaat sleutel|label. De sleutel wordt in de "
+"database opgeslagen en moet overeen komen met het veldopslagtype "
+"(%type). Het label is optioneel. Als geen label wordt ingevoerd zal de "
+"sleutel ook worden gebruikt als label. Toegestane HTML-tags: "
+"@tags"
+
+#: number.module:120
+msgid "PHP code"
+msgstr "PHP code"
+
+#: number.module:127;136
+msgid "Code"
+msgstr "Code"
+
+#: number.module:130
+msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above."
+msgstr ""
+"Alleen voor geavanceerd gebruik: PHP-code die een array met sleutels "
+"geeft van de toegestane waardes. Moet niet beginnen en eindigen met "
+"<?php ?>. Als dit veld in ingevuld zullen de bovenstaande "
+"toegestane waardes worden genegeerd."
+
+#: number.module:137
+msgid "<none>"
+msgstr "<geen>"
+
+#: number.module:138
+msgid "You're not allowed to input PHP code."
+msgstr "Je mag geen PHP-code gebruiken."
+
+#: number.module:138
+msgid "This PHP code was set by an administrator and will override the allowed values list above."
+msgstr ""
+"Deze PHP-code is door een beheerder ingesteld en zal worden uitgevoerd "
+"in plaats van de toegestane waardeslijst hierboven."
+
+#: number.module:178
+msgid "@label (!name) - Allowed values"
+msgstr "@label (!name) - Toegestane waardes"
+
+#: number.module:195
+msgid "\"Minimum\" must be a number."
+msgstr "\"Minimum\" moet een nummer zijn."
+
+#: number.module:202
+msgid "\"Maximum\" must be a number."
+msgstr "\"Maximum\" moet een nummer zijn."
+
+#: number.module:219
+msgid "%name: the value may be no smaller than %min."
+msgstr "%name: de waarde mag niet kleiner zijn dan %min."
+
+#: number.module:222
+msgid "%name: the value may be no larger than %max."
+msgstr "%name: de waarde mag niet groter zijn dan %max."
+
+#: number.module:235
+msgid "%name: illegal value."
+msgstr "%name: niet toegestane waarde."
+
+#: number.module:270
+msgid "unformatted"
+msgstr "ongeformatteerd"
+
+#: number.module:353
+msgid "Text field"
+msgstr "Tekstveld"
+
+#: number.module:512
+msgid "Only numbers and decimals are allowed in %field."
+msgstr "Alleen nummers en decimalen zijn toegestaan in %field."
+
+#: number.module:535
+msgid "Only numbers are allowed in %field."
+msgstr "Alleen nummers zijn toegestaan in %field."
+
+#: number.module:559
+msgid "Only numbers and the decimal character (%decimal) are allowed in %field."
+msgstr ""
+"Alleen nummers en het decimalenkarakter (%decimal) zijn toegestaan in "
+"%field."
+
+#: number.module:0
+msgid "number"
+msgstr "getal"
+
+#: number.info:0
+msgid "Number"
+msgstr "Nummer"
+
+#: number.info:0
+msgid "Defines numeric field types."
+msgstr "Levert numerieke veldtypes."
+
+#: number.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.pot
new file mode 100644
index 00000000000..a9c136e41d6
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.pot
@@ -0,0 +1,137 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-number)
+# Copyright YEAR NAME
+# Generated from files:
+# number.module,v 1.91.2.35 2009/04/29 20:51:53 karens
+# number.info,v 1.7 2008/04/23 18:02:16 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/number/number.module:34
+msgid "Integer"
+msgstr ""
+
+#: modules/number/number.module:35
+msgid "Store a number in the database as an integer."
+msgstr ""
+
+#: modules/number/number.module:39
+msgid "Decimal"
+msgstr ""
+
+#: modules/number/number.module:40
+msgid "Store a number in the database in a fixed decimal format."
+msgstr ""
+
+#: modules/number/number.module:44
+msgid "Float"
+msgstr ""
+
+#: modules/number/number.module:45
+msgid "Store a number in the database in a floating point format."
+msgstr ""
+
+#: modules/number/number.module:60
+msgid "Minimum"
+msgstr ""
+
+#: modules/number/number.module:66
+msgid "Maximum"
+msgstr ""
+
+#: modules/number/number.module:74
+msgid "Precision"
+msgstr ""
+
+#: modules/number/number.module:75
+msgid "The total number of digits to store in the database, including those to the right of the decimal."
+msgstr ""
+
+#: modules/number/number.module:81
+msgid "Scale"
+msgstr ""
+
+#: modules/number/number.module:82
+msgid "The number of digits to the right of the decimal."
+msgstr ""
+
+#: modules/number/number.module:88
+msgid "Decimal marker"
+msgstr ""
+
+#: modules/number/number.module:89
+msgid "The character users will input to mark the decimal point in forms."
+msgstr ""
+
+#: modules/number/number.module:95
+msgid "Prefix"
+msgstr ""
+
+#: modules/number/number.module:98
+msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr ""
+
+#: modules/number/number.module:102
+msgid "Suffix"
+msgstr ""
+
+#: modules/number/number.module:105
+msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr ""
+
+#: modules/number/number.module:198
+msgid "\"Minimum\" must be a number."
+msgstr ""
+
+#: modules/number/number.module:205
+msgid "\"Maximum\" must be a number."
+msgstr ""
+
+#: modules/number/number.module:222
+msgid "%name: the value may be no smaller than %min."
+msgstr ""
+
+#: modules/number/number.module:225
+msgid "%name: the value may be no larger than %max."
+msgstr ""
+
+#: modules/number/number.module:273
+msgid "unformatted"
+msgstr ""
+
+#: modules/number/number.module:515
+msgid "Only numbers and decimals are allowed in %field."
+msgstr ""
+
+#: modules/number/number.module:538
+msgid "Only numbers are allowed in %field."
+msgstr ""
+
+#: modules/number/number.module:562
+msgid "Only numbers and the decimal character (%decimal) are allowed in %field."
+msgstr ""
+
+#: modules/number/number.module:0
+msgid "number"
+msgstr ""
+
+#: modules/number/number.info:0
+msgid "Number"
+msgstr ""
+
+#: modules/number/number.info:0
+msgid "Defines numeric field types."
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.sv.po
new file mode 100644
index 00000000000..46dc779809c
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/number/translations/modules-number.sv.po
@@ -0,0 +1,190 @@
+# $Id$
+#
+# Swedish translation of Drupal (number)
+# Generated from files:
+# number.module,v 1.91.2.35 2009/04/29 20:51:53 karens
+# number.info,v 1.7 2008/04/23 18:02:16 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CCK - Number 6.x\n"
+"POT-Creation-Date: 2009-05-27 13:47+0200\n"
+"PO-Revision-Date: 2009-05-27 14:20+0100\n"
+"Last-Translator: Magnus Gunnarsson \n"
+"Language-Team: drupalsverige.se\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: Swedish\n"
+"X-Poedit-Country: SWEDEN\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: number.module:34
+msgid "Integer"
+msgstr "Heltal"
+
+#: number.module:35
+msgid "Store a number in the database as an integer."
+msgstr "Lagra ett tal i databasen som ett heltal."
+
+#: number.module:39
+msgid "Decimal"
+msgstr "Decimaltal"
+
+#: number.module:40
+msgid "Store a number in the database in a fixed decimal format."
+msgstr "Lagra ett tal i databasen som ett bestämt format för decimaltal."
+
+#: number.module:44
+msgid "Float"
+msgstr "Flyttal"
+
+#: number.module:45
+msgid "Store a number in the database in a floating point format."
+msgstr "Lagra ett tal i databasen som ett flytande format för tal."
+
+#: number.module:60
+msgid "Minimum"
+msgstr "Lägsta"
+
+#: number.module:66
+msgid "Maximum"
+msgstr "Högsta"
+
+#: number.module:74
+msgid "Precision"
+msgstr "Precision"
+
+#: number.module:75
+msgid "The total number of digits to store in the database, including those to the right of the decimal."
+msgstr "Det totala antalet siffror att lagra i databasen, inklusive de till höger om decimalkommat."
+
+#: number.module:81
+msgid "Scale"
+msgstr "Skala"
+
+#: number.module:82
+msgid "The number of digits to the right of the decimal."
+msgstr "Antalet siffror till höger om decimalkommat."
+
+#: number.module:88
+msgid "Decimal marker"
+msgstr "Decimalmärke"
+
+#: number.module:89
+msgid "The character users will input to mark the decimal point in forms."
+msgstr "Tecken användare kommer att mata in för att markera decimalpunkten i formulär."
+
+#: number.module:95
+msgid "Prefix"
+msgstr "Prefix"
+
+#: number.module:98
+msgid "Define a string that should be prefixed to the value, like $ or €. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr "Definiera en sträng som skall sättas in före värdet, till exempel $ eller €. Utelämna för tomt värde. Separera enstaka och flerfaldiga värden med en stående streck (krona|kronor)."
+
+#: number.module:102
+msgid "Suffix"
+msgstr "Suffix"
+
+#: number.module:105
+msgid "Define a string that should suffixed to the value, like m², m/s², kb/s. Leave blank for none. Separate singular and plural values with a pipe (pound|pounds)."
+msgstr "Definiera en sträng som skall sättas in efter värdet, såsom m², m/s², kb/s. Utelämna för tomt värde. Separera enstaka och flervärdiga värden med ett stående streck (krona|kronor)."
+
+#: number.module:109
+msgid "Allowed values"
+msgstr "Tillåtna värden"
+
+#: number.module:115
+msgid "Allowed values list"
+msgstr "Tillåtna listvärden"
+
+#: number.module:119
+msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified. Allowed HTML tags: @tags"
+msgstr "De möjliga värdena detta fält kan innehålla. Ange ett värde per rad i formatet nyckel/etikett. Denna nyckel är värdet som kommer att lagras i databasen och måste överensstämma typen för fältlagring (%type). Etikett är valfritt, och nyckeln som kommer att användas är etiketten om ingen etikett är specificerad. Tillåtna HTML-taggar: @tags"
+
+#: number.module:123
+msgid "PHP code"
+msgstr "PHP-kod"
+
+#: number.module:130;139
+msgid "Code"
+msgstr "Kod"
+
+#: number.module:133
+msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above."
+msgstr "Enbart avancerat användande: PHP-kod som skall returnera en spärrad lista av tillåtna värden. Skall inte inkludera avgränsarna <?php ?>. Om detta fält är ifyllt kommer listan som returneras av denna kod att åsidosätta det tillåtna värdet i listan ovan."
+
+#: number.module:140
+msgid "<none>"
+msgstr "<ingen>"
+
+#: number.module:141
+msgid "You're not allowed to input PHP code."
+msgstr "Du har inte tillåtelse att mata in PHP-kod."
+
+#: number.module:141
+msgid "This PHP code was set by an administrator and will override the allowed values list above."
+msgstr "Denna PHP-kod angavs av en administratör och kommer att åsidosätta det tillåtna värdet ovan."
+
+#: number.module:181
+msgid "@label (!name) - Allowed values"
+msgstr "@label (!name) - Tillåtna värden"
+
+#: number.module:198
+msgid "\"Minimum\" must be a number."
+msgstr "\"Lägsta\" måste vara ett tal."
+
+#: number.module:205
+msgid "\"Maximum\" must be a number."
+msgstr "\"Högsta\" måste vara ett tal."
+
+#: number.module:222
+msgid "%name: the value may be no smaller than %min."
+msgstr "%name: värdet får inte vara mindre än %min."
+
+#: number.module:225
+msgid "%name: the value may be no larger than %max."
+msgstr "%name: värdet får inte större än %max."
+
+#: number.module:238
+msgid "%name: illegal value."
+msgstr "%name: otillåtet värde."
+
+#: number.module:273
+msgid "unformatted"
+msgstr "oformaterad"
+
+#: number.module:356
+msgid "Text field"
+msgstr "Textfält"
+
+#: number.module:515
+msgid "Only numbers and decimals are allowed in %field."
+msgstr "Enbart sifror och decimaltal är tillåtna i %field."
+
+#: number.module:538
+msgid "Only numbers are allowed in %field."
+msgstr "Enbart siffror är tillåtna i %field."
+
+#: number.module:562
+msgid "Only numbers and the decimal character (%decimal) are allowed in %field."
+msgstr "Enbart siffror och decimaltalstecken (%decimal) är tillåtna i %field."
+
+#: number.module:0
+msgid "number"
+msgstr "number"
+
+#: number.info:0
+msgid "Number"
+msgstr "Nummer"
+
+#: number.info:0
+msgid "Defines numeric field types."
+msgstr "Definierar numeriska fälttyper."
+
+#: number.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.help.ini
new file mode 100644
index 00000000000..d758d5590cb
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.help.ini
@@ -0,0 +1,11 @@
+; $Id$
+
+[advanced help settings]
+hide = TRUE
+
+[overview]
+title = Overview
+
+[optionwidgets]
+title = Optionwidgets
+parent = content%fields
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.html
new file mode 100644
index 00000000000..c7f444f424e
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/help/optionwidgets.html
@@ -0,0 +1,2 @@
+
Optionwidgets creates drop-down select lists, checkboxes, and radio widgets that can be used with fields that have specific allowed values.
+
The Number and Text fields have settings for creating lists of allowed values that can be used in Optionwidgets. The Nodereference and Userreference fields use Optionwidgets to present the possible values in select lists or checkboxes.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.info
new file mode 100644
index 00000000000..aac00fd57c4
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.info
@@ -0,0 +1,12 @@
+; $Id$
+name = Option Widgets
+description = Defines selection, check box and radio button widgets for text and numeric fields.
+dependencies[] = content
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.install
new file mode 100644
index 00000000000..5b905649b75
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/optionwidgets.install
@@ -0,0 +1,76 @@
+'. t('Create a list of options as a list in Allowed values list or as an array in PHP code. These values will be the same for %field in all content types.', array('%field' => $label)) .'';
+
+ if ($widget_type == 'optionwidgets_onoff') {
+ $output .= '
'. t("For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the Allowed values section. Note that the checkbox will be labeled with the label of the 'on' value.") .'
'. t("The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed.") .'
';
+ }
+
+ if (in_array($field_type, array('text', 'number_integer', 'number_float', 'number_decimal'))
+ && in_array($widget_type, array('optionwidgets_onoff', 'optionwidgets_buttons', 'optionwidgets_select'))) {
+ $form['field']['allowed_values_fieldset']['#collapsed'] = FALSE;
+ $form['field']['allowed_values_fieldset']['#description'] = $output;
+
+ // If no 'allowed values' were set yet, add a remainder in the messages area.
+ if (empty($form_state['post'])
+ && empty($form['field']['allowed_values_fieldset']['allowed_values']['#default_value'])
+ && empty($form['field']['allowed_values_fieldset']['advanced_options']['allowed_values_php']['#default_value'])) {
+ drupal_set_message(t("You need to specify the 'allowed values' for this field."), 'warning');
+ }
+ }
+ }
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function optionwidgets_theme() {
+ return array(
+ 'optionwidgets_select' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'optionwidgets_buttons' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'optionwidgets_onoff' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'optionwidgets_none' => array(
+ 'arguments' => array('widget_type' => NULL, 'field_name' => NULL, 'node_type' => NULL),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_widget_info().
+ *
+ * We need custom handling of multiple values because we need
+ * to combine them into a options list rather than display
+ * multiple elements. We will use the content module's default
+ * handling for default values.
+ *
+ * Callbacks can be omitted if default handing is used.
+ * They're included here just so this module can be used
+ * as an example for custom modules that might do things
+ * differently.
+ */
+function optionwidgets_widget_info() {
+
+ return array(
+ 'optionwidgets_select' => array(
+ 'label' => t('Select list'),
+ 'field types' => array('text', 'number_integer', 'number_decimal', 'number_float'),
+ 'multiple values' => CONTENT_HANDLE_MODULE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ 'optionwidgets_buttons' => array(
+ 'label' => t('Check boxes/radio buttons'),
+ 'field types' => array('text', 'number_integer', 'number_decimal', 'number_float'),
+ 'multiple values' => CONTENT_HANDLE_MODULE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ 'optionwidgets_onoff' => array(
+ 'label' => t('Single on/off checkbox'),
+ 'field types' => array('text', 'number_integer', 'number_decimal', 'number_float'),
+ 'multiple values' => CONTENT_HANDLE_MODULE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ );
+}
+
+/**
+ * Implementation of FAPI hook_elements().
+ *
+ * Any FAPI callbacks needed for individual widgets can be declared here,
+ * and the element will be passed to those callbacks for processing.
+ *
+ * Drupal will automatically theme the element using a theme with
+ * the same name as the hook_elements key.
+ */
+function optionwidgets_elements() {
+ return array(
+ 'optionwidgets_select' => array(
+ '#input' => TRUE,
+ '#columns' => array('value'), '#delta' => 0,
+ '#process' => array('optionwidgets_select_process'),
+ ),
+ 'optionwidgets_buttons' => array(
+ '#input' => TRUE,
+ '#columns' => array('value'), '#delta' => 0,
+ '#process' => array('optionwidgets_buttons_process'),
+ ),
+ 'optionwidgets_onoff' => array(
+ '#input' => TRUE,
+ '#columns' => array('value'), '#delta' => 0,
+ '#process' => array('optionwidgets_onoff_process'),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_widget().
+ *
+ * Attach a single form element to the form. It will be built out and
+ * validated in the callback(s) listed in hook_elements. We build it
+ * out in the callbacks rather than here in hook_widget so it can be
+ * plugged into any module that can provide it with valid
+ * $field information.
+ *
+ * Content module will set the weight, field name and delta values
+ * for each form element. This is a change from earlier CCK versions
+ * where the widget managed its own multiple values.
+ *
+ * If there are multiple values for this field, the content module will
+ * call this function as many times as needed.
+ *
+ * @param $form
+ * the entire form array, $form['#node'] holds node information
+ * @param $form_state
+ * the form_state, $form_state['values'][$field['field_name']]
+ * holds the field's form values.
+ * @param $field
+ * the field array
+ * @param $items
+ * an array of default values for this element
+ * @param $delta
+ * the order of this item in the array of subelements (0, 1, 2, etc)
+ *
+ * @return
+ * the form item for a single element for this field
+ */
+function optionwidgets_widget(&$form, &$form_state, $field, $items, $delta = NULL) {
+ $element = array(
+ '#type' => $field['widget']['type'],
+ '#default_value' => !empty($items) ? $items : array(),
+ );
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function optionwidgets_buttons_process($element, $edit, &$form_state, $form) {
+ $field_name = $element['#field_name'];
+ $field = $form['#field_info'][$field_name];
+ $field_key = $element['#columns'][0];
+
+ // See if this element is in the database format or the transformed format,
+ // and transform it if necessary.
+ if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) {
+ $element['#value'] = optionwidgets_data2form($element, $element['#default_value'], $field);
+ }
+ $options = optionwidgets_options($field);
+ $element[$field_key] = array(
+ '#type' => $field['multiple'] ? 'checkboxes' : 'radios',
+ '#title' => $element['#title'],
+ '#description' => $element['#description'],
+ '#required' => isset($element['#required']) ? $element['#required'] : $field['required'],
+ '#multiple' => isset($element['#multiple']) ? $element['#multiple'] : $field['multiple'],
+ '#options' => $options,
+ '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL,
+ );
+
+ // Set #element_validate in a way that it will not wipe out other
+ // validation functions already set by other modules.
+ if (empty($element['#element_validate'])) {
+ $element['#element_validate'] = array();
+ }
+ array_unshift($element['#element_validate'], 'optionwidgets_validate');
+
+ // Make sure field info will be available to the validator which
+ // does not get the values in $form.
+ $form_state['#field_info'][$field['field_name']] = $field;
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function optionwidgets_select_process($element, $edit, &$form_state, $form) {
+ $field_name = $element['#field_name'];
+ $field = $form['#field_info'][$field_name];
+ $field_key = $element['#columns'][0];
+
+ // See if this element is in the database format or the transformed format,
+ // and transform it if necessary.
+ if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) {
+ $element['#value'] = optionwidgets_data2form($element, $element['#default_value'], $field);
+ }
+
+ $options = optionwidgets_options($field, FALSE);
+
+ // For this specific widget, HTML should be filtered out and entities left unencoded.
+ // See content_allowed_values / content_filter_xss / filter_xss.
+ content_allowed_values_filter_html($options);
+
+ $element[$field_key] = array(
+ '#type' => 'select',
+ '#title' => $element['#title'],
+ '#description' => $element['#description'],
+ '#required' => isset($element['#required']) ? $element['#required'] : $field['required'],
+ '#multiple' => isset($element['#multiple']) ? $element['#multiple'] : $field['multiple'],
+ '#options' => $options,
+ '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL,
+ );
+
+ // Set #element_validate in a way that it will not wipe out other
+ // validation functions already set by other modules.
+ if (empty($element['#element_validate'])) {
+ $element['#element_validate'] = array();
+ }
+ array_unshift($element['#element_validate'], 'optionwidgets_validate');
+
+ // Make sure field info will be available to the validator which
+ // does not get the values in $form.
+
+ // TODO for some reason putting the $field array into $form_state['storage']
+ // causes the node's hook_form_alter to be invoked twice, garbling the
+ // results. Need to investigate why that is happening (a core bug?), but
+ // in the meantime avoid using $form_state['storage'] to store anything.
+ $form_state['#field_info'][$field['field_name']] = $field;
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function optionwidgets_onoff_process($element, $edit, &$form_state, $form) {
+ $field_name = $element['#field_name'];
+ $field = $form['#field_info'][$field_name];
+ $field_key = $element['#columns'][0];
+
+ // See if this element is in the database format or the transformed format,
+ // and transform it if necessary.
+ if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) {
+ $element['#value'] = optionwidgets_data2form($element, $element['#default_value'], $field);
+ }
+ $options = optionwidgets_options($field);
+ $keys = array_keys($options);
+ $on_value = (!empty($keys) && isset($keys[1])) ? $keys[1] : NULL;
+ $element[$field_key] = array(
+ '#type' => 'checkbox',
+ '#title' => isset($options[$on_value]) ? $options[$on_value] : '',
+ '#description' => $element['#description'],
+ '#required' => isset($element['#required']) ? $element['#required'] : $field['required'],
+ '#default_value' => isset($element['#value'][$field_key][0]) ? $element['#value'][$field_key][0] == $on_value : FALSE,
+ '#return_value' => $on_value,
+ );
+
+ // Set #element_validate in a way that it will not wipe out other
+ // validation functions already set by other modules.
+ if (empty($element['#element_validate'])) {
+ $element['#element_validate'] = array();
+ }
+ array_unshift($element['#element_validate'], 'optionwidgets_validate');
+
+ // Make sure field info will be available to the validator which
+ // does not get the values in $form.
+ $form_state['#field_info'][$field['field_name']] = $field;
+ return $element;
+}
+
+/**
+ * FAPI function to validate optionwidgets element.
+ */
+function optionwidgets_validate($element, &$form_state) {
+ // Transpose selections from field => delta to delta => field,
+ // turning multiple selected options into multiple parent elements.
+ // Immediate parent is the delta, need to get back to parent's parent
+ // to create multiple elements.
+ $field = $form_state['#field_info'][$element['#field_name']];
+ $items = optionwidgets_form2data($element, $field);
+ form_set_value($element, $items, $form_state);
+
+ // Check we don't exceed the allowed number of values.
+ if ($field['multiple'] >= 2) {
+ // Filter out 'none' value (if present, will always be in key 0)
+ $field_key = $element['#columns'][0];
+ if (isset($items[0][$field_key]) && $items[0][$field_key] === '') {
+ unset($items[0]);
+ }
+ if (count($items) > $field['multiple']) {
+ $field_key = $element['#columns'][0];
+ form_error($element[$field_key], t('%name: this field cannot hold more than @count values.', array('%name' => t($field['widget']['label']), '@count' => $field['multiple'])));
+ }
+ }
+}
+
+/**
+ * Helper function to transpose the values as stored in the database
+ * to the format the widget needs. Can be called anywhere this
+ * transformation is needed.
+ */
+function optionwidgets_data2form($element, $items, $field) {
+ $field_key = $element['#columns'][0];
+ $options = optionwidgets_options($field);
+
+ $items_transposed = content_transpose_array_rows_cols($items);
+ $values = (isset($items_transposed[$field_key]) && is_array($items_transposed[$field_key])) ? $items_transposed[$field_key] : array();
+ $keys = array();
+ foreach ($values as $value) {
+ $key = array_search($value, array_keys($options));
+ if (isset($key)) {
+ $keys[] = $value;
+ }
+ }
+ if ($field['multiple'] || $element['#type'] == 'optionwidgets_onoff') {
+ return array($field_key => $keys);
+ }
+ else {
+ return !empty($keys) ? array($field_key => $value) : array();
+ }
+}
+
+/**
+ * Helper function to transpose the values returned by submitting the widget
+ * to the format to be stored in the field. Can be called anywhere this
+ * transformation is needed.
+ */
+function optionwidgets_form2data($element, $field) {
+ $field_key = $element['#columns'][0];
+ $items = (array) $element[$field_key]['#value'];
+ $options = optionwidgets_options($field);
+
+ $values = array_values($items);
+
+ if ($element['#type'] == 'optionwidgets_onoff' && ($values[0] === 0)) {
+ $keys = array_keys($options);
+ $values = array(array_key_exists(0, $keys) ? $keys[0] : NULL);
+ }
+
+ if (empty($values)) {
+ $values[] = NULL;
+ }
+ $result = content_transpose_array_rows_cols(array($field_key => $values));
+ return $result;
+}
+
+/**
+ * Helper function for finding the allowed values list for a field.
+ *
+ * See if there is a module hook for the option values.
+ * Otherwise, try content_allowed_values() for an options list.
+ *
+ * @param $field
+ * The field whose allowed values are requested.
+ * @param $flatten
+ * Optional. Use TRUE to return a flattened array (default).
+ * FALSE can be used to support optgroups for select widgets
+ * when allowed values list is generated using PHP code.
+ */
+function optionwidgets_options($field, $flatten = TRUE) {
+ $function = $field['module'] .'_allowed_values';
+ $options = function_exists($function) ? $function($field) : (array) content_allowed_values($field, $flatten);
+ // Add an empty choice for :
+ // - non required radios
+ // - non required selects
+ if (!$field['required']) {
+ if ((in_array($field['widget']['type'], array('optionwidgets_buttons', 'nodereference_buttons', 'userreference_buttons')) && !$field['multiple'])
+ || (in_array($field['widget']['type'], array('optionwidgets_select', 'nodereference_select', 'userreference_select')))) {
+ $options = array('' => theme('optionwidgets_none', $field)) + $options;
+ }
+ }
+ return $options;
+}
+
+/**
+ * Theme the label for the empty value for options that are not required.
+ * The default theme will display N/A for a radio list and blank for a select.
+ */
+function theme_optionwidgets_none($field) {
+ switch ($field['widget']['type']) {
+ case 'optionwidgets_buttons':
+ case 'nodereference_buttons':
+ case 'userreference_buttons':
+ return t('N/A');
+ case 'optionwidgets_select':
+ case 'nodereference_select':
+ case 'userreference_select':
+ return t('- None -');
+ default :
+ return '';
+ }
+}
+
+/**
+ * FAPI themes for optionwidgets.
+ *
+ * The select, checkboxes or radios are already rendered by the
+ * select, checkboxes, or radios themes and the HTML output
+ * lives in $element['#children']. Override this theme to
+ * make custom changes to the output.
+ *
+ * $element['#field_name'] contains the field name
+ * $element['#delta] is the position of this element in the group
+ */
+function theme_optionwidgets_select($element) {
+ return $element['#children'];
+}
+
+function theme_optionwidgets_onoff($element) {
+ return $element['#children'];
+}
+
+function theme_optionwidgets_buttons($element) {
+ return $element['#children'];
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.de.po
new file mode 100644
index 00000000000..43ae44cee83
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.de.po
@@ -0,0 +1,79 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2008-11-05 12:54+0100\n"
+"PO-Revision-Date: 2008-11-05 13:34+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/optionwidgets/optionwidgets.module:19
+msgid "Create a list of options as a list in Allowed values list or as an array in PHP code. These values will be the same for %field in all content types."
+msgstr "Eine Liste von Optionen als Liste in der zulässigen Werteliste oder als ein Array in PHP-Code erstellen. Diese Werte werden für %field in allen Inhaltsstypen gleich sein."
+
+#: modules/optionwidgets/optionwidgets.module:22
+msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the Allowed values section. Note that the checkbox will be labeled with the label of the 'on' value."
+msgstr "Für ein einzelnes „an/aus“ Ankreuzfeld-Steuerelement sollte zuerst der ‚aus‘ Wert und dann der ‚an‘ Wert im Bereich der gültigen Werte angegeben werden. Das Ankreuzfeld wird mit der Beschriftung des ‚an‘ Wertes beschriftet."
+
+#: modules/optionwidgets/optionwidgets.module:25
+msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed."
+msgstr "Das ‚Ankreuzfeld/Auswahlknöpfe‘-Steuerelement wird Ankreuzfelder anzeigen, wenn die Option für mehrere Werte bei diesem Feld ausgewählt wurde, ansonsten werden Auswahlknöpfe anzeigt."
+
+#: modules/optionwidgets/optionwidgets.module:37
+msgid "You need to specify the 'allowed values' for this field."
+msgstr "Für dieses Feld müssen die „zulässigen Werte“ angegeben werden."
+
+#: modules/optionwidgets/optionwidgets.module:96
+msgid "Single on/off checkbox"
+msgstr "Einzelnes an/aus Ankreuzfeld"
+
+#: modules/optionwidgets/optionwidgets.module:326
+msgid "%name: this field cannot hold more than @count values."
+msgstr "%name: Dieses Feld kann nicht mehr als @count Werte enthalten."
+
+#: modules/optionwidgets/optionwidgets.module:411
+msgid "N/A"
+msgstr "k.A."
+
+#: modules/optionwidgets/optionwidgets.module:415
+msgid "- None -"
+msgstr "- Keine -"
+
+#: modules/optionwidgets/optionwidgets.module:0
+msgid "optionwidgets"
+msgstr "Options-Steuerelemente"
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid "Option Widgets"
+msgstr "Options-Steuerelemente"
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid "Defines selection, check box and radio button widgets for text and numeric fields."
+msgstr "Definiert Auswahlfeld-, Ankreuzfeld- und Auswahlknopf-Steuerelemente für Texte und numerische Felder."
+
+#: modules/text/text.module:41
+#: modules/text/text.info:0
+msgid "Text"
+msgstr "Text"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.fr.po
new file mode 100644
index 00000000000..c02d63bb2b1
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.fr.po
@@ -0,0 +1,75 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-07-03 13:24+0100\n"
+"Last-Translator: Damien Tournoud \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: modules/optionwidgets/optionwidgets.module:10
+msgid ""
+"Create a list of options as a list in Allowed values or as "
+"an array in PHP code. These values will be the same for %field in all "
+"content types."
+msgstr ""
+"Créez une liste d'options en tant que liste dans les Valeurs "
+"permises ou en tant que tableau dans le code PHP. Ces valeurs "
+"seront identiques pour '%field' dans tous les types de contenus."
+
+#: modules/optionwidgets/optionwidgets.module:12
+msgid ""
+"For a 'single on/off checkbox' widget, define the 'off' value first, then "
+"the 'on' value in the Allowed values section. Note that the "
+"checkbox will be labeled with the label of the 'on' value."
+msgstr ""
+"Pour un widget 'case à cocher on/off unique', définissez d'abord la valeur "
+"'off' puis la valeur 'on' dans la section Valeurs permises. "
+"Notez que l'intitulé de la case à cocher sera celui de la valeur 'on'."
+
+#: modules/optionwidgets/optionwidgets.module:15
+msgid ""
+"The 'checkboxes/radio buttons' widget will display checkboxes if the "
+"multiple values option is selected for this field, otherwise radios will be "
+"displayed."
+msgstr ""
+"Le widget 'cases à cocher/bouton radio' fera apparaître des cases à cocher "
+"si l'option 'valeurs multiples' est sélectionnée pour ce champ ; dans le cas "
+"contraire, ce seront des boutons radio."
+
+#: modules/optionwidgets/optionwidgets.module:70
+msgid "Check boxes/radio buttons"
+msgstr "Cases à cocher/boutons radio"
+
+#: modules/optionwidgets/optionwidgets.module:78
+msgid "Single on/off checkbox"
+msgstr "Case à cocher on/off unique"
+
+#: modules/optionwidgets/optionwidgets.module:364
+msgid "N/A"
+msgstr "Non disponible"
+
+#: modules/optionwidgets/optionwidgets.module:0
+msgid "optionwidgets"
+msgstr "optionwidgets"
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid "Option Widgets"
+msgstr "Option Widgets"
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid ""
+"Defines selection, check box and radio button widgets for text and numeric "
+"fields."
+msgstr ""
+"Permet de créer des widgets de sélection, cases à cocher et boutons radio "
+"pour les champs de texte et numériques."
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.hu.po
new file mode 100644
index 00000000000..f4e15e87571
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.hu.po
@@ -0,0 +1,84 @@
+# Hungarian translation of cck (6.x-2.0-rc10)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# optionwidgets.module,v 1.69.2.18 2008/10/06 15:11:39 karens
+# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cck (6.x-2.0-rc10)\n"
+"POT-Creation-Date: 2008-10-31 12:16-0500\n"
+"PO-Revision-Date: 2008-10-26 11:40-0500\n"
+"Last-Translator: Balogh Zoltán\n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: modules/optionwidgets/optionwidgets.module:401
+msgid "- None -"
+msgstr "- Nincs -"
+
+#: modules/optionwidgets/optionwidgets.module:397
+msgid "N/A"
+msgstr "N/A"
+
+#: modules/optionwidgets/optionwidgets.module:19
+msgid ""
+"Create a list of options as a list in Allowed values "
+"list or as an array in PHP code. These values will be the "
+"same for %field in all content types."
+msgstr ""
+"A választható értékek megadása az Engedélyezett "
+"értékek mezőben, vagy egy PHP kóddal előállított "
+"tömbben. Erre a mezőre (%field) vonatkozóan ezek az értékek "
+"minden tartalomtípusnál megegyeznek."
+
+#: modules/optionwidgets/optionwidgets.module:22
+msgid ""
+"For a 'single on/off checkbox' widget, define the 'off' value first, "
+"then the 'on' value in the Allowed values section. "
+"Note that the checkbox will be labeled with the label of the 'on' "
+"value."
+msgstr ""
+"Az „egyszerű jelölőnégyzet” felületi elemnél először a "
+"„ki”, majd a „be” állapothoz tartozó értéket kell megadni "
+"az Engedélyezett értékek részben. A "
+"jelölőnégyzet címkéje a „be” állapothoz tartozó érték "
+"címkéje lesz."
+
+#: modules/optionwidgets/optionwidgets.module:25
+msgid ""
+"The 'checkboxes/radio buttons' widget will display checkboxes if the "
+"multiple values option is selected for this field, otherwise radios "
+"will be displayed."
+msgstr ""
+"A „Jelölőnégyzetek/választógombok” felületi elem "
+"jelölőnégyzeteket jelenít meg, ha a mezőnek több értéke is "
+"lehet, különben választógombok jelennek meg."
+
+#: modules/optionwidgets/optionwidgets.module:37
+msgid "You need to specify the 'allowed values' for this field."
+msgstr "Ki kell tölteni a „Megengedett értékek”-et ennél a mezőnél."
+
+#: modules/optionwidgets/optionwidgets.module:96
+msgid "Single on/off checkbox"
+msgstr "Egyszerű be/ki jelölőnégyzet"
+
+#: modules/optionwidgets/optionwidgets.module:0
+msgid "optionwidgets"
+msgstr "optionwidgets"
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid "Option Widgets"
+msgstr "Kapcsoló felületi elemek"
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid ""
+"Defines selection, check box and radio button widgets for text and "
+"numeric fields."
+msgstr ""
+"A szöveg és szám mezőtípushoz legördülő lista, "
+"jelölőnégyzet és választógomb típusú felületi elemeket ad."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.nl.po
new file mode 100644
index 00000000000..be13b61ddd7
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.nl.po
@@ -0,0 +1,89 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched
+# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:26+0200\n"
+"PO-Revision-Date: 2009-06-03 14:26+0200\n"
+"Last-Translator: NAME \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: optionwidgets.module:19
+msgid "Create a list of options as a list in Allowed values list or as an array in PHP code. These values will be the same for %field in all content types."
+msgstr ""
+"Maak een lijst met opties als in Toegestane "
+"waardeslijst of als een array in PHP. Deze waarde zullen "
+"hetzelfde zijn in %field in alle inhoudstypes."
+
+#: optionwidgets.module:22
+msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the Allowed values section. Note that the checkbox will be labeled with the label of the 'on' value."
+msgstr ""
+"Voor een aan/uit vinkjewidget moet je eerst de 'uit'-waarde opgeven en "
+"daarna de 'aan'-waarde in de Toegestane "
+"waarde-sectie. Merk op dat het vinkje zal worden gelabeled "
+"met de waarde van 'aan'."
+
+#: optionwidgets.module:25
+msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed."
+msgstr ""
+"De 'vinkje-/radio button'widget zal een vinkje tonen als de meerdere "
+"toegestane waardes is geselecteerd voor dit veld, anders zullen radio "
+"buttons worden gebruikt."
+
+#: optionwidgets.module:37
+msgid "You need to specify the 'allowed values' for this field."
+msgstr "Je moet de toegestane waardes voor dit veld opgeven."
+
+#: optionwidgets.module:80
+msgid "Select list"
+msgstr "Selectielijst"
+
+#: optionwidgets.module:88
+msgid "Check boxes/radio buttons"
+msgstr "Vinkje/radio buttons"
+
+#: optionwidgets.module:96
+msgid "Single on/off checkbox"
+msgstr "Een aan/uit vinkje"
+
+#: optionwidgets.module:331
+msgid "%name: this field cannot hold more than @count values."
+msgstr "%name: dit veld kan niet meer dan @count waardes bevatten."
+
+#: optionwidgets.module:416
+msgid "N/A"
+msgstr "Niet beschikbaar"
+
+#: optionwidgets.module:420
+msgid "- None -"
+msgstr "- Geen -"
+
+#: optionwidgets.module:0
+msgid "optionwidgets"
+msgstr "optiewidgets"
+
+#: optionwidgets.info:0
+msgid "Option Widgets"
+msgstr "Optiewidgets"
+
+#: optionwidgets.info:0
+msgid "Defines selection, check box and radio button widgets for text and numeric fields."
+msgstr ""
+"Levert selectie-, vinkje- en radio buttonwidgets voor tekst- en "
+"numerieke velden."
+
+#: optionwidgets.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.pot
new file mode 100644
index 00000000000..06a70597efa
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.pot
@@ -0,0 +1,71 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-optionwidgets)
+# Copyright YEAR NAME
+# Generated from files:
+# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched
+# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww
+# text.module,v 1.95.2.29 2009/04/29 20:51:53 karens
+# text.info,v 1.9 2008/04/23 18:02:31 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/optionwidgets/optionwidgets.module:19
+msgid "Create a list of options as a list in Allowed values list or as an array in PHP code. These values will be the same for %field in all content types."
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:22
+msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the Allowed values section. Note that the checkbox will be labeled with the label of the 'on' value."
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:25
+msgid "The 'checkboxes/radio buttons' widget will display checkboxes if the multiple values option is selected for this field, otherwise radios will be displayed."
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:37
+msgid "You need to specify the 'allowed values' for this field."
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:96
+msgid "Single on/off checkbox"
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:331
+msgid "%name: this field cannot hold more than @count values."
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:416
+msgid "N/A"
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:420
+msgid "- None -"
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.module:0
+msgid "optionwidgets"
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid "Option Widgets"
+msgstr ""
+
+#: modules/optionwidgets/optionwidgets.info:0
+msgid "Defines selection, check box and radio button widgets for text and numeric fields."
+msgstr ""
+
+#: modules/text/text.module:41 modules/text/text.info:0
+msgid "Text"
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.sv.po
new file mode 100644
index 00000000000..99e0dd4ebe5
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/optionwidgets/translations/modules-optionwidgets.sv.po
@@ -0,0 +1,78 @@
+# $Id$
+#
+# Swedish translation of Drupal (optionwidgets)
+# Generated from files:
+# optionwidgets.module,v 1.69.2.23 2009/03/18 21:00:58 yched
+# optionwidgets.info,v 1.7 2008/04/23 18:02:24 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CCK - Optionwidgets 6.x\n"
+"POT-Creation-Date: 2009-05-27 13:47+0200\n"
+"PO-Revision-Date: 2009-05-27 14:01+0100\n"
+"Last-Translator: Magnus Gunnarsson \n"
+"Language-Team: drupalsverige.se\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: Swedish\n"
+"X-Poedit-Country: SWEDEN\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: optionwidgets.module:19
+msgid "Create a list of options as a list in Allowed values list or as an array in PHP code. These values will be the same for %field in all content types."
+msgstr "Skapa en lista av alternativ som en lista i Tillåtna värden eller som en lista i PHP-kod. Dessa värden kommer att vara likadana för %field i alla innehållstyper."
+
+#: optionwidgets.module:22
+msgid "For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the Allowed values section. Note that the checkbox will be labeled with the label of the 'on' value."
+msgstr "För en gränssnittskomponent \"enstaka kryssruta för av/på\", definiera värdet för \"av\" först, sedan värdet för \"på\" i Tillåtna värdenThe Text field stores textual data in the database. It can either be a simple textfield to hold up to 255 characters, or a textarea of an unlimited size that can be combined with input filters to store lengthy descriptions and HTML code.
+
The Text field provides a place for the administrator to create a list of 'Allowed values' for the field. When used with Optionwidgets, the allowed values are presented to the end user in a drop-down select list, checkboxes, or radios.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.info
new file mode 100644
index 00000000000..526f53ab634
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.info
@@ -0,0 +1,12 @@
+; $Id$
+name = Text
+description = Defines simple text field types.
+dependencies[] = content
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.install
new file mode 100644
index 00000000000..a6569c54af4
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.install
@@ -0,0 +1,156 @@
+ 1) ? 'text_textarea' : 'text_textfield';
+ $ret[] = update_sql("UPDATE {". content_instance_tablename() ."} SET widget_module = 'text', widget_type = '". $new_widget_type ."' WHERE field_name = '{$field_instance['field_name']}' AND type_name = '{$field_instance['type_name']}'");
+ }
+ content_associate_fields('text');
+ return $ret;
+}
+
+/**
+ * Set all columns to accept NULL values and set empty string values in the
+ * database to NULL.
+ *
+ * Leaving it up to module developers to handle conversion of numbers to
+ * NULL values, since there are times when zeros are valid data and times
+ * when they should be NULL.
+ *
+ */
+function text_update_6001(&$sandbox) {
+ include_once('./'. drupal_get_path('module', 'content') .'/content.install');
+ drupal_load('module', 'content');
+
+ $ret = array();
+
+ if (!isset($sandbox['progress'])) {
+ if ($abort = content_check_update('text')) {
+ return $abort;
+ }
+
+ // Get the latest cache values and schema.
+ content_clear_type_cache(TRUE, TRUE);
+ $types = content_types_install();
+
+ if (empty($types)) {
+ return $ret;
+ }
+
+ $sandbox['fields'] = array();
+ foreach ($types as $type_name => $fields) {
+ foreach ($fields as $field) {
+ if ($field['type'] == 'text') {
+ $sandbox['fields'][] = $field;
+ }
+ }
+ }
+
+ if (empty($sandbox['fields'])) {
+ return $ret;
+ }
+
+ $sandbox['progress'] = 0;
+ $sandbox['visited'] = array();
+ }
+
+ $field = $sandbox['fields'][$sandbox['progress']];
+
+ // We only want to process a field once -- if we hit it a second time,
+ // that means it's its own table and it should have already been updated.
+ if (!in_array($field['field_name'], $sandbox['visited'])) {
+ $db_info = content_database_info($field);
+ $table = $db_info['table'];
+ foreach ($db_info['columns'] as $column => $attributes) {
+ $attributes['not null'] = FALSE;
+ $column = $attributes['column'];
+ db_change_field($ret, $table, $column, $column, $attributes);
+ // TODO: errors on text/blob columns: no default value allowed (!)
+ db_field_set_no_default($ret, $table, $column);
+ if ($attributes['type'] == 'varchar' || $attributes['type'] == 'text') {
+ $ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NULL WHERE ". $column ." = ''");
+ }
+ else {
+ // TODO: replace format = 0 with format = NULL ?? Is this right ?
+ $ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NULL WHERE ". $column ." = 0");
+ }
+ }
+ $sandbox['visited'][] = $field['field_name'];
+ }
+
+ $sandbox['progress']++;
+ $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']);
+
+ return $ret;
+}
+
+/**
+ * Update 6000 and 6001 were possibly broken if they were executed while
+ * the modules were still disabled, so we re-run them.
+ * Having them run a second time on sites that got updated correctly has no
+ * side-effect (see http://drupal.org/node/310873).
+ */
+function text_update_6002() {
+ return text_update_6000();
+}
+function text_update_6003(&$sandbox) {
+ return text_update_6001($sandbox);
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.module
new file mode 100644
index 00000000000..48585f98272
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/text.module
@@ -0,0 +1,485 @@
+ array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'text_textfield' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'text_formatter_default' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'text_formatter_plain' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'text_formatter_trimmed' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'text_formatter_foo' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function text_field_info() {
+ return array(
+ 'text' => array(
+ 'label' => t('Text'),
+ 'description' => t('Store text in the database.'),
+// 'content_icon' => 'icon_content_text.png',
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_field_settings().
+ */
+function text_field_settings($op, $field) {
+ switch ($op) {
+ case 'form':
+ $form = array();
+ $options = array(0 => t('Plain text'), 1 => t('Filtered text (user selects input format)'));
+ $form['text_processing'] = array(
+ '#type' => 'radios',
+ '#title' => t('Text processing'),
+ '#default_value' => is_numeric($field['text_processing']) ? $field['text_processing'] : 0,
+ '#options' => $options,
+ );
+ $form['max_length'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Maximum length'),
+ '#default_value' => is_numeric($field['max_length']) ? $field['max_length'] : '',
+ '#required' => FALSE,
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#description' => t('The maximum length of the field in characters. Leave blank for an unlimited size.'),
+ );
+ $form['allowed_values_fieldset'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Allowed values'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ );
+ $form['allowed_values_fieldset']['allowed_values'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Allowed values list'),
+ '#default_value' => !empty($field['allowed_values']) ? $field['allowed_values'] : '',
+ '#required' => FALSE,
+ '#rows' => 10,
+ '#description' => t('The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified. Allowed HTML tags: @tags', array('%type' => $field['type'], '@tags' => _content_filter_xss_display_allowed_tags())),
+ );
+ $form['allowed_values_fieldset']['advanced_options'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('PHP code'),
+ '#collapsible' => TRUE,
+ '#collapsed' => empty($field['allowed_values_php']),
+ );
+ if (user_access('Use PHP input for field settings (dangerous - grant with care)')) {
+ $form['allowed_values_fieldset']['advanced_options']['allowed_values_php'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Code'),
+ '#default_value' => !empty($field['allowed_values_php']) ? $field['allowed_values_php'] : '',
+ '#rows' => 6,
+ '#description' => t('Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above.'),
+ );
+ }
+ else {
+ $form['allowed_values_fieldset']['advanced_options']['markup_allowed_values_php'] = array(
+ '#type' => 'item',
+ '#title' => t('Code'),
+ '#value' => !empty($field['allowed_values_php']) ? ''. check_plain($field['allowed_values_php']) .'' : t('<none>'),
+ '#description' => empty($field['allowed_values_php']) ? t("You're not allowed to input PHP code.") : t('This PHP code was set by an administrator and will override the allowed values list above.'),
+ );
+ }
+ return $form;
+
+ case 'save':
+ return array('text_processing', 'max_length', 'allowed_values', 'allowed_values_php');
+
+ case 'database columns':
+ if (empty($field['max_length']) || $field['max_length'] > 255) {
+ $columns['value'] = array('type' => 'text', 'size' => 'big', 'not null' => FALSE, 'sortable' => TRUE, 'views' => TRUE);
+ }
+ else {
+ $columns['value'] = array('type' => 'varchar', 'length' => $field['max_length'], 'not null' => FALSE, 'sortable' => TRUE, 'views' => TRUE);
+ }
+ if (!empty($field['text_processing'])) {
+ $columns['format'] = array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'views' => FALSE);
+ }
+ return $columns;
+
+ case 'views data':
+ $allowed_values = content_allowed_values($field);
+ if (count($allowed_values)) {
+ $data = content_views_field_views_data($field);
+ $db_info = content_database_info($field);
+ $table_alias = content_views_tablename($field);
+
+ // Filter: Add a 'many to one' filter.
+ $copy = $data[$table_alias][$field['field_name'] .'_value'];
+ $copy['title'] = t('@label (!name) - Allowed values', array('@label' => t($field['widget']['label']), '!name' => $field['field_name']));
+ $copy['filter']['handler'] = 'content_handler_filter_many_to_one';
+ unset($copy['field'], $copy['argument'], $copy['sort']);
+ $data[$table_alias][$field['field_name'] .'_value_many_to_one'] = $copy;
+ // Argument : swap the handler to the 'many to one' operator.
+ $data[$table_alias][$field['field_name'] .'_value']['argument']['handler'] = 'content_handler_argument_many_to_one';
+ return $data;
+ }
+ }
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function text_field($op, &$node, $field, &$items, $teaser, $page) {
+ switch ($op) {
+ case 'validate':
+ $allowed_values = content_allowed_values($field);
+ if (is_array($items)) {
+ foreach ($items as $delta => $item) {
+ $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
+ if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']);
+ if (!empty($item['value'])) {
+ if (count($allowed_values) && !array_key_exists($item['value'], $allowed_values)) {
+ form_set_error($error_element, t('%name: illegal value.', array('%name' => t($field['widget']['label']))));
+ }
+ if (!empty($field['max_length']) && drupal_strlen($item['value']) > $field['max_length']) {
+ form_set_error($error_element, t('%name: the value may not be longer than %max characters.', array('%name' => $field['widget']['label'], '%max' => $field['max_length'])));
+ }
+ }
+ }
+ }
+ return $items;
+
+ case 'sanitize':
+ foreach ($items as $delta => $item) {
+ if (!empty($field['text_processing'])) {
+ $text = isset($item['value']) ? check_markup($item['value'], $item['format'], FALSE) : '';
+ }
+ else {
+ $text = isset($item['value']) ? check_plain($item['value']) : '';
+ }
+ $items[$delta]['safe'] = $text;
+ }
+ }
+}
+
+/**
+ * Implementation of hook_content_is_empty().
+ */
+function text_content_is_empty($item, $field) {
+ if (empty($item['value']) && (string)$item['value'] !== '0') {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of hook_field_formatter_info().
+ */
+function text_field_formatter_info() {
+ return array(
+ 'default' => array(
+ 'label' => t('Default'),
+ 'field types' => array('text'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ 'plain' => array(
+ 'label' => t('Plain text'),
+ 'field types' => array('text'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ 'trimmed' => array(
+ 'label' => t('Trimmed'),
+ 'field types' => array('text'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ );
+}
+
+/**
+ * Theme function for 'default' text field formatter.
+ */
+function theme_text_formatter_default($element) {
+ return ($allowed =_text_allowed_values($element)) ? $allowed : $element['#item']['safe'];
+}
+
+/**
+ * Theme function for 'plain' text field formatter.
+ */
+function theme_text_formatter_plain($element) {
+ return ($allowed =_text_allowed_values($element)) ? $allowed : strip_tags($element['#item']['safe']);
+}
+
+/**
+ * Theme function for 'trimmed' text field formatter.
+ */
+function theme_text_formatter_trimmed($element) {
+ $field = content_fields($element['#field_name'], $element['#type_name']);
+ return ($allowed =_text_allowed_values($element)) ? $allowed : node_teaser($element['#item']['safe'], $field['text_processing'] ? $element['#item']['format'] : NULL);
+}
+
+function _text_allowed_values($element) {
+ $field = content_fields($element['#field_name'], $element['#type_name']);
+ if (($allowed_values = content_allowed_values($field)) && isset($allowed_values[$element['#item']['value']])) {
+ return $allowed_values[$element['#item']['value']];
+ }
+}
+
+/**
+ * Implementation of hook_widget_info().
+ *
+ * Here we indicate that the content module will handle
+ * the default value and multiple values for these widgets.
+ *
+ * Callbacks can be omitted if default handing is used.
+ * They're included here just so this module can be used
+ * as an example for custom modules that might do things
+ * differently.
+ */
+function text_widget_info() {
+ return array(
+ 'text_textfield' => array(
+ 'label' => t('Text field'),
+ 'field types' => array('text'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ 'text_textarea' => array(
+ 'label' => t('Text area (multiple rows)'),
+ 'field types' => array('text'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ );
+}
+
+/**
+ * Implementation of FAPI hook_elements().
+ *
+ * Any FAPI callbacks needed for individual widgets can be declared here,
+ * and the element will be passed to those callbacks for processing.
+ *
+ * Drupal will automatically theme the element using a theme with
+ * the same name as the hook_elements key.
+ *
+ * Autocomplete_path is not used by text_widget but other widgets can use it
+ * (see nodereference and userreference).
+ */
+function text_elements() {
+ return array(
+ 'text_textfield' => array(
+ '#input' => TRUE,
+ '#columns' => array('value'), '#delta' => 0,
+ '#process' => array('text_textfield_process'),
+ '#autocomplete_path' => FALSE,
+ ),
+ 'text_textarea' => array(
+ '#input' => TRUE,
+ '#columns' => array('value', 'format'), '#delta' => 0,
+ '#process' => array('text_textarea_process'),
+ '#filter_value' => FILTER_FORMAT_DEFAULT,
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_widget_settings().
+ */
+function text_widget_settings($op, $widget) {
+ switch ($op) {
+ case 'form':
+ $form = array();
+ $rows = (isset($widget['rows']) && is_numeric($widget['rows'])) ? $widget['rows'] : 5;
+ $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60;
+ if ($widget['type'] == 'text_textfield') {
+ $form['rows'] = array('#type' => 'hidden', '#value' => $rows);
+ $form['size'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Size of textfield'),
+ '#default_value' => $size,
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#required' => TRUE,
+ );
+ }
+ else {
+ $form['rows'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Rows'),
+ '#default_value' => $rows,
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#required' => TRUE,
+ );
+ $form['size'] = array('#type' => 'hidden', '#value' => $size);
+ }
+ return $form;
+
+ case 'save':
+ return array('rows', 'size');
+ }
+}
+
+/**
+ * Implementation of hook_widget().
+ *
+ * Attach a single form element to the form. It will be built out and
+ * validated in the callback(s) listed in hook_elements. We build it
+ * out in the callbacks rather than here in hook_widget so it can be
+ * plugged into any module that can provide it with valid
+ * $field information.
+ *
+ * Content module will set the weight, field name and delta values
+ * for each form element. This is a change from earlier CCK versions
+ * where the widget managed its own multiple values.
+ *
+ * If there are multiple values for this field, the content module will
+ * call this function as many times as needed.
+ *
+ * @param $form
+ * the entire form array, $form['#node'] holds node information
+ * @param $form_state
+ * the form_state, $form_state['values'][$field['field_name']]
+ * holds the field's form values.
+ * @param $field
+ * the field array
+ * @param $items
+ * array of default values for this field
+ * @param $delta
+ * the order of this item in the array of subelements (0, 1, 2, etc)
+ *
+ * @return
+ * the form item for a single element for this field
+ */
+function text_widget(&$form, &$form_state, $field, $items, $delta = 0) {
+ $element = array(
+ '#type' => $field['widget']['type'],
+ '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
+ );
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function text_textfield_process($element, $edit, $form_state, $form) {
+ $field = $form['#field_info'][$element['#field_name']];
+ $field_key = $element['#columns'][0];
+ $delta = $element['#delta'];
+ $element[$field_key] = array(
+ '#type' => 'textfield',
+ '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL,
+ '#autocomplete_path' => $element['#autocomplete_path'],
+ '#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60,
+ '#attributes' => array('class' => 'text'),
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#description' => $element['#description'],
+ '#required' => $element['#required'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+
+ $element[$field_key]['#maxlength'] = !empty($field['max_length']) ? $field['max_length'] : NULL;
+
+ if (!empty($field['text_processing'])) {
+ $filter_key = $element['#columns'][1];
+ $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT;
+ $parents = array_merge($element['#parents'] , array($filter_key));
+ $element[$filter_key] = filter_form($format, 1, $parents);
+ }
+
+ // Used so that hook_field('validate') knows where to flag an error.
+ $element['_error_element'] = array(
+ '#type' => 'value',
+ '#value' => implode('][', array_merge($element['#parents'], array($field_key))),
+ );
+
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function text_textarea_process($element, $edit, $form_state, $form) {
+ $field = $form['#field_info'][$element['#field_name']];
+ $field_key = $element['#columns'][0];
+ $element[$field_key] = array(
+ '#type' => 'textarea',
+ '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL,
+ '#rows' => !empty($field['widget']['rows']) ? $field['widget']['rows'] : 10,
+ '#weight' => 0,
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#description' => $element['#description'],
+ '#required' => $element['#required'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+
+ if (!empty($field['text_processing'])) {
+ $filter_key = (count($element['#columns']) == 2) ? $element['#columns'][1] : 'format';
+ $format = isset($element['#value'][$filter_key]) ? $element['#value'][$filter_key] : FILTER_FORMAT_DEFAULT;
+ $parents = array_merge($element['#parents'] , array($filter_key));
+ $element[$filter_key] = filter_form($format, 1, $parents);
+ }
+
+ // Used so that hook_field('validate') knows where to flag an error.
+ $element['_error_element'] = array(
+ '#type' => 'value',
+ '#value' => implode('][', array_merge($element['#parents'], array($field_key))),
+ );
+
+ return $element;
+}
+
+/**
+ * FAPI theme for an individual text elements.
+ *
+ * The textfield or textarea is already rendered by the
+ * textfield or textarea themes and the html output
+ * lives in $element['#children']. Override this theme to
+ * make custom changes to the output.
+ *
+ * $element['#field_name'] contains the field name
+ * $element['#delta] is the position of this element in the group
+ */
+function theme_text_textfield($element) {
+ return $element['#children'];
+}
+
+function theme_text_textarea($element) {
+ return $element['#children'];
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.de.po
new file mode 100644
index 00000000000..6f71b7fda07
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.de.po
@@ -0,0 +1,74 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: 2009-06-16 19:10+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/text/text.module:42
+msgid "Store text in the database."
+msgstr "Text in der Datenbank speichern."
+
+#: modules/text/text.module:55
+msgid "Filtered text (user selects input format)"
+msgstr "Gefilterter Text (Benutzer wählt Eingabeformat aus)"
+
+#: modules/text/text.module:58
+msgid "Text processing"
+msgstr "Textverarbeitung"
+
+#: modules/text/text.module:64
+msgid "Maximum length"
+msgstr "Maximallänge"
+
+#: modules/text/text.module:68
+msgid "The maximum length of the field in characters. Leave blank for an unlimited size."
+msgstr "Die maximale Zeichenlänge des Feldes. Für eine unbegrenzte Länge freilassen."
+
+#: modules/text/text.module:160
+msgid "%name: the value may not be longer than %max characters."
+msgstr "%name: Der Wert darf nicht länger als %max Zeichen sein."
+
+#: modules/text/text.module:207
+msgid "Trimmed"
+msgstr "Getrimmt"
+
+#: modules/text/text.module:265
+msgid "Text area (multiple rows)"
+msgstr "Textfeld (mehrere Zeilen)"
+
+#: modules/text/text.module:326
+msgid "Rows"
+msgstr "Zeilen"
+
+#: modules/text/text.module:0
+msgid "text"
+msgstr "Text"
+
+#: modules/text/text.info:0
+msgid "Defines simple text field types."
+msgstr "Definiert einfache Typen von Textfeldern."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.fr.po
new file mode 100644
index 00000000000..29e611c6d4a
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.fr.po
@@ -0,0 +1,33 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-07-03 13:24+0100\n"
+"Last-Translator: Damien Tournoud \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: modules/text/text.module:50
+msgid "Store text in the database."
+msgstr "Enregistre le texte dans la base de données."
+
+#: modules/text/text.module:272
+msgid "Text area (multiple rows)"
+msgstr "Zone de texte (plusieurs lignes)"
+
+#: modules/text/text.module:0
+msgid "text"
+msgstr "texte"
+
+#: modules/text/text.info:0
+msgid "Defines simple text field types."
+msgstr "Définit les types de champs en texte simple."
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.hu.po
new file mode 100644
index 00000000000..5e748933efb
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.hu.po
@@ -0,0 +1,156 @@
+# Hungarian translation of text (all releases)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# text.module,v 1.95.2.20 2008/10/01 17:04:31 karens
+# text.info,v 1.9 2008/04/23 18:02:31 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: text (all releases)\n"
+"POT-Creation-Date: 2008-10-26 11:32-0500\n"
+"PO-Revision-Date: 2008-10-26 09:41-0500\n"
+"Last-Translator: Fehér János \n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: text.module:103,112
+msgid "Code"
+msgstr "Kód"
+
+#: text.module:202
+msgid "Default"
+msgstr "Alapértelmezett"
+
+#: text.module:66,207
+msgid "Plain text"
+msgstr "Egyszerű szöveg"
+
+#: text.info:0
+msgid "CCK"
+msgstr "CCK"
+
+#: text.module:96
+msgid "PHP code"
+msgstr "PHP kód"
+
+#: text.module:113
+msgid "<none>"
+msgstr "<nincs>"
+
+#: text.module:114
+msgid "You're not allowed to input PHP code."
+msgstr "Nem engedélyezett a PHP kód bevitele."
+
+#: text.module:82
+msgid "Allowed values"
+msgstr "Megengedett értékek"
+
+#: text.module:88
+msgid "Allowed values list"
+msgstr "Megengedett értékek"
+
+#: text.module:92
+msgid ""
+"The possible values this field can contain. Enter one value per line, "
+"in the format key|label. The key is the value that will be stored in "
+"the database, and it must match the field storage type (%type). The "
+"label is optional, and the key will be used as the label if no label "
+"is specified. Allowed HTML tags: @tags"
+msgstr ""
+"A mező lehetséges értékei. Egy sorban egy értéket lehet megadni "
+"kulcs|címke formában. A kulcs értéke kerül az adatbázisba, és "
+"ennek meg kell felelnie az adatbázisban tárolt típussal (%type). A "
+"címke nem kötelező, ha nincs megadva, akkor a kulcs kerül "
+"felhasználásra, mint címke. Engedélyezett HTML elemek: @tags"
+
+#: text.module:106
+msgid ""
+"Advanced usage only: PHP code that returns a keyed array of allowed "
+"values. Should not include <?php ?> delimiters. If this field is "
+"filled out, the array returned by this code will override the allowed "
+"values list above."
+msgstr ""
+"Csak haladóknak: PHP kód, ami visszaadja a megengedett értékek "
+"tömbjét. Nem szükséges <?php ?> elemek közé zárni. Ha ez "
+"a mező ki van töltve, a kód által visszaadott tömb felülír "
+"minden fentebb megadott értéket."
+
+#: text.module:114
+msgid ""
+"This PHP code was set by an administrator and will override the "
+"allowed values list above."
+msgstr ""
+"Ezt a PHP kódot egy adminisztrátor állította be, és felül fogja "
+"írni a fentebb megadott elfogadható értékek listáját."
+
+#: text.module:162
+msgid "%name: illegal value."
+msgstr "%name: érvénytelen érték."
+
+#: text.module:262
+msgid "Text field"
+msgstr "Szöveg mező"
+
+#: text.module:50
+msgid "Store text in the database."
+msgstr "Szöveget tárol az adatbázisban."
+
+#: text.module:66
+msgid "Filtered text (user selects input format)"
+msgstr "Formázott szöveg (a felhasználó választja ki a beviteli formát)"
+
+#: text.module:69
+msgid "Text processing"
+msgstr "Szövegfeldolgozás"
+
+#: text.module:75
+msgid "Maximum length"
+msgstr "Maximális hossz"
+
+#: text.module:78
+msgid ""
+"The maximum length of the field in characters. Leave blank for an "
+"unlimited size."
+msgstr ""
+"A mező karakterben mért maximális hossza. Üresen hagyva nincs "
+"korlátozva."
+
+#: text.module:165
+msgid "%name: the value may not be longer than %max characters."
+msgstr "%name: az érték nem lehet hosszabb %max karakternél."
+
+#: text.module:212
+msgid "Trimmed"
+msgstr "Levágva"
+
+#: text.module:270
+msgid "Text area (multiple rows)"
+msgstr "Szövegdoboz (többsoros)"
+
+#: text.module:322
+msgid "Size of textfield"
+msgstr "A szövegmező mérete"
+
+#: text.module:331
+msgid "Rows"
+msgstr "Sorok"
+
+#: text.module:348
+msgid "\"Rows\" must be a positive integer."
+msgstr "A „Sorok” számának pozitív egész számot lehet megadni."
+
+#: text.module:355
+msgid "\"Size\" must be a positive integer."
+msgstr "A méret csak pozitív egész szám lehet."
+
+#: text.module:0
+msgid "text"
+msgstr "szöveg"
+
+#: text.module:49; text.info:0
+msgid "Text"
+msgstr "Szöveg"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.nl.po
new file mode 100644
index 00000000000..670ce8348a0
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.nl.po
@@ -0,0 +1,147 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# text.module,v 1.95.2.28 2008/12/30 00:00:54 yched
+# text.info,v 1.9 2008/04/23 18:02:31 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:26+0200\n"
+"PO-Revision-Date: 2009-06-03 14:26+0200\n"
+"Last-Translator: NAME \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: text.module:41 text.info:0
+msgid "Text"
+msgstr "Tekst"
+
+#: text.module:42
+msgid "Store text in the database."
+msgstr "Bewaar tekst in de database."
+
+#: text.module:54;201
+msgid "Plain text"
+msgstr "Platte tekst"
+
+#: text.module:54
+msgid "Filtered text (user selects input format)"
+msgstr "Gefilterede tekst (gebruiker geeft invoerformaat op)"
+
+#: text.module:57
+msgid "Text processing"
+msgstr "Tekstverwerking"
+
+#: text.module:63
+msgid "Maximum length"
+msgstr "Maximum lengte"
+
+#: text.module:67
+msgid "The maximum length of the field in characters. Leave blank for an unlimited size."
+msgstr ""
+"De maximum lengte van het veld in karakters. Laat leeg voor "
+"ongelimiteerde grootte."
+
+#: text.module:71
+msgid "Allowed values"
+msgstr "Toegestane waardes"
+
+#: text.module:77
+msgid "Allowed values list"
+msgstr "Lijst met toegestane waardes"
+
+#: text.module:81
+msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified. Allowed HTML tags: @tags"
+msgstr ""
+"De mogelijke waardes die in dit veld kunnen staan. Voer één waarde "
+"per regel in, in het formaat sleutel|label. De sleutel wordt in de "
+"database opgeslagen en moet overeen komen met het veldopslagtype "
+"(%type). Het label is optioneel. Als geen label wordt ingevoerd zal de "
+"sleutel ook worden gebruikt als label. Toegestane HTML-tags: "
+"@tags"
+
+#: text.module:85
+msgid "PHP code"
+msgstr "PHP code"
+
+#: text.module:92;101
+msgid "Code"
+msgstr "Code"
+
+#: text.module:95
+msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above."
+msgstr ""
+"Alleen voor geavanceerd gebruik: PHP-code die een array met sleutels "
+"geeft van de toegestane waardes. Moet niet beginnen en eindigen met "
+"<?php ?>. Als dit veld in ingevuld zullen de bovenstaande "
+"toegestane waardes worden genegeerd."
+
+#: text.module:102
+msgid "<none>"
+msgstr "<geen>"
+
+#: text.module:103
+msgid "You're not allowed to input PHP code."
+msgstr "Je mag geen PHP-code gebruiken."
+
+#: text.module:103
+msgid "This PHP code was set by an administrator and will override the allowed values list above."
+msgstr ""
+"Deze PHP-code is door een beheerder ingesteld en zal worden uitgevoerd "
+"in plaats van de toegestane waardeslijst hierboven."
+
+#: text.module:132
+msgid "@label (!name) - Allowed values"
+msgstr "@label (!name) - Toegestane waardes"
+
+#: text.module:156
+msgid "%name: illegal value."
+msgstr "%name: niet toegestane waarde."
+
+#: text.module:159
+msgid "%name: the value may not be longer than %max characters."
+msgstr "%name: de waarde mag niet langer zijn dan %max karakters."
+
+#: text.module:196
+msgid "Default"
+msgstr "Standaard"
+
+#: text.module:206
+msgid "Trimmed"
+msgstr "Ingekort"
+
+#: text.module:256
+msgid "Text field"
+msgstr "Tekstveld"
+
+#: text.module:264
+msgid "Text area (multiple rows)"
+msgstr "Tekstveld (meerdere rijen)"
+
+#: text.module:316
+msgid "Size of textfield"
+msgstr "Maat van het tekstveld"
+
+#: text.module:325
+msgid "Rows"
+msgstr "Rijen"
+
+#: text.module:0
+msgid "text"
+msgstr "tekst"
+
+#: text.info:0
+msgid "Defines simple text field types."
+msgstr "Levert simpele tekstveldtypes."
+
+#: text.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.pot
new file mode 100644
index 00000000000..0313ebd39ad
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.pot
@@ -0,0 +1,65 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-text)
+# Copyright YEAR NAME
+# Generated from files:
+# text.module,v 1.95.2.29 2009/04/29 20:51:53 karens
+# text.info,v 1.9 2008/04/23 18:02:31 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/text/text.module:42
+msgid "Store text in the database."
+msgstr ""
+
+#: modules/text/text.module:55
+msgid "Filtered text (user selects input format)"
+msgstr ""
+
+#: modules/text/text.module:58
+msgid "Text processing"
+msgstr ""
+
+#: modules/text/text.module:64
+msgid "Maximum length"
+msgstr ""
+
+#: modules/text/text.module:68
+msgid "The maximum length of the field in characters. Leave blank for an unlimited size."
+msgstr ""
+
+#: modules/text/text.module:160
+msgid "%name: the value may not be longer than %max characters."
+msgstr ""
+
+#: modules/text/text.module:207
+msgid "Trimmed"
+msgstr ""
+
+#: modules/text/text.module:265
+msgid "Text area (multiple rows)"
+msgstr ""
+
+#: modules/text/text.module:326
+msgid "Rows"
+msgstr ""
+
+#: modules/text/text.module:0
+msgid "text"
+msgstr ""
+
+#: modules/text/text.info:0
+msgid "Defines simple text field types."
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.sv.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.sv.po
new file mode 100644
index 00000000000..54756ea98b9
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/text/translations/modules-text.sv.po
@@ -0,0 +1,135 @@
+# $Id$
+#
+# Swedish translation of Drupal (text)
+# Generated from files:
+# text.module,v 1.95.2.29 2009/04/29 20:51:53 karens
+# text.info,v 1.9 2008/04/23 18:02:31 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CCK - Text 6.x\n"
+"POT-Creation-Date: 2009-05-27 13:47+0200\n"
+"PO-Revision-Date: 2009-05-27 14:27+0100\n"
+"Last-Translator: Magnus Gunnarsson \n"
+"Language-Team: drupalsverige.se\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: Swedish\n"
+"X-Poedit-Country: SWEDEN\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: text.module:41
+#: text.info:0
+msgid "Text"
+msgstr "Text"
+
+#: text.module:42
+msgid "Store text in the database."
+msgstr "Lagra text i databasen."
+
+#: text.module:55;202
+msgid "Plain text"
+msgstr "Ren text"
+
+#: text.module:55
+msgid "Filtered text (user selects input format)"
+msgstr "Filtrerade text (användare väljer inmatningsformat)"
+
+#: text.module:58
+msgid "Text processing"
+msgstr "Bearbetning av text"
+
+#: text.module:64
+msgid "Maximum length"
+msgstr "Maximal längd"
+
+#: text.module:68
+msgid "The maximum length of the field in characters. Leave blank for an unlimited size."
+msgstr "Maximalt antal tecken för fältet. Lämna blankt för oändlig storlek."
+
+#: text.module:72
+msgid "Allowed values"
+msgstr "Tillåtna värden"
+
+#: text.module:78
+msgid "Allowed values list"
+msgstr "Tillåtna listvärden"
+
+#: text.module:82
+msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and it must match the field storage type (%type). The label is optional, and the key will be used as the label if no label is specified. Allowed HTML tags: @tags"
+msgstr "De möjliga värdena detta fält kan innehålla. Ange ett värde per rad i formatet nyckel/etikett. Denna nyckel är värdet som kommer att lagras i databasen och måste överensstämma typen för fältlagring (%type). Etikett är valfritt, och nyckeln som kommer att användas är etiketten om ingen etikett är specificerad. Tillåtna HTML-taggar: @tags"
+
+#: text.module:86
+msgid "PHP code"
+msgstr "PHP-kod"
+
+#: text.module:93;102
+msgid "Code"
+msgstr "Kod"
+
+#: text.module:96
+msgid "Advanced usage only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above."
+msgstr "Enbart avancerat användande: PHP-kod som skall returnera en spärrad lista av tillåtna värden. Skall inte inkludera avgränsarna <?php ?>. Om detta fält är ifyllt kommer listan som returneras av denna kod att åsidosätta det tillåtna värdet i listan ovan."
+
+#: text.module:103
+msgid "<none>"
+msgstr "<ingen>"
+
+#: text.module:104
+msgid "You're not allowed to input PHP code."
+msgstr "Du har inte tillåtelse att mata in PHP-kod."
+
+#: text.module:104
+msgid "This PHP code was set by an administrator and will override the allowed values list above."
+msgstr "Denna PHP-kod angavs av en administratör och kommer att åsidosätta det tillåtna värdet ovan."
+
+#: text.module:133
+msgid "@label (!name) - Allowed values"
+msgstr "@label (!name) - Tillåtna värden"
+
+#: text.module:157
+msgid "%name: illegal value."
+msgstr "%name: otillåtet värde."
+
+#: text.module:160
+msgid "%name: the value may not be longer than %max characters."
+msgstr "%name: värdet får inte vara längre än %max tecken."
+
+#: text.module:197
+msgid "Default"
+msgstr "Standard"
+
+#: text.module:207
+msgid "Trimmed"
+msgstr "Avkortad"
+
+#: text.module:257
+msgid "Text field"
+msgstr "Textfält"
+
+#: text.module:265
+msgid "Text area (multiple rows)"
+msgstr "Textområde (flera rader)"
+
+#: text.module:317
+msgid "Size of textfield"
+msgstr "Storlek på textfält"
+
+#: text.module:326
+msgid "Rows"
+msgstr "Rader"
+
+#: text.module:0
+msgid "text"
+msgstr "text"
+
+#: text.info:0
+msgid "Defines simple text field types."
+msgstr "Definierar enkla typer av textfält."
+
+#: text.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.help.ini b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.help.ini
new file mode 100644
index 00000000000..4b4cb95acfb
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.help.ini
@@ -0,0 +1,8 @@
+; $Id$
+
+[advanced help settings]
+hide = TRUE
+
+[userreference]
+title = Userreference field
+parent = content%fields
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.html b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.html
new file mode 100644
index 00000000000..ef8125172c2
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/help/userreference.html
@@ -0,0 +1,3 @@
+
The Userreference field stores the uid of a related user. The name of the related user is usually displayed as the value of this field.
+
The Userreference field can use an autocomplete widget, or, when used with Optionwidgets, the available values can be presented to the end user in a drop-down select list, checkboxes, or radios.
+
A Userreference field can be used in Views to create a Relationship to a user, to allow you to use any field, argument, or filter from the related user in your view.
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/panels/relationships/user_from_userref.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/panels/relationships/user_from_userref.inc
new file mode 100644
index 00000000000..4af22ad2680
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/panels/relationships/user_from_userref.inc
@@ -0,0 +1,65 @@
+ t('User from reference'),
+ 'keyword' => 'userreference',
+ 'description' => t('Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only.'),
+ 'required context' => new ctools_context_required(t('Node'), 'node'),
+ 'context' => 'userreference_user_from_userref_context',
+ 'settings form' => 'userreference_user_from_userref_settings_form',
+ 'settings form validate' => 'userreference_user_from_userref_settings_form_validate',
+ );
+}
+
+/**
+ * Return a new ctools context based on an existing context.
+ */
+function userreference_user_from_userref_context($context, $conf) {
+ // If unset it wants a generic, unfilled context, which is just NULL.
+ if (empty($context->data)) {
+ return ctools_context_create_empty('user', NULL);
+ }
+
+ // Prevent whitescreens on stale data.
+ if (empty($conf)) {
+ return ctools_context_create_empty('user', NULL);
+ }
+
+ if (isset($context->data->{$conf['field_name']}[0]['uid']) && ($uid = $context->data->{$conf['field_name']}[0]['uid'])) {
+ if ($account = user_load(array('uid' => $uid))) {
+ return ctools_context_create('user', $account);
+ }
+ }
+}
+
+/**
+ * Settings form for the ctools relationship.
+ */
+function userreference_user_from_userref_settings_form($conf) {
+ $options = array();
+ foreach (content_fields() as $field) {
+ if ($field['type'] == 'userreference') {
+ $options[$field['field_name']] = t($field['widget']['label']);
+ }
+ }
+ $form['field_name'] = array(
+ '#title' => t('User reference field'),
+ '#type' => 'select',
+ '#options' => $options,
+ '#default_value' => isset($conf['field_name']) ? $conf['field_name'] : '',
+ '#prefix' => '
',
+ '#suffix' => '
',
+ );
+
+ return $form;
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.de.po
new file mode 100644
index 00000000000..9e46e5d5b74
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.de.po
@@ -0,0 +1,42 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: 2009-06-16 19:12+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/userreference/panels/relationships/user_from_userref.inc:14
+msgid "User from reference"
+msgstr "Benutzer der Referenz"
+
+#: modules/userreference/panels/relationships/user_from_userref.inc:16
+msgid "Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only."
+msgstr ""
+
+#: modules/userreference/panels/relationships/user_from_userref.inc:50
+msgid "User reference field"
+msgstr "Benutzerreferenzfeld"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.pot
new file mode 100644
index 00000000000..37a78d6f466
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference-panels-relationships.pot
@@ -0,0 +1,31 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-userreference-panels-relationships)
+# Copyright YEAR NAME
+# Generated from file: user_from_userref.inc,v 1.1.2.1 2009/06/02 12:24:04 yched
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/userreference/panels/relationships/user_from_userref.inc:14
+msgid "User from reference"
+msgstr ""
+
+#: modules/userreference/panels/relationships/user_from_userref.inc:16
+msgid "Adds a user from a user reference in a node context; if multiple users are referenced, this will get the first referenced user only."
+msgstr ""
+
+#: modules/userreference/panels/relationships/user_from_userref.inc:50
+msgid "User reference field"
+msgstr ""
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.de.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.de.po
new file mode 100644
index 00000000000..3d7837ab138
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.de.po
@@ -0,0 +1,136 @@
+# $Id$
+# German translation of CCK
+# Copyright 2006 Lukas Gangoly
+# Copyright 2006 Jakob Petsovits
+# Generated from files:
+# field.php,v 1.3 2006/04/16 13:47:13 luke
+# text.module,v 1.34 2006/06/12 19:59:53 luke
+# number.module,v 1.28 2006/05/02 13:52:16 luke
+# content_admin.inc,v 1.16 2006/06/12 19:36:54 luke
+# content.module,v 1.64 2006/06/12 19:36:54 luke
+# nodereference.module,v 1.28 2006/06/12 19:36:54 luke
+# optionwidgets.module,v 1.8 2006/05/01 15:45:29 luke
+# userreference.module,v 1.24 2006/05/05 14:10:44 luke
+# weburl.module,v 1.8 2006/06/12 19:36:54 luke
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: German translation of CCK\n"
+"POT-Creation-Date: 2009-03-09 22:08+0100\n"
+"PO-Revision-Date: 2009-03-09 23:01+0100\n"
+"Last-Translator: Alexander Haß\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: modules/userreference/userreference.rules.inc:15
+msgid "Load a referenced user"
+msgstr "Einen referenzierten Benutzer laden"
+
+#: modules/userreference/userreference.rules.inc:19
+msgid "Content containing the user reference field"
+msgstr "Der Inhalt der das Benutzerreferenzfeld enthält"
+
+#: modules/userreference/userreference.rules.inc:25
+msgid "Referenced user"
+msgstr "Referenzierter Benutzer"
+
+#: modules/userreference/userreference.rules.inc:29
+msgid "Note that if the field has multiple values, only the first user will be loaded."
+msgstr "Sollte ein Feld mehrere Werte enthalten, wird nur der erste Benutzer geladen."
+
+#: modules/userreference/userreference.rules.inc:52
+msgid "There are no userreference fields defined."
+msgstr "Es sind keine Benutzerreferenzfelder vorhanden."
+
+#: modules/userreference/userreference.module:52
+msgid "User reference"
+msgstr "Benutzerreferenz"
+
+#: modules/userreference/userreference.module:53
+msgid "Store the ID of a related user as an integer value."
+msgstr "Speichert die ID eines zugehörigen Benutzers als ganzzahligen Wert."
+
+#: modules/userreference/userreference.module:67
+msgid "User roles that can be referenced"
+msgstr "Benutzerrollen auf die referenziert werden kann"
+
+#: modules/userreference/userreference.module:73
+msgid "User status that can be referenced"
+msgstr "Benutzerstatus der referenziert werden kann"
+
+#: modules/userreference/userreference.module:75
+msgid "Active"
+msgstr "Aktiv"
+
+#: modules/userreference/userreference.module:75
+msgid "Blocked"
+msgstr "Gesperrt"
+
+#: modules/userreference/userreference.module:94
+msgid "Advanced - Users that can be referenced (View)"
+msgstr "Erweitert - Benutzer die referenziert werden können (Ansicht)"
+
+#: modules/userreference/userreference.module:101
+msgid "View used to select the users"
+msgstr "Die zur Auswahl von Benutzern verwendete Ansicht"
+
+#: modules/userreference/userreference.module:104
+#, fuzzy
+msgid "
Choose the \"Views module\" view that selects the users that can be referenced. Note:
"
+msgstr "
Wähle die „Views-Modul“-Ansicht das die Beiträge auswählt, die Referenziert werden können. Hinweis:
Only views that have fields will work for this purpose.
This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.
Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.
Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.
"
+msgstr "
Nur Ansichten mit Feldern werden für diesen Zweck nutzbar sein.
Dies wird die obigen Einstellungen der „referenzierbaren Rollen“ und „referenzierbaren Status“ verwerfen. Stattdessen sollte hierfür der „Filter“-Bereich der Ansicht verwendet werden.
Um weitere Informationen über Beitragskandidaten für das Erstellungs-/Bearbeitungsformular anzuzeigen, kann das Ansichten-Feld verwendet werden.
Um die Reihenfolge der Beitragskandidaten festzulegen sollte das „Sortierkriterium“ von Ansichten verwendet werden.
The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. Note:
"
+msgstr ""
+
+#: modules/userreference/userreference.module:196
+msgid "%name: invalid user."
+msgstr "%name: Der Benutzer ist ungültig."
+
+#: modules/userreference/userreference.module:349
+msgid "Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of users."
+msgstr "Die Methode zur Sammlung von Autovervollständigungsvorschlägen auswählen. Dabei ist zu beachten, dass Enthält auf Websites mit tausenden von Benutzern große Performanceprobleme verursachen kann."
+
+#: modules/userreference/userreference.module:357
+msgid "Reverse link"
+msgstr "‚Zurück‘-Link"
+
+#: modules/userreference/userreference.module:359
+msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record."
+msgstr "Sobald ausgewählt, wird auf dem referenzierten Benutzerdatensatz ein ‚Zurück‘-Link zu dem referenzierten Beitrag angezeigt."
+
+#: modules/userreference/userreference.module:594
+msgid "%name: found no valid user with that name."
+msgstr "%name: Kein Benutzer mit diesem Namen gefunden."
+
+#: modules/userreference/userreference.module:889
+msgid "Related content"
+msgstr "Zugehöriger Inhalt"
+
+#: modules/userreference/userreference.module:15
+msgid "Userreference autocomplete"
+msgstr "Autovervollständigung der Benutzerreferenzen"
+
+#: modules/userreference/userreference.module:0
+msgid "userreference"
+msgstr "Benutzerreferenz"
+
+#: modules/userreference/userreference.info:0
+msgid "User Reference"
+msgstr "Benutzerreferenz"
+
+#: modules/userreference/userreference.info:0
+msgid "Defines a field type for referencing a user from a node."
+msgstr "Definiert einen Feldtyp mit dem von einem Beitrag auf einen Benutzer verwiesen werden kann."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.fr.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.fr.po
new file mode 100644
index 00000000000..3a9c8e6d81d
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.fr.po
@@ -0,0 +1,89 @@
+# translation of SB-cck-6.x-2.x-dev.po to
+# translation of cck-6.x-2.x-dev.po to
+msgid ""
+msgstr ""
+"Project-Id-Version: SB-cck-6.x-2.x-dev\n"
+"POT-Creation-Date: 2008-07-03 07:41+0200\n"
+"PO-Revision-Date: 2008-07-03 13:24+0100\n"
+"Last-Translator: Damien Tournoud \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: France\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: modules/userreference/userreference.module:52
+msgid "User reference"
+msgstr "Référence utilisateur"
+
+#: modules/userreference/userreference.module:53
+msgid "Store the ID of a related user as an integer value."
+msgstr ""
+"Enregistre l'identifiant d'un utilisateur associé, sous la forme d'une "
+"valeur entière."
+
+#: modules/userreference/userreference.module:71
+msgid "User roles that can be referenced"
+msgstr "Rôles utilisateur pouvant être référencés"
+
+#: modules/userreference/userreference.module:77
+msgid "User status that can be referenced"
+msgstr "Statuts utilisateur pouvant être référencés"
+
+#: modules/userreference/userreference.module:79
+msgid "Active"
+msgstr "Actif"
+
+#: modules/userreference/userreference.module:79
+msgid "Blocked"
+msgstr "Bloqué"
+
+#: modules/userreference/userreference.module:122
+msgid "%name: Invalid user."
+msgstr "Champ '%name' : utilisateur invalide."
+
+#: modules/userreference/userreference.module:253
+msgid "Reverse link"
+msgstr "Lien réciproque"
+
+#: modules/userreference/userreference.module:255
+msgid "No"
+msgstr "Non"
+
+#: modules/userreference/userreference.module:255
+msgid "Yes"
+msgstr "Oui"
+
+#: modules/userreference/userreference.module:257
+msgid ""
+"If selected, a reverse link back to the referencing node will displayed on "
+"the referenced user record."
+msgstr ""
+"Si cette option est sélectionnée, un lien réciproque vers le nœud "
+"référençant sera affiché dans l'enregistrement utilisateur référencé."
+
+#: modules/userreference/userreference.module:586
+msgid "Related content"
+msgstr "Contenus liés"
+
+#: modules/userreference/userreference.module:15
+msgid "Userreference autocomplete"
+msgstr "Autocomplètement de la référence utilisateur"
+
+#: modules/userreference/userreference.module:0
+msgid "userreference"
+msgstr "userreference"
+
+#: modules/userreference/userreference.info:0
+msgid "User Reference"
+msgstr "User Reference"
+
+#: modules/userreference/userreference.info:0
+msgid "Defines a field type for referencing a user from a node."
+msgstr ""
+"Définit un type de champ qui permet d'établir des liens entre les nœuds et "
+"les utilisateurs."
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.hu.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.hu.po
new file mode 100644
index 00000000000..1e1c86dcc72
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.hu.po
@@ -0,0 +1,137 @@
+# Hungarian translation of cck (6.x-2.0-rc10)
+# Copyright (c) 2008 by the Hungarian translation team
+# Generated from files:
+# userreference.module,v 1.106.2.21 2008/10/07 10:17:51 karens
+# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens
+# userreference.info,v 1.8 2008/04/23 18:02:38 dww
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cck (6.x-2.0-rc10)\n"
+"POT-Creation-Date: 2008-10-31 12:16-0500\n"
+"PO-Revision-Date: 2008-10-26 16:42-0500\n"
+"Last-Translator: Balogh Zoltán\n"
+"Language-Team: Drupal.hu Fordítói Csapat \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: modules/userreference/userreference.module:97
+msgid "Active"
+msgstr "Aktív"
+
+#: modules/userreference/userreference.module:97
+msgid "Blocked"
+msgstr "Blokkolt"
+
+#: modules/userreference/userreference.rules.inc:15
+msgid "Load a referenced user"
+msgstr "Egy hivatkozott felhasználó betöltése"
+
+#: modules/userreference/userreference.rules.inc:19
+msgid "Content containing the user reference field"
+msgstr "A felhasználóhivatkozás mező tartalma"
+
+#: modules/userreference/userreference.rules.inc:25
+msgid "Referenced user"
+msgstr "Hivatkozott felhasználó"
+
+#: modules/userreference/userreference.rules.inc:29
+msgid ""
+"Note that if the field has multiple values, only the first user will "
+"be loaded."
+msgstr ""
+"Megjegyzés: Ha a mezőnek több értéke is lehet, akkor csak az "
+"első felhasználó lesz betöltve."
+
+#: modules/userreference/userreference.rules.inc:52
+msgid "There are no userreference fields defined."
+msgstr "Nincsenek felhasználóhivatkozás mezők meghatározva."
+
+#: modules/userreference/userreference.module:70
+msgid "User reference"
+msgstr "Hivatkozás felhasználóra"
+
+#: modules/userreference/userreference.module:71
+msgid "Store the ID of a related user as an integer value."
+msgstr ""
+"A hivatkozott felhasználó azonosítójának tárolása egész "
+"számként."
+
+#: modules/userreference/userreference.module:89
+msgid "User roles that can be referenced"
+msgstr "Felhasználói csoport, amelyre hivatkozni lehet"
+
+#: modules/userreference/userreference.module:95
+msgid "User status that can be referenced"
+msgstr "Felhasználói állapot, amelyre hivatkozni lehet"
+
+#: modules/userreference/userreference.module:117
+msgid "Advanced - Users that can be referenced (View)"
+msgstr "Haladó - Felhasználók, akikre hivatkozni lehet (Nézet)"
+
+#: modules/userreference/userreference.module:123
+msgid "View used to select the users"
+msgstr "A felhasználók kiválasztásához használt nézet"
+
+#: modules/userreference/userreference.module:126
+msgid ""
+"Choose the \"Views module\" view that selects the users that can be "
+"referenced. Note:
Only views that have fields will work "
+"for this purpose.
This will discard the \"Referenceable "
+"Roles\" and \"Referenceable Status\" settings above. Use the view's "
+"\"filters\" section instead.
Use the view's \"fields\" section "
+"to display additional informations about candidate users on user "
+"creation/edition form.
Use the view's \"sort criteria\" "
+"section to determine the order in which candidate users will be "
+"displayed.
"
+msgstr ""
+"A „Nézet modul” egyik nézetének kiválasztása, mely azokat a "
+"felhasználókat mutatja, akikre hivatkozni "
+"lehet. Megjegyzés:
Itt csak olyan nézet működik, melynek "
+"vannak mezői.
Ez felülírja a fenti „Hivatkozható "
+"csoportok” és „Hivatkozható állapotok” beállításokat. A "
+"nézet „szűrő” feltétele használható e helyett.
A "
+"nézet „mezők” része használható arra, hogy bővebb "
+"információkat jelenítsen meg a lehetséges felhasználókról a "
+"szerkesztő űrlapon.
A nézet „sorrend” része "
+"befolyásolja a lehetséges felhasználók megjelenítési "
+"sorrendjét.
"
+
+#: modules/userreference/userreference.module:185
+msgid "%name: invalid user."
+msgstr "%name: érvénytelen felhasználó."
+
+#: modules/userreference/userreference.module:329
+msgid "Reverse link"
+msgstr "Visszamutató hivatkozás"
+
+#: modules/userreference/userreference.module:331
+msgid ""
+"If selected, a reverse link back to the referencing node will "
+"displayed on the referenced user record."
+msgstr ""
+"Ha be van jelölve, akkor a felhasználó adatlapján egy hivatkozás "
+"visszamutat a hivatkozó tartalomra."
+
+#: modules/userreference/userreference.module:830
+msgid "Related content"
+msgstr "Kapcsolódó tartalom"
+
+#: modules/userreference/userreference.module:15
+msgid "Userreference autocomplete"
+msgstr "Felhasználóhivatkozás automatikus kiegészítéssel"
+
+#: modules/userreference/userreference.module:0
+msgid "userreference"
+msgstr "felhasználóhivatkozás"
+
+#: modules/userreference/userreference.info:0
+msgid "User Reference"
+msgstr "Felhasználói hivatkozás"
+
+#: modules/userreference/userreference.info:0
+msgid "Defines a field type for referencing a user from a node."
+msgstr "Olyan mezőtípus, amely a tartalomban egy felhasználóra hivatkozik."
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.nl.po b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.nl.po
new file mode 100644
index 00000000000..efdea016f11
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.nl.po
@@ -0,0 +1,209 @@
+# $Id$
+#
+# Dutch translation of Drupal (general)
+# Copyright YEAR NAME
+# Generated from files:
+# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens
+# userreference.module,v 1.106.2.36 2009/03/18 21:00:58 yched
+# userreference.info,v 1.8 2008/04/23 18:02:38 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-03 14:26+0200\n"
+"PO-Revision-Date: 2009-06-03 14:26+0200\n"
+"Last-Translator: NAME \n"
+"Language-Team: Dutch \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+
+#: userreference.rules.inc:15
+msgid "Load a referenced user"
+msgstr "Laad een gerefereerde gebruiker"
+
+#: userreference.rules.inc:19
+msgid "Content containing the user reference field"
+msgstr "Inhoud dat het gebruikersreferentieveld bevat"
+
+#: userreference.rules.inc:25
+msgid "Referenced user"
+msgstr "Gerefereerde gebruiker"
+
+#: userreference.rules.inc:29
+msgid "Note that if the field has multiple values, only the first user will be loaded."
+msgstr ""
+"Merk op dat als het veld meerdere waardes heeft, alleen de eerste "
+"gebruiker zal worden geladen."
+
+#: userreference.rules.inc:47
+msgid "Field"
+msgstr "Veld"
+
+#: userreference.rules.inc:52
+msgid "There are no userreference fields defined."
+msgstr "Er zijn geen gebruikersreferentievelden ingesteld."
+
+#: userreference.module:52
+msgid "User reference"
+msgstr "Gebruikersreferentie"
+
+#: userreference.module:53
+msgid "Store the ID of a related user as an integer value."
+msgstr "Bewaar de ID van een gerelateerde gebruiker als een integer-waarde"
+
+#: userreference.module:67
+msgid "User roles that can be referenced"
+msgstr "Gebruikersrollen die kunnen worden gerefereerd"
+
+#: userreference.module:73
+msgid "User status that can be referenced"
+msgstr "Gebruikersstatus die kan worden gerefereerd"
+
+#: userreference.module:75
+msgid "Active"
+msgstr "Actief"
+
+#: userreference.module:75
+msgid "Blocked"
+msgstr "Geblokkeerd"
+
+#: userreference.module:84
+msgid "Default Views"
+msgstr "Standaard views"
+
+#: userreference.module:87
+msgid "Existing Views"
+msgstr "Bestaande Views"
+
+#: userreference.module:94
+msgid "Advanced - Users that can be referenced (View)"
+msgstr "Geavanceerd - Gebruikers die kunnen worden gerefereerd (View)"
+
+#: userreference.module:101
+msgid "View used to select the users"
+msgstr "View die gebruikt wordt om gebruikers te selecteren"
+
+#: userreference.module:104
+msgid "
Choose the \"Views module\" view that selects the users that can be referenced. Note:
"
+msgstr ""
+"
Kies de \"Views module\"-view die de gebruikers selecteert die "
+"kunnen worden gerefereerd. Merk op:
"
+
+#: userreference.module:105;118
+msgid "
Only views that have fields will work for this purpose.
This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.
Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.
Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.
"
+msgstr ""
+"
Alleen Views met velden zullen werken voor dit "
+"doel.
Dit zal de \"Refereerbare Rollen-\" en \"Refereerbare "
+"Status\"-instellingen boven negeren. Gebruik anders de view z'n "
+"\"filters\" sectie.
Gebruik de view z'n \"velden\"-sectie om "
+"extra informatie over gebruikers op het bewerkformulier weer te "
+"geven.
Gebruik de view z'n \"sorteercriteria\"-sectie om de "
+"volgorde te bepalen waarin gebruikers worden weergegeven.
"
+
+#: userreference.module:109
+msgid "View arguments"
+msgstr "Bekijk argumenten"
+
+#: userreference.module:112
+msgid "Provide a comma separated list of arguments to pass to the view."
+msgstr ""
+"Geef een door komma's gescheiden lijst met argumenten op om naar de "
+"view te sturen."
+
+#: userreference.module:117
+msgid "
The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. Note:
"
+msgstr ""
+"
De lijst met gebruikers die kunnen worden gerefereerd op basis van "
+"een \"Views module\"-view, maar geen passende views gevonden. Merk op:
"
+
+#: userreference.module:184
+msgid "%name: invalid input."
+msgstr "%name: geen toegestane waarde."
+
+#: userreference.module:196
+msgid "%name: invalid user."
+msgstr "%name: geen toegestane gebruiker."
+
+#: userreference.module:221
+msgid "Default"
+msgstr "Standaard"
+
+#: userreference.module:226
+msgid "Plain text"
+msgstr "Platte tekst"
+
+#: userreference.module:273
+msgid "Select list"
+msgstr "Selectielijst"
+
+#: userreference.module:281
+msgid "Check boxes/radio buttons"
+msgstr "Vinkje/radio buttons"
+
+#: userreference.module:289
+msgid "Autocomplete text field"
+msgstr "Automatisch aanvullend tekstveld"
+
+#: userreference.module:343
+msgid "Autocomplete matching"
+msgstr "Automatisch aanvullende overeenkomst"
+
+#: userreference.module:346
+msgid "Starts with"
+msgstr "Begint met"
+
+#: userreference.module:347
+msgid "Contains"
+msgstr "Bevat"
+
+#: userreference.module:349
+msgid "Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of users."
+msgstr ""
+"Selecteer de methode die wordt gebruikt om automatisch aangevulde "
+"suggesties te geven. Merk op Bevat prestatieproblemen kan "
+"veroorzaken op sites met vele duizenden gebruikers."
+
+#: userreference.module:357
+msgid "Reverse link"
+msgstr "Link terug"
+
+#: userreference.module:359
+msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record."
+msgstr ""
+"Als geselecteerd zal een links terug worden geplaatst naar de "
+"gerefereerde node in de gerefereerde gebruiker."
+
+#: userreference.module:594
+msgid "%name: found no valid user with that name."
+msgstr "%name: geen toegestane gebruiker gevonden met die naam."
+
+#: userreference.module:887
+msgid "Related content"
+msgstr "Gerelateerde inhoud"
+
+#: userreference.module:15
+msgid "Userreference autocomplete"
+msgstr "Gebruikersreferentie automatische aanvulling"
+
+#: userreference.module:0
+msgid "userreference"
+msgstr "gebruikersreferentie"
+
+#: userreference.info:0
+msgid "User Reference"
+msgstr "Gebruikersreferentie"
+
+#: userreference.info:0
+msgid "Defines a field type for referencing a user from a node."
+msgstr ""
+"Levert een veldtype for het refereren van een gebruiker vanuit een "
+"node."
+
+#: userreference.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.pot b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.pot
new file mode 100644
index 00000000000..38eaf2a2b47
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/translations/modules-userreference.pot
@@ -0,0 +1,126 @@
+# $Id$
+#
+# LANGUAGE translation of Drupal (modules-userreference)
+# Copyright YEAR NAME
+# Generated from files:
+# userreference.rules.inc,v 1.1.2.2 2008/10/06 15:02:03 karens
+# userreference.module,v 1.106.2.43 2009/06/02 12:24:04 yched
+# userreference.info,v 1.8 2008/04/23 18:02:38 dww
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2009-06-16 19:00+0200\n"
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
+"Last-Translator: NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: modules/userreference/userreference.rules.inc:15
+msgid "Load a referenced user"
+msgstr ""
+
+#: modules/userreference/userreference.rules.inc:19
+msgid "Content containing the user reference field"
+msgstr ""
+
+#: modules/userreference/userreference.rules.inc:25
+msgid "Referenced user"
+msgstr ""
+
+#: modules/userreference/userreference.rules.inc:29
+msgid "Note that if the field has multiple values, only the first user will be loaded."
+msgstr ""
+
+#: modules/userreference/userreference.rules.inc:52
+msgid "There are no userreference fields defined."
+msgstr ""
+
+#: modules/userreference/userreference.module:61
+msgid "User reference"
+msgstr ""
+
+#: modules/userreference/userreference.module:62
+msgid "Store the ID of a related user as an integer value."
+msgstr ""
+
+#: modules/userreference/userreference.module:77
+msgid "User roles that can be referenced"
+msgstr ""
+
+#: modules/userreference/userreference.module:83
+msgid "User status that can be referenced"
+msgstr ""
+
+#: modules/userreference/userreference.module:85
+msgid "Active"
+msgstr ""
+
+#: modules/userreference/userreference.module:85
+msgid "Blocked"
+msgstr ""
+
+#: modules/userreference/userreference.module:104
+msgid "Advanced - Users that can be referenced (View)"
+msgstr ""
+
+#: modules/userreference/userreference.module:111
+msgid "View used to select the users"
+msgstr ""
+
+#: modules/userreference/userreference.module:114
+msgid "
Choose the \"Views module\" view that selects the users that can be referenced. Note:
Only views that have fields will work for this purpose.
This will discard the \"Referenceable Roles\" and \"Referenceable Status\" settings above. Use the view's \"filters\" section instead.
Use the view's \"fields\" section to display additional informations about candidate users on user creation/edition form.
Use the view's \"sort criteria\" section to determine the order in which candidate users will be displayed.
"
+msgstr ""
+
+#: userreference.module:110
+msgid "View arguments"
+msgstr "Argument för vy"
+
+#: userreference.module:113
+msgid "Provide a comma separated list of arguments to pass to the view."
+msgstr "Tillhandahåll en kommaseparerad lista av argument att skicka till vyn."
+
+#: userreference.module:118
+msgid "
The list of user that can be referenced can be based on a \"Views module\" view but no appropriate views were found. Note:
"
+msgstr ""
+
+#: userreference.module:186
+msgid "%name: invalid input."
+msgstr "%name: ogiltig inmatning."
+
+#: userreference.module:198
+msgid "%name: invalid user."
+msgstr ""
+
+#: userreference.module:223
+msgid "Default"
+msgstr "Standard"
+
+#: userreference.module:228
+msgid "Plain text"
+msgstr "Ren text"
+
+#: userreference.module:275
+msgid "Select list"
+msgstr "Listval"
+
+#: userreference.module:283
+msgid "Check boxes/radio buttons"
+msgstr "Kryssrutor/radioknappar"
+
+#: userreference.module:291
+msgid "Autocomplete text field"
+msgstr "Automatiskt kompletterande textfält"
+
+#: userreference.module:346
+msgid "Autocomplete matching"
+msgstr "Automatiskt kompletterande som överensstämmer"
+
+#: userreference.module:349
+msgid "Starts with"
+msgstr "Börjar med"
+
+#: userreference.module:350
+msgid "Contains"
+msgstr "Innehåller"
+
+#: userreference.module:352
+msgid "Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of users."
+msgstr ""
+
+#: userreference.module:356
+msgid "Size of textfield"
+msgstr ""
+
+#: userreference.module:368
+msgid "Reverse link"
+msgstr ""
+
+#: userreference.module:370
+msgid "If selected, a reverse link back to the referencing node will displayed on the referenced user record."
+msgstr ""
+
+#: userreference.module:605
+msgid "%name: found no valid user with that name."
+msgstr ""
+
+#: userreference.module:899
+msgid "Related content"
+msgstr ""
+
+#: userreference.module:15
+msgid "Userreference autocomplete"
+msgstr ""
+
+#: userreference.module:0
+msgid "userreference"
+msgstr ""
+
+#: userreference.info:0
+msgid "User Reference"
+msgstr ""
+
+#: userreference.info:0
+msgid "Defines a field type for referencing a user from a node."
+msgstr ""
+
+#: userreference.info:0
+msgid "CCK"
+msgstr "CCK"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.info b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.info
new file mode 100644
index 00000000000..b128a00f0d4
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.info
@@ -0,0 +1,14 @@
+; $Id$
+name = User Reference
+description = Defines a field type for referencing a user from a node.
+dependencies[] = content
+dependencies[] = text
+dependencies[] = optionwidgets
+package = CCK
+core = 6.x
+; Information added by Drupal.org packaging script on 2015-06-17
+version = "6.x-2.10"
+core = "6.x"
+project = "cck"
+datestamp = "1434568159"
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.install b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.install
new file mode 100644
index 00000000000..2e0d3b13ffe
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.install
@@ -0,0 +1,153 @@
+ $fields) {
+ foreach ($fields as $field) {
+ if ($field['type'] == 'userreference') {
+ $sandbox['fields'][] = $field;
+ }
+ }
+ }
+
+ if (empty($sandbox['fields'])) {
+ return $ret;
+ }
+
+ $sandbox['progress'] = 0;
+ $sandbox['visited'] = array();
+ }
+
+ $field = $sandbox['fields'][$sandbox['progress']];
+
+ // We only want to process a field once -- if we hit it a second time,
+ // that means it's its own table and it should have already been updated.
+ if (!in_array($field['field_name'], $sandbox['visited'])) {
+ $db_info = content_database_info($field);
+ $table = $db_info['table'];
+ $attributes = $db_info['columns']['uid'];
+ $column = $attributes['column'];
+ if (!content_db_index_exists($table, $column)) {
+ db_add_index($ret, $table, $column, array($column));
+ }
+ $sandbox['visited'][] = $field['field_name'];
+ }
+
+ $sandbox['progress']++;
+ $ret['#finished'] = $sandbox['progress'] / count($sandbox['fields']);
+
+ return $ret;
+}
+
+/**
+ * Convert 'referenceable_status' option from array to integer to match the
+ * change in the field settings form where the element has been changed from
+ * a checkboxes element (array) to a radios element (integer).
+ *
+ * Reference: @link http://drupal.org/node/416134 @endlink
+ */
+function userreference_update_6002() {
+ $ret = array();
+
+ drupal_load('module', 'content');
+
+ $result = db_query("SELECT field_name, global_settings FROM {". content_field_tablename() ."} WHERE type = 'userreference'");
+ while ($userreference = db_fetch_object($result)) {
+ $global_settings = unserialize($userreference->global_settings);
+
+ if (isset($global_settings['referenceable_status']) && is_array($global_settings['referenceable_status'])) {
+ $referenceable_status = array_filter($global_settings['referenceable_status']);
+ $global_settings['referenceable_status'] = (!empty($referenceable_status) ? 1 : '');
+
+ // We can't use update_sql() here because of curly braces in serialized
+ // array.
+ db_query("UPDATE {". content_field_tablename() ."} SET global_settings = '%s' WHERE field_name = '%s'", serialize($global_settings), $userreference->field_name);
+ $ret[] = array(
+ 'success' => TRUE,
+ 'query' => t("The 'referenceable_status' option for %field has been fixed.", array('%field' => $userreference->field_name)),
+ );
+ }
+ }
+
+ // Rebuild content caches only if necessary.
+ if (!empty($ret)) {
+ content_clear_type_cache();
+ }
+
+ return $ret;
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.module b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.module
new file mode 100644
index 00000000000..daf2b50c8f1
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.module
@@ -0,0 +1,933 @@
+ 'Userreference autocomplete',
+ 'page callback' => 'userreference_autocomplete',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK
+ );
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function userreference_theme() {
+ return array(
+ 'userreference_select' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'userreference_buttons' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'userreference_autocomplete' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'userreference_formatter_default' => array(
+ 'arguments' => array('element'),
+ ),
+ 'userreference_formatter_plain' => array(
+ 'arguments' => array('element'),
+ ),
+ );
+}
+
+/**
+ * Implementaion of hook_ctools_plugin_directory().
+ */
+function userreference_ctools_plugin_directory($module, $plugin) {
+ if ($module == 'ctools' && $plugin == 'relationships') {
+ return 'panels/' . $plugin;
+ }
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function userreference_field_info() {
+ return array(
+ 'userreference' => array(
+ 'label' => t('User reference'),
+ 'description' => t('Store the ID of a related user as an integer value.'),
+// 'content_icon' => 'icon_content_noderef.png',
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_field_settings().
+ */
+function userreference_field_settings($op, $field) {
+ switch ($op) {
+ case 'form':
+ $form = array();
+ $form['referenceable_roles'] = array(
+ '#type' => 'checkboxes',
+ '#title' => t('User roles that can be referenced'),
+ '#default_value' => isset($field['referenceable_roles']) && is_array($field['referenceable_roles']) ? array_filter($field['referenceable_roles']) : array(),
+ '#options' => user_roles(1),
+ );
+ $form['referenceable_status'] = array(
+ '#type' => 'radios',
+ '#title' => t('User status that can be referenced'),
+ '#default_value' => isset($field['referenceable_status']) ? $field['referenceable_status'] : '',
+ '#options' => array('' => t('All users'), 1 => t('Active users'), 0 => t('Blocked users')),
+ );
+ if (module_exists('views')) {
+ $views = array('--' => '--');
+ $all_views = views_get_all_views();
+ foreach ($all_views as $view) {
+ // Only 'users' views that have fields will work for our purpose.
+ if ($view->base_table == 'users' && !empty($view->display['default']->display_options['fields'])) {
+ if ($view->type == 'Default') {
+ $views[t('Default Views')][$view->name] = $view->name;
+ }
+ else {
+ $views[t('Existing Views')][$view->name] = $view->name;
+ }
+ }
+ }
+
+ $form['advanced'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Advanced - Users that can be referenced (View)'),
+ '#collapsible' => TRUE,
+ '#collapsed' => !isset($field['advanced_view']) || $field['advanced_view'] == '--',
+ );
+ if (count($views) > 1) {
+ $form['advanced']['advanced_view'] = array(
+ '#type' => 'select',
+ '#title' => t('View used to select the users'),
+ '#options' => $views,
+ '#default_value' => isset($field['advanced_view']) ? $field['advanced_view'] : '--',
+ '#description' => t('
Choose the "Views module" view that selects the users that can be referenced. Note:
') .
+ t('
Only views that have fields will work for this purpose.
This will discard the "Referenceable Roles" and "Referenceable Status" settings above. Use the view\'s "filters" section instead.
Use the view\'s "fields" section to display additional informations about candidate users on user creation/edition form.
Use the view\'s "sort criteria" section to determine the order in which candidate users will be displayed.
'),
+ );
+ $form['advanced']['advanced_view_args'] = array(
+ '#type' => 'textfield',
+ '#title' => t('View arguments'),
+ '#default_value' => isset($field['advanced_view_args']) ? $field['advanced_view_args'] : '',
+ '#required' => FALSE,
+ '#description' => t('Provide a comma separated list of arguments to pass to the view.'),
+ );
+ }
+ else {
+ $form['advanced']['no_view_help'] = array(
+ '#value' => t('
The list of user that can be referenced can be based on a "Views module" view but no appropriate views were found. Note:
') .
+ t('
Only views that have fields will work for this purpose.
This will discard the "Referenceable Roles" and "Referenceable Status" settings above. Use the view\'s "filters" section instead.
Use the view\'s "fields" section to display additional informations about candidate users on user creation/edition form.
Use the view\'s "sort criteria" section to determine the order in which candidate users will be displayed.
'),
+ );
+ }
+ }
+ return $form;
+
+ case 'save':
+ $settings = array('referenceable_roles', 'referenceable_status');
+ if (module_exists('views')) {
+ $settings[] = 'advanced_view';
+ $settings[] = 'advanced_view_args';
+ }
+ return $settings;
+
+ case 'database columns':
+ $columns = array(
+ 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'index' => TRUE),
+ );
+ return $columns;
+
+ case 'views data':
+ $data = content_views_field_views_data($field);
+ $db_info = content_database_info($field);
+ $table_alias = content_views_tablename($field);
+
+ // Filter : swap the handler to the 'in' operator.
+ $data[$table_alias][$field['field_name'] .'_uid']['filter']['handler'] = 'content_handler_filter_many_to_one';
+ // Argument: get the user name for summaries.
+ // We need to join a new instance of the users table.
+ $data["users_$table_alias"]['table']['join']['node'] = array(
+ 'table' => 'users',
+ 'field' => 'uid',
+ 'left_table' => $table_alias,
+ 'left_field' => $field['field_name'] .'_uid',
+ );
+ $data[$table_alias][$field['field_name'] .'_uid']['argument']['handler'] = 'content_handler_argument_reference';
+ $data[$table_alias][$field['field_name'] .'_uid']['argument']['name table'] = "users_$table_alias";
+ $data[$table_alias][$field['field_name'] .'_uid']['argument']['name field'] = 'name';
+ // Relationship: Add a relationship for related user.
+ $data[$table_alias][$field['field_name'] .'_uid']['relationship'] = array(
+ 'base' => 'users',
+ 'field' => $db_info['columns']['uid']['column'],
+ 'handler' => 'content_handler_relationship',
+ 'label' => t($field['widget']['label']),
+ 'content_field_name' => $field['field_name'],
+ );
+ return $data;
+
+ }
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function userreference_field($op, &$node, $field, &$items, $teaser, $page) {
+ switch ($op) {
+ case 'validate':
+ // Extract uids to check.
+ $ids = array();
+ foreach ($items as $delta => $item) {
+ if (is_array($item) && !empty($item['uid'])) {
+ if (is_numeric($item['uid'])) {
+ $ids[] = $item['uid'];
+ }
+ else {
+ $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
+ if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']);
+ form_set_error($error_element, t('%name: invalid input.', array('%name' => t($field['widget']['label']))));
+ }
+ }
+ }
+ // Prevent performance hog if there are no ids to check.
+ if ($ids) {
+ $refs = _userreference_potential_references($field, '', NULL, $ids);
+ foreach ($items as $delta => $item) {
+ if (is_array($item)) {
+ $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
+ if (is_array($item) && isset($item['_error_element'])) unset($item['_error_element']);
+ if (!empty($item['uid']) && !isset($refs[$item['uid']])) {
+ form_set_error($error_element, t('%name: invalid user.', array('%name' => t($field['widget']['label']))));
+ }
+ }
+ }
+ }
+ return $items;
+ }
+}
+
+/**
+ * Implementation of hook_content_is_empty().
+ */
+function userreference_content_is_empty($item, $field) {
+ if (empty($item['uid'])) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of hook_field_formatter_info().
+ */
+function userreference_field_formatter_info() {
+ return array(
+ 'default' => array(
+ 'label' => t('Default'),
+ 'field types' => array('userreference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ 'plain' => array(
+ 'label' => t('Plain text'),
+ 'field types' => array('userreference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ ),
+ );
+}
+
+/**
+ * Theme function for 'default' userreference field formatter.
+ */
+function theme_userreference_formatter_default($element) {
+ $output = '';
+
+ if (isset($element['#item']['uid']) && $account = user_load(array('uid' => $element['#item']['uid']))) {
+ $output = theme('username', $account);
+ }
+ return $output;
+}
+
+/**
+ * Theme function for 'plain' userreference field formatter.
+ */
+function theme_userreference_formatter_plain($element) {
+ $output = '';
+ if (isset($element['#item']['uid']) && $account = user_load(array('uid' => $element['#item']['uid']))) {
+ $output = $account->name;
+ }
+ return $output;
+}
+
+/**
+ * Implementation of hook_widget_info().
+ *
+ * We need custom handling of multiple values for the userreference_select
+ * widget because we need to combine them into a options list rather
+ * than display multiple elements.
+ *
+ * We will use the content module's default handling for default value.
+ *
+ * Callbacks can be omitted if default handing is used.
+ * They're included here just so this module can be used
+ * as an example for custom modules that might do things
+ * differently.
+ */
+function userreference_widget_info() {
+ return array(
+ 'userreference_select' => array(
+ 'label' => t('Select list'),
+ 'field types' => array('userreference'),
+ 'multiple values' => CONTENT_HANDLE_MODULE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ 'userreference_buttons' => array(
+ 'label' => t('Check boxes/radio buttons'),
+ 'field types' => array('userreference'),
+ 'multiple values' => CONTENT_HANDLE_MODULE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ 'userreference_autocomplete' => array(
+ 'label' => t('Autocomplete text field'),
+ 'field types' => array('userreference'),
+ 'multiple values' => CONTENT_HANDLE_CORE,
+ 'callbacks' => array(
+ 'default value' => CONTENT_CALLBACK_DEFAULT,
+ ),
+ ),
+ );
+}
+
+/**
+ * Implementation of FAPI hook_elements().
+ *
+ * Any FAPI callbacks needed for individual widgets can be declared here,
+ * and the element will be passed to those callbacks for processing.
+ *
+ * Drupal will automatically theme the element using a theme with
+ * the same name as the hook_elements key.
+ *
+ * Autocomplete_path is not used by text_widget but other widgets can use it
+ * (see nodereference and userreference).
+ */
+function userreference_elements() {
+ return array(
+ 'userreference_select' => array(
+ '#input' => TRUE,
+ '#columns' => array('uid'), '#delta' => 0,
+ '#process' => array('userreference_select_process'),
+ ),
+ 'userreference_buttons' => array(
+ '#input' => TRUE,
+ '#columns' => array('uid'), '#delta' => 0,
+ '#process' => array('userreference_buttons_process'),
+ ),
+ 'userreference_autocomplete' => array(
+ '#input' => TRUE,
+ '#columns' => array('name'), '#delta' => 0,
+ '#process' => array('userreference_autocomplete_process'),
+ '#autocomplete_path' => FALSE,
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_widget_settings().
+ */
+function userreference_widget_settings($op, $widget) {
+ switch ($op) {
+ case 'form':
+ $form = array();
+ $match = isset($widget['autocomplete_match']) ? $widget['autocomplete_match'] : 'contains';
+ $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60;
+ if ($widget['type'] == 'userreference_autocomplete') {
+ $form['autocomplete_match'] = array(
+ '#type' => 'select',
+ '#title' => t('Autocomplete matching'),
+ '#default_value' => $match,
+ '#options' => array(
+ 'starts_with' => t('Starts with'),
+ 'contains' => t('Contains'),
+ ),
+ '#description' => t('Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of users.'),
+ );
+ $form['size'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Size of textfield'),
+ '#default_value' => $size,
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#required' => TRUE,
+ );
+ }
+ else {
+ $form['autocomplete_match'] = array('#type' => 'hidden', '#value' => $match);
+ $form['size'] = array('#type' => 'hidden', '#value' => $size);
+ }
+ $form['reverse_link'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Reverse link'),
+ '#default_value' => isset($widget['reverse_link']) ? $widget['reverse_link'] : 0,
+ '#description' => t('If selected, a reverse link back to the referencing node will displayed on the referenced user record.'),
+ );
+ return $form;
+
+ case 'save':
+ return array('autocomplete_match', 'size', 'reverse_link');
+ }
+}
+
+/**
+ * Implementation of hook_widget().
+ *
+ * Attach a single form element to the form. It will be built out and
+ * validated in the callback(s) listed in hook_elements. We build it
+ * out in the callbacks rather than here in hook_widget so it can be
+ * plugged into any module that can provide it with valid
+ * $field information.
+ *
+ * Content module will set the weight, field name and delta values
+ * for each form element. This is a change from earlier CCK versions
+ * where the widget managed its own multiple values.
+ *
+ * If there are multiple values for this field, the content module will
+ * call this function as many times as needed.
+ *
+ * @param $form
+ * the entire form array, $form['#node'] holds node information
+ * @param $form_state
+ * the form_state, $form_state['values'][$field['field_name']]
+ * holds the field's form values.
+ * @param $field
+ * the field array
+ * @param $items
+ * array of default values for this field
+ * @param $delta
+ * the order of this item in the array of subelements (0, 1, 2, etc)
+ *
+ * @return
+ * the form item for a single element for this field
+ */
+function userreference_widget(&$form, &$form_state, $field, $items, $delta = 0) {
+ switch ($field['widget']['type']) {
+ case 'userreference_select':
+ $element = array(
+ '#type' => 'userreference_select',
+ '#default_value' => $items,
+ );
+ break;
+
+ case 'userreference_buttons':
+ $element = array(
+ '#type' => 'userreference_buttons',
+ '#default_value' => $items,
+ );
+ break;
+
+ case 'userreference_autocomplete':
+ $element = array(
+ '#type' => 'userreference_autocomplete',
+ '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL,
+ '#value_callback' => 'userreference_autocomplete_value',
+ );
+ break;
+ }
+ return $element;
+}
+
+/**
+ * Value for a userreference autocomplete element.
+ *
+ * Substitute in the user name for the uid.
+ */
+function userreference_autocomplete_value($element, $edit = FALSE) {
+ $field_key = $element['#columns'][0];
+ if (!empty($element['#default_value'][$field_key])) {
+ $value = db_result(db_query("SELECT name FROM {users} WHERE uid = '%d'", $element['#default_value'][$field_key]));
+ return array($field_key => $value);
+ }
+ return array($field_key => NULL);
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function userreference_select_process($element, $edit, $form_state, $form) {
+ // The userreference_select widget doesn't need to create its own
+ // element, it can wrap around the optionwidgets_select element.
+ // Add a validation step where the value can be unwrapped.
+ $field_key = $element['#columns'][0];
+ $element[$field_key] = array(
+ '#type' => 'optionwidgets_select',
+ '#default_value' => isset($element['#value']) ? $element['#value'] : '',
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#required' => $element['#required'],
+ '#description' => $element['#description'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+ if (empty($element[$field_key]['#element_validate'])) {
+ $element[$field_key]['#element_validate'] = array();
+ }
+ array_unshift($element[$field_key]['#element_validate'], 'userreference_optionwidgets_validate');
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $form['#field_info'][$element['#field_name']].
+ */
+function userreference_buttons_process($element, $edit, $form_state, $form) {
+ // The userreference_select widget doesn't need to create its own
+ // element, it can wrap around the optionwidgets_select element.
+ // Add a validation step where the value can be unwrapped.
+ $field_key = $element['#columns'][0];
+ $element[$field_key] = array(
+ '#type' => 'optionwidgets_buttons',
+ '#default_value' => isset($element['#value']) ? $element['#value'] : '',
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#required' => $element['#required'],
+ '#description' => $element['#description'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+ if (empty($element[$field_key]['#element_validate'])) {
+ $element[$field_key]['#element_validate'] = array();
+ }
+ array_unshift($element[$field_key]['#element_validate'], 'userreference_optionwidgets_validate');
+ return $element;
+}
+
+/**
+ * Process an individual element.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ */
+function userreference_autocomplete_process($element, $edit, $form_state, $form) {
+ // The userreference autocomplete widget doesn't need to create its own
+ // element, it can wrap around the text_textfield element and add an autocomplete
+ // path and some extra processing to it.
+ // Add a validation step where the value can be unwrapped.
+ $field_key = $element['#columns'][0];
+
+ $element[$field_key] = array(
+ '#type' => 'text_textfield',
+ '#default_value' => isset($element['#value']) ? $element['#value'] : '',
+ '#autocomplete_path' => 'userreference/autocomplete/'. $element['#field_name'],
+ // The following values were set by the content module and need
+ // to be passed down to the nested element.
+ '#title' => $element['#title'],
+ '#required' => $element['#required'],
+ '#description' => $element['#description'],
+ '#field_name' => $element['#field_name'],
+ '#type_name' => $element['#type_name'],
+ '#delta' => $element['#delta'],
+ '#columns' => $element['#columns'],
+ );
+ if (empty($element[$field_key]['#element_validate'])) {
+ $element[$field_key]['#element_validate'] = array();
+ }
+ array_unshift($element[$field_key]['#element_validate'], 'userreference_autocomplete_validate');
+
+ // Used so that hook_field('validate') knows where to flag an error.
+ $element['_error_element'] = array(
+ '#type' => 'value',
+ // Wrapping the element around a text_textfield element creates a
+ // nested element, so the final id will look like 'field-name-0-uid-uid'.
+ '#value' => implode('][', array_merge($element['#parents'], array($field_key, $field_key))),
+ );
+ return $element;
+}
+
+/**
+ * Validate a select/buttons element.
+ *
+ * Remove the wrapper layer and set the right element's value.
+ * We don't know exactly where this element is, so we drill down
+ * through the element until we get to our key.
+ *
+ * We use $form_state['values'] instead of $element['#value']
+ * to be sure we have the most accurate value when other modules
+ * like optionwidgets are using #element_validate to alter the value.
+ */
+function userreference_optionwidgets_validate($element, &$form_state) {
+ $field_key = $element['#columns'][0];
+
+ $value = $form_state['values'];
+ $new_parents = array();
+ foreach ($element['#parents'] as $parent) {
+ $value = $value[$parent];
+ // Use === to be sure we get right results if parent is a zero (delta) value.
+ if ($parent === $field_key) {
+ $element['#parents'] = $new_parents;
+ form_set_value($element, $value, $form_state);
+ break;
+ }
+ $new_parents[] = $parent;
+ }
+}
+
+/**
+ * Validate an autocomplete element.
+ *
+ * Remove the wrapper layer and set the right element's value.
+ * This will move the nested value at 'field-name-0-uid-uid'
+ * back to its original location, 'field-name-0-uid'.
+ */
+function userreference_autocomplete_validate($element, &$form_state) {
+ $field_name = $element['#field_name'];
+ $type_name = $element['#type_name'];
+ $field = content_fields($field_name, $type_name);
+ $field_key = $element['#columns'][0];
+ $value = $element['#value'][$field_key];
+ $uid = NULL;
+ if (!empty($value)) {
+ $reference = _userreference_potential_references($field, $value, 'equals', NULL, 1);
+ if (empty($reference)) {
+ form_error($element[$field_key], t('%name: found no valid user with that name.', array('%name' => t($field['widget']['label']))));
+ }
+ else {
+ $uid = key($reference);
+ }
+ }
+ form_set_value($element, $uid, $form_state);
+}
+
+/**
+ * Implementation of hook_allowed_values().
+ */
+function userreference_allowed_values($field) {
+ $references = _userreference_potential_references($field);
+
+ $options = array();
+ foreach ($references as $key => $value) {
+ $options[$key] = $value['rendered'];
+ }
+
+ return $options;
+}
+
+/**
+ * Fetch an array of all candidate referenced users.
+ *
+ * This info is used in various places (aloowed values, autocomplete results,
+ * input validation...). Some of them only need the uids, others nid + names,
+ * others yet uid + names + rendered row (for display in widgets).
+ * The array we return contains all the potentially needed information, and lets
+ * consumers use the parts they actually need.
+ *
+ * @param $field
+ * The field description.
+ * @param $string
+ * Optional string to filter usernames on (used by autocomplete)
+ * @param $match
+ * Operator to match filtered name against, can be any of:
+ * 'contains', 'equals', 'starts_with'
+ * @param $ids
+ * Optional user ids to lookup (the $string and $match arguments will be
+ * ignored).
+ * @param $limit
+ * If non-zero, limit the size of the result set.
+ *
+ * @return
+ * An array of valid users in the form:
+ * array(
+ * uid => array(
+ * 'title' => The user name,
+ * 'rendered' => The text to display in widgets (can be HTML)
+ * ),
+ * ...
+ * )
+ */
+function _userreference_potential_references($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) {
+ static $results = array();
+
+ // Create unique id for static cache.
+ $cid = $field['field_name'] .':'. $match .':'. ($string !== '' ? $string : implode('-', $ids)) .':'. $limit;
+ if (!isset($results[$cid])) {
+ $references = FALSE;
+ if (module_exists('views') && !empty($field['advanced_view']) && $field['advanced_view'] != '--') {
+ $references = _userreference_potential_references_views($field, $string, $match, $ids, $limit);
+ }
+ // If the view doesn't exist, we got FALSE, and fallback to the regular 'standard mode'.
+
+ if ($references === FALSE) {
+ $references = _userreference_potential_references_standard($field, $string, $match, $ids, $limit);
+ }
+
+ // Store the results.
+ $results[$cid] = !empty($references) ? $references : array();
+ }
+
+ return $results[$cid];
+}
+
+/**
+ * Helper function for _userreference_potential_references():
+ * case of Views-defined referenceable users.
+ */
+function _userreference_potential_references_views($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) {
+ $view_name = $field['advanced_view'];
+
+ if ($view = views_get_view($view_name)) {
+ // We add a display, and let it derive from the 'default' display.
+ // TODO: We should let the user pick a display in the fields settings - sort of requires AHAH...
+ $display = $view->add_display('content_references');
+ $view->set_display($display);
+
+ // TODO from merlinofchaos on IRC : arguments using summary view can defeat the style setting.
+ // We might also need to check if there's an argument, and set *its* style_plugin as well.
+ $view->display_handler->set_option('style_plugin', 'content_php_array_autocomplete');
+ $view->display_handler->set_option('row_plugin', 'fields');
+ // Used in content_plugin_style_php_array::render(), to get
+ // the 'field' to be used as title.
+ $view->display_handler->set_option('content_title_field', 'name');
+
+ // Additional options to let content_plugin_display_references::query()
+ // narrow the results.
+ $options = array(
+ 'table' => 'users',
+ 'field_string' => 'name',
+ 'string' => $string,
+ 'match' => $match,
+ 'field_id' => 'uid',
+ 'ids' => $ids,
+ );
+ $view->display_handler->set_option('content_options', $options);
+
+ // TODO : for consistency, a fair amount of what's below
+ // should be moved to content_plugin_display_references
+
+ // Limit result set size.
+ $limit = isset($limit) ? $limit : 0;
+ $view->display_handler->set_option('items_per_page', $limit);
+
+ // Get arguments for the view.
+ if (!empty($field['advanced_view_args'])) {
+ // TODO: Support Tokens using token.module ?
+ $view_args = array_map('trim', explode(',', $field['advanced_view_args']));
+ }
+ else {
+ $view_args = array();
+ }
+
+ // We do need name field, so add it if not present (unlikely, but...)
+ $fields = $view->get_items('field', $display);
+ if (!isset($fields['name'])) {
+ $view->add_item($display, 'field', 'users', 'name');
+ }
+
+ // If not set, make all fields inline and define a separator.
+ $options = $view->display_handler->get_option('row_options');
+ if (empty($options['inline'])) {
+ $options['inline'] = drupal_map_assoc(array_keys($view->get_items('field', $display)));
+ }
+ if (empty($options['separator'])) {
+ $options['separator'] = '-';
+ }
+ $view->display_handler->set_option('row_options', $options);
+
+ // Make sure the query is not cached
+ $view->is_cacheable = FALSE;
+
+ // Get the results.
+ $result = $view->execute_display($display, $view_args);
+ }
+ else {
+ $result = FALSE;
+ }
+
+ return $result;
+}
+
+/**
+ * Helper function for _userreference_potential_references():
+ * referenceable users defined by user role and status
+ */
+function _userreference_potential_references_standard($field, $string = '', $match = 'contains', $ids = array(), $limit = NULL) {
+ $where = array();
+ $args = array();
+ $join = array();
+
+ if ($string !== '') {
+ $like = $GLOBALS["db_type"] == 'pgsql' ? "ILIKE" : "LIKE";
+ $match_clauses = array(
+ 'contains' => "$like '%%%s%%'",
+ 'equals' => "= '%s'",
+ 'starts_with' => "$like '%s%%'",
+ );
+ $where[] = 'u.name '. (isset($match_clauses[$match]) ? $match_clauses[$match] : $match_clauses['contains']);
+ $args[] = $string;
+ }
+ elseif ($ids) {
+ $where[] = 'u.uid IN (' . db_placeholders($ids) . ')';
+ $args = array_merge($args, $ids);
+ }
+ else {
+ $where[] = "u.uid > 0";
+ }
+
+ $roles = array();
+ if (isset($field['referenceable_roles']) && is_array($field['referenceable_roles'])) {
+ // keep only selected checkboxes
+ $roles = array_filter($field['referenceable_roles']);
+ // filter invalid values that seems to get through sometimes ??
+ $roles = array_intersect(array_keys(user_roles(1)), $roles);
+ }
+ if (!empty($roles) && !in_array(DRUPAL_AUTHENTICATED_RID, $roles)) {
+ $where[] = "r.rid IN (". implode($roles, ',') .")";
+ $join[] = 'LEFT JOIN {users_roles} r ON u.uid = r.uid';
+ }
+
+ if (isset($field['referenceable_status']) && is_numeric($field['referenceable_status'])) {
+ $where[] = 'u.status = %d';
+ $args[] = $field['referenceable_status'];
+ }
+
+ $users = array();
+ $where_clause = $where ? 'WHERE ('. implode(') AND (', $where) .')' : '';
+ $result = db_query('SELECT u.name, u.uid FROM {users} u '. implode(' ', $join) ." $where_clause ORDER BY u.name ASC", $args);
+ while ($user = db_fetch_object($result)) {
+ $users[$user->uid] = array(
+ 'title' => $user->name,
+ 'rendered' => check_plain($user->name),
+ );
+ }
+ return $users;
+}
+
+/**
+ * Menu callback; Retrieve a pipe delimited string of autocomplete suggestions for existing users
+ */
+function userreference_autocomplete($field_name, $string = '') {
+ $fields = content_fields();
+ $field = $fields[$field_name];
+ $match = isset($field['widget']['autocomplete_match']) ? $field['widget']['autocomplete_match'] : 'contains';
+ $matches = array();
+
+ $references = _userreference_potential_references($field, $string, $match, array(), 10);
+ foreach ($references as $id => $row) {
+ // Add a class wrapper for a few required CSS overrides.
+ $matches[$row['title']] = '
'. $row['rendered'] . '
';
+ }
+ drupal_json($matches);
+}
+
+/**
+ * Implementation of hook_user().
+ */
+function userreference_user($type, &$edit, &$account) {
+ switch ($type) {
+ case 'load':
+ // Only add links if we are on the user 'view' page.
+ if (arg(0) != 'user' || arg(2)) {
+ return;
+ }
+ // find CCK userreference field tables
+ // search through them for matching user ids and load those nodes
+ $additions = array();
+ $types = content_types();
+
+ // Find the table and columns to search through, if the same
+ // table comes up in more than one content type, we only need
+ // to search it once.
+ $search_tables = array();
+ foreach ($types as $type_name => $type) {
+ foreach ($type['fields'] as $field) {
+ // Only add tables when reverse link has been selected.
+ if ($field['type'] == 'userreference' && !empty($field['widget']['reverse_link'])) {
+ $db_info = content_database_info($field);
+ $search_tables[$db_info['table']][] = $db_info['columns']['uid']['column'];
+ }
+ }
+ }
+ foreach ($search_tables as $table => $columns) {
+ foreach ($columns as $column) {
+ $ids = db_query(db_rewrite_sql("SELECT DISTINCT(n.nid), n.title, n.type FROM {node} n LEFT JOIN {". $table ."} f ON n.vid = f.vid WHERE f.". $column ."=". $account->uid. " AND n.status = 1"));
+ while ($data = db_fetch_object($ids)) {
+ $additions[$data->type][$data->nid] = $data->title;
+ }
+ }
+ }
+ $account->userreference = $additions;
+ break;
+
+ case 'view':
+ if (!empty($account->userreference)) {
+ $node_types = content_types();
+ $additions = array();
+ $values = array();
+ foreach ($account->userreference as $node_type => $nodes) {
+ foreach ($nodes as $nid => $title) {
+ $values[$node_type][] = l($title, 'node/'. $nid);
+ }
+ if (isset($values[$node_type])) {
+ $additions[] = array(
+ '#type' => 'user_profile_item',
+ '#title' => check_plain($node_types[$node_type]['name']),
+ '#value' => theme('item_list', $values[$node_type]),
+ );
+ }
+ }
+ if ($additions) {
+ $account->content['userreference'] = $additions + array(
+ '#type' => 'user_profile_category',
+ '#attributes' => array('class' => 'user-member'),
+ '#title' => t('Related content'),
+ '#weight' => 10,
+ );
+ }
+ }
+ break;
+ }
+}
+
+/**
+ * FAPI theme for an individual elements.
+ *
+ * The textfield or select is already rendered by the
+ * textfield or select themes and the html output
+ * lives in $element['#children']. Override this theme to
+ * make custom changes to the output.
+ *
+ * $element['#field_name'] contains the field name
+ * $element['#delta] is the position of this element in the group
+ */
+function theme_userreference_select($element) {
+ return $element['#children'];
+}
+
+function theme_userreference_buttons($element) {
+ return $element['#children'];
+}
+
+function theme_userreference_autocomplete($element) {
+ return $element['#children'];
+}
\ No newline at end of file
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.rules.inc b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.rules.inc
new file mode 100644
index 00000000000..454df99cae1
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/modules/userreference/userreference.rules.inc
@@ -0,0 +1,62 @@
+ t('Load a referenced user'),
+ 'arguments' => array(
+ 'node' => array(
+ 'type' => 'node',
+ 'label' => t('Content containing the user reference field'),
+ ),
+ ),
+ 'new variables' => array(
+ 'referenced_user' => array(
+ 'type' => 'user',
+ 'label' => t('Referenced user'),
+ ),
+ ),
+ 'module' => 'CCK',
+ 'help' => t('Note that if the field has multiple values, only the first user will be loaded.'),
+ );
+ return $info;
+}
+
+function userreference_rules_action_load($node, $settings) {
+ $uid = $node->{$settings['field']}[0]['uid'];
+ if (isset($uid)) {
+ $user = user_load(array('uid' => $uid));
+ return array('referenced_user' => $user);
+ }
+}
+
+function userreference_rules_action_load_form($settings, &$form) {
+ $settings += array('field' => '');
+ $options = content_rules_get_field_names_by_type('userreference');
+ $form['settings']['field'] = array(
+ '#type' => 'select',
+ '#title' => t('Field'),
+ '#default_value' => $settings['field'],
+ '#options' => $options,
+ '#required' => TRUE,
+ '#disabled' => empty($options),
+ '#description' => empty($options) ? t('There are no userreference fields defined.') : '',
+ );
+}
+
+/**
+ * Helps upgrading from the workflow-ng action.
+ * "workflow_ng_action_load_referenced_user" to the equivalent rules action.
+ */
+function workflow_ng_action_load_referenced_user_upgrade(&$element) {
+ $element['#name'] = 'userreference_rules_action_load';
+}
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/tests/content.crud.test b/drupal/sites/default/boinc/modules/contrib/cck/tests/content.crud.test
new file mode 100644
index 00000000000..070a3d0a1af
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/tests/content.crud.test
@@ -0,0 +1,1236 @@
+ array(
+ * 'st_f1' => array('delta', 'field_f1' => array('value, 'format')),
+ * 'st_f2' => NULL, // no content_field_f2 table
+ * ),
+ * 'per_type' => array(
+ * 'st_t1' => array('field_f2' => array('value'), 'field_f3' => array('value', 'format')),
+ * 'st_t2' => array(), // only 'nid' and 'vid' columns
+ * 'st_t3' => NULL, // no content_type_t3 table
+ * ),
+ * )
+ * Then the database and schema will be checked to ensure that:
+ * content_st_f1 table contains fields nid, vid, delta, field_f1_value, field_f1_format
+ * content_st_f2 table is absent
+ * content_type_st_t1 table contains fields nid, vid, field_f2_value, field_f3_value, field_f3_format
+ * content_type_st_t2 table contains fields nid, vid
+ * content_type_st_t3 table is absent
+ */
+ function assertSchemaMatchesTables($tables) {
+ $groups = array('per_field' => 'content_', 'per_type' => 'content_type_');
+
+ foreach ($groups as $group => $table_prefix) {
+ if (isset($tables[$group])) {
+ foreach ($tables[$group] as $entity => $columns) {
+ if (isset($columns)) {
+ $db_columns = array('nid', 'vid');
+ foreach ($columns as $prefix => $items) {
+ if (is_array($items)) {
+ foreach ($items as $item) {
+ $db_columns[] = $prefix .'_'. $item;
+ }
+ }
+ else {
+ $db_columns[] = $items;
+ }
+ }
+ $this->_assertSchemaMatches($table_prefix . $entity, $db_columns);
+ }
+ else {
+ $this->_assertTableNotExists($table_prefix . $entity);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper function for assertSchemaMatchesTables
+ * Checks that the given database table does NOT exist
+ * @param $table Name of the table to check
+ */
+ function _assertTableNotExists($table) {
+ $this->assertFalse(db_table_exists($table), t('Table !table is absent', array('!table' => $table)));
+ }
+
+ /**
+ * Helper function for assertSchemaMatchesTables
+ * Checks that the database and schema for the given table contain only the expected fields.
+ * @param $table Name of the table to check
+ * @param $columns Array of column names
+ */
+ function _assertSchemaMatches($table, $columns) {
+ // First test: check the expected structure matches the stored schema.
+ $schema = drupal_get_schema($table, TRUE);
+ $mismatches = array();
+ if ($schema === FALSE) {
+ $mismatches[] = t('table does not exist');
+ }
+ else {
+ $fields = $schema['fields'];
+ foreach ($columns as $field) {
+ if (!isset($fields[$field])) {
+ $mismatches[] = t('field !field is missing from table', array('!field' => $field));
+ }
+ }
+ $columns_reverse = array_flip($columns);
+ foreach ($fields as $name => $info) {
+ if(!isset($columns_reverse[$name])) {
+ $mismatches[] = t('table contains unexpected field !field', array('!field' => $name));
+ }
+ }
+ }
+ $this->assertEqual(count($mismatches), 0, t('Table !table matches schema: !details',
+ array('!table' => $table, '!details' => implode($mismatches, ', '))));
+
+ // Second test: check the schema matches the actual db structure.
+ // This is the part that relies on schema.module.
+ if (!$this->enabled_schema) {
+ $this->enabled_schema = module_exists('schema');
+ }
+ if ($this->enabled_schema) {
+ // Clunky workaround for http://drupal.org/node/215198
+ $prefixed_table = db_prefix_tables('{'. $table .'}');
+ $inspect = schema_invoke('inspect', $prefixed_table);
+ $inspect = isset($inspect[$table]) ? $inspect[$table] : NULL;
+ $compare = schema_compare_table($schema, $inspect);
+ if ($compare['status'] == 'missing') {
+ $compare['reasons'] = array(t('table does not exist'));
+ }
+ }
+ else {
+ $compare = array('status' => 'unknown', 'reasons' => array(t('cannot enable schema module')));
+ }
+ $this->assertEqual($compare['status'], 'same', t('Table schema for !table matches database: !details',
+ array('!table' => $table, '!details' => implode($compare['reasons'], ', '))));
+ }
+
+ // Node data helper functions
+
+ /**
+ * Helper function for assertNodeSaveValues. Recursively checks that
+ * all the keys of a table are present in a second and have the same value.
+ */
+ function _compareArrayForChanges($fields, $data, $message, $prefix = '') {
+ foreach ($fields as $key => $value) {
+ $newprefix = ($prefix == '') ? $key : $prefix .']['. $key;
+ if (is_array($value)) {
+ $compare_to = isset($data[$key]) ? $data[$key] : array();
+ $this->_compareArrayForChanges($value, $compare_to, $message, $newprefix);
+ }
+ else {
+ $this->assertEqual($value, $data[$key], t($message, array('!key' => $newprefix)));
+ }
+ }
+ }
+
+ /**
+ * Checks that after a node is saved using node_save, the values to be saved
+ * match up with the output from node_load.
+ * @param $node Either a node object, or the index of an acquired node
+ * @param $values Array of values to be merged with the node and passed to node_save
+ * @return The values array
+ */
+ function assertNodeSaveValues($node, $values) {
+ if (is_numeric($node) && isset($this->nodes[$node])) {
+ $node = $this->nodes[$node];
+ }
+ $node = $values + (array)$node;
+ $node = (object)$node;
+ node_save($node);
+ $this->assertNodeValues($node, $values);
+ return $values;
+ }
+
+ /**
+ * Checks that the output from node_load matches the expected values.
+ * @param $node Either a node object, or the index of an acquired node (only the nid field is used)
+ * @param $values Array of values to check against node_load. The node object must contain the keys in the array,
+ * and the values must be equal, but the node object may also contain other keys.
+ */
+ function assertNodeValues($node, $values) {
+ if (is_numeric($node) && isset($this->nodes[$node])) {
+ $node = $this->nodes[$node];
+ }
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->_compareArrayForChanges($values, (array)$node, 'Node data [!key] is correct');
+ }
+
+ /**
+ * Checks that the output from node_load is missing certain fields
+ * @param $node Either a node object, or the index of an acquired node (only the nid field is used)
+ * @param $fields Array containing a list of field names
+ */
+ function assertNodeMissingFields($node, $fields) {
+ if (is_numeric($node) && isset($this->nodes[$node])) {
+ $node = $this->nodes[$node];
+ }
+ $node = (array)node_load($node->nid, NULL, TRUE);
+ foreach ($fields as $field) {
+ $this->assertFalse(isset($node[$field]), t('Node should be lacking field !key', array('!key' => $field)));
+ }
+ }
+
+ /**
+ * Creates random values for a text field
+ * @return An array containing a value key and a format key
+ */
+ function createRandomTextFieldData() {
+ return array(
+ 'value' => '!SimpleTest! test value' . $this->randomName(60),
+ 'format' => 2,
+ );
+ }
+
+ // Login/user helper functions
+
+ /**
+ * Creates a user / role with certain permissions and then logs in as that user
+ * @param $permissions Array containing list of permissions. If not given, defaults to
+ * access content, administer content types, administer nodes and administer filters.
+ */
+ function loginWithPermissions($permissions = NULL) {
+ if (!isset($permissions)) {
+ $permissions = array(
+ 'access content',
+ 'administer content types',
+ 'administer nodes',
+ 'administer filters',
+ );
+ }
+ $user = $this->drupalCreateUser($permissions);
+ $this->drupalLogin($user);
+ }
+
+ // Creation helper functions
+
+ /**
+ * Creates a number of content types with predictable names (simpletest_t1 ... simpletest_tN)
+ * These content types can later be accessed via $this->content_types[0 ... N-1]
+ * @param $count Number of content types to create
+ */
+ function acquireContentTypes($count) {
+ $this->content_types = array();
+ for ($i = 0; $i < $count; $i++) {
+ $name = 'simpletest_t'. ($i + 1);
+ $this->content_types[$i] = $this->drupalCreateContentType(array(
+ 'name' => $name,
+ 'type' => $name,
+ ));
+ }
+ content_clear_type_cache();
+ }
+
+ /**
+ * Creates a number of nodes of each acquired content type.
+ * Remember to call acquireContentTypes() before calling this, else the content types won't exist.
+ * @param $count Number of nodes to create per acquired content type (defaults to 1)
+ */
+ function acquireNodes($count = 1) {
+ $this->nodes = array();
+ foreach ($this->content_types as $content_type) {
+ for ($i = 0; $i < $count; $i++) {
+ $this->nodes[] = $this->drupalCreateNode(array('type' => $content_type->type));
+ }
+ }
+ }
+
+ /**
+ * Creates a field instance with a predictable name. Also makes all future calls to functions
+ * which take an optional field use this one as the default.
+ * @param $settings Array to be passed to content_field_instance_create. If the field_name
+ * or type_name keys are missing, then they will be added. The default field name is
+ * simpletest_fN, where N is 1 for the first created field, and increments. The default
+ * type name is type name of the $content_type argument.
+ * @param $content_type Either a content type object, or the index of an acquired content type
+ * @return The newly created field instance.
+ */
+ function createField($settings, $content_type = 0) {
+ if (is_numeric($content_type) && isset($this->content_types[$content_type])) {
+ $content_type = $this->content_types[$content_type];
+ }
+ $defaults = array(
+ 'field_name' => 'simpletest_f'. $this->next_field_n++,
+ 'type_name' => $content_type->type,
+ );
+ $settings = $settings + $defaults;
+ $this->last_field = content_field_instance_create($settings);
+ return $this->last_field;
+ }
+
+ /**
+ * Creates a textfield instance. Identical to createField() except it ensures that the text module
+ * is enabled, and adds default settings of type (text) and widget_type (text_textfield) if they
+ * are not given in $settings.
+ * @sa createField()
+ */
+ function createFieldText($settings, $content_type = 0) {
+ $defaults = array(
+ 'type' => 'text',
+ 'widget_type' => 'text_textfield',
+ );
+ $settings = $settings + $defaults;
+ return $this->createField($settings, $content_type);
+ }
+
+ // Field manipulation helper functions
+
+ /**
+ * Updates a field instance. Also makes all future calls to functions which take an optional
+ * field use the updated one as the default.
+ * @param $settings New settings for the field instance. If the field_name or type_name keys
+ * are missing, then they will be taken from $field.
+ * @param $field The field instance to update (defaults to the last worked upon field)
+ * @return The updated field instance.
+ */
+ function updateField($settings, $field = NULL) {
+ if (!isset($field)) {
+ $field = $this->last_field;
+ }
+ $defaults = array(
+ 'field_name' => $field['field_name'],
+ 'type_name' => $field['type_name'] ,
+ );
+ $settings = $settings + $defaults;
+ $this->last_field = content_field_instance_update($settings);
+ return $this->last_field;
+ }
+
+ /**
+ * Makes a copy of a field instance on a different content type, effectively sharing the field with a new
+ * content type. Also makes all future calls to functions which take an optional field use the shared one
+ * as the default.
+ * @param $new_content_type Either a content type object, or the index of an acquired content type
+ * @param $field The field instance to share (defaults to the last worked upon field)
+ * @return The shared (newly created) field instance.
+ */
+ function shareField($new_content_type, $field = NULL) {
+ if (!isset($field)) {
+ $field = $this->last_field;
+ }
+ if (is_numeric($new_content_type) && isset($this->content_types[$new_content_type])) {
+ $new_content_type = $this->content_types[$new_content_type];
+ }
+ $field['type_name'] = $new_content_type->type;
+ $this->last_field = content_field_instance_create($field);
+ return $this->last_field;
+ }
+
+ /**
+ * Deletes an instance of a field.
+ * @param $content_type Either a content type object, or the index of an acquired content type (used only
+ * to get field instance type name).
+ * @param $field The field instance to delete (defaults to the last worked upon field, used only to get
+ * field instance field name).
+ */
+ function deleteField($content_type, $field = NULL) {
+ if (!isset($field)) {
+ $field = $this->last_field;
+ }
+ if (is_numeric($content_type) && isset($this->content_types[$content_type])) {
+ $content_type = $this->content_types[$content_type];
+ }
+ content_field_instance_delete($field['field_name'], $content_type->type);
+ }
+}
+
+class ContentCrudBasicTest extends ContentCrudTestCase {
+ function getInfo() {
+ return array(
+ 'name' => t('CRUD - Basic API tests'),
+ 'description' => t('Tests the field CRUD (create, read, update, delete) API. Requires Schema module.', array('@schema_link' => 'http://www.drupal.org/project/schema')),
+ 'group' => t('CCK'),
+ );
+ }
+
+ function setUp() {
+ parent::setUp();
+ $this->acquireContentTypes(1);
+ }
+
+ function testBasic() {
+ // Create a field with both field and instance settings.
+ $field = $this->createFieldText(array('widget_type' => 'text_textarea', 'text_processing' => 1, 'rows' => 5), 0);
+
+
+ // Check that collapse and expand are inverse.
+ $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type));
+ $field1 = array_pop($fields);
+
+ $field2 = content_field_instance_collapse($field1);
+ $field3 = content_field_instance_expand($field2);
+ $field4 = content_field_instance_collapse($field3);
+
+ $this->assertIdentical($field1, $field3, 'collapse then expand is identity');
+ $this->assertIdentical($field2, $field4, 'expand then collapse is identity');
+
+
+ // Check that collapse and expand are both final
+ // (e.g. do not further alter the data when called multiple times).
+ $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type));
+ $field1 = array_pop($fields);
+
+ $field2 = content_field_instance_collapse($field1);
+ $field3 = content_field_instance_collapse($field2);
+ $this->assertIdentical($field2, $field3, 'collapse is final');
+
+ $field2 = content_field_instance_expand($field1);
+ $field3 = content_field_instance_expand($field2);
+ $this->assertIdentical($field2, $field3, 'expand is final');
+
+
+ // Check that updating a field as is leaves it unchanged.
+ $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type));
+ $field1 = array_pop($fields);
+ $field2 = content_field_instance_update($field1);
+ $fields = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $this->content_types[0]->type));
+ $field3 = array_pop($fields);
+
+ $this->assertIdentical($field1, $field3, 'read, update, read is identity');
+ }
+}
+
+class ContentCrudSingleToMultipleTest extends ContentCrudTestCase {
+ function getInfo() {
+ return array(
+ 'name' => t('CRUD - Single to multiple'),
+ 'description' => t('Tests the field CRUD (create, read, update, delete) API by creating a single value field and changing it to a multivalue field, sharing it between several content types. Requires Schema module.', array('@schema_link' => 'http://www.drupal.org/project/schema')),
+ 'group' => t('CCK'),
+ );
+ }
+
+ function setUp() {
+ parent::setUp();
+ $this->loginWithPermissions();
+ $this->acquireContentTypes(3);
+ $this->acquireNodes();
+ }
+
+ function testSingleToMultiple() {
+ // Create a simple text field
+ $this->createFieldText(array('text_processing' => 1));
+ $target_schema = array(
+ 'per_type' => array(
+ 'simpletest_t1' => array('simpletest_f1' => array('value', 'format'))
+ ),
+ 'per_field' => array(),
+ );
+ $this->assertSchemaMatchesTables($target_schema);
+ $node0values = $this->assertNodeSaveValues(0, array(
+ 'simpletest_f1' => array(
+ 0 => $this->createRandomTextFieldData(),
+ )
+ ));
+
+ // Change the text field to allow multiple values
+ $this->updateField(array('multiple' => 1));
+ $target_schema = array(
+ 'per_type' => array(
+ 'simpletest_t1' => array(),
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => array('delta', 'simpletest_f1' => array('value', 'format')),
+ ),
+ );
+ $this->assertSchemaMatchesTables($target_schema);
+ $this->assertNodeValues(0, $node0values);
+
+ // Share the text field with 2 additional types t2 and t3.
+ for ($share_with_content_type = 1; $share_with_content_type <= 2; $share_with_content_type++) {
+ $this->shareField($share_with_content_type);
+ // There should be a new 'empty' per-type table for each content type that has fields.
+ $target_schema['per_type']['simpletest_t'. ($share_with_content_type + 1)] = array();
+ $this->assertSchemaMatchesTables($target_schema);
+ // The acquired node index will match the content type index as exactly one node is acquired per content type
+ $this->assertNodeSaveValues($share_with_content_type, array(
+ 'simpletest_f1' => array(
+ 0 => $this->createRandomTextFieldData(),
+ )
+ ));
+ }
+
+ // Delete the text field from all content types
+ for ($delete_from_content_type = 2; $delete_from_content_type >= 0; $delete_from_content_type--) {
+ $this->deleteField($delete_from_content_type);
+ // Content types that don't have fields any more shouldn't have any per-type table.
+ $target_schema['per_type']['simpletest_t'. ($delete_from_content_type + 1)] = NULL;
+ // After removing the last instance, there should be no table for the field either.
+ if ($delete_from_content_type == 0) {
+ $target_schema['per_field']['simpletest_f1'] = NULL;
+ }
+ $this->assertSchemaMatchesTables($target_schema);
+ // The acquired node index will match the content type index as exactly one node is acquired per content type
+ $this->assertNodeMissingFields($this->nodes[$delete_from_content_type], array('simpletest_f1'));
+ }
+ }
+}
+
+class ContentCrudMultipleToSingleTest extends ContentCrudTestCase {
+ function getInfo() {
+ return array(
+ 'name' => t('CRUD - Multiple to single'),
+ 'description' => t('Tests the field CRUD (create, read, update, delete) API by creating a multivalue field and changing it to a single value field, sharing it between several content types. Requires Schema module.', array('@schema_link' => 'http://www.drupal.org/project/schema')),
+ 'group' => t('CCK'),
+ );
+ }
+
+ function setUp() {
+ parent::setUp();
+ $this->loginWithPermissions();
+ $this->acquireContentTypes(3);
+ $this->acquireNodes();
+ }
+
+ function testMultipleToSingle() {
+ // Create a multivalue text field
+ $this->createFieldText(array('text_processing' => 1, 'multiple' => 1));
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ 'simpletest_t1' => array(),
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => array('delta', 'simpletest_f1' => array('value', 'format')),
+ ),
+ ));
+ $this->assertNodeSaveValues(0, array(
+ 'simpletest_f1' => array(
+ 0 => $this->createRandomTextFieldData(),
+ 1 => $this->createRandomTextFieldData(),
+ 2 => $this->createRandomTextFieldData(),
+ )
+ ));
+
+ // Change to a simple text field
+ $this->updateField(array('multiple' => 0));
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ 'simpletest_t1' => array('simpletest_f1' => array('value', 'format')),
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => NULL,
+ ),
+ ));
+ $node0values = $this->assertNodeSaveValues(0, array(
+ 'simpletest_f1' => array(
+ 0 => $this->createRandomTextFieldData(),
+ )
+ ));
+
+ // Share the text field with other content type
+ $this->shareField(1);
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ 'simpletest_t1' => array(),
+ 'simpletest_t2' => array(),
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => array('simpletest_f1' => array('value', 'format')),
+ ),
+ ));
+ $node1values = $this->assertNodeSaveValues(1, array(
+ 'simpletest_f1' => array(
+ 0 => $this->createRandomTextFieldData(),
+ )
+ ));
+ $this->assertNodeValues(0, $node0values);
+
+ // Share the text field with a 3rd type
+ $this->shareField(2);
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ 'simpletest_t1' => array(),
+ 'simpletest_t2' => array(),
+ 'simpletest_t3' => array(),
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => array('simpletest_f1' => array('value', 'format')),
+ ),
+ ));
+ $this->assertNodeSaveValues(2, array(
+ 'simpletest_f1' => array(
+ 0 => $this->createRandomTextFieldData(),
+ )
+ ));
+ $this->assertNodeValues(1, $node1values);
+ $this->assertNodeValues(0, $node0values);
+
+ // Remove text field from 3rd type
+ $this->deleteField(2);
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ 'simpletest_t1' => array(),
+ 'simpletest_t2' => array(),
+ 'simpletest_t3' => NULL,
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => array('simpletest_f1' => array('value', 'format')),
+ ),
+ ));
+ $this->assertNodeMissingFields($this->nodes[2], array('simpletest_f1'));
+
+ // Remove text field from 2nd type (field isn't shared anymore)
+ $this->deleteField(1);
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ 'simpletest_t1' => array('simpletest_f1' => array('value', 'format')),
+ 'simpletest_t2' => NULL,
+ 'simpletest_t3' => NULL,
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => NULL,
+ ),
+ ));
+ $this->assertNodeMissingFields(1, array('simpletest_f1'));
+ $this->assertNodeValues(0, $node0values);
+
+ // Remove text field from original type
+ $this->deleteField(0);
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ 'simpletest_t1' => NULL,
+ 'simpletest_t2' => NULL,
+ 'simpletest_t3' => NULL,
+ ),
+ 'per_field' => array(
+ 'simpletest_f1' => NULL,
+ ),
+ ));
+ $this->assertNodeMissingFields(0, array('simpletest_f1'));
+ }
+}
+
+class ContentUICrud extends ContentCrudTestCase {
+ function getInfo() {
+ return array(
+ 'name' => t('Admin UI'),
+ 'description' => t('Tests the CRUD (create, read, update, delete) operations for content fields via the UI. Requires Schema module.', array('@schema_link' => 'http://www.drupal.org/project/schema')),
+ 'group' => t('CCK'),
+ );
+ }
+
+ function setUp() {
+ parent::setUp('fieldgroup');
+ $this->loginWithPermissions();
+ }
+
+ function testAddFieldUI() {
+ // Add a content type with a random name (to avoid schema module problems).
+ $type1 = 'simpletest'. mt_rand();
+ $type1_name = $this->randomName(10);
+ $edit = array(
+ 'type' => $type1,
+ 'name' => $type1_name,
+ );
+ $this->drupalPost('admin/content/types/add', $edit, 'Save content type');
+ $admin_type1_url = 'admin/content/node-type/'. $type1;
+
+ // Create a text field via the UI.
+ $field_name = strtolower($this->randomName(10));
+ $field_label = $this->randomName(10);
+ $edit = array(
+ '_add_new_field[label]' => $field_label,
+ '_add_new_field[field_name]' => $field_name,
+ '_add_new_field[type]' => 'text',
+ '_add_new_field[widget_type]' => 'text_textfield',
+ );
+ $this->drupalPost($admin_type1_url .'/fields', $edit, 'Save');
+ $this->assertRaw('These settings apply only to the '. $field_label .' field', 'Field settings page displayed');
+ $this->assertRaw('Size of textfield', 'Field and widget types correct.');
+ $this->assertNoRaw('Change basic information', 'No basic information displayed');
+ $field_name = 'field_'. $field_name;
+
+ $edit = array();
+ // POST to the page without reloading.
+ $this->drupalPost(NULL, $edit, 'Save field settings');
+ $this->assertRaw('Added field '. $field_label .'.', 'Field settings saved');
+ $field_type1_url = $admin_type1_url .'/fields/'. $field_name;
+ $this->assertRaw($field_type1_url, 'Field displayed on overview.');
+
+ // Check the schema - the values should be in the per-type table.
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ $type1 => array($field_name => array('value')),
+ ),
+ ));
+
+
+ // Add a second content type.
+ $type2 = 'simpletest'. mt_rand();
+ $type2_name = $this->randomName(10);
+ $edit = array(
+ 'type' => $type2,
+ 'name' => $type2_name,
+ );
+ $this->drupalPost('admin/content/types/add', $edit, 'Save content type');
+ $admin_type2_url = 'admin/content/node-type/'. $type2;
+
+ // Add the same field to the second content type.
+ $edit = array(
+ '_add_existing_field[label]' => $field_label,
+ '_add_existing_field[field_name]' => $field_name,
+ '_add_existing_field[widget_type]' => 'text_textarea',
+ );
+ $this->drupalPost($admin_type2_url .'/fields', $edit, 'Save');
+ $this->assertRaw('These settings apply only to the '. $field_label .' field', 'Field settings page displayed');
+ $this->assertRaw('Rows', 'Field and widget types correct.');
+ $this->assertNoRaw('Change basic information', 'No basic information displayed');
+
+ $edit = array();
+ $this->drupalPost(NULL, $edit, 'Save field settings');
+ $this->assertRaw('Added field '. $field_label .'.', 'Field settings saved');
+ $field_type2_url = $admin_type2_url .'/fields/'. $field_name;
+ $this->assertRaw($field_type2_url, 'Field displayed on overview.');
+
+ // Check that a separate table is created for the shared field, and
+ // that it's values are no longer in the per-type tables.
+ $this->assertSchemaMatchesTables(array(
+ 'per_field' => array(
+ $field_name => array($field_name => array('value')),
+ ),
+ 'per_type' => array(
+ $type1 => array(),
+ $type2 => array(),
+ ),
+ ));
+
+
+ // Chancge the basic settings for this field.
+ $edit = array();
+ $this->drupalPost($field_type2_url, $edit, 'Change basic information');
+ $this->assertRaw('Edit basic information', 'Basic information form displayed');
+
+ $field_label2 = $this->randomName(10);
+ $edit = array(
+ 'label' => $field_label2,
+ 'widget_type' => 'text_textfield',
+ );
+ $this->drupalPost(NULL, $edit, 'Continue');
+ $this->assertRaw('These settings apply only to the '. $field_label2 .' field', 'Label changed');
+ $this->assertRaw('Size of textfield', 'Widget changed');
+
+ $edit = array();
+ // POST to the page without reloading.
+ $this->drupalPost(NULL, $edit, 'Save field settings');
+ $this->assertRaw('Saved field '. $field_label2 .'.', 'Field settings saved');
+
+
+ // Add a group to the second content type.
+ $group1_name = strtolower($this->randomName(10));
+ $group1_label = $this->randomName(10);
+ $edit = array(
+ '_add_new_group[label]' => $group1_label,
+ '_add_new_group[group_name]' => $group1_name,
+ );
+ $this->drupalPost($admin_type2_url .'/fields', $edit, 'Save');
+ $group1_name = 'group_'. $group1_name;
+ $this->assertRaw($admin_type2_url .'/groups/'. $group1_name, 'Group created');
+
+
+ // Remove the field from the second type.
+ $edit = array();
+ $this->drupalPost($field_type2_url .'/remove', $edit, 'Remove');
+ $this->assertRaw('Removed field '. $field_label2 .' from '. $type2_name .'', 'Field removed');
+ $this->assertNoRaw($field_type2_url, 'Field not displayed on overview.');
+
+ // Check the schema - the values should be in the per-type table.
+ $this->assertSchemaMatchesTables(array(
+ 'per_type' => array(
+ $type1 => array($field_name => array('value')),
+ ),
+ ));
+
+ // Add a new field, an existing field, and a group in the same submit.
+ $field2_label = $this->randomName(10);
+ $field2_name = strtolower($this->randomName(10));
+ $group2_label = $this->randomName(10);
+ $group2_name = strtolower($this->randomName(10));
+ $edit = array(
+ '_add_new_field[label]' => $field2_label,
+ '_add_new_field[field_name]' => $field2_name,
+ '_add_new_field[type]' => 'text',
+ '_add_new_field[widget_type]' => 'text_textfield',
+ '_add_new_field[parent]' => $group1_name,
+ '_add_existing_field[label]' => $field_label,
+ '_add_existing_field[field_name]' => $field_name,
+ '_add_existing_field[widget_type]' => 'text_textarea',
+ '_add_existing_field[parent]' => '_add_new_group',
+ '_add_new_group[label]' => $group2_label,
+ '_add_new_group[group_name]' => $group2_name,
+ );
+ $this->drupalPost($admin_type2_url .'/fields', $edit, 'Save');
+ $this->assertRaw('These settings apply only to the '. $field2_label .' field', 'Field settings page for new field displayed');
+ // Submit new field settings
+ $edit = array();
+ $this->drupalPost(NULL, $edit, 'Save field settings');
+ $this->assertRaw('Added field '. $field2_label .'.', 'Field settings for new field saved');
+ $this->assertRaw('These settings apply only to the '. $field_label .' field', 'Field settings page for existing field displayed');
+ // Submit existing field settings
+ $edit = array();
+ $this->drupalPost(NULL, $edit, 'Save field settings');
+ $this->assertRaw('Added field '. $field_label .'.', 'Field settings for existing field saved');
+ $field2_name = 'field_'. $field2_name;
+ $field2_type2_url = $admin_type2_url .'/fields/'. $field2_name;
+ $this->assertRaw($field2_type2_url, 'New field displayed in overview');
+ $this->assertRaw($field_type2_url, 'Existing field displayed in overview');
+ $group2_name = 'group_'. $group2_name;
+ $this->assertRaw($admin_type2_url .'/groups/'. $group2_name, 'New group displayed in overview');
+
+ // Check Parenting
+ $groups = fieldgroup_groups($type2, FALSE, TRUE);
+ $this->assertTrue(isset($groups[$group1_name]['fields'][$field2_name]), 'New field in correct group');
+ $this->assertTrue(isset($groups[$group2_name]['fields'][$field_name]), 'Existing field in correct group');
+ $this->assertFieldByXPath('//select[@id="edit-'. strtr($field2_name, '_', '-') .'-parent"]//option[@selected]', $group1_name, 'Parenting for new field correct in overview');
+ $this->assertFieldByXPath('//select[@id="edit-'. strtr($field_name, '_', '-') .'-parent"]//option[@selected]', $group2_name, 'Parenting for existing field correct in overview');
+
+ // Check the schema : field1 is shared, field2 is in the per-type table.
+ $this->assertSchemaMatchesTables(array(
+ 'per_field' => array(
+ $field_name => array($field_name => array('value')),
+ ),
+ 'per_type' => array(
+ $type1 => array(),
+ $type2 => array($field2_name => array('value')),
+ ),
+ ));
+
+ // TODO : test validation failures...
+ // TODO : test ordering and extra fields...
+ }
+
+ function testFieldContentUI() {
+ // Create a content type with a field
+ $type1 = 'simpletest'. mt_rand();
+ $type1_obj = $this->drupalCreateContentType(array('type' => $type1));
+ $admin_type1_url = 'admin/content/node-type/'. $type1;
+ $field_name = strtolower($this->randomName(10));
+ $field_url = 'field_'. $field_name;
+ $field = $this->createFieldText(array('text_processing' => 1, 'multiple' => 0, 'field_name' => $field_url), $type1_obj);
+
+ // Save a node with content in the text field
+ $edit = array();
+ $edit['title'] = $this->randomName(20);
+ $edit['body'] = $this->randomName(20);
+ $value = $this->randomName(20);
+ $edit[$field_url.'[0][value]'] = $value;
+ $this->drupalPost('node/add/'. $type1, $edit, 'Save');
+ $node = node_load(array('title' => $edit['title']));
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value, 'Textfield value saved and displayed');
+
+ // Alter the field to have unlimited values
+ $edit = array();
+ $edit['multiple'] = '1';
+ $this->drupalPost($admin_type1_url .'/fields/'. $field_url, $edit, 'Save field settings');
+
+ // Save a node with content in multiple text fields
+ $edit = array();
+ $edit['title'] = $this->randomName(20);
+ $edit['body'] = $this->randomName(20);
+ // Add more textfields (non-JS).
+ $this->drupalPost('node/add/'. $type1, $edit, "Add another item");
+ $this->drupalPost(NULL, $edit, "Add another item");
+ $value1 = $this->randomName(20);
+ $value2 = $this->randomName(20);
+ $value3 = $this->randomName(20);
+ $edit[$field_url.'[0][value]'] = $value1;
+ $edit[$field_url.'[1][value]'] = $value2;
+ $edit[$field_url.'[2][value]'] = $value3;
+
+ // This will fail if we don't have at least 3 textfields.
+ $this->drupalPost(NULL, $edit, 'Save');
+ $node = node_load(array('title' => $edit['title']));
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value3, '3rd textfield value saved and displayed');
+ }
+}
+
+class ContentOptionWidgetTest extends ContentCrudTestCase {
+ function getInfo() {
+ return array(
+ 'name' => t('Option widgets'),
+ 'description' => t('Tests the optionwidgets.'),
+ 'group' => t('CCK'),
+ );
+ }
+
+ function setUp() {
+ parent::setUp('optionwidgets');
+ $this->loginWithPermissions();
+ $this->acquireContentTypes(1);
+ }
+
+ // TODO: test a number field with optionwidgets stores 0 correctly ?
+ // TODO: test the case where aliases and values overlap ? (http://drupal.org/node/281749)
+ // TODO: test noderef select widget...
+
+ /**
+ * On/Off Checkbox, not required:
+ * - Create a node with the value checked.
+ * - FAILS: Edit the node and uncheck the value.
+ *
+ * On/Off Checkbox, required:
+ * - TODO: what behavior do we want ?
+ */
+ function testOnOffCheckbox() {
+ $type = $this->content_types[0];
+ $type_url = str_replace('_', '-', $type->type);
+
+ // Create the field.
+ $on_text = $this->randomName(5);
+ $on_value = $this->randomName(5);
+ $off_text = $on_text. '_off';
+ $off_value = $on_value. '_off';
+
+ $settings = array(
+ 'type' => 'text',
+ 'widget_type' => 'optionwidgets_onoff',
+ 'allowed_values' => "$off_value|$off_text\r\n$on_value|$on_text",
+ );
+ $field = $this->createField($settings, 0);
+ $field_name = $field['field_name'];
+
+ // Create a node with the checkbox on.
+ $edit = array(
+ 'title' => $this->randomName(20),
+ 'body' => $this->randomName(20),
+ $field_name.'[value]' => $on_value,
+ );
+ $this->drupalPost('node/add/'. $type_url, $edit, 'Save');
+ $node = node_load(array('title' => $edit['title']));
+ $this->assertEqual($node->{$field_name}[0]['value'], $on_value, 'Checkbox: checked (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($on_text, 'Checkbox: checked (displayed)');
+
+ // Edit the node and uncheck the box.
+ $edit = array(
+ $field_name.'[value]' => FALSE,
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertEqual($node->{$field_name}[0]['value'], $off_value, 'Checkbox: unchecked (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($off_text, 'Checkbox: unchecked (displayed)');
+ }
+
+ /**
+ * Single select, not required:
+ * - TODO: check there's a 'none' choice in the form.
+ * - Create a node with one value selected.
+ * - Edit the node and unselect the value (selecting '- None -').
+ *
+ * Single select, required:
+ * - TODO: check there's no 'none' choice in the form.
+ *
+ * Multiple select, not required:
+ * - TODO: check there's a 'none' choice in the form.
+ * - Edit the node and select multiple values.
+ * - Edit the node and unselect one value.
+ * - Edit the node and unselect the values (selecting '- None -').
+ * - Edit the node and unselect the values (selecting nothing).
+ *
+ * Multiple select, required:
+ * - TODO: check there's no 'none' choice in the form.
+ * - Check the form doesn't submit when nothing is selected.
+ */
+ function testSelect() {
+ $type = $this->content_types[0];
+ $type_url = str_replace('_', '-', $type->type);
+
+ // Create the field - start with 'single'.
+ $value1 = $this->randomName(5);
+ $value1_alias = $value1 .'_alias';
+ $value2 = $this->randomName(5);
+ $value2_alias = $value2 .'_alias';
+
+ $settings = array(
+ 'type' => 'text',
+ 'widget_type' => 'optionwidgets_select',
+ 'allowed_values' => "$value1|$value1_alias\r\n$value2|$value2_alias",
+ );
+ $field = $this->createField($settings, 0);
+ $field_name = $field['field_name'];
+
+ // Create a node with one value selected
+ $edit = array(
+ 'title' => $this->randomName(20),
+ 'body' => $this->randomName(20),
+ );
+ $edit[$field_name.'[value]'] = $value1;
+ $this->drupalPost('node/add/'. $type_url, $edit, 'Save');
+ $node = node_load(array('title' => $edit['title']));
+ $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Select: selected (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value1_alias, 'Select: selected (displayed)');
+
+ // Edit the node and unselect the value (selecting '- None -').
+ $edit = array(
+ $field_name.'[value]' => '',
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Select: unselected (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertNoText($value1_alias, 'Select: unselected (displayed)');
+
+ // Change to a multiple field
+ $field = $this->updateField(array('multiple' => '1', 'required' => '0'));
+
+ // Edit the node and select multiple values.
+ $edit = array(
+ $field_name.'[value][]' => array($value1 => $value1, $value2 => $value2),
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Multiple Select: selected 1 (saved)');
+ $this->assertEqual($node->{$field_name}[1]['value'], $value2, 'Multiple Select: selected 2 (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value1_alias, 'Multiple Select: selected 1 (displayed)');
+ $this->assertText($value2_alias, 'Multiple Select: selected 2 (displayed)');
+
+ // Edit the node and unselect one value.
+ $edit = array(
+ $field_name.'[value][]' => array($value1 => $value1),
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Multiple Select: selected 1 (saved)');
+ $this->assertTrue(!isset($node->{$field_name}[1]), 'Multiple Select: unselected 2 (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value1_alias, 'Multiple Select: selected 1 (displayed)');
+ $this->assertNoText($value2_alias, 'Multiple Select: unselected 2 (displayed)');
+
+ // Edit the node and unselect the values (selecting '- None -').
+ $edit = array(
+ $field_name.'[value][]' => array('' => ''),
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Multiple Select: unselected 1 ("-none-" selected) (saved)');
+ $this->assertTrue(!isset($node->{$field_name}[1]), 'Multiple Select: unselected 2 ("-none-" selected) (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertNoText($value1_alias, 'Multiple Select: unselected 1 ("-none-" selected) (displayed)');
+ $this->assertNoText($value2_alias, 'Multiple Select: unselected 2 ("-none-" selected) (displayed)');
+
+ // Edit the node and unselect the values (selecting nothing).
+ // We first need to put values back in (no test needed).
+ $edit = array();
+ $edit[$field_name.'[value][]'] = array($value1 => FALSE, $value2 => FALSE);
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $edit = array();
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Multiple Select: unselected 1 (no selection) (saved)');
+ $this->assertTrue(!isset($node->{$field_name}[1]), 'Multiple Select: unselected 2 (no selection) (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertNoText($value1_alias, 'Multiple Select: unselected 1 (no selection) (displayed)');
+ $this->assertNoText($value2_alias, 'Multiple Select: unselected 2 (no selection) (displayed)');
+
+ // Change the field to 'required'.
+ $field = $this->updateField(array('required' => '1'));
+
+ // Check the form doesn't submit when nothing is selected.
+ $edit = array();
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Multiple Select: "required" property is respected');
+
+ $edit = array(
+ 'title' => $this->randomName(20),
+ 'body' => $this->randomName(20),
+ );
+ $this->drupalPost('node/add/'. $type_url, $edit, 'Save');
+ $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Multiple Select: "required" property is respected');
+
+ }
+
+ /**
+ * Single (radios), not required:
+ * - TODO: check there's a 'none' choice in the form.
+ * - Create a node with one value selected.
+ * - Edit the node and unselect the value (selecting '- None -').
+ *
+ * Single (radios), required:
+ * - TODO: check there's no 'none' choice in the form.
+ * - Check the form doesn't submit when nothing is selected.
+ */
+ function testRadios() {
+ $type = $this->content_types[0];
+ $type_url = str_replace('_', '-', $type->type);
+
+ // Create the field - 'single' (radios).
+ $value1 = $this->randomName(5);
+ $value1_alias = $value1 .'_alias';
+ $value2 = $this->randomName(5);
+ $value2_alias = $value2 .'_alias';
+ $settings = array(
+ 'type' => 'text',
+ 'widget_type' => 'optionwidgets_buttons',
+ 'allowed_values' => "$value1|$value1_alias\r\n$value2|$value2_alias",
+ );
+ $field = $this->createField($settings, 0);
+ $field_name = $field['field_name'];
+
+ // Create a node with one value selected
+ $edit = array();
+ $edit['title'] = $this->randomName(20);
+ $edit['body'] = $this->randomName(20);
+ $edit[$field_name.'[value]'] = $value1;
+ $this->drupalPost('node/add/'. $type_url, $edit, 'Save');
+ $node = node_load(array('title' => $edit['title']));
+ $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Radios: checked (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value1_alias, 'Radios: checked (displayed)');
+
+ // Edit the node and unselect the value (selecting '- None -').
+ $edit = array();
+ $edit[$field_name.'[value]'] = '';
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Radios: unchecked (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertNoText($value1_alias, 'Radios: unchecked (displayed)');
+
+ // Change field to required.
+ $field = $this->updateField(array('required' => '1'));
+
+ // Check the form doesn't submit when nothing is selected.
+ // Doing this on the pre-filled node doesn't take, so we test that on a new node.
+ $edit = array();
+ $edit['title'] = $this->randomName(20);
+ $edit['body'] = $this->randomName(20);
+ $this->drupalPost('node/add/'. $type_url, $edit, 'Save');
+ $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Radios: "required" property is respected');
+ }
+
+ /**
+ * Multiple (checkboxes), not required:
+ * - TODO: check there's no 'none' choice in the form.
+ * - Create a node with two values.
+ * - Edit the node and select only one value.
+ * - Edit the node and unselect the values (selecting nothing).
+ *
+ * Multiple (checkboxes), required:
+ * - TODO: check there's no 'none' choice in the form.
+ * - Check the form doesn't submit when nothing is selected.
+ */
+ function testChecboxes() {
+ $type = $this->content_types[0];
+ $type_url = str_replace('_', '-', $type->type);
+
+ // Create the field - 'multiple' (checkboxes).
+ $value1 = $this->randomName(5);
+ $value1_alias = $value1 .'_alias';
+ $value2 = $this->randomName(5);
+ $value2_alias = $value2 .'_alias';
+ $settings = array(
+ 'type' => 'text',
+ 'multiple' => '1',
+ 'widget_type' => 'optionwidgets_buttons',
+ 'allowed_values' => "$value1|$value1_alias\r\n$value2|$value2_alias",
+ );
+ $field = $this->createField($settings, 0);
+ $field_name = $field['field_name'];
+
+ // Create a node with two values selected
+ $edit = array(
+ 'title' => $this->randomName(20),
+ 'body' => $this->randomName(20),
+ $field_name.'[value]['. $value1 .']' => $value1,
+ $field_name.'[value]['. $value2 .']' => $value2,
+ );
+ $this->drupalPost('node/add/'. $type_url, $edit, 'Save');
+ $node = node_load(array('title' => $edit['title']));
+ $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Checkboxes: selected 1 (saved)');
+ $this->assertEqual($node->{$field_name}[1]['value'], $value2, 'Checkboxes: selected 2 (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value1_alias, 'Checkboxes: selected 1 (displayed)');
+ $this->assertText($value2_alias, 'Checkboxes: selected 2 (displayed)');
+
+ // Edit the node and unselect the values (selecting nothing -
+ // there is no 'none' choice for checkboxes).
+ $edit = array(
+ $field_name.'[value]['. $value1 .']' => $value1,
+ $field_name.'[value]['. $value2 .']' => FALSE,
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertEqual($node->{$field_name}[0]['value'], $value1, 'Checkboxes: selected 1 (saved)');
+ $this->assertTrue(!isset($node->{$field_name}[1]), 'Checkboxes: unselected 2 (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertText($value1_alias, 'Checkboxes: selected 1 (displayed)');
+ $this->assertNoText($value2_alias, 'Checkboxes: unselected 2 (displayed)');
+
+ // Edit the node and unselect the values (selecting nothing -
+ // there is no 'none' choice for checkboxes).
+ $edit = array(
+ $field_name.'[value]['. $value1 .']' => FALSE,
+ $field_name.'[value]['. $value2 .']' => FALSE,
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $node = node_load($node->nid, NULL, TRUE);
+ $this->assertIdentical($node->{$field_name}[0]['value'], NULL, 'Checkboxes: unselected 1 (no selection) (saved)');
+ $this->assertTrue(!isset($node->{$field_name}[1]), 'Checkboxes: unselected 2 (no selection) (saved)');
+ $this->drupalGet('node/'. $node->nid);
+ $this->assertNoText($value1_alias, 'Checkboxes: unselected 1 (no selection) (displayed)');
+ $this->assertNoText($value2_alias, 'Checkboxes: unselected 2 (no selection) (displayed)');
+
+ // Change field to required.
+ $field = $this->updateField(array('required' => '1'));
+
+ // Check the form doesn't submit when nothing is selected.
+ $edit = array(
+ $field_name.'[value]['. $value1 .']' => FALSE,
+ $field_name.'[value]['. $value2 .']' => FALSE,
+ );
+ $this->drupalPost('node/'. $node->nid .'/edit', $edit, 'Save');
+ $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Checkboxes: "required" property is respected');
+
+ $edit = array();
+ $edit['title'] = $this->randomName(20);
+ $edit['body'] = $this->randomName(20);
+ $this->drupalPost('node/add/'. $type_url, $edit, 'Save');
+ $this->assertRaw(t('!name field is required.', array('!name' => t($field['widget']['label']))), 'Checkboxes: "required" property is respected');
+ }
+
+}
+
diff --git a/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-display-overview-form.tpl.php b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-display-overview-form.tpl.php
new file mode 100644
index 00000000000..3658ac5768f
--- /dev/null
+++ b/drupal/sites/default/boinc/modules/contrib/cck/theme/content-admin-display-overview-form.tpl.php
@@ -0,0 +1,40 @@
+
+