View source
<?php
define('MEE_RENDERED_COPYRIGHT_PATTERN', '/<!--\\s*copyright=(\\d+)\\s*-->(.*)<!--\\s*END copyright=\\1\\s*-->/sU');
function mee_menu() {
$items['atom/ajax-widget-expand/%scald_atom_fallback'] = array(
'page callback' => 'mee_ajax_widget_expand',
'page arguments' => array(
2,
),
'access callback' => TRUE,
'delivery callback' => 'ajax_deliver',
'theme callback' => 'ajax_base_page_theme',
);
return $items;
}
function mee_theme($existing, $type, $theme, $path) {
return array(
'mee_resource_manager' => array(
'render element' => 'resource_manager',
),
'mee_widget_embed' => array(
'variables' => array(
'atom' => NULL,
'context' => NULL,
'options' => NULL,
'align' => NULL,
'caption' => NULL,
'content' => NULL,
'wysiwyg' => FALSE,
),
),
);
}
function mee_library() {
$path = drupal_get_path('module', 'mee');
$libraries['library'] = array(
'title' => 'MEE Library',
'website' => 'http://drupal.org/project/scald',
'version' => '1.x',
'js' => array(
$path . '/mee.js' => array(),
array(
'type' => 'setting',
'data' => array(
'mee' => array(
'sas' => mee_store_format() == 'sas',
'editors' => array(),
),
),
),
),
'css' => array(
$path . '/css/mee.css' => array(),
),
);
$plugin = mee_store_format() !== 'embed_div' ? 'ckeditor' : 'dndck4';
$libraries['library']['js'][$path . '/plugins/' . $plugin . '/lang/en.js'] = array();
return $libraries;
}
function mee_wysiwyg_plugin($editor, $version) {
$plugins = array();
$mee_store_format = mee_store_format();
switch ($editor) {
case 'ckeditor':
if ($mee_store_format == 'sas') {
$plugins['dnd'] = array(
'path' => drupal_get_path('module', 'mee') . '/plugins/ckeditor',
'filename' => 'plugin.js',
'buttons' => array(
'dnd' => t('Scald DnD integration'),
),
'load' => TRUE,
);
}
elseif ($mee_store_format == 'embed_div') {
$plugins['dndck4'] = array(
'path' => drupal_get_path('module', 'mee') . '/plugins/dndck4',
'filename' => 'plugin.js',
'buttons' => array(
'dndck4' => t('Scald DnD integration - CKEditor 4 widgets'),
),
'load' => TRUE,
);
}
break;
}
return $plugins;
}
function mee_ckeditor_plugin() {
$plugins = array();
$mee_store_format = mee_store_format();
if ($mee_store_format == 'sas') {
$plugins['dnd'] = array(
'name' => 'dnd',
'desc' => t('Scald Drag and Drop integration'),
'path' => drupal_get_path('module', 'mee') . '/plugins/ckeditor/',
'buttons' => array(
'ScaldAtom' => array(
'icon' => 'icons/atom.png',
'label' => t('Edit atom properties'),
),
),
);
}
elseif ($mee_store_format == 'embed_div' && version_compare(ckeditor_get_version(), '4.3.0') >= 0) {
$plugins['dndck4'] = array(
'name' => 'dndck4',
'desc' => t('Scald Drag and Drop integration - CKEditor 4 widgets'),
'path' => drupal_get_path('module', 'mee') . '/plugins/dndck4/',
'buttons' => array(
'ScaldAtom' => array(
'icon' => 'icons/atom.png',
'label' => t('Edit atom properties'),
),
),
);
}
return $plugins;
}
function mee_editor_ckeditor_plugins() {
$plugins = array();
$mee_store_format = mee_store_format();
if ($mee_store_format == 'sas') {
$plugins['dnd'] = array(
'name' => 'dnd',
'desc' => t('Scald Drag and Drop integration'),
'path' => drupal_get_path('module', 'mee') . '/plugins/ckeditor',
'buttons' => array(
'ScaldAtom' => array(
'label' => t('Edit atom properties'),
'image' => drupal_get_path('module', 'mee') . '/plugins/ckeditor/icons/atom.png',
),
),
'file' => 'plugin.js',
'enabled callback' => TRUE,
);
}
elseif ($mee_store_format == 'embed_div') {
$plugins['dndck4'] = array(
'name' => 'dndck4',
'desc' => t('Scald Drag and Drop integration - CKEditor 4 widgets'),
'path' => drupal_get_path('module', 'mee') . '/plugins/dndck4',
'buttons' => array(
'ScaldAtom' => array(
'label' => t('Edit atom properties'),
'image' => drupal_get_path('module', 'mee') . '/plugins/dndck4/icons/atom.png',
),
),
'file' => 'plugin.js',
'enabled callback' => TRUE,
);
}
return $plugins;
}
function mee_views_api($module = NULL, $api = NULL) {
return array(
"api" => "3.0",
);
}
function mee_field_info_alter(&$info) {
foreach (mee_field_types() as $name) {
$info[$name]['instance_settings']['dnd_enabled'] = 0;
$info[$name]['instance_settings']['mee_enabled'] = 0;
$info[$name]['instance_settings']['context'] = '';
}
}
function mee_store_format() {
return variable_get('mee_store_format', 'embed_div');
}
function mee_form_alter(&$form, &$form_state, $form_id) {
if ($form_id !== 'field_ui_field_edit_form' || !in_array($form['#field']['type'], mee_field_types())) {
return;
}
$settings = $form['#instance']['settings'];
$context_options = array();
foreach (scald_contexts_public() as $name => $context) {
$context_options[$name] = $context['title'];
}
$form['instance']['settings']['dnd_enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Drag\'n\'Drop Enabled'),
'#description' => t('Enable DnD for this field will show the Atom library and will allow you to drag and drop atoms to this field.'),
'#default_value' => $settings['dnd_enabled'],
);
$form['instance']['settings']['mee_enabled'] = array(
'#type' => 'checkbox',
'#title' => t('MEE Enabled'),
'#description' => t('Enable MEE for this field to get access to an advance resource management interface. MEE will automatically detect the resources embedded in this field, and allow you to define a few metadata properties on them, e.g. choose if the node should be unpublished if at some point in the future the resource became unavailable.'),
'#default_value' => $settings['mee_enabled'],
);
$form['instance']['settings']['context_default'] = array(
'#type' => 'select',
'#title' => t('Scald default context'),
'#description' => t('You can customize field level default context for drag and drop atoms.'),
'#default_value' => isset($settings['context_default']) ? $settings['context_default'] : variable_get('dnd_context_default', 'sdl_editor_representation'),
'#options' => $context_options,
);
$form['instance']['settings']['context'] = array(
'#type' => 'select',
'#title' => t('Scald fallback context'),
'#description' => t('The fallback context is only used when the specified context for embedded atom is not available (e.g. deleted).'),
'#default_value' => $settings['context'],
'#options' => $context_options,
);
}
function text_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
if (mee_store_format() != 'sas') {
return;
}
foreach ($items as $delta => &$item) {
if (!empty($item['value'])) {
$item['value'] = scald_rendered_to_sas($item['value']);
}
}
}
function text_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
if (!_mee_field_instance_enabled($instance, 'mee')) {
return;
}
list($id, $revision_id) = _mee_extract_id($entity_type, $entity);
foreach ($items as $delta => $item) {
list($sids, $copyrights) = _mee_process_item_value($item, $entity_type, $entity, $field, $delta);
$separator = $item['mee']['resource_manager'][0]['weight'];
foreach ($sids as $sid) {
$resource = $item['mee']['resource_manager'][$sid];
db_insert('mee_resource')
->fields(array(
'entity_type' => $entity_type,
'entity_id' => $id,
'revision_id' => $revision_id,
'atom_sid' => $sid,
'field' => $field['field_name'],
'delta' => $delta,
'weight' => $resource['weight'] - $separator,
'required' => (int) $resource['required'],
'copyright' => isset($copyrights[$sid]) ? $copyrights[$sid] : '',
))
->execute();
}
}
}
function text_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
if (!_mee_field_instance_enabled($instance, 'mee')) {
return;
}
list($id, $revision_id) = _mee_extract_id($entity_type, $entity);
foreach ($items as $delta => $item) {
list($sids, $copyrights) = _mee_process_item_value($item, $entity_type, $entity, $field, $delta);
db_delete('mee_resource')
->condition('entity_type', $entity_type)
->condition('entity_id', $id)
->condition('revision_id', $revision_id)
->condition('field', $field['field_name'])
->condition('delta', $delta)
->execute();
$separator = $item['mee']['resource_manager'][0]['weight'];
foreach ($sids as $sid) {
$resource = $item['mee']['resource_manager'][$sid];
db_insert('mee_resource')
->fields(array(
'entity_type' => $entity_type,
'entity_id' => $id,
'revision_id' => $revision_id,
'atom_sid' => $sid,
'field' => $field['field_name'],
'delta' => $delta,
'weight' => $resource['weight'] - $separator,
'required' => isset($resource['required']) ? (int) $resource['required'] : 0,
'copyright' => isset($copyrights[$sid]) ? $copyrights[$sid] : '',
))
->execute();
}
}
}
function text_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
if (!_mee_field_instance_enabled($instance, 'mee')) {
return;
}
list($id, ) = _mee_extract_id($entity_type, $entity);
db_delete('mee_resource')
->condition('entity_type', $entity_type)
->condition('entity_id', $id)
->condition('field', $field['field_name'])
->execute();
}
function mee_field_attach_view_alter(&$output, $context) {
$store_format = mee_store_format();
if ($store_format == 'sas' || $store_format == 'embed_div') {
list($id, $revision_id, $bundle) = entity_extract_ids($context['entity_type'], $context['entity']);
$fields = field_info_instances($context['entity_type'], $bundle);
foreach ($fields as $name => $field) {
if (!empty($field['settings']['dnd_enabled']) && isset($output[$name])) {
foreach (element_children($output[$name]) as $key) {
if ($store_format == 'embed_div') {
$input_format = $output[$name]['#items'][$key]['format'];
$list = filter_list_format($input_format);
if (empty($list['mee_scald_widgets']) || $list['mee_scald_widgets']->status != 1) {
$output[$name][$key]['#markup'] = mee_filter_process($output[$name][$key]['#markup']);
}
}
$output[$name][$key]['#markup'] = scald_sas_to_rendered($output[$name][$key]['#markup'], $field['settings']['context'], FALSE, dnd_scald_wysiwyg_context_slugs());
}
}
}
}
}
function mee_panels_pane_content_alter($content, $pane, $args, $context) {
if ($pane->type === 'custom' && $pane->subtype === 'custom' && $content->type === 'custom' && is_string($content->content)) {
$store_format = mee_store_format();
if ($store_format == 'embed_div') {
$input_format = $pane->configuration['format'];
$list = filter_list_format($input_format);
if (empty($list['mee_scald_widgets']) || $list['mee_scald_widgets']->status != 1) {
$content->content = mee_filter_process($content->content);
}
}
$content->content = scald_sas_to_rendered($content->content, NULL, FALSE, dnd_scald_wysiwyg_context_slugs());
}
}
function mee_form_ctools_custom_content_type_edit_form_alter(&$form, &$form_state) {
$form['body']['#attached']['library'] = array(
array(
'dnd',
'library',
),
);
}
function mee_field_widget_form_alter(&$element, &$form_state, $context) {
$enables = _mee_field_instance_enabled($context['instance']);
if (in_array($context['field']['type'], mee_field_types()) && isset($element['#default_value'])) {
if (mee_store_format() == 'sas') {
$element['#default_value'] = scald_sas_to_rendered($element['#default_value'], $context['instance']['settings']['context'], FALSE, dnd_scald_wysiwyg_context_slugs());
}
}
if (!empty($enables['dnd'])) {
$settings = $context['instance']['settings'];
$context_default = isset($settings['context_default']) ? $settings['context_default'] : variable_get('dnd_context_default', 'sdl_editor_representation');
$element['#attributes']['data-dnd-context'][] = $context_default;
$element['#attached']['library'][] = array(
'dnd',
'library',
);
if (isset($element['summary'])) {
$element['summary']['#attributes']['data-dnd-context'][] = $context_default;
}
}
if (empty($enables['mee'])) {
return;
}
$element['mee'] = array(
'#prefix' => '<div class="mee-wrap-editor-library">',
'#suffix' => '</div>',
'#attached' => array(
'library' => array(
array(
'mee',
'library',
),
),
),
'#element_validate' => array(
'mee_field_text_validate',
),
'#weight' => 0.5,
'resource_manager' => array(
'#theme' => 'mee_resource_manager',
),
);
$resource_manager = array();
if (isset($form_state['input'][$context['field']['field_name']][$context['langcode']])) {
$resource_manager = $form_state['input'][$context['field']['field_name']][$context['langcode']][$context['delta']]['mee']['resource_manager'];
}
elseif (isset($element['#entity'])) {
$item = array();
_mee_load_resources($element['#entity_type'], $element['#entity'], $context['field'], $context['delta'], $item);
$resource_manager = $item['mee']['resource_manager'];
}
foreach ($resource_manager as $sid => $item) {
$atom = scald_fetch($sid);
if (!is_object($atom)) {
continue;
}
$title = scald_render($atom, 'title');
$element['mee']['resource_manager'][$sid] = array(
'title' => array(
'#markup' => $title,
),
'required' => array(
'#type' => 'select',
'#options' => array(
t('Optional'),
t('Required'),
),
'#default_value' => $item['required'],
),
'weight' => array(
'#type' => 'weight',
'#default_value' => $item['weight'],
),
'#weight' => $item['weight'],
);
}
$element['mee']['resource_manager'][0] = array(
'title' => array(
'#markup' => t('< Primary / Secondary >'),
),
'required' => array(
'#markup' => '-',
),
'weight' => array(
'#type' => 'weight',
'#prefix' => '<div class="mee-rm-separator">',
'#suffix' => '</div>',
),
'#weight' => isset($resource_manager[0]['weight']) ? $resource_manager[0]['weight'] : 0,
);
}
function mee_field_text_validate($element, &$form_state) {
foreach ($form_state['field'] as $field_name => $values) {
foreach ($values as $langcode => $data) {
if (isset($form_state['values'][$field_name][$langcode]) && is_array($form_state['values'][$field_name][$langcode]) && isset($form_state['values'][$field_name][$langcode][0]['mee']) && isset($form_state['input'][$field_name][$langcode][0]['mee'])) {
$form_state['values'][$field_name][$langcode][0]['mee'] = $form_state['input'][$field_name][$langcode][0]['mee'];
}
}
}
}
function mee_field_types() {
return variable_get('mee_field_types', array(
'text',
'text_long',
'text_with_summary',
));
}
function mee_scald_atom_delete($atom) {
db_delete('mee_resource')
->condition('atom_sid', $atom->sid)
->execute();
}
function mee_node_revision_delete($revision) {
db_delete('mee_resource')
->condition('entity_type', 'node')
->condition('entity_id', $revision->nid)
->condition('revision_id', $revision->vid)
->execute();
}
function mee_ckeditor_filter_xss_allowed_tags() {
return array(
'!--',
);
}
function theme_mee_resource_manager($variables) {
$form = $variables['resource_manager'];
static $count = 0;
$id = 'mee-resource-manager-' . $count;
drupal_add_tabledrag($id, 'order', 'sibling', 'mee-rm-weight');
$count++;
$header = array(
t('Title'),
t('Required'),
t('Weight'),
);
$rows = array();
foreach (element_children($form) as $key) {
$form[$key]['weight']['#attributes']['class'] = array(
'mee-rm-weight',
);
$row = array();
$row[] = drupal_render($form[$key]['title']);
$row[] = drupal_render($form[$key]['required']);
$row[] = drupal_render($form[$key]['weight']);
$rows[] = array(
'data' => $row,
'class' => array(
'draggable',
),
);
}
$output = theme('table', array(
'header' => $header,
'rows' => $rows,
'attributes' => array(
'id' => $id,
'class' => array(
'mee-resource-manager',
),
),
'caption' => t('Resource Manager'),
));
$output .= drupal_render_children($form);
return $output;
}
function theme_mee_widget_embed($vars) {
$options = array();
if (isset($vars['options'])) {
$options = drupal_json_decode($vars['options']);
}
$classes = array(
'dnd-widget-wrapper',
'context-' . $vars['context'],
'type-' . $vars['atom']->type,
);
if ($vars['align'] != 'none') {
$classes[] = 'atom-align-' . $vars['align'];
}
if (!empty($options['additionalClasses'])) {
foreach (explode(' ', $options['additionalClasses']) as $class) {
$classes[] = $class;
}
}
$output = '<div class="' . implode(' ', $classes) . '">';
$output .= '<div class="dnd-atom-rendered">' . $vars['content'] . '</div>';
if (!empty($vars['caption']) || $vars['wysiwyg']) {
$output .= '<div class="dnd-caption-wrapper">' . $vars['caption'] . '</div>';
}
$output .= '</div>';
return $output;
}
function mee_ajax_widget_expand($atom) {
$context = isset($_GET['context']) && in_array($_GET['context'], dnd_scald_wysiwyg_context_slugs()) ? $_GET['context'] : NULL;
if ($atom->type == 'scald_atom_fallback') {
$context = 'invalid-id';
}
$options = isset($_GET['options']) ? urldecode($_GET['options']) : '';
$align = isset($_GET['align']) && in_array($_GET['align'], array(
'left',
'right',
'center',
)) ? $_GET['align'] : 'none';
$output = $context ? scald_render($atom, $context, $options) : scald_render($atom, 'title');
if (empty($atom->omit_legend)) {
$legend = theme('sdl_editor_legend', array(
'atom' => $atom,
));
}
else {
$legend = '';
}
$commands = array();
$commands[] = array(
'command' => 'dndck4_cache_atom_metadatadata',
'data' => array(
'sid' => $atom->sid,
'meta' => array(
'title' => $atom->title,
'type' => $atom->type,
'data' => !empty($atom->data) ? $atom->data : array(),
'provider' => $atom->provider,
'legend' => $legend,
),
'actions' => array_keys(scald_atom_actions_available($atom)),
),
);
if ($context) {
$commands[] = array(
'command' => 'dndck4_expand_widget',
'data' => theme('mee_widget_embed', array(
'atom' => $atom,
'context' => $context,
'options' => $options,
'align' => $align,
'content' => $output,
'wysiwyg' => TRUE,
)),
);
}
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
}
function _mee_field_instance_enabled($instance, $key = NULL) {
$enables = array(
'mee' => FALSE,
'dnd' => FALSE,
);
if (!empty($instance['settings']['mee_enabled'])) {
$enables['mee'] = TRUE;
}
if (!empty($instance['settings']['dnd_enabled'])) {
$enables['dnd'] = TRUE;
}
return $key ? $enables[$key] : $enables;
}
function _mee_extract_id($entity_type, $entity) {
list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
if (!isset($revision_id)) {
$revision_id = $entity_id;
}
return array(
$entity_id,
$revision_id,
);
}
function _mee_process_item_value(&$item, $entity_type, $entity, $field, $delta) {
if (mee_store_format() == 'embed_div') {
$sids = array();
$copyrights = array();
foreach (_mee_extract_widget_embed_info(filter_dom_load($item['value'])) as $info) {
$sids[] = $info['sid'];
$copyrights[$info['sid']] = $info['caption'];
}
if (!empty($item['summary'])) {
foreach (_mee_extract_widget_embed_info(filter_dom_load($item['summary'])) as $info) {
$sids[] = $info['sid'];
$copyrights[$info['sid']] = $info['caption'];
}
}
$sids = array_unique($sids);
}
else {
$sas = scald_rendered_to_sas($item['value']);
$scald_included = scald_included($sas);
$sids = array_unique($scald_included);
$copyrights = mee_extract_copyrights($item['value']);
}
if (empty($item['mee']) || !is_array($item['mee']['resource_manager'])) {
_mee_load_resources($entity_type, $entity, $field, $delta, $item);
}
foreach ($sids as $sid) {
if (!isset($item['mee']['resource_manager'][$sid])) {
$item['mee']['resource_manager'][$sid] = array(
'required' => FALSE,
'weight' => 0,
);
}
}
return array(
$sids,
$copyrights,
);
}
function _mee_load_resources($entity_type, $entity, $field, $delta, &$item) {
list($id, $revision_id) = _mee_extract_id($entity_type, $entity);
$result = db_select('mee_resource', 'r')
->fields('r', array(
'atom_sid',
'weight',
'required',
))
->condition('entity_type', $entity_type)
->condition('entity_id', $id)
->condition('revision_id', $revision_id)
->condition('field', $field['field_name'])
->condition('delta', $delta)
->execute();
$item['mee']['resource_manager'] = array();
$item['mee']['resource_manager'] = $result
->fetchAllAssoc('atom_sid', PDO::FETCH_ASSOC);
$item['mee']['resource_manager'][0] = array(
'weight' => 0,
'required' => FALSE,
);
}
function mee_extract_copyrights($string) {
$copyrights = array();
if (preg_match_all(MEE_RENDERED_COPYRIGHT_PATTERN, $string, $matches)) {
foreach ($matches[1] as $key => $sid) {
$copyrights[$sid] = $matches[2][$key];
}
}
return $copyrights;
}
function mee_wysiwyg_include_directory($type) {
switch ($type) {
case 'plugins':
return $type;
}
}
function mee_filter_info() {
$filters['mee_scald_widgets'] = array(
'title' => t('Embedded atoms'),
'description' => t('This is only needed when using the Scald plugin for CKEditor 4'),
'process callback' => 'mee_filter_process',
);
return $filters;
}
function mee_filter_process($text) {
$dom = filter_dom_load($text);
if ($embed_info = _mee_extract_widget_embed_info($dom)) {
$sids = array();
foreach ($embed_info as $info) {
$sids[] = $info['sid'];
}
$atoms = scald_atom_load_multiple(array_unique($sids));
foreach ($embed_info as $info) {
$html = '';
if (isset($atoms[$info['sid']])) {
$html = theme('mee_widget_embed', array(
'atom' => $atoms[$info['sid']],
'context' => $info['context'],
'options' => $info['options'],
'align' => $info['align'],
'caption' => $info['caption'],
'content' => '[scald=' . $info['sid'] . ':' . $info['context'] . ($info['options'] ? ' ' . $info['options'] : '') . ']',
));
}
$node = $info['node'];
$fragment = $dom
->createDocumentFragment();
$fragment
->appendXML($html);
$node->parentNode
->replaceChild($fragment, $node);
}
$text = filter_dom_serialize($dom);
}
return $text;
}
function _mee_extract_widget_embed_info($dom) {
$embed_info = array();
$xpath = new DOMXPath($dom);
$nodes = $xpath
->query("//div[@class='dnd-atom-wrapper']|//figure[@class='dnd-atom-wrapper']|//span[@class='dnd-atom-wrapper']");
foreach ($nodes as $node) {
$info = array(
'node' => $node,
'sid' => $node
->getAttribute('data-scald-sid'),
'align' => $node
->getAttribute('data-scald-align'),
'context' => $node
->getAttribute('data-scald-context'),
'options' => urldecode($node
->getAttribute('data-scald-options')),
'caption' => '',
);
$result = $xpath
->query("div[@class='dnd-caption-wrapper']|figcaption[@class='dnd-caption-wrapper']", $node);
if ($result->length) {
foreach ($result
->item(0)->childNodes as $child) {
$info['caption'] .= $dom
->saveXML($child);
}
}
$embed_info[] = $info;
}
return $embed_info;
}