File: /home/nexper/www/sites/all/modules/node_gallery/node_gallery_api.inc
<?php
/**
* @file
* Node Gallery API function
*/
/**
* Get Node Gallery Relationships.
*
* @param int $gallery_nid
* Gallery NID
* @param int $item_nid
* Item NID
* @param int $id
* Relationship entity ID
* @param bool $ids_only
* If true, skip loading the entities.
*
* @return array
* Array of Node Gallery relationships matching parameters.
*/
function node_gallery_api_get_relationships($gallery_nid = NULL, $item_nid = NULL, $id = NULL, $ids_only = FALSE) {
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node_gallery_relationship');
if (!empty($item_nid)) {
$query->propertyCondition('nid', $item_nid);
}
if (!empty($gallery_nid)) {
$query->propertyCondition('ngid', $gallery_nid);
}
if (!empty($id)) {
$query->propertyCondition('id', (int) $id);
}
$relationships = $query->execute();
if (!empty($relationships['node_gallery_relationship'])) {
$relationships = array_keys($relationships['node_gallery_relationship']);
if ($ids_only) {
return $relationships;
}
return entity_load('node_gallery_relationship', $relationships);
}
return array();
}
/**
* Convenience wrapper for getting all relationships.
*
* @return array
* An associative array of relationship arrays.
*/
function node_gallery_api_get_all_relationship_types() {
return node_gallery_api_get_relationship_type(NULL, NULL);
}
/**
* Fetches a gallery-to-image relationship from the database.
*
* If one of either $gallery_type or $item_type are supplied, this function
* returns a single relationship. If neither are specified, it returns all
* relationships, keyed by the gallery content type. If both are supplied,
* $item_type will be ignored.
*
* @param string $gallery_type
* (optional) The content type of the gallery in the relationship. If
* this is an int, we'll use that as the rid.
* Defaults to NULL.
* @param string $item_type
* (optional) The content type of the image in the relationship.
* Defaults to NULL.
*
* @return array
* An associative array containing:
* - rid: An integer representing the rid column in the database.
* - gallery_type: A string that is the content type of the gallery.
* - item_type: A string that is the content type of the image.
* - filefield_name: The name of the imagefield for the image.
* - settings: An associative array of settings for the relationship.
*/
function node_gallery_api_get_relationship_type($gallery_type = NULL, $item_type = NULL, $id = NULL, $reset = FALSE) {
$relationship_types = &drupal_static(__FUNCTION__);
if (!isset($relationship_types) || $reset) {
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node_gallery_relationship_type');
$entities = $query->execute();
if (!empty($entities['node_gallery_relationship_type'])) {
$relationship_types = entity_load('node_gallery_relationship_type', array_keys($entities['node_gallery_relationship_type']));
}
}
if (empty($relationship_types)) {
return NULL;
}
elseif (empty($gallery_type) && empty($item_type) && empty($id)) {
return $relationship_types;
}
$filtered_types = $relationship_types;
foreach ($filtered_types as $i => $type) {
if (!empty($id) && $i != $id) {
unset($filtered_types[$i]);
}
if (!empty($gallery_type) && !in_array($gallery_type, $type->settings['relationship_type']['gallery_types'])) {
unset($filtered_types[$i]);
}
if (!empty($item_type) && !in_array($item_type, $type->settings['relationship_type']['item_types'])) {
unset($filtered_types[$i]);
}
}
if (empty($filtered_types)) {
return NULL;
}
else {
return array_shift($filtered_types);
}
}
/**
* Is this NID a for a gallery node.
*
* @param int $nid
* NID to check.
*
* @return bool
* Whether this is a gallery.
*/
function node_gallery_api_is_gallery($nid) {
return (bool) db_select('node_gallery_galleries', 'ngg')
->fields('ngg', array('ngid'))
->condition('ngid', $nid)
->execute()
->fetchField();
}
/**
* Gets the count of published images within a gallery.
*
* @param int $ngid
* The nid of the gallery to query.
* @param bool $reset
* (optional) If TRUE, clears the cache, defaults to FALSE.
*
* @return int
* A count of all images in the gallery.
*/
function node_gallery_api_get_item_count($ngid, $reset = FALSE) {
return count(node_gallery_api_get_item_list($ngid, $reset));
}
/**
* Returns a list of all possible content types of galleries, images, or both.
*
* @param string $type
* (optional) 'gallery', 'image' or 'all'.
*
* @return array
* An array containing the list of content types.
*/
function node_gallery_api_get_types($type = 'gallery', $reset = FALSE) {
$ng_types = &drupal_static(__FUNCTION__);
if (empty($ng_types) || $reset) {
$ng_types['gallery'] = array();
$ng_types['item'] = array();
$ng_rels = node_gallery_api_get_all_relationship_types();
if (is_array($ng_rels)) {
foreach ($ng_rels as $relationship_type) {
foreach ($relationship_type->gallery_types as $gallery_type) {
$ng_types['gallery'][] = $gallery_type;
}
foreach ($relationship_type->item_types as $item_type) {
$ng_types['item'][] = $item_type;
}
}
}
}
if ($type == 'all') {
return array_merge($ng_types['gallery'], $ng_types['item']);
}
else {
return $ng_types[$type];
}
}
/**
* Retrieves image properties sorted by the image sort view in a
* gallery, the returned objects are NOT complete nodes.
*
* @param object $gallery
* The node object of the gallery.
* @param boolean $sorted
* Whether to keep the order as effective in the UI. Defaults to true.
* @param boolean $filtered
* Whether to filter down the resulting images by publish status.
*
* @return array
* An array of image objects with the basic properties nid,
* title, status, created, changed, filepath and weight.
*/
function node_gallery_api_get_items($gallery, $sorted = TRUE, $filtered = TRUE, $reset = FALSE) {
$items = &drupal_static(__FUNCTION__, array(), $reset);
$cache_keys[] = 'node_gallery';
$cache_keys[] = $gallery->nid;
$cache_keys[] = 'items';
$cache_keys[] = $sorted ? 'sort-true' : 'sort-false';
$cache_keys[] = $filtered ? 'filtered-true' : 'filtered-false';
$cache_key = implode(':', $cache_keys);
if (!isset($images[$cache_key]) || $reset) {
if (!$reset && ($cache = cache_get($cache_key)) && !empty($cache->data)) {
return $cache->data;
}
else {
$items[$cache_key] = array();
// Get the order currently in effect; the criteria is unknown
// here because the user can change the view.
$item_nids = node_gallery_api_get_item_nids($gallery->nid, $sorted, $filtered);
if (count($item_nids) == 0) {
cache_set($cache_key, $items[$cache_key], 'cache', CACHE_TEMPORARY);
return $items[$cache_key];
}
// Get CCK information for retrieving the filepath.
$relationship_type = node_gallery_api_get_relationship_type($gallery->type);
$field = field_info_field($relationship_type->filefield_name);
foreach ($item_nids as $nid) {
$item = node_load($nid);
if (!empty($relationship_type->filefield_name)) {
$files = field_get_items('node', $item, $relationship_type->filefield_name);
if (!empty($files)) {
$item->node_gallery['item_file'] = $files[0];
$item->node_gallery['item_file_url'] = file_create_url($files[0]['uri']);
}
}
$items[$cache_key][] = $item;
}
cache_set($cache_key, $items[$cache_key], 'cache', CACHE_TEMPORARY);
}
}
return $items[$cache_key];
}
/**
* Clears all the caches for a specific gallery.
*
* @param int $ngid
* The nid of the gallery to clear caches on.
*/
function node_gallery_api_clear_gallery_caches($ngid) {
cache_clear_all('node_gallery:' . $ngid, 'cache', TRUE);
}
/**
* Batch API sorting callback.
*/
function node_gallery_api_batch_sorting_callback($images, &$context) {
if (empty($context['sandbox'])) {
$context['sandbox']['iterator'] = 0;
$context['sandbox']['count'] = count($images);
$context['results']['ngid'] = $images[0]['ngid'];
}
$context['results'][] = drupal_write_record('node_gallery_relationship', $images[$context['sandbox']['iterator']], 'nid');
$context['sandbox']['iterator']++;
if ($context['sandbox']['iterator'] < $context['sandbox']['count']) {
$context['finished'] = $context['sandbox']['iterator'] / (float) $context['sandbox']['count'];
}
else {
$context['finished'] = 1;
}
}
/**
* Batch API sorting finished callback.
*/
function node_gallery_api_batch_sorting_finished($success, $results, $operation) {
if ($success) {
// $results contains ['ngid'] as well as the actual results,
// so we subtract one here.
$message = format_plural(count($results) - 1, 'One image processed.', '@count images processed.');
}
else {
$message = t('Finished with an error.');
}
node_gallery_api_clear_gallery_caches($results['ngid']);
drupal_set_message($message);
}
/**
* Get item files from NIDs.
*
* @param array $nids
* Array of node NIDs.
* @param string $fieldname
* File field name
*
* @return array
* Files
*/
function node_gallery_api_get_item_file($nids, $fieldname) {
$fields = &drupal_static(__FUNCTION__, array());
static $fields = array();
if ($fieldname == 'node_gallery_none') {
return array();
}
if (!isset($fields[$fieldname])) {
$field_info = field_info_field($fieldname);
$fields[$fieldname]['db_info'] = array_shift(array_values($field_info['storage']['details']['sql'][FIELD_LOAD_CURRENT]));
$fields[$fieldname]['db_info'] += array('table' => array_shift(array_keys($field_info['storage']['details']['sql'][FIELD_LOAD_CURRENT])));
}
$query = db_select($fields[$fieldname]['db_info']['table'], 'field_table');
$query->fields('field_table', array($fields[$fieldname]['db_info']['fid'], 'entity_id'));
$query->condition('field_table.entity_type', 'node', '=');
if (!is_array($nids)) {
$query->condition('field_table.entity_id', $nids, '=');
}
else {
$query->condition('field_table.entity_id', $nids, 'IN');
}
$results = $query->execute();
$files = array();
foreach ($results as $record) {
if (!empty($record->{$fields[$fieldname]['db_info']['fid']})) {
$files[$record->entity_id] = file_load($record->{$fields[$fieldname]['db_info']['fid']});
}
}
// TODO: Get rid of this inconsistency of use.
if (count($nids) == 1) {
$files = array_shift($files);
}
return $files;
}
/**
* Batch API save callback.
*/
function node_gallery_api_batch_node_save($nodes, &$context) {
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = count($nodes);
}
if (!isset($context['sandbox']['nodes'])) {
if (is_array($nodes)) {
$context['sandbox']['nodes'] = $nodes;
}
else {
$context['sandbox']['nodes'] = array($nodes);
}
}
$count = 0;
while (!empty($context['sandbox']['nodes']) && $count <= NODE_GALLERY_BATCH_CHUNK_SIZE) {
$count++;
$node = array_shift($context['sandbox']['nodes']);
$node = (object) array_merge((array) node_load($node->nid), (array) $node);
watchdog('batch_save', print_r($node, TRUE));
node_save_action($node);
watchdog('batch_save', print_r($node, TRUE));
$context['sandbox']['progress']++;
}
// Let the batch engine know how close we are to completion.
if ($context['sandbox']['progress'] == $context['sandbox']['max']) {
// Done!
$context['finished'] = 1;
}
else {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
/**
* Get the gallery ref field name for a set of types.
*
* @param string $gallery_type
* Gallery type
* @param string $item_type
* Item type
* @param int $relationship_type_id
* Relationship ID
*
* @return bool|string
* Name of the ref field, or FALSE is there is not one.
*/
function node_gallery_api_get_item_field_name($gallery_type = NULL, $item_type = NULL, $relationship_type_id = NULL) {
if (empty($relationship_type_id)) {
$relationship_type = node_gallery_api_get_relationship_type($gallery_type, $item_type);
$relationship_id = $relationship_type->id;
}
if (!empty($relationship_type_id)) {
return NODE_GALLERY_REF_FIELD . '_' . $relationship_type_id;
}
return FALSE;
}
/**
* Deletes batches of images for batch API.
*
* @param array $imagenids
* Array of nids to delete.
* @param array $context
* Array provided by batch API.
*/
function node_gallery_api_batch_node_delete($imagenids, &$context) {
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = count($imagenids);
}
if (!isset($context['sandbox']['imagenids'])) {
if (is_array($imagenids)) {
$context['sandbox']['imagenids'] = $imagenids;
}
else {
$context['sandbox']['imagenids'] = array($imagenids);
}
}
$count = 0;
while (!empty($context['sandbox']['imagenids']) && $count <= NODE_GALLERY_BATCH_CHUNK_SIZE) {
$count++;
$nid = array_shift($context['sandbox']['imagenids']);
node_delete($nid);
$context['sandbox']['progress']++;
}
// Let the batch engine know how close we are to completion.
if ($context['sandbox']['progress'] == $context['sandbox']['max']) {
// Done!
$context['finished'] = 1;
}
else {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
/**
* Batch API rotate callback.
*/
function node_gallery_api_batch_rotate($fid, $degrees, &$context) {
$result = 0;
$file = file_load($fid);
$filepath_new = preg_replace_callback(
'~(?:_r([0-9]+))?(?=(?:\.[^./]*)?$)~',
create_function('$matches', 'return "_r".(!empty($matches[1]) ? $matches[1]+1 : 1);'),
$file->uri, 1);
$new_file = file_move($file, $filepath_new);
$image = image_load($new_file->uri);
global $conf;
$conf['image_jpeg_quality'] = 100;
if ($image !== FALSE) {
if ($image->toolkit == 'imagemagick') {
$result = image_rotate($image, $degrees, 0x000000);
}
else {
$result = image_rotate($image, $degrees);
}
image_save($image);
$new_file->image_dimensions['width'] = $image->width;
$new_file->image_dimensions['height'] = $image->height;
file_save($new_file);
image_path_flush($image->source);
}
else {
watchdog('node_gallery', 'Could not open image for rotation');
}
$context['results'][] = $result;
}
/**
* Used as a finished callback for batch API deletion of images.
*
* @param int $success
* Scalar provided by batch API.
* @param array $results
* Array provided by batch API.
* @param array $operations
* Array provided by batch API.
*/
function node_gallery_api_batch_item_process_finished($success, $results, $operations) {
if ($success) {
drupal_set_message(t('Item modifications complete.'));
cache_clear_all('node_gallery', 'cache', TRUE);
cache_clear_all();
}
else {
// An error occurred.
// $operations contains the operations that remained unprocessed.
$error_operation = reset($operations);
$operation = array_shift($error_operation);
$arguments = array_shift($error_operation);
$arguments_as_string = implode(', ', $arguments);
watchdog('node_gallery', "Error when calling operation '%s'('%s')", array($operation, $arguments_as_string));
drupal_set_message(t('An error occurred and has been recorded in the system log.'), 'error');
}
}
/**
* Default values for relationship types.
*/
function node_gallery_api_relationship_type_settings_defaults() {
$settings = array(
'relationship' => array(
'name' => 'Node Gallery Default',
),
'item_view' => array(
'display_navigator' => 1,
'view_navigator_item_display' => 'node_gallery_gallery_image_views:page_7',
'page_fragment' => 0,
),
'manage_items' => array(
'items_fields' => array('title' => 'title'),
'items_per_page' => 20,
'enable_rotation' => TRUE,
'rotation_radios' => TRUE,
'rotation_modal' => TRUE,
),
'og' => array(
'sync_items' => TRUE,
),
);
drupal_alter('node_gallery_relationship_default_settings', $settings);
return $settings;
}
/**
* Get view mode info for nodes.
*
* @return array
* All view modes for nodes
*/
function node_gallery_api_get_view_modes() {
$entity_info = entity_get_info('node');
$view_modes = array();
foreach ($entity_info['view modes'] as $name => $info) {
$view_modes[$name] = $info['label'];
}
return $view_modes;
}
/**
* Gets a sorted list of images nids within a gallery.
*
* @param int $ngid
* The nid of the gallery to query.
* @param bool $reset
* (optional) If TRUE, clears the cache, defaults to FALSE.
*
* @return array
* An array of sorted image nids with a status of published.
*/
function node_gallery_api_get_item_list($ngid, $reset = FALSE) {
$item_list = drupal_static(__FUNCTION__, array(), $reset);
if (!isset($item_list[$ngid]) || $reset) {
if (!$reset && ($cache = cache_get('node_gallery:' . $ngid . ':item_list'))) {
$item_list[$ngid] = $cache->data;
}
else {
_node_gallery_api_cache_sorted_item_nids($ngid);
$cache = cache_get('node_gallery:' . $ngid . ':item_list');
$item_list[$ngid] = $cache->data;
}
}
return $item_list[$ngid];
}
/**
* Builds the caches for a gallery and saves them to the db.
*
* There are two caches stored for each gallery. One is a sorted array of nids
* that represents the items in proper search order.
* The second is an associative array where the key is the nid of the image
* and the value is that nid's respective position in the list (1-based).
*
* @param int $ngid
* The nid of the gallery to build caches for.
*/
function _node_gallery_api_cache_sorted_item_nids($ngid) {
$item_list = node_gallery_api_get_item_nids($ngid, TRUE, TRUE);
$item_position = array();
$position = 1;
foreach ($item_list as $nid) {
$item_position[$nid] = $position;
$position++;
}
cache_set('node_gallery:' . $ngid . ':item_position', $item_position, 'cache', CACHE_TEMPORARY);
cache_set('node_gallery:' . $ngid . ':item_list', $item_list, 'cache', CACHE_TEMPORARY);
}
/**
* Gets the first image nid within a gallery.
*
* @param int $ngid
* The nid of the gallery to query.
* @param bool $reset
* (optional) If TRUE, clears the cache, defaults to FALSE.
*
* @return int
* The nid of the first image in the gallery.
*/
function node_gallery_api_get_first_item($ngid, $reset = FALSE) {
$item_list = node_gallery_api_get_item_list($ngid, $reset);
return $item_list[0];
}
/**
* Gets the last image nid within a gallery.
*
* @param int $ngid
* The nid of the gallery to query.
* @param bool $reset
* (optional) If TRUE, clears the cache, defaults to FALSE.
*
* @return int
* The nid of the last image in the gallery.
*/
function node_gallery_api_get_last_item($ngid, $reset = FALSE) {
$item_list = node_gallery_api_get_item_list($ngid, $reset);
return $item_list[count($item_list) - 1];
}
/**
* Gets the next image in the gallery.
*
* @param int $ngid
* The nid of the gallery node.
* @param int $nid
* The nid of the image node.
* @param bool $reset
* (optional) If TRUE, the caches are cleared.
*
* @return int
* The nid of the next image in the gallery.
*/
function node_gallery_api_get_next_item($ngid, $nid, $reset = FALSE) {
return node_gallery_api_seek_from_current_item($ngid, $nid, 1, $reset);
}
/**
* Gets the previous image in the gallery.
*
* @param int $ngid
* The nid of the gallery node.
* @param int $nid
* The nid of the image node.
* @param bool $reset
* (optional) If TRUE, the caches are cleared.
*
* @return int
* The nid of the previous image in the gallery.
*/
function node_gallery_api_get_prev_item($ngid, $nid, $reset = FALSE) {
return node_gallery_api_seek_from_current_item($ngid, $nid, -1, $reset);
}
/**
* Returns the nid of the image +/-N steps away from the current image node.
*
* @param int $ngid
* The nid of the gallery to query.
* @param int $nid
* The nid of the current image.
* @param int $seek
* The postive or negative number of slots to seek to.
* @param bool $reset
* (optional) If TRUE, clears the caches. Defaults to FALSE.
*/
function node_gallery_api_seek_from_current_item($ngid, $nid, $seek, $reset) {
$item_list = node_gallery_api_get_item_list($ngid, $reset);
$current_position = node_gallery_api_get_item_position($ngid, $nid, $reset);
$current_index = $current_position - 1;
$seek_index = $current_index + $seek;
return isset($item_list[$seek_index]) ? $item_list[$seek_index] : NULL;
}
/**
* Publishes the child image nodes when publishing a gallery.
*
* When publishing a gallery, we publish the image nodes within that gallery.
* We use batch api to provide for galleries with a large amount of images.
*
* @param object $node
* A reference to a gallery node object
* @param int $status
* The new publish status to set on the node
*/
function _node_gallery_api_set_publish(&$node, $status) {
$ngid = $node->nid;
$imagenids = node_gallery_api_get_item_nids($ngid, FALSE, FALSE);
// Split our operations into NODE_GALLERY_BATCH_CHUNK_SIZE a time.
$node_updates = array_chunk($imagenids, NODE_GALLERY_BATCH_CHUNK_SIZE);
array_walk_recursive($node_updates,
create_function('&$v,$k,$status', '$v = (object)array(\'nid\' => $v, \'status\' => $status);'), $status);
foreach ($node_updates as $node_update) {
$operations[] = array('node_gallery_api_batch_node_save', array($node_update));
}
if (!empty($operations)) {
$batch = array(
'operations' => $operations,
'finished' => 'node_gallery_api_item_process_finished',
'title' => t('Processing gallery publish status update.'),
'init_message' => t('Gallery publish status is cascading to images.'),
'progress_message' => t('Processing publishing of images.'),
'error_message' => t('Image publish status change has encountered an error.'),
);
batch_set($batch);
node_gallery_api_clear_gallery_caches($ngid);
}
}
/**
* Get all item NIDs for a Gallery
*/
function node_gallery_api_get_item_nids($ngid, $sorted = TRUE, $filtered = TRUE, $fallback = FALSE, $reset = FALSE) {
static $nids = array();
$cache_keys[] = 'node_gallery';
$cache_keys[] = $ngid;
$cache_keys[] = 'item_nids';
$cache_keys[] = $sorted ? 'sort-true' : 'sort-false';
$cache_keys[] = $filtered ? 'filtered-true' : 'filtered-false';
$cache_keys[] = $fallback ? 'fallback-true' : 'fallback-false';
$cache_key = implode(':', $cache_keys);
if (!isset($nids[$cache_key]) || $reset) {
if (!$reset && ($cache = cache_get($cache_key)) && !empty($cache->data)) {
$nids[$cache_key] = $cache->data;
}
else {
if (!$fallback) {
$gallery = node_load($ngid);
$relationship_type = node_gallery_api_get_relationship_type($gallery->type);
$view_name = '';
$view_display = '';
if (!empty($relationship_type->settings['item_view']['view_navigator_item_display'])) {
list($view_name, $view_display) = explode(':', $relationship_type->settings['item_view']['view_navigator_item_display']);
}
if (isset($view_name)) {
$view = views_get_view($view_name);
if (isset($view->display[$view_display])) {
$view->set_display($view_display);
$view->set_arguments(array($gallery->nid));
if (!$sorted) {
$sorts = $view->get_items('sort', $view_display);
foreach ($sorts as $sort) {
$view->set_item($view_display, 'sort', $sort['id'], NULL);
}
}
if (!$filtered) {
$filters = $view->get_items('filter', $view_display);
foreach ($filters as $filter) {
$view->set_item($view_display, 'filter', $filter['id'], NULL);
}
}
$view->build();
if (isset($view->field['nid'])) {
$query = $view->build_info['query'];
$query_field_name = $view->field['nid']->field_alias;
}
else {
$message = t("Found the image sort view, but the 'Node: Nid' field wasn't found.", array());
}
}
}
}
if (isset($message) || $fallback || !isset($query)) {
$query_field_name = 'nid';
$query = db_select('node_gallery_relationship', 'ng')->fields('ng', array('nid'));
$query->join('node', 'n', 'ng.nid = n.nid');
// Use our default sql.
if (isset($message)) {
if (user_access('administer node gallery')) {
drupal_set_message($message, 'warning');
}
watchdog('node_gallery', $message, NULL, WATCHDOG_WARNING);
}
if ($filtered) {
$query->condition('n.status', 1);
}
if ($sorted) {
$query->orderBy('ng.weight', 'ASC');
$query->orderBy('n.nid', 'ASC');
}
$query->condition('ng.ngid', $ngid);
}
$result = $query->execute();
$nids[$cache_key] = array();
foreach ($result as $r) {
$nids[$cache_key][] = $r->{$query_field_name};
}
cache_set($cache_key, $nids[$cache_key], 'cache', CACHE_TEMPORARY);
}
}
return $nids[$cache_key];
}
/**
* Returns the position (starting at one) of the image in the gallery list.
*
* @param int $ngid
* The nid of the gallery to use.
* @param int $nid
* The nid of the image to return the position of.
*
* @return int
* The position of the image in the list of published images in the gallery.
*/
function node_gallery_api_get_item_position($ngid, $nid, $reset = FALSE) {
static $item_position = array();
if (!isset($item_position[$ngid]) || $reset) {
if (!$reset && ($cache = cache_get('node_gallery:' . $ngid . ':item_position')) && !empty($cache->data)) {
$item_position[$ngid] = $cache->data;
}
else {
_node_gallery_api_cache_sorted_item_nids($ngid);
$cache = cache_get('node_gallery:' . $ngid . ':item_position');
$item_position[$ngid] = $cache->data;
}
}
return $item_position[$ngid][$nid];
}
/**
* Given a gallery, returns it's cover image.
*
* @param int $ngid
* A populated node object.
*
* @return int
* The nid of the cover image.
*/
function node_gallery_api_get_cover_nid($ngid) {
return db_query("SELECT cover_item FROM {node_gallery_galleries} WHERE ngid = :ngid", array(':ngid' => $ngid))->fetchField();
}
/**
* Sets the cover image in the DB if necessary.
*
* @param int $item_nid
* A reference to the node object of a node gallery image.
*/
function node_gallery_api_set_gallery_cover_item($item_nid, $ngid = NULL) {
if (empty($ngid)) {
$relationships = node_gallery_api_get_relationships(NULL, $item_nid);
if (!empty($relationships)) {
$relationship = array_shift($relationships);
$ngid = $relationships->ngid;
}
if (empty($ngid)) {
return FALSE;
}
}
db_update('node_gallery_galleries')
->fields(array('cover_item' => $item_nid))
->condition('ngid', $ngid)
->execute();
return TRUE;
}
/**
* Reset Gallery cover.
*
* @param int $ngid
* Gallery NID
*/
function node_gallery_api_reset_cover_item($ngid) {
$new_cover = db_query('SELECT nid FROM {node_gallery_relationship} WHERE ngid = :ngid LIMIT 1',
array(':ngid' => $ngid))->fetchField();
if ($new_cover !== FALSE) {
$result = db_update('node_gallery_galleries')
->fields(array('cover_item' => $new_cover))
->condition('ngid', $ngid)
->execute();
}
else {
// Gallery is now empty, set cover to NULL.
db_update('node_gallery_galleries')
->fields(array('cover_item' => NULL))
->condition('ngid', $ngid)
->execute();
}
}
/**
* Get all entity reference fields with Node Gallery behavior.
*
* @return array
* EntityReference fields
*/
function node_gallery_api_get_gallery_ref_fields() {
$gallery_ref_fields = &drupal_static(__FUNCTION__);
if (!isset($gallery_ref_fields)) {
$gallery_ref_fields = array();
$fields = field_info_fields();
foreach ($fields as $field_name => $field_info) {
if ($field_info['type'] == 'entityreference' && !empty($field_info['settings']['handler_settings']['behaviors']['node_gallery_behavior']['status'])) {
$gallery_ref_fields[$field_name] = $field_info;
}
}
}
return $gallery_ref_fields;
}
/**
* Check if we need to update this image.
*/
function node_gallery_api_items_check_update($old_image, $_new_image, $compare_fields) {
// a list of node attributes that are flattened one level by node_save
$flattened_attributes = array('options');
$new_image = clone $_new_image;
$new_image = node_submit($new_image);
if ($extra = node_invoke($new_image, 'presave')) {
foreach ($extra as $key => $value) {
$new_image->$key = $value;
}
}
if ($extra = module_invoke_all('node_presave', $new_image)) {
foreach ($extra as $key => $value) {
$new_image->$key = $value;
}
}
if ($extra = node_invoke($old_image, 'presave')) {
foreach ($extra as $key => $value) {
$old_image->$key = $value;
}
}
if ($extra = module_invoke_all('node_presave', $old_image)) {
foreach ($extra as $key => $value) {
$old_image->$key = $value;
}
}
foreach ($compare_fields as $f) {
if (in_array($f, $flattened_attributes)) {
// We make the old node look like the new one,
// ie $old_node->options['status'] = $old_node->status
foreach (array_keys($new_image->{$f}) as $option) {
$old_image->{$f}[$option] = $old_image->$option;
}
}
//a hack for cck field validate;
if (is_array($new_image->{$f})) {
foreach ($new_image->{$f} as &$ff) {
if (is_array($ff)) {
unset($ff['_error_element']);
}
}
}
if ($new_image->{$f} != $old_image->{$f}) {
return TRUE;
}
}
return FALSE;
}
/**
* Update image counts related to the Node Gallery node.
*
* @param int $ngid
* a gallery or an image node object
*/
function node_gallery_api_update_image_counts($ngid) {
$res = db_query("SELECT n.status AS status, COUNT(*) AS num
FROM {node_gallery_relationship} ngi
INNER JOIN {node} n ON ngi.nid = n.nid
WHERE ngi.ngid = :ngid GROUP BY n.status", array(':ngid' => $ngid));
$counts = array(
0 => 0,
1 => 0,
);
foreach ($res as $row) {
$counts[(int) $row->status] = (int) $row->num;
}
db_update('node_gallery_galleries')
->fields(array(
'item_count' => $counts[0] + $counts[1],
'pub_item_count' => $counts[1],
))
->condition('ngid', $ngid)
->execute();
}
/**
* Returns an array of galleries, suitable for use in a form select.
*
* @param string $type
* The content type of the galleries to be queried.
* @param int $uid
* (optional) if specified, the list returned will only contain
* galleries the user can modify.
*
* @return array
* Associative array where the keys are the nid, and the value
* is the node title.
*/
function node_gallery_api_get_gallery_list($type, $uid = NULL) {
$query = db_select('node', 'n')->fields('n', array('nid', 'title'))->condition('type', $type);
$items = array();
if ($uid) {
$query->condition('uid', $uid);
}
$result = $query->execute();
foreach ($result as $r) {
$items[$r->nid] = $r->title;
}
return $items;
}
/**
* Metadata Controller for Node Gallery Relationships
*/
class NodeGalleryRelationshipMetadataController extends EntityDefaultMetadataController {
public function entityPropertyInfo() {
$info = parent::entityPropertyInfo();
$properties = &$info[$this->type]['properties'];
$properties['nid']['type'] = 'node';
$properties['nid']['label'] = t('Gallery Item');
$properties['nid']['description'] = t('The Gallery Item associated with the Node Gallery relationship');
$properties['ngid']['type'] = 'node';
$properties['ngid']['label'] = t('Gallery');
$properties['ngid']['description'] = t('The Gallery associated with the Node Gallery relationship');
$properties['relationship_type']['type'] = 'node_gallery_relationship_type';
$properties['relationship_type']['label'] = t('Relationship Type');
$properties['relationship_type']['description'] = t('The Relationship Type of the Node Gallery relationship.');
$properties['weight']['label'] = t('Item Weight (Sort Order)');
$properties['weight']['description'] = t('The Item Weight (sort order) of the Node Gallery relationship.');
return $info;
}
}
/**
* Metadata Controller for Node Gallery Relationship Types
*/
class NodeGalleryRelationshipTypeMetadataController extends EntityDefaultMetadataController {
public function entityPropertyInfo() {
$info = parent::entityPropertyInfo();
$properties = &$info[$this->type]['properties'];
$properties['filefield_name']['label'] = t('File Field Name');
$properties['filefield_name']['description'] = t('The name of the file field for this Node Gallery relationship type.');
return $info;
}
}