View source
<?php
function outline_designer_help($section) {
global $node;
switch ($section) {
case 'admin':
return t("Outline Designer redoes how books / content is created system wide.");
case 'nodeid':
return $node->nid;
}
}
function outline_designer_perm() {
return array(
'access outline designer',
'drag-and-drop content',
'change content types',
'duplicate nodes',
);
}
function outline_designer_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks[0]['info'] = t("Outline Designer");
return $blocks;
break;
case 'view':
$output = '';
switch ($delta) {
case 0:
$block['subject'] = t("Outline Designer");
$block['content'] = '<ul><li class="leaf">' . l(t('Outline Designer'), 'outline_designer') . '</li>';
$block['content'] .= '<li class="leaf">' . l(t('Settings'), 'admin/settings/outline_designer') . '</li></ul>';
break;
}
break;
}
return $block;
}
function outline_designer_menu($may_cache) {
$items = array();
$items[] = array(
'path' => 'outline_designer/ajax',
'access' => user_access('access outline designer'),
'callback' => '_outline_designer_ajax',
'title' => t('Ajax Page'),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'outline_designer',
'title' => t('Outline Designer'),
'description' => t('The Outline Designers Outline allows you to quickly (re)structure your entire website.'),
'callback' => '_outline_designer_outline',
'access' => user_access('access outline designer'),
);
$items[] = array(
'path' => 'admin/settings/outline_designer',
'title' => t('Outline Designer'),
'description' => t('The Outline Designer settings allow you to define what content types can be created quickly as well as associating icons to content types.'),
'callback' => 'drupal_get_form',
'callback arguments' => 'outline_designer_settings',
'type' => MENU_NORMAL_ITEM,
'access' => user_access('access administration pages'),
);
return $items;
}
function outline_designer_settings() {
$packaged_icons = 'Outline Designer Icons: ';
$icons = array(
'add',
'edit',
'delete',
'duplicate',
'rename',
'node',
'page',
'folder',
);
foreach ($icons as $title) {
$packaged_icons .= '<img src="' . base_path() . drupal_get_path('module', 'outline_designer') . '/images/' . $title . '.png" title="' . $title . '" alt="' . $title . '" hspace="2px" />';
}
$packaged_icons .= ' <br />Uploaded Icons: ';
$dir = file_create_path(file_directory_path() . '/outline_designer');
file_check_directory($dir, 1);
if ($handle = opendir('./' . file_directory_path() . '/outline_designer')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$packaged_icons .= '<img src="' . base_path() . file_directory_path() . '/outline_designer/' . $file . '" title="' . $file . '" alt="' . $file . '" hspace="2px" />';
}
}
closedir($handle);
}
$form["outline_designer_hidden"] = array(
'#type' => 'hidden',
'#title' => 'Available icons',
'#suffix' => $packaged_icons,
);
$content_types = array();
$result = db_query("SELECT type,name FROM {node_type}");
while ($value = db_fetch_array($result)) {
array_push($content_types, t($value['type']));
$form["outline_designer_" . $value['type'] . "_icon_link"] = array(
'#type' => 'textfield',
'#title' => t("Link to " . $value['name'] . " Icon"),
'#default_value' => variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png"),
'#description' => '<img src="' . base_path() . variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png") . '" /> ' . t("You can drag the icons from above onto this field to get the full path or add a path of your own."),
'#required' => false,
);
$form["outline_designer_" . $value['type'] . "_icon"] = array(
'#type' => 'file',
'#size' => '10',
'#title' => t("Icon for " . $value['name']),
'#default_value' => variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png"),
'#description' => t("This is what icon will be associated to each content type in the outline designer. They must be 16x16 gif or png format."),
'#required' => false,
);
}
$form["outline_designer_default_type"] = array(
'#type' => 'select',
'#title' => t("Default Content Type"),
'#default_value' => variable_get("outline_designer_default_type", "page"),
'#options' => drupal_map_assoc($content_types),
'#description' => t("This is what content type will be used when creating a new outline as well as the default if a user has the ability to create content but not change types."),
'#required' => true,
'#multiple' => false,
);
$form["outline_designer_content_types"] = array(
'#type' => 'select',
'#title' => t("Valid Content Types"),
'#default_value' => variable_get("outline_designer_content_types", ""),
'#options' => drupal_map_assoc($content_types),
'#description' => t("This defines which content types are accessible by this method of content creation"),
'#required' => true,
'#multiple' => true,
);
$form['#attributes'] = array(
'enctype' => "multipart/form-data",
);
return system_settings_form($form);
}
function outline_designer_settings_submit($form_id, $form_values) {
$dir = file_create_path(file_directory_path() . '/outline_designer');
$is_writable = file_check_directory($dir, 1);
if ($is_writable) {
$result = db_query("SELECT type,name FROM {node_type}");
while ($value = db_fetch_array($result)) {
$source = file_check_upload("outline_designer_" . $value['type'] . "_icon");
if ($source->filename != '') {
$source->filename = upload_munge_filename($source->filename);
if ($file = file_save_upload($source, $dir)) {
$image_ary = image_get_info($file->filepath);
if ($image_ary) {
if ($image_ary['mime_type'] != 'image/png' && $image_ary['mime_type'] != 'image/gif') {
file_delete($file->filepath);
drupal_set_message('Uploaded file must be PNG or GIF format.', 'error');
}
else {
if ($image_ary['height'] != 16 || $image_ary['width'] != 16) {
file_delete($file->filepath);
drupal_set_message('Uploaded image must be 16x16 pixels.', 'error');
}
else {
drupal_set_message(t('New ' . $value['name'] . ' icon saved.'));
variable_set("outline_designer_" . $value['type'] . "_icon", $file->filepath);
}
}
}
else {
file_delete($file->filepath);
drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.', 'error');
}
}
}
else {
$icon = $form_values["outline_designer_" . $value['type'] . "_icon_link"];
$base_path = base_path();
if ($base_path != '/' && $base_path != '') {
if (strpos(' ' . $icon, $base_path) != 0) {
$pos = strpos($icon, $base_path) + strlen($base_path);
$icon = substr($icon, $pos);
}
}
$icon = substr($icon, strpos($icon, drupal_get_path('module', 'outline_designer')));
$icon = substr($icon, strpos($icon, file_directory_path()));
variable_set("outline_designer_" . $value['type'] . "_icon", $icon);
}
}
}
variable_set("outline_designer_default_type", $form_values['outline_designer_default_type']);
variable_set("outline_designer_content_types", $form_values['outline_designer_content_types']);
}
function _outline_designer_outline() {
global $base_url;
$drag = user_access('drag-and-drop content');
if ($drag == '') {
$drag = 0;
}
$change_type = user_access('change content types');
if ($change_type == '') {
$change_type = 0;
}
$outline_posts = user_access('outline posts in books');
if ($outline_posts == '') {
$outline_posts = 0;
}
$duplicate = user_access('duplicate nodes');
if ($duplicate == '') {
$duplicate = 0;
}
$od_path = drupal_get_path('module', 'outline_designer');
$js = '//Setup Drupal specific path variables
var AJAX_URL = "' . $base_url . '/?q=outline_designer/ajax/"
var DRUPAL_OD_PATH = "' . $od_path . '";
var DRUPAL_PATH = "' . $base_url . '";
//Setup privs for rendering based on what users are allowed to do.
var DRAG_AND_DROP_CONTENT = ' . $drag . ';
var CHANGE_CONTENT_TYPES = ' . $change_type . ';
var OUTLINE_POSTS = ' . $outline_posts . ';
var ALLOW_DUPLICATE = ' . $duplicate . ';
var treeObj;
var factor = 1;';
drupal_add_js($js, 'inline');
drupal_add_css($od_path . '/style.css');
drupal_add_js($od_path . '/scripts.js');
$output = 'To drag nodes: Click and drag the type icon or the title<br />
To perform actions: Click on the smaller edit icon (double-click in Opera and IE)' . theme('outline_designer_top');
if (user_access('create new books') == 1) {
$output .= theme('outline_designer_options');
}
$output .= theme('outline_designer_bottom');
return $output;
}
function theme_outline_designer_bottom() {
return '</div>
<div style="padding:5px;">
<a href="#" onclick="treeObj.collapseAll();">Collapse all</a>
<a href="#" onclick="treeObj.expandAll();">Expand all</a>
Scale Interface:
<a href="#" onclick="scale_outline_designer(' . "'down'" . ');">Smaller</a>
<a href="#" onclick="scale_outline_designer(' . "'up'" . ');">Bigger</a>
<a href="#" onclick="scale_outline_designer(' . "'reset'" . ');">Reset</a>
</div>
<div>
<ul id="node0" class="dhtmlgoodies_tree">
<ul style="display:inline"></ul>
</ul>
</div>
</div>';
}
function theme_outline_designer_options() {
return '<input type="button" onclick="new_structure();" value="New">
<input type="button" onclick="duplicate_structure();" value="Duplicate">
<input type="button" onclick="delete_structure();" value="Delete">';
}
function theme_outline_designer_top() {
return '<div id="tree_container" style="padding:10px;border:1px #000000 dotted;" class="tree_normal">
<div style="padding:5px;"><select id="selected_outline" onchange="load_outline(this.value);"></select></div>
<div style="padding:5px;">';
}
function _outline_designer_tree_recurse($nid, $tree = array()) {
global $user;
$result = db_query("SELECT n.uid,n.nid,parent,title,type FROM {book} as b JOIN {node} as n ON n.vid=b.vid WHERE b.parent=%d ORDER BY weight", $nid);
while ($value = db_fetch_array($result)) {
if (user_access(_outline_designer_get_pstr('edit', $value['type']))) {
$allow_edit = 1;
}
elseif ($user->uid == $value['uid'] && user_access(_outline_designer_get_pstr('edit own', $value['type']))) {
$allow_edit = 1;
}
else {
$allow_edit = 0;
}
array_push($tree, array(
$value['nid'],
$value['parent'],
$value['title'],
variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png"),
$allow_edit,
));
$tree = _outline_designer_tree_recurse($value['nid'], $tree);
}
return $tree;
}
function _outline_designer_recurse_duplicate_nodes($nid, $tree = array()) {
$result = db_query("SELECT n.nid FROM {book} as b JOIN {node} as n ON n.vid=b.vid WHERE b.parent=%d ORDER BY weight", $nid);
while ($value = db_fetch_array($result)) {
$tree[$value['nid']] = 0;
$tree = _outline_designer_recurse_duplicate_nodes($value['nid'], $tree);
}
return $tree;
}
function _outline_designer_ajax() {
global $user;
$action = arg(2);
$var1 = arg(3);
$var2 = arg(4);
if (isset($action)) {
switch ($action) {
case 'add_node':
$parent = $var1;
$title = $var2;
$node->title = $title;
$node->status = 1;
$node->uid = $user->uid;
if ($parent == 0 || !user_access('change content types')) {
$node->type = variable_get("outline_designer_default_type", "page");
}
else {
$result = db_query("SELECT n.type FROM {node} as n JOIN {book} as b ON b.vid = n.vid WHERE b.parent=%d ORDER BY weight DESC", $parent);
$num_rows = db_num_rows($result);
if ($num_rows == 0) {
$parent_node = node_load($parent);
if (user_access(_outline_designer_get_pstr('create', $parent_node->type))) {
$node->type = $parent_node->type;
}
else {
$node->type = variable_get("outline_designer_default_type", "page");
}
}
else {
$value = db_fetch_array($result);
if (user_access(_outline_designer_get_pstr('create', $value['type']))) {
$node->type = $value['type'];
}
else {
$node->type = variable_get("outline_designer_default_type", "page");
}
}
}
$node->weight = -15;
$node->parent = $parent;
node_save($node);
if ($node->type != 'book') {
db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $parent, -15);
}
if (user_access(_outline_designer_get_pstr('edit', $node->type)) || user_access(_outline_designer_get_pstr('edit own', $node->type))) {
$allow_edit = 1;
}
else {
$allow_edit = 0;
}
print serialize(array(
$node->nid,
$node->type,
variable_get("outline_designer_" . $node->type . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png"),
$allow_edit,
));
break;
case 'change_type':
$nid = $var1;
$new_type = $var2;
$node = node_load($nid);
$type = db_result(db_query("SELECT type FROM {node_type} WHERE name='%s'", $new_type));
if ($node->type != $type) {
$node->type = $type;
node_save($node);
}
print variable_get("outline_designer_" . $node->type . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png");
break;
case 'delete':
$ids = $var1;
$ary = unserialize($ids);
for ($i = 0; $i < count($ary); $i++) {
node_delete($ary[$i]);
}
print 'Nodes successfully removed!';
break;
case 'drag_drop_update':
$parent = $var1;
$nid = $var2;
$node = node_load($nid);
$node->parent = $parent;
$node->log = 'Outline Designer reweighting update on drag-and-drop';
node_save($node);
break;
case 'duplicate_nodes':
$root = $var1;
$tree = array();
$value = db_fetch_array(db_query("SELECT n.nid FROM {book} as b JOIN {node} as n ON n.vid=b.vid WHERE n.nid=%d", $root));
$tree[$value['nid']] = 0;
$tree = _outline_designer_recurse_duplicate_nodes($root, $tree);
foreach ($tree as $old_nid => $new_nid) {
$node = node_load($old_nid);
$node->nid = null;
$node->created = null;
if ($old_nid == $root) {
$node->title = "Duplicate of " . $node->title;
}
else {
$node->parent = $tree[$node->parent];
}
node_save($node);
if ($node->type != 'book') {
db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->parent, $node->weight);
}
$tree[$old_nid] = $node->nid;
}
print_r($tree[$root]);
break;
case 'get_icons':
if (user_access('change content types')) {
$ary = array();
$ary2 = array();
$ary = variable_get('outline_designer_content_types', array(
'page',
));
foreach ($ary as $value) {
$name = db_result(db_query("SELECT name FROM {node_type} WHERE type='%s'", $value));
if (user_access(_outline_designer_get_pstr('create', $value))) {
array_push($ary2, array(
$name,
variable_get("outline_designer_" . $value . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png"),
));
}
}
print serialize($ary2);
}
break;
case 'get_book_roots':
$roots = array();
$result = db_query("SELECT n.nid,n.title FROM {node} as n JOIN {book} as b ON b.vid = n.vid WHERE parent=0 ORDER BY n.nid");
while ($value = db_fetch_array($result)) {
array_push($roots, array(
$value['nid'],
$value['title'],
));
}
print serialize($roots);
break;
case 'load_tree':
$nid = $var1;
$tree = array();
if ($nid != 0) {
$value = db_fetch_array(db_query("SELECT n.uid,n.nid,b.parent,n.title,n.type FROM {book} as b JOIN {node} as n ON n.vid=b.vid WHERE n.nid=%d ORDER BY weight", $nid));
if ($value['type'] == 'book') {
$term = 'pages';
}
else {
$term = 'content';
}
if (user_access('edit ' . $value['type'] . ' ' . $term)) {
$allow_edit = 1;
}
elseif ($user->uid == $value['uid'] && user_access('edit own ' . $value['type'] . ' ' . $term)) {
$allow_edit = 1;
}
else {
$allow_edit = 0;
}
}
else {
$value['nid'] = 0;
$value['parent'] = 0;
$value['title'] = 'Root Node';
$value['type'] = 'book';
$allow_edit = 0;
}
array_push($tree, array(
$value['nid'],
$value['parent'],
$value['title'],
variable_get("outline_designer_" . $value['type'] . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png"),
$allow_edit,
));
$tree = _outline_designer_tree_recurse($nid, $tree);
print serialize($tree);
break;
case 'rename':
$nid = $var1;
$newtitle = $var2;
$node = node_load($nid);
$node->title = $newtitle;
$node->revision = 1;
node_save($node);
break;
case 'save_tree':
$tree = $var1;
$ary = unserialize($tree);
$type = array();
for ($no = 0; $no < count($ary); $no++) {
$nid = $ary[$no][0];
$parent = $ary[$no][1];
$weight = $no;
$title = $ary[$no][2];
$node = node_load($nid);
if ($node->type == '') {
$node->type = variable_get("outline_designer_default_type", "page");
print serialize(array(
$node->nid,
variable_get("outline_designer_" . $node->type . "_icon", drupal_get_path('module', 'outline_designer') . "/images/node.png"),
));
}
else {
$type[$nid] = array(
$node->type,
);
$type[$parent] = array(
$node->type,
);
}
if ($node->weight != $weight || $node->parent != $parent || $node->title != $title) {
$node->weight = $weight;
$node->parent = $parent;
$node->title = $title;
$node->revision = 1;
node_save($node);
}
}
break;
case 'update_weights':
$weight = $var1;
$ary = unserialize($weight);
foreach ($ary as $weight) {
$node = node_load($weight[1]);
$node->weight = $weight[0];
$node->log = 'Outline Designer reweighting update';
node_save($node);
}
break;
}
}
exit;
}
function _outline_designer_get_pstr($op, $type) {
$term = 'content';
switch ($type) {
case 'panel':
if ($op == 'create') {
return 'create panel-nodes';
}
elseif ($op == 'edit') {
return 'administer panel-nodes';
}
elseif ($op == 'edit own') {
return 'edit own panel-nodes';
}
break;
case 'book':
$term = 'pages';
break;
default:
break;
}
return $op . ' ' . $type . ' ' . $term;
}