欢迎各位兄弟 发布技术文章
这里的技术是共享的
user_access('chuli kefuguanbi') //kefuguanbi是权限名称
看是否返回真 判断其权限
一个模块 可以实现多处功能
一般情况下 只需要用 devel 清空缓存就可以了
(也可以模块 先关闭 再开启 比较麻烦)
1)menu 菜单机制 模块管理机制
它是导航系统
所有的菜单 模块都是实现了 hook_menu 钩子函数
2)
http://api.drupal.org/api/function/hook_menu/5
实现菜单系统
只有一个入口 index.php
url->是否维护->否->get menu array
->q 后面参数 取过来-> 看有调用无钩子函数 它会调用(回调函数)
->如果没有 调用回调函数->不同的主题模板 不同的节点类型 这个过程完成的
->如果有 调用回调函数-> 看回调函数的定义是否存在
->如果不存在 回调函数的定义 ->返回 menu_not found
->如果存在 回调函数的定义 ->用户是否有权限(hook_perm)
->如果没有权限-> 返回 menu_access_denied(拒绝)
->如果有权限 根据url参数 和回调函数需要的参数进行处理->调用回调函数->生成页面
function hook_menu($may_cache) {
}
//drupal 6 是没有参数
//drupal 6
//type 菜单类型 最常用两种 MENU_NORMAL_ITEM (显示菜单项)
// MENU_CALLBACK(不显示菜单项)
//drupal 6 好像是没有采用 什么分缓存和不缓存了 全部缓存
function hook_menu() {
$items = array();
$items['example'] = array(
'title' => 'Example Page', //必须
'page callback' => 'example_page',
'access arguments' => array('access content'), //必须 // 要让所有可以访问,
//'access arguments' =>true,
'type' => MENU_SUGGESTED_ITEM,
);
$items['example/feed'] = array(
'title' => 'Example RSS feed',
'page callback' => 'example_feed',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
//这是 drupal5 不适用了
function hello_page_menu($may_cache) {
$item = array();
if ($may_cache) //有缓存的时候 把下面注册在菜单项中 $items就是菜单项
{
//path url中路径 title 显示在菜单管理中,作为菜单项进行管理
//callback 指示 当访问 url时,执行哪个函数(它是回调函数,不是钩子,随便起什么名,不一定要 模块名_函数名()的格式),
//此函数里执行各种
//逻辑.输出html脚本,此函数也在本文件里实现
//access 访问权限
//如果不设它 那会drupal 会提示 access 被拒绝(所有人都看不到)
//所以这是drupal一个bug 必须要写 只要写成跟 drupal 里的随便哪个权限一样就可以
//还要让这个权限对所有角色默认允许
//也可以自己定义一个权限
//如 funtion hello_page_perm(){
// return array('access hellodrupal blocks');
// }
//先这里是
$items[] = array('path'=>'hello','title'=>t('hello'),
'callback'=>'hello_page_test',
//'access'=> user_access('access hello page'));
'access'=> 'access hellodrupal blocks');
//path hello/sayhello 两层 自动把它注册为 hello的子菜单项
//type 告诉drupal 菜单项的类型 默认就是普通菜单项 可以在菜单中进行管理删除
$items[] = array('path'=>'hello/sayhello','
title'=>t('Say hello'),
'callback'=>'hello_page2_test',
'type'=> MENU_CALLBACK);
}
return $items;
}
//drupal 5
$may_cache //第一次访问 可以被缓存 它为true
//会调用两次 要注册的菜单 要么放在真下 要么放在假下,否则会出错
一)第一次为true
二)第一次为false 样式表文件等
//drupal 6
function your_module_menu() {
$items['admin/settings/your_module'] = array(
'title' => 'Your Module Settings', // NOTE: t() not needed
'description' => 'Menu description', // ... for these elements
'page callback' => 'page_callback_funtion',
'page arguments' => array('page callback arguments'),//它的优先级 大于 url传来的参数 也就是此时url如果放参数,参数不起作用 我
//如果要默认值 就放在回调函数的形参上 (默认的时候要注意,第几个有默认值, page arguments=>array(......)) 中第几个元素就必须没有,假如有的话 虽不在url中赋值,但是是有值的 值为两个单或双引号括起来
//它是默认参数的意思 //它是静态的 被存入缓存的
//'page arguments' => array(1,2),
//它的优先级 大于 url传来的参数我
//如果要默认值 就放在回调函数的形参上 放在page_callback_funtion函数的形参上
//如果用array(1,2)表示只取url前两个参数 array(1)表示只取url第一个参数 ,
'access callback' => 'user_access', // Check that the current user
'access arguments' => array('Administer Your Module'), // ... has this permission.
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
//回调函数的参数 就是url/参数
多个参数 url/参数/参数
funtion hello_page_perm(){
return array('access hellodrupal blocks');
}
funtion hello_page_test(){
$output = 'hello drupal page';
return $output;
}
funtion hello_page_test($name = null){
$output = '';
if(empty($name)){
$output = "hello andbody";
}
else {
$output = "hello ".$name;
}
return $output;
}
funtion hello_page_test($name = null, $nickname = null){
$output = '';
if(empty($name)){
$output = "hello andbody";
}
else {
$output = "hello ".$name;
}
if(!empty($nickname)){
$output .= 'your nick name is ".$nickname;
}
return $output;
}
3)表单验证 表单名_validate
function test001_admin_validate($form, &$form_state)
{
$maxdisp = $form_state['values']['test001_maxdisp'];
if (!is_numeric($maxdisp))
{
form_set_error('test001_maxdisp', t('You must select a number for the maximum number of links.'));
//第一个参数是字段名 ,,好像也可以为空
}
else if ($maxdisp <= 0) {
form_set_error('test001_maxdisp', t('Maximum number of links must be positive.'));
}
}
<?php
function nodeself_form_submit($form, &$form_state) {
global $user;
$node = node_form_submit_build_node($form, $form_state);
$insert = empty($node->nid);
node_save($node);
$node_link = l(t('view'), 'node/'. $node->nid);
$watchdog_args = array('@type' => $node->type, '%title' => $node->title);
$t_args = array('@type' => node_get_types('name', $node), '%title' => $node->title);
if ($insert) {
watchdog('content', '@type: added %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
drupal_set_message(t('@type %title has been created.', $t_args));
}
else {
watchdog('content', '@type: updated %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
drupal_set_message(t('@type %title has been updated.', $t_args));
}
if ($node->nid) {
unset($form_state['rebuild']);
$form_state['nid'] = $node->nid;
$form_state['redirect'] = 'node/'. $node->nid;
}
else {
// In the unlikely case something went wrong on save, the node will be
// rebuilt and node form redisplayed the same way as in preview.
drupal_set_message(t('The post could not be saved.'), 'error');
}
}
/**
* Build a node by processing submitted form values and prepare for a form rebuild.
*/
function nodeself_form_submit_build_node($form, &$form_state) {
// Unset any button-level handlers, execute all the form-level submit
// functions to process the form values into an updated node.
unset($form_state['submit_handlers']);
form_execute_handlers('submit', $form, $form_state);
$node = node_submit($form_state['values']);
$form_state['node'] = (array)$node;
$form_state['rebuild'] = TRUE;
return $node;
}
/**
* Generate the node add/edit form array.
*/
function nodeself_form(&$form_state, $node) {
global $user;
if (isset($form_state['node'])) {
$node = $form_state['node'] + (array)$node;
}
if (isset($form_state['node_preview'])) {
$form['#prefix'] = $form_state['node_preview'];
}
$node = (object)$node;
foreach (array('body', 'title', 'format') as $key) {
if (!isset($node->$key)) {
$node->$key = NULL;
}
}
if (!isset($form_state['node_preview'])) {
node_object_prepare($node);
}
else {
$node->build_mode = NODE_BUILD_PREVIEW;
}
// Set the id of the top-level form tag
$form['#id'] = 'node-form';
// Basic node information.
// These elements are just values so they are not even sent to the client.
foreach (array('nid', 'vid', 'uid', 'created', 'type', 'language') as $key) {
$form[$key] = array(
'#type' => 'value',
'#value' => isset($node->$key) ? $node->$key : NULL,
);
}
// Changed must be sent to the client, for later overwrite error checking.
$form['changed'] = array(
'#type' => 'hidden',
'#default_value' => isset($node->changed) ? $node->changed : NULL,
);
// Get the node-specific bits.
if ($extra = node_invoke($node, 'form', $form_state)) {
$form = array_merge_recursive($form, $extra);
}
if (!isset($form['title']['#weight'])) {
$form['title']['#weight'] = -5;
}
$form['#node'] = $node;
// Add a log field if the "Create new revision" option is checked, or if the
// current user has the ability to check that option.
if (!empty($node->revision) || user_access('administer nodes')) {
$form['revision_information'] = array(
'#type' => 'fieldset',
'#title' => t('Revision information'),
'#collapsible' => TRUE,
// Collapsed by default when "Create new revision" is unchecked
'#collapsed' => !$node->revision,
'#weight' => 20,
);
$form['revision_information']['revision'] = array(
'#access' => user_access('administer nodes'),
'#type' => 'checkbox',
'#title' => t('Create new revision'),
'#default_value' => $node->revision,
);
$form['revision_information']['log'] = array(
'#type' => 'textarea',
'#title' => t('Log message'),
'#default_value' => (isset($node->log) ? $node->log : ''),
'#rows' => 2,
'#description' => t('An explanation of the additions or updates being made to help other authors understand your motivations.'),
);
}
// Node author information for administrators
$form['author'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer nodes'),
'#title' => t('Authoring information'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 20,
);
$form['author']['name'] = array(
'#type' => 'textfield',
'#title' => t('Authored by'),
'#maxlength' => 60,
'#autocomplete_path' => 'user/autocomplete',
'#default_value' => $node->name ? $node->name : '',
'#weight' => -1,
'#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous')))),
);
$form['author']['date'] = array(
'#type' => 'textfield',
'#title' => t('Authored on'),
'#maxlength' => 25,
'#description' => t('Format: %time. Leave blank to use the time of form submission.', array('%time' => !empty($node->date) ? $node->date : format_date($node->created, 'custom', 'Y-m-d H:i:s O'))),
);
if (isset($node->date)) {
$form['author']['date']['#default_value'] = $node->date;
}
// Node options for administrators
$form['options'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer nodes'),
'#title' => t('Publishing options'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 25,
);
$form['options']['status'] = array(
'#type' => 'checkbox',
'#title' => t('Published'),
'#default_value' => $node->status,
);
$form['options']['promote'] = array(
'#type' => 'checkbox',
'#title' => t('Promoted to front page'),
'#default_value' => $node->promote,
);
$form['options']['sticky'] = array(
'#type' => 'checkbox',
'#title' => t('Sticky at top of lists'),
'#default_value' => $node->sticky,
);
// These values are used when the user has no administrator access.
foreach (array('uid', 'created') as $key) {
$form[$key] = array(
'#type' => 'value',
'#value' => $node->$key,
);
}
// Add the buttons.
$form['buttons'] = array();
$form['buttons']['submit'] = array(
'#type' => 'submit',
'#access' => !variable_get('node_preview', 0) || (!form_get_errors() && isset($form_state['node_preview'])),
'#value' => t('Save'),
'#weight' => 5,
'#submit' => array('node_form_submit'),
);
$form['buttons']['preview'] = array(
'#type' => 'submit',
'#value' => t('Preview'),
'#weight' => 10,
'#submit' => array('node_form_build_preview'),
);
if (!empty($node->nid) && node_access('delete', $node)) {
$form['buttons']['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
'#weight' => 15,
'#submit' => array('node_form_delete_submit'),
);
}
$form['#validate'][] = 'node_form_validate';
$form['#theme'] = array($node->type .'_node_form', 'node_form');
return $form;
}
/**
* Present a node submission form.
*
* @ingroup themeable
*/
/*function theme_node_form($form) {
$output = "\n<div class=\"node-form\">\n";
// Admin form fields and submit buttons must be rendered first, because
// they need to go to the bottom of the form, and so should not be part of
// the catch-all call to drupal_render().
$admin = '';
if (isset($form['author'])) {
$admin .= " <div class=\"authored\">\n";
$admin .= drupal_render($form['author']);
$admin .= " </div>\n";
}
if (isset($form['options'])) {
$admin .= " <div class=\"options\">\n";
$admin .= drupal_render($form['options']);
$admin .= " </div>\n";
}
$buttons = drupal_render($form['buttons']);
// Everything else gets rendered here, and is displayed before the admin form
// field and the submit buttons.
$output .= " <div class=\"standard\">\n";
$output .= drupal_render($form);
$output .= " </div>\n";
if (!empty($admin)) {
$output .= " <div class=\"admin\">\n";
$output .= $admin;
$output .= " </div>\n";
}
$output .= $buttons;
$output .= "</div>\n";
return $output;
}
*/
/**
* Button sumit function: handle the 'Delete' button on the node form.
*/
function nodeself_form_delete_submit($form, &$form_state) {
$destination = '';
if (isset($_REQUEST['destination'])) {
$destination = drupal_get_destination();
unset($_REQUEST['destination']);
}
$node = $form['#node'];
$form_state['redirect'] = array('node/'. $node->nid .'/delete', $destination);
}
function nodeself_form_build_preview($form, &$form_state) {
$node = node_form_submit_build_node($form, $form_state);
$form_state['node_preview'] = node_preview($node);
}
function nodeself_form_validate($form, &$form_state) {
node_validate($form_state['values'], $form);
}
function nodeself_forms() {
$forms = array();
if ($types = node_get_types()) {
foreach (array_keys($types) as $type) {
$forms[$type .'_node_form']['callback'] = 'node_form';
}
}
return $forms;
}
/**
* Implementation of hook_form_alter().
*/
function nodeself_form_alter(&$form, $form_state, $form_id) {
// Advanced node search form
if ($form_id == 'search_form' && $form['module']['#value'] == 'node' && user_access('use advanced search')) {
// Keyword boxes:
$form['advanced'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced search'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#attributes' => array('class' => 'search-advanced'),
);
$form['advanced']['keywords'] = array(
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
);
$form['advanced']['keywords']['or'] = array(
'#type' => 'textfield',
'#title' => t('Containing any of the words'),
'#size' => 30,
'#maxlength' => 255,
);
$form['advanced']['keywords']['phrase'] = array(
'#type' => 'textfield',
'#title' => t('Containing the phrase'),
'#size' => 30,
'#maxlength' => 255,
);
$form['advanced']['keywords']['negative'] = array(
'#type' => 'textfield',
'#title' => t('Containing none of the words'),
'#size' => 30,
'#maxlength' => 255,
);
// Taxonomy box:
if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
$form['advanced']['category'] = array(
'#type' => 'select',
'#title' => t('Only in the category(s)'),
'#prefix' => '<div class="criterion">',
'#size' => 10,
'#suffix' => '</div>',
'#options' => $taxonomy,
'#multiple' => TRUE,
);
}
// Node types:
$types = array_map('check_plain', node_get_types('names'));
$form['advanced']['type'] = array(
'#type' => 'checkboxes',
'#title' => t('Only of the type(s)'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $types,
);
$form['advanced']['submit'] = array(
'#type' => 'submit',
'#value' => t('Advanced search'),
'#prefix' => '<div class="action">',
'#suffix' => '</div>',
);
$form['#validate'][] = 'node_search_validate';
}
}
drupal6的upload模块只能上传英文名字的文件,我经过一段时间的测试,完美解决了drupal下中文文档上传的问题。
其实文档上传,无非涉及到两个方面。
第一:文档存到数据库中的名字。
第二:文档上传后存到服务器的文件夹里的名字。
这两个名字如果都是中文的名字,问题就解决了。
根据以上的设想,我开始修改file.inc文件。
为什么要修改这个文件呢?
因为文件的上传是用到upload.module的upload_node_form_submit(&$form, &$form_state)这个函数是管上传的。
但是这个函数上传主要用到了函数里面的这句代码
if (($user->uid != 1 || user_access('upload files')) && ($file = file_save_upload('upload', $validators, file_directory_path())))
也就是 file_save_upload函数才是最终的上传函数。而file_save_upload函数就是在file.inc这个文件里。
所以我们其实就是修改file.inc这个文件里的file_save_upload函数。
修改两个地方就可以
第一个地方,管数据库文件名字的
语句是:
<?php
$file->filename = file_munge_filename(trim(basename($_FILES['files']['name'][$source]), '.'), $extensions);
?>
修改后:
<?php
$file->filename = file_munge_filename(trim($_FILES['files']['name'][$source], '.'), $extensions);
?>
第二个地方,管上传到服务器的文件夹里的文件名字的。
原句是:
<?php
if (!move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->filepath))
?>
修改后:
<?php
if (!move_uploaded_file($_FILES['files']['tmp_name'][$source],iconv("UTF-8","gb2312",$file->filepath)))
?>