tft.module in Taxonomy File Tree 7.2
Same filename and directory in other branches
Hook implementations and module logic for TFT.
File
tft.moduleView source
<?php
/**
* @file
* Hook implementations and module logic for TFT.
*/
/**
* @defgroup tft_permission List of permissions, defined as constants.
* @{
*/
define('TFT_PERM__ACCESS_FULL_TREE', 'tft access file tree');
define('TFT_PERM__ADMIN', 'aminister tft');
define('TFT_PERM__REORDER_ITEMS', 'tft reorder terms');
define('TFT_PERM__ADD_FILE', 'tft add a file to any term');
define('TFT_PERM__ADD_TERMS', 'tft add child terms');
define('TFT_PERM__DELETE_TERMS', 'tft delete child terms');
/**
* @} End of "defgroup tft_permission".
*/
/**
* @defgroup tft_hook_implementations All hook implementations for TFT.
* @{
*/
/**
* Implementation of hook_menu().
*/
function tft_menu() {
$menu = array(
'tft/download/file/%' => array(
'title' => 'Download',
'page callback' => 'tft_download_file',
'page arguments' => array(
3,
),
'access arguments' => array(
'access content',
),
'file' => 'includes/tft.pages.inc',
'type' => MENU_CALLBACK,
),
'tft/%' => array(
'title' => "Taxonomy File Tree",
'access arguments' => array(
TFT_PERM__ACCESS_FULL_TREE,
),
'page callback' => 'tft',
'page arguments' => array(
1,
),
'file' => 'includes/tft.pages.inc',
'type' => MENU_CALLBACK,
),
'tft' => array(
'title' => "Taxonomy File Tree",
'page callback' => 'tft',
'access arguments' => array(
TFT_PERM__ACCESS_FULL_TREE,
),
'file' => 'includes/tft.pages.inc',
'type' => MENU_CALLBACK,
),
'tft/term/add' => array(
'title' => "Add a folder",
'access callback' => 'tft_term_access',
'access arguments' => array(
NULL,
NULL,
'add-folder',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'tft_add_term_form',
),
'file' => 'includes/tft.pages.inc',
'type' => MENU_CALLBACK,
),
'tft/term/edit/%' => array(
'title' => "Edit a folder",
'access callback' => 'tft_term_access',
'access arguments' => array(
3,
NULL,
'edit',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'tft_edit_term_form',
3,
),
'file' => 'includes/tft.pages.inc',
'type' => MENU_CALLBACK,
),
'tft/term/delete/%' => array(
'title' => "Delete a folder",
'access callback' => 'tft_term_access',
'access arguments' => array(
3,
NULL,
'delete',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'tft_delete_term_form',
3,
),
'file' => 'includes/tft.pages.inc',
'type' => MENU_CALLBACK,
),
'tft/terms/reorder/%' => array(
'title' => t("Reorder items"),
'access callback' => 'tft_term_access',
'access arguments' => array(
3,
NULL,
'reorder',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'tft_manage_folders_form',
3,
),
'file' => 'includes/tft.pages.inc',
),
'tft/ajax/get-folder' => array(
'title' => "Ajax callback",
'access callback' => 'tft_term_access',
'access arguments' => array(
NULL,
NULL,
'view',
),
'page callback' => 'tft_ajax_get_folder',
'file' => 'includes/tft.ajax.inc',
'type' => MENU_CALLBACK,
),
'admin/config/media/tft' => array(
'title' => "Taxonomy File Tree Settings",
'access arguments' => array(
TFT_PERM__ADMIN,
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'tft_settings_form',
),
'file' => 'includes/tft.admin.inc',
),
);
return $menu;
}
/**
* Implements hook_permission().
*/
function tft_permission() {
return array(
TFT_PERM__ACCESS_FULL_TREE => array(
'title' => t("Access file tree"),
),
TFT_PERM__ADMIN => array(
'title' => t("Administer Taxonomy file tree"),
),
TFT_PERM__REORDER_ITEMS => array(
'title' => t("Reorder items in the tree"),
),
TFT_PERM__ADD_FILE => array(
'title' => t("Add file"),
),
TFT_PERM__ADD_TERMS => array(
'title' => t("Add new folders"),
),
TFT_PERM__DELETE_TERMS => array(
'title' => t("Remove folders"),
),
);
}
/**
* Implements hook_block_info().
*/
function tft_block_info() {
return array(
'tft_file_tree' => array(
'info' => 'TFT file explorer',
),
);
}
/**
* Implements hook_block_view().
*/
function tft_block_view() {
return array(
'subject' => 'File explorer',
'content' => theme('tft_folder_explorer', array(
'folders' => tft_output_tree(tft_folder_tree(0)),
'vid' => variable_get('tft_vocabulary_vid', 0),
)),
);
}
/**
* Implements hook_theme().
*/
function tft_theme() {
return array(
'tft' => array(
'variables' => array(
'folder_name' => NULL,
'folder_menu' => NULL,
'folder_content' => NULL,
'folder_add_content_links' => NULL,
),
'template' => 'theme/tft',
),
'tft_folder_explorer' => array(
'variables' => array(
'folders' => NULL,
'vid' => NULL,
),
'template' => 'theme/tft-folder-explorer',
),
'tft_folder_menu' => array(
'variables' => array(
'name' => NULL,
'path' => '/',
'ops_links' => '',
),
'template' => 'theme/tft-folder-menu',
),
'tft_manage_folders_form' => array(
'render element' => 'form',
),
);
}
/**
* Implements hook_node_prepare().
*/
function tft_node_prepare($node) {
$setting = tft_get_file_setting();
if ($node->type == $setting['type']) {
if (isset($_GET['tid']) && tft_term_access((int) $_GET['tid'])) {
$node->tft_folder[LANGUAGE_NONE][0]['tid'] = (int) $_GET['tid'];
}
}
}
/**
* Implements hook_form_alter()
*/
function tft_form_alter(&$form, &$form_state, $form_id) {
$setting = tft_get_file_setting();
switch ($form_id) {
case $setting['type'] . '_node_form':
$path = drupal_get_path('module', 'tft');
drupal_add_js("{$path}/js/tft.select-folder.js");
drupal_add_css("{$path}/css/tft.css");
module_load_include('inc', 'tft', 'tft.pages');
$form['tft_folder'][LANGUAGE_NONE]['#prefix'] = '<div class="tft-hide-element element-hidden">' . (!empty($form['tft_folder'][LANGUAGE_NONE]['#prefix']) ? $form['tft_folder'][LANGUAGE_NONE]['#prefix'] : '');
$form['tft_folder'][LANGUAGE_NONE]['#suffix'] = (!empty($form['tft_folder'][LANGUAGE_NONE]['#suffix']) ? $form['tft_folder'][LANGUAGE_NONE]['#suffix'] : '') . '</div>';
$form['tft_select_folder'] = array(
'#type' => 'fieldset',
'#title' => t("Select folder"),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#weight' => $form['tft_folder']['#weight'],
);
if (isset($_GET['tid'])) {
$tid = $_GET['tid'];
}
elseif (isset($form['#node']->tft_folder[LANGUAGE_NONE][0]['tid'])) {
$tid = $form['#node']->tft_folder[LANGUAGE_NONE][0]['tid'];
}
$tid = !empty($tid) ? $tid : 0;
$form['tft_select_folder']['tft_js_folder'] = array(
'#markup' => '<div id="folder-explorer-container" class="tft-node-form">' . tft_output_tree(tft_folder_tree(0, TRUE)) . '</div>',
);
$form['tft_selected_folder'] = array(
'#type' => 'hidden',
'#default_value' => $tid,
);
break;
}
}
/**
* Implements hook_image_default_styles().
*/
function tft_image_default_styles() {
$styles = array();
$styles['tft_thumb'] = array(
'label' => 'TFT Image Preview',
'effects' => array(
array(
'name' => 'image_scale_and_crop',
'data' => array(
'width' => 30,
'height' => 20,
),
'weight' => 0,
),
),
);
return $styles;
}
/**
* @} End of "defgroup tft_hook_implementations".
*/
/**
* @defgroup tft_api All API functions for TFT.
* @{
*/
/**
* Check if the user has access to the term.
*
* Will first check if the term is part of an OG term tree. If so, it will check if the user has access to the OG.
* If the term is not part of an OG term tree, it will check against the Tac Lite schemes.
*
* @param int $tid
* @param stdClass $account = NULL
* The user account to check against. If no account is given, the
* current user will be used.
* @param string $op = 'view'
*
* @return boolean
*/
function tft_term_access($tid, $account = NULL, $op = 'view') {
if (!$account) {
global $user;
$account = $user;
}
if ($account->uid == 1 || user_access(TFT_PERM__ADMIN, $account)) {
return TRUE;
}
if (!isset($tid)) {
if (!empty($_GET['tid'])) {
$tid = $_GET['tid'];
}
elseif (!empty($_GET['parent'])) {
$tid = $_GET['parent'];
}
else {
$tid = 0;
}
}
// Check if any other module has some saying in this matter.
foreach (module_implements('tft_term_access') as $module) {
$result = module_invoke($module, 'tft_term_access', $tid, $account, $op);
if (isset($result)) {
watchdog('returning access', '<pre>' . print_r($result, TRUE) . '</pre>');
return $result;
}
}
if ($op == 'view' && user_access(TFT_PERM__ACCESS_FULL_TREE, $account)) {
return TRUE;
}
elseif (($op == 'edit' || $op == 'add-folder') && user_access(TFT_PERM__ADD_TERMS, $account)) {
return TRUE;
}
elseif ($op == 'delete' && user_access(TFT_PERM__DELETE_TERMS, $account)) {
return TRUE;
}
elseif ($op == 'add-file' && user_access(TFT_PERM__ADD_FILE, $account)) {
return TRUE;
}
elseif ($op == 'add-folder' && user_access(TFT_PERM__ADD_TERMS, $account)) {
return TRUE;
}
elseif ($op == 'reorder' && user_access(TFT_PERM__REORDER_ITEMS, $account)) {
return TRUE;
}
else {
watchdog('returning false at end', '<pre>' . print_r($account, TRUE) . '</pre>');
return FALSE;
}
}
/**
* Get the folder content in HTML table format.
*
* @param int $tid
*
* @return string
*/
function tft_content_table($tid) {
$headers = array(
array(
'data' => '<span>' . t("Name") . '</span>',
'id' => 'table-th-name',
),
array(
'data' => '<span>' . t("Loaded by") . '</span>',
'id' => 'table-th-loaded-by',
),
array(
'data' => '<span>' . t("Last modified") . '</span>',
'id' => 'table-th-date',
),
array(
'data' => '<span>' . t("Type") . '</span>',
'id' => 'table-th-type',
),
array(
'data' => '<span>' . t("Operations") . '</span>',
'id' => 'table-th-ops',
),
);
$rows = tft_get_content($tid);
return theme('table', array(
'header' => $headers,
'rows' => $rows,
));
}
/**
* Output the tree as an HTML unordered list.
* @see tft_output_children().
*
* @param array $tree
* The folder tree.
*
* @return string
*/
function tft_output_tree($tree) {
return tft_output_children($tree, TRUE);
}
/**
* Return the sub-tree as an unordered list.
*
* @param array $tree
* The folder tree.
* @param boolean $root = FALSE
* A flag for setting this <ul> as the root <ul>.
*
* @return string
*/
function tft_output_children($tree, $root = FALSE) {
$html = '<ul class="' . ($root ? 'root-folder' : 'sub-folder') . '">';
$first = TRUE;
$odd = TRUE;
$count = count($tree);
$i = 1;
foreach ($tree as $tid => $item) {
$span_class = '';
if ($odd) {
$odd = FALSE;
$class = ' odd';
}
else {
$odd = TRUE;
$class = ' even';
}
if ($first) {
$class .= ' first';
$first = FALSE;
}
if ($i == $count) {
$class .= ' last';
}
if (isset($item['children'])) {
$class .= ' parent-folder closed';
$span_class = ' closed-icon';
}
$html .= tft_li($item['name'], $tid, $class, $span_class);
if (isset($item['children'])) {
$html .= tft_output_children($item['children']);
}
$html .= '</li>';
$i++;
}
$html .= '</ul>';
return $html;
}
/**
* Format an <li> tag for the file explorer.
*
* @param string $name
* The folder name
* @param int $tid
* @param string $li_class
* CSS classes for the <li>
* @param string $span_class
* CSS classes for the child <span>
*
* @return string
*/
function tft_li($name, $tid, $li_class, $span_class) {
return '<li id="tid-' . $tid . '" class="folder' . $li_class . '"><span class="icon' . $span_class . '"></span><span class="link-wrapper"><a href="#tft/' . $tid . '" class="folder-link">' . $name . '</a></span>';
}
/**
* Get the folder content and return it in an array form for the theme_table call.
*
* @param int $tid
*
* @return array
*/
function tft_get_content($tid) {
if (!tft_term_access($tid)) {
drupal_access_denied();
exit;
}
$content = array();
$elements = tft_folder_content($tid, FALSE);
$setting = tft_get_file_setting();
$db_table = 'field_data_' . $setting['field'];
$db_table = db_escape_field($db_table);
$db_field = db_escape_field($setting['field'] . '_fid');
foreach ($elements as $element) {
if ($element['type'] == 'term') {
if (!tft_term_access($element['id'])) {
continue;
}
$term = taxonomy_term_load($element['id']);
$content[] = array(
tft_l($term->name, $element['id'], 'folder'),
'',
'',
t("Folder"),
tft_theme_item_operation_links(tft_item_operation_links('folder', $element['id'], $tid)),
);
}
else {
$node = node_load($element['id']);
if (node_access('view', $node)) {
if (db_table_exists($db_table)) {
$result = db_query("SELECT f.filemime, f.filename, v.title, n.changed, n.uid FROM {node_revision} v\n LEFT JOIN {node} n ON n.vid = v.vid\n LEFT JOIN {" . $db_table . "} c ON c.revision_id = v.vid\n LEFT JOIN {file_managed} f ON c.{$db_field} = f.fid\n WHERE n.nid = :nid AND n.status = 1", array(
':nid' => $element['id'],
));
if ($row = $result
->fetchAssoc()) {
$parts = explode('.', $row['filename']);
$content[] = array(
tft_l($row['title'], $element['id'], $row['filemime']),
tft_get_username($row['uid']),
date('d/m/Y H:i', $row['changed']),
t('!type file', array(
'!type' => strtoupper(array_pop($parts)),
)),
tft_theme_item_operation_links(tft_item_operation_links('file', $element['id'], $tid)),
);
}
}
}
}
}
return $content;
}
/**
* Format a folder or file link.
*
* @param string $title
* The link title
* @param int $id
* Either the taxonomy term tid or the node nid
* @param string $mime
* The mime type of the file (for a folder, use 'folder')
*
* @return string
* HTML string with the formatted link
*/
function tft_l($title, $id, $mime) {
if ($mime == 'folder') {
return '<a href="#tft/' . $id . '" class="folder-folder-link" id="tid-' . $id . '">' . $title . '</a>';
}
else {
$class = 'file';
$settings = tft_get_file_setting();
switch ($mime) {
case 'image/png':
case 'image/jpeg':
case 'image/gif':
if (module_exists('image')) {
$node = node_load($id);
$icon = image_style_url('tft_thumb', $node->{$settings['field']}[LANGUAGE_NONE][0]['uri']);
$class .= ' thumbnail';
$href = file_create_url($node->{$settings['field']}[LANGUAGE_NONE][0]['uri']);
if (module_exists('lightbox2')) {
$class .= ' enable-lightbox lightbox';
}
break;
}
// Fall through to default if the image module is not available.
default:
// Get the filefield icon
$file = (object) array(
'filemime' => $mime,
);
$icon = base_path() . file_icon_path($file);
$class .= ' generic';
$href = "tft/download/file/{$id}";
break;
}
return l($title, $href, array(
'attributes' => array(
'class' => $class,
'style' => "background-image: url({$icon})",
'target' => '_blank',
),
));
}
}
/**
* Get the username.
*
* @param int $uid
*
* @return string
*/
function tft_get_username($uid) {
return db_query("SELECT name FROM {users} WHERE uid = :uid", array(
':uid' => $uid,
))
->fetchField();
}
/**
* Loads the given folder content.
*
* Can optionally load only child folders. By default, will load folders and files.
*
* @param int $tid
* @param bool $only_terms = FALSE
*
* @return array
*/
function tft_folder_content($tid, $only_terms = FALSE) {
$content = array();
// Get all child folders (terms)
$result = db_query("SELECT td.tid FROM {taxonomy_term_data} td\n LEFT JOIN {taxonomy_term_hierarchy} th ON th.tid = td.tid\n WHERE th.parent = :ptid AND td.vid = :vid ORDER BY td.name", array(
':ptid' => $tid,
':vid' => variable_get('tft_vocabulary_vid', 0),
));
while ($term = $result
->fetchObject()) {
if (variable_get('tft_use_weight', 0) && ($res = db_query("SELECT weight FROM {tft_folder_content_weight} WHERE id = :tid AND type = 'term'", array(
':tid' => $term->tid,
)))) {
$weight = $res
->fetchField();
}
$content[] = array(
'id' => $term->tid,
'type' => 'term',
'weight' => !empty($weight) ? $weight : 0,
);
}
if ($only_terms) {
if (variable_get('tft_use_weight', 0)) {
usort($content, '_tft_array_weight_sort');
}
return $content;
}
// Get the files
$result = db_query("SELECT DISTINCT(tn.nid) FROM {node_revision} v\n LEFT JOIN {node} n ON n.vid = v.vid\n LEFT JOIN {taxonomy_index} tn ON tn.nid = n.nid\n WHERE tn.tid = :tid AND n.status = 1 ORDER BY v.title", array(
':tid' => $tid,
));
while ($file = $result
->fetchObject()) {
if (variable_get('tft_use_weight', 0) && ($res = db_query("SELECT weight FROM {tft_folder_content_weight} WHERE id = :nid AND type = 'node'", array(
':nid' => $file->nid,
)))) {
$weight = $res
->fetchField();
}
$content[] = array(
'id' => $file->nid,
'type' => 'node',
'weight' => !empty($weight) ? $weight : 0,
);
}
if (variable_get('tft_use_weight', 0)) {
usort($content, '_tft_array_weight_sort');
}
return $content;
}
/**
* Implements hook_tft_item_operation_links_access()
*/
function tft_tft_item_operation_links_access($op, $type, $id, $parent_tid = NULL) {
if ($type == 'folder') {
if ($op == 'edit') {
return user_access(TFT_PERM__ADD_TERMS);
}
elseif ($op == 'delete') {
return user_access(TFT_PERM__DELETE_TERMS);
}
}
}
/**
* Returns a list of operation links for the given item.
*
* @param string $type
* The type of operation links. Can be 'folder' or 'file'.
* @param int $id
* Either the taxonomy term tid or the node nid.
* @param int $parent_tid = NULL
*
* @return array
*/
function tft_item_operation_links($type, $id, $parent_tid = NULL) {
$links = array();
$query = isset($_SESSION['tft']['q']) ? $_SESSION['tft']['q'] : '';
switch ($type) {
case 'folder':
if (tft_term_access($id, NULL, 'edit')) {
$links['edit'] = array(
'title' => t("edit"),
'href' => "tft/term/edit/{$id}",
'attributes' => array(
'class' => 'ops-link term-edit-link',
),
'query' => array(
'destination' => $query . (isset($parent_tid) ? "#tft/{$parent_tid}" : ''),
),
);
}
if (tft_term_access($id, NULL, 'delete')) {
$links['delete'] = array(
'title' => t("delete"),
'href' => "tft/term/delete/{$id}",
'attributes' => array(
'class' => 'ops-link term-edit-link',
),
'query' => array(
'destination' => $query . (isset($parent_tid) ? "#tft/{$parent_tid}" : ''),
),
);
}
break;
case 'file':
$node = node_load($id);
if (node_access('update', $node)) {
$links['edit'] = array(
'title' => t("edit"),
'href' => "node/{$id}/edit",
'attributes' => array(
'class' => 'ops-link node-edit-link',
),
'query' => array(
'destination' => $query . (isset($parent_tid) ? "#tft/{$parent_tid}" : ''),
),
);
}
$links['view'] = array(
'title' => t("more info"),
'href' => "node/{$id}",
'attributes' => array(
'class' => 'ops-link',
),
);
break;
}
drupal_alter('tft_item_operation_links', $links, $type, $id, $parent_tid);
return $links;
}
/**
* Helper function to check operation links access.
*/
function tft_item_operation_links_access($op, $type, $id, $parent_tid = NULL) {
$results = module_invoke_all('tft_item_operation_links_access', 'edit', $type, $id, $parent_tid);
foreach ($results as $result) {
if ($result) {
return TRUE;
}
}
return FALSE;
}
/**
* Render the add file and add folder links.
*
* @param int $tid = 0
* The term tid of the current folder, or 0 for root
*
* @return array
*/
function tft_get_add_content_links($tid = 0) {
$links = array();
$add_file_query = array(
'destination' => $_SESSION['tft']['q'] . "#tft/{$tid}",
);
$add_term_query = array(
'destination' => $_SESSION['tft']['q'] . "#tft/{$tid}",
);
$setting = tft_get_file_setting();
// Do we have a tid ?
if ($tid) {
$add_file_query['tid'] = $tid;
$add_term_query['parent'] = $tid;
}
// Can the user create files ?
if (user_access('create ' . $setting['type'] . ' content') && tft_term_access($tid, NULL, 'add-file')) {
$links['add_file'] = array(
'title' => t("Add a file"),
'href' => 'node/add/' . str_replace('_', '-', $setting['type']),
'attributes' => array(
'id' => 'add-child-file',
),
'query' => array_reverse($add_file_query),
);
}
if (tft_term_access($tid, NULL, 'add-folder')) {
$links['add_term'] = array(
'title' => t("Add a folder"),
'href' => 'tft/term/add',
'attributes' => array(
'id' => 'add-child-folder',
),
'query' => array_reverse($add_term_query),
);
}
drupal_alter('tft_get_add_content_links', $links, $tid);
return $links;
}
/**
* Construct the folder tree.
*
* @param int $tid = 0
* @param boolean $inclusive = FALSE
* Whether the current term should be included as well
*
* @return array
*/
function tft_folder_tree($tid = 0, $inclusive = FALSE) {
$folders = array();
$content = tft_folder_content($tid, TRUE);
foreach ($content as $term) {
if (tft_term_access($term['id'])) {
$folders[$term['id']]['tid'] = $term['id'];
$folders[$term['id']]['name'] = db_query("SELECT name FROM {taxonomy_term_data} WHERE tid = :tid", array(
':tid' => $term['id'],
))
->fetchField();
$folders[$term['id']]['weight'] = $term['weight'];
$folders[$term['id']]['parent'] = $tid ? $tid : 0;
if ($child_terms = tft_folder_tree($term['id'])) {
$folders[$term['id']]['children'] = $child_terms;
}
}
}
if ($inclusive) {
if ($tid == 0) {
$name = t("Root");
}
else {
$name = db_query("SELECT name FROM {taxonomy_term_data} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField();
}
$folders = array(
$tid => array(
'name' => $name,
'tid' => $tid,
'weight' => 0,
'parent' => 0,
'children' => $folders,
),
);
}
return $folders;
}
/**
* Get the parent tid based on a tid.
*
* @param int $tid
*
* @return int
* The parent tid or 0 if there's no parent. Will return -1 if the tid is null or 0.
*/
function tft_get_parent_tid($tid) {
static $cache = array();
if (!(int) $tid) {
return -1;
}
if (isset($cache[$tid])) {
return $cache[$tid];
}
$result = db_query("SELECT `parent` FROM {taxonomy_term_hierarchy} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField();
$cache[$tid] = is_null($result) ? -1 : $result;
return (int) $cache[$tid];
}
/**
* Get the depth of the term
*
* @param int $tid
* The taxonomy term tid
*
* @return int
* The depth of the term, or 0 if no valid term tid was given
*/
function tft_get_depth($tid) {
static $cache = array();
if (!$tid || !db_query("SELECT COUNT(tid) FROM {taxonomy_term_data} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField()) {
return 0;
}
if (isset($cache[$tid])) {
return $cache[$tid];
}
$depth = 0;
$pid = $tid;
while ($pid = db_query("SELECT parent FROM {taxonomy_term_hierarchy} WHERE tid = :tid", array(
':tid' => $pid,
))
->fetchField()) {
$depth++;
}
$cache[$tid] = $depth;
return $depth;
}
/**
* Helper function to sort item arrays with usort().
*/
function _tft_array_weight_sort($a, $b) {
if ($a['weight'] != $b['weight']) {
return $a['weight'] < $b['weight'] ? -1 : 1;
}
return 0;
}
/**
* Construct the folder tree recursively.
*
* @param int $tid
* @param bool $inclusive = FALSE
* Whether to include the passed term.
*
* @return array
*/
function tft_tree($tid = 0, $inclusive = FALSE) {
$folders = array();
$content = tft_folder_content($tid);
foreach ($content as $item) {
$folders[$item['id']]['weight'] = isset($item['weight']) ? $item['weight'] : 0;
$folders[$item['id']]['parent'] = $tid ? $tid : 0;
$folders[$item['id']]['type'] = $item['type'];
if ($item['type'] == 'term' && tft_term_access($item['id'])) {
$folders[$item['id']]['tid'] = $item['id'];
$folders[$item['id']]['name'] = db_query("SELECT name FROM {taxonomy_term_data} WHERE tid = :tid", array(
':tid' => $item['id'],
))
->fetchField();
if ($child_terms = tft_tree($item['id'])) {
$folders[$item['id']]['children'] = $child_terms;
}
}
elseif ($item['type'] == 'node' && node_access('view', node_load($item['id']))) {
$folders[$item['id']]['nid'] = $item['id'];
$folders[$item['id']]['name'] = db_query("SELECT v.title FROM {node} n LEFT JOIN {node_revision} v ON v.vid = n.vid WHERE n.nid = :nid", array(
':nid' => $item['id'],
))
->fetchField();
}
}
if ($inclusive) {
if ($tid == 0) {
$name = t("Root");
}
else {
$name = db_query("SELECT name FROM {taxonomy_term_data} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField();
}
$folders = array(
$tid => array(
'name' => $name,
'tid' => $tid,
'weight' => 0,
'parent' => 0,
'type' => 'term',
'children' => $folders,
),
);
}
return $folders;
}
/**
* Get the settings for the node type used as the 'file'.
*
* This function is kept for historical reasons. These settings cannot be changed anymore.
*
* @return array
* An array with a 'type' key for the node type and a 'field' key for the file field.
*/
function tft_get_file_setting() {
$temp = explode('-', variable_get('tft_content_type', 'tft_file-tft_file'));
return array(
'type' => $temp[0],
'field' => $temp[1],
);
}
/**
* Return a list of links for the folder menu.
*
* Links include:
* - "go to parent"
* - "reorder elements"
*
* @param int $tid
*
* @return array
*/
function tft_get_folder_menu_links($tid) {
$links = array();
$parent_tid = tft_get_parent_tid($tid);
$disabled = FALSE;
if ($parent_tid >= 0 && $tid != $_SESSION['tft']['root_tid']) {
if (!tft_term_access($parent_tid)) {
$disabled = TRUE;
}
}
else {
$disabled = TRUE;
}
$links['parent_folder'] = array(
'title' => t("parent folder"),
'href' => 'tft',
'fragment' => $disabled ? 'tft/0' : "tft/{$parent_tid}",
'external' => TRUE,
'attributes' => array(
'id' => 'tft-back',
'class' => array(
'folder-menu-ops-link',
$disabled ? 'disabled' : 'enabled',
),
),
);
if (user_access(TFT_PERM__REORDER_ITEMS)) {
$links['reorder_items'] = array(
'title' => t("reorder elements"),
'href' => "tft/terms/reorder/{$tid}",
'attributes' => array(
'id' => 'manage-folders',
'class' => array(
'folder-menu-ops-link',
),
),
'query' => array(
'destination' => (!empty($_SESSION['tft']['q']) ? $_SESSION['tft']['q'] : '') . "#tft/{$tid}",
),
);
}
drupal_alter('tft_folder_menu_links', $links, $tid);
return $links;
}
/**
* Helper function to render the operation links.
*
* @param array $links
*
* @return string
*/
function tft_theme_folder_menu_links($links) {
// We don't use the theme('links') Drupal function, as we want to set custom classes and IDs on the <li>s.
// This is not possible (without a lot of overhead) with theme('links').
$html = '<ul class="tabs primary" id="folder-menu-ops-links">';
foreach ($links as $link) {
$html .= '<li class="folder-menu-ops-link" id="' . (isset($link['attributes']['id']) ? $link['attributes']['id'] : '') . '">';
// Change the ID for the <a>.
if (isset($link['attributes']['id'])) {
$link['attributes']['id'] .= '-link';
}
$html .= l($link['title'], $link['href'], $link);
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
/**
* Helper function to render the content addition links.
*
* @param array $links
*
* @return string
*/
function tft_theme_add_content_links($links) {
// We don't use the theme('links') Drupal function, as we want to set custom classes and IDs on the <li>s.
// This is not possible (without a lot of overhead) with theme('links').
$html = '<ul id="folder-add-content-links">';
foreach ($links as $link) {
$html .= '<li class="folder-add-content-link" id="' . (isset($link['attributes']['id']) ? $link['attributes']['id'] : '') . '">';
// Change the ID for the <a>.
if (isset($link['attributes']['id'])) {
$link['attributes']['id'] .= '-link';
}
$html .= l($link['title'], $link['href'], $link);
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
/**
* Helper function to render the item operation links.
*
* @param array $links
*
* @return string
*/
function tft_theme_item_operation_links($links) {
return theme('links', array(
'links' => $links,
'attributes' => array(
'class' => array(
'inline',
),
),
));
}
/**
* Add a new term and return its ID.
*
* @param string $name
* @param int $parent
*
* @return int
*/
function tft_add_term($name, $parent) {
// Add the term data
$tid = db_insert('taxonomy_term_data')
->fields(array(
'tid' => NULL,
'vid' => variable_get('tft_vocabulary_vid', 0),
'name' => $name,
'description' => '',
'weight' => 0,
))
->execute();
if (empty($parent)) {
$parent = 0;
}
// Add the term hierarchy
db_insert('taxonomy_term_hierarchy')
->fields(array(
'tid' => $tid,
'parent' => $parent,
))
->execute();
return $tid;
}
/**
* Update the term name.
*
* @param int $tid
* @param string $name
*/
function tft_update_term($tid, $name) {
db_update('taxonomy_term_data')
->fields(array(
'name' => $name,
))
->condition('tid', $tid)
->execute();
}
/**
* Check if the term has no files or child terms.
*
* @param int $tid
*
* @return bool
*/
function tft_check_term_is_deletable($tid) {
$count = (int) db_query("SELECT COUNT(tid) FROM {taxonomy_term_hierarchy} WHERE parent = :tid", array(
':tid' => $tid,
))
->fetchField();
if ($count) {
return FALSE;
}
$count = (int) db_query("SELECT COUNT({taxonomy_index}.nid) FROM {taxonomy_index}\n RIGHT JOIN {node} ON {node}.nid = {taxonomy_index}.nid\n WHERE {taxonomy_index}.tid = :tid", array(
':tid' => $tid,
))
->fetchField();
if ($count) {
return FALSE;
}
return TRUE;
}
/**
* @} End of "defgroup tft_api".
*/
/**
* @deprecated Archive folders are OG specific
*
* Checks if the term is an "Archive" term.
* These cannot be edited or deleted.
*
* @param int $tid
*
* @return bool
*/
// @todo OG logic
function tft_is_archive_folder($tid) {
// Must be a direct child.
if (tft_get_depth($tid) == 1) {
$title = db_select('taxonomy_term_data', 't')
->fields('t', array(
'name',
))
->condition('tid', $tid)
->execute()
->fetchField();
if ($title == t('Archives')) {
return TRUE;
}
}
return FALSE;
}
/**
* @deprecated Archive folders are OG specific
*
* Finds the archive folder for the current OG term.
*
* @param int $og_tid
*
* @return int|null
*/
// @todo OG logic
function tft_get_archive_tid($og_tid) {
return db_query("SELECT td.tid FROM {taxonomy_term_data} td\n LEFT JOIN {taxonomy_term_hierarchy} th ON th.tid = td.tid\n WHERE th.parent = :tid AND td.name = :name", array(
':name' => t('Archives'),
':tid' => $og_tid,
))
->fetchField();
}
/**
* @deprecated Archive folders are OG specific
*
* Checks if the term is already archived.
*
* @param int $tid
*
* @return bool
*/
// @todo OG logic
function tft_is_term_archived($tid) {
$og_nid = tft_get_og_nid($tid);
$og_tid = tft_get_og_tid($og_nid);
$archive_tid = tft_get_archive_tid($og_tid);
$root_tid = $tid;
$depth = tft_get_depth($tid);
while ($depth > 1 && $root_tid) {
$root_tid = db_query("SELECT parent FROM {taxonomy_term_hierarchy} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField();
$depth--;
}
return $root_tid == $archive_tid;
}
/**
* @deprecated Archive folders are OG specific
*
* Checks if the file is already archived.
*
* @param int $nid
*
* @return bool
*/
// @todo OG logic
function tft_is_file_archived($nid) {
$node = node_load($nid);
$folder_tids = array();
// Get original folder
foreach (array_keys($node->taxonomy) as $tid) {
if (variable_get('tft_vocabulary_vid', 0) == db_query("SELECT vid FROM {taxonomy_term_data} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField()) {
$folder_tids[] = $tid;
}
}
foreach ($folder_tids as $tid) {
if (tft_is_term_archived($tid)) {
return TRUE;
}
}
return FALSE;
}
/**
* @deprecated move this to tft_og
*
* Check if the current term is part of a OG term and return the OG nid. If no nid is found, return FALSE.
*
* @param int $tid
* The tid (and its ancestor tree) to check against
*
* @return int|boolean
* The OG nid if found, else FALSE
*/
function tft_get_og_nid($tid) {
static $cache = array();
if (is_array($tid)) {
$tid = $tid[0];
}
$tid = (int) $tid;
if (!$tid) {
return FALSE;
}
if (isset($cache[$tid])) {
return $cache[$tid];
}
$param_tid = $tid;
$depth = tft_get_depth($tid);
$og_nid = db_query("SELECT og_nid FROM {tft_tid_og_nid} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField();
while ($depth && $tid && !$og_nid) {
$tid = db_query("SELECT parent FROM {taxonomy_term_hierarchy} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField();
$depth--;
$og_nid = db_query("SELECT og_nid FROM {tft_tid_og_nid} WHERE tid = :tid", array(
':tid' => $tid,
))
->fetchField();
}
if ($og_nid) {
$cache[$param_tid] = (int) $og_nid;
}
else {
$cache[$param_tid] = FALSE;
}
return $cache[$param_tid];
}
/**
* @deprecated move this to tft_og
*
* Get the term tid associated with the OG.
*
* @param int $nid
* The OG nid
*
* @return int|NULL
* The term tid
*/
function tft_get_og_tid($nid) {
return db_query("SELECT tid FROM {tft_tid_og_nid} WHERE og_nid = :nid", array(
':nid' => $nid,
))
->fetchField();
}
/**
* @deprecated
* Check that a valid vocabulary vid is set in the settings. Else, redirect to either the settings page (if the user has access)
* or the home page.
*/
function tft_check_vocabulary_setting() {
if (!variable_get('tft_vocabulary_vid', 0) || !db_query("SELECT COUNT(vid) FROM {taxonomy_vocabulary} WHERE vid = :vid", array(
':vid' => variable_get('tft_vocabulary_vid', 0),
))
->fetchField()) {
drupal_set_message(t("You must first enter which vocabulary is used by Taxonomy File Tree."), 'error');
watchdog('tft', "TFT isn't properly configured. A valid vocabulary must be set as the TFT vocabulary.", array(), WATCHDOG_ERROR);
if (user_access(TFT_PERM__ADMIN)) {
drupal_goto('admin/settings/tft');
}
else {
drupal_goto();
}
}
}
/**
* @deprecated Client specific. REmove.
* Get an array with all the terms to which the user has no access.
*
* @param int $tid = 0
* The root term tid. 0 by default (looks through the entire tree)
* @param array() &$forbidden
* The forbidden elements array
* @param stdClass $account = NULL
* An optional account to test access. By default, the current user is used.
*/
function tft_get_forbidden_terms($tid = 0, &$forbidden, $account = NULL) {
// Start by all root terms, and build up from there
$result = db_query("SELECT tid FROM {taxonomy_term_hierarchy} WHERE parent = :tid AND vid = :vid", array(
':tid' => $tid,
':vid' => variable_get('tft_vocabulary_vid', 0),
));
while ($tid = $result
->fetchObject()) {
if (!tft_term_access($tid, $account)) {
$forbidden[] = $tid;
}
else {
tft_get_forbidden_terms($tid, $forbidden, $account);
}
}
}
/**
* @deprecated Archives are OG specific
*
* Defines a batch for adding an archive folder to all groups that do not have one.
*/
function tft_archive_folder_batch() {
$batch = array(
'title' => t("Adding archive folders"),
'operations' => array(
array(
'tft_archive_folder_batch_process',
array(),
),
),
);
batch_set($batch);
}
/**
* @deprecated Archives are OG specific
*
* Processes the batch logic.
*/
function tft_archive_folder_batch_process(&$context) {
module_load_include('inc', 'tft', 'tft.admin');
if (empty($context['sandbox'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = (int) db_query("SELECT COUNT(*) FROM {node} WHERE type = 'og'")
->fetchField();
$context['finished'] = 0;
}
$result = db_query("SELECT * FROM {node} WHERE type = 'og' LIMIT :limit, 10", array(
':limit' => $context['sandbox']['progress'],
));
while ($node = $result
->fetchObject()) {
$og_tid = tft_get_og_tid($node->nid);
$archive_tid = tft_get_archive_tid($og_tid);
if (empty($archive_tid)) {
tft_add_term("Archives", $og_tid);
}
$context['sandbox']['progress']++;
}
// Set the percentage for the loadbar
if ($context['sandbox']['progress'] < $context['sandbox']['max'] && !$stop) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
else {
$context['finished'] = 1;
}
}
/**
* @deprecated Archives are OG specific
*
*/
function tft_log_archive($id, $type, $previous_tid, $og_nid) {
db_insert('tft_archive_restore')
->fields(array(
'id' => $id,
'type' => $type,
'previous_parent_tid' => $previous_tid,
'og_nid' => $og_nid,
))
->execute();
}
/**
* @param $id
* @param $type
* @param $og_nid
* @return bool
*
* @deprecated Archives are OG specific
*/
function tft_restore_archived_element($id, $type, $og_nid) {
$log = db_query("SELECT * FROM {tft_archive_restore} WHERE type = :type AND id = :id", array(
':type' => $type,
':id' => $id,
))
->fetchAssoc();
$og_tid = tft_get_og_tid($og_nid);
$return = TRUE;
if (empty($log)) {
$return = FALSE;
$log = array(
'id' => $id,
'previous_parent_tid' => $og_tid,
);
}
elseif (!db_query("SELECT COUNT(*) FROM {taxonomy_term_data} WHERE tid = :tid", array(
':tid' => $log['previous_parent_tid'],
))
->fetchField()) {
$return = FALSE;
$log['previous_parent_tid'] = $og_tid;
}
else {
if (tft_is_term_archived($log['previous_parent_tid'])) {
$return = FALSE;
$log['previous_parent_tid'] = $og_tid;
}
}
if ($type == 'node') {
$archive_tid = tft_get_archive_tid($og_tid);
$node = node_load($log['id']);
// Get original folder.
// Reconstruct list of terms by removing all folder terms.
$taxonomy = array();
foreach ($node->taxonomy as $term) {
if ($term->tid != $archive_tid) {
$taxonomy[] = $term->tid;
}
}
$taxonomy[] = $log['previous_parent_tid'];
$node->taxonomy = $taxonomy;
node_save($node);
}
else {
db_update('taxonomy_term_hierarchy')
->fields(array(
'parent' => $log['previous_parent_tid'],
))
->condition('tid', $log['id'])
->execute();
}
db_delete('tft_archive_restore')
->condition('id', $id)
->condition('type', $type)
->execute();
return $return;
}
/**
* @deprecated Archives are OG specific
*/
function tft_restore_element($og_nid, $id, $type) {
if (tft_restore_archived_element($id, $type, $og_nid)) {
drupal_set_message("L'élément a été restauré à son ancien emplacement.");
}
else {
drupal_set_message("Impossible de restaurer l'élément à son ancien emplacement, car il n'existe plus. Il a été restauré à la racine de l'arborescence.", 'warning');
}
if (isset($_GET['destination'])) {
drupal_goto($_GET['destination']);
}
else {
drupal_goto();
}
}
Functions
Name | Description |
---|---|
tft_add_term | Add a new term and return its ID. |
tft_archive_folder_batch Deprecated | |
tft_archive_folder_batch_process Deprecated | |
tft_block_info | Implements hook_block_info(). |
tft_block_view | Implements hook_block_view(). |
tft_check_term_is_deletable | Check if the term has no files or child terms. |
tft_check_vocabulary_setting Deprecated | |
tft_content_table | Get the folder content in HTML table format. |
tft_folder_content | Loads the given folder content. |
tft_folder_tree | Construct the folder tree. |
tft_form_alter | Implements hook_form_alter() |
tft_get_add_content_links | Render the add file and add folder links. |
tft_get_archive_tid | |
tft_get_content | Get the folder content and return it in an array form for the theme_table call. |
tft_get_depth | Get the depth of the term |
tft_get_file_setting | Get the settings for the node type used as the 'file'. |
tft_get_folder_menu_links | Return a list of links for the folder menu. |
tft_get_forbidden_terms Deprecated | |
tft_get_og_nid Deprecated | |
tft_get_og_tid Deprecated | |
tft_get_parent_tid | Get the parent tid based on a tid. |
tft_get_username | Get the username. |
tft_image_default_styles | Implements hook_image_default_styles(). |
tft_is_archive_folder | |
tft_is_file_archived | |
tft_is_term_archived | |
tft_item_operation_links | Returns a list of operation links for the given item. |
tft_item_operation_links_access | Helper function to check operation links access. |
tft_l | Format a folder or file link. |
tft_li | Format an <li> tag for the file explorer. |
tft_log_archive Deprecated | |
tft_menu | Implementation of hook_menu(). |
tft_node_prepare | Implements hook_node_prepare(). |
tft_output_children | Return the sub-tree as an unordered list. |
tft_output_tree | Output the tree as an HTML unordered list. |
tft_permission | Implements hook_permission(). |
tft_restore_archived_element Deprecated | |
tft_restore_element Deprecated | |
tft_term_access | Check if the user has access to the term. |
tft_tft_item_operation_links_access | Implements hook_tft_item_operation_links_access() |
tft_theme | Implements hook_theme(). |
tft_theme_add_content_links | Helper function to render the content addition links. |
tft_theme_folder_menu_links | Helper function to render the operation links. |
tft_theme_item_operation_links | Helper function to render the item operation links. |
tft_tree | Construct the folder tree recursively. |
tft_update_term | Update the term name. |
_tft_array_weight_sort | Helper function to sort item arrays with usort(). |