You are here

天下代码一大抄

我常给人说,自己不会php,确实不怎么会,仅有的一点知识,还是学习drupal的时候顺便学习的.但是这并不妨碍使用drupal.其实很多熟悉drupal的人并不大懂php.

 

下面将一下,我是怎么实现这个自定义的模块的.我批判过直接修改模块的代码.实际上,自己也常常直接修改.当我看到了switchtheme,看完它的代码以后。我首先阅读了list_themes这个函数,通过这个函数的定义,我了解到了,drupal的theme是存放在system表中的。打开数据库,浏览了一下这个表的内容。如果实在不行,自己还可以直接读取数据库。我是这么想的。

 

  $result = db_query("SELECT * FROM {system} WHERE type = '%s'", 'theme');

读完代码了,类似的功能也找到了。那么就开始动工了,直接修改switchtheme.module. 不过需要现有一个思路,比如动态的显示前一个主题这样一个区块。首先想到的,显示一个静态的主题区块。然后再将它改造成动态的。

 

在switchtheme_block函数中,添加以下内容:

$blocks[2]['info'] = t('Previous theme');

elseif ($delta == 2 && $op == 'view' && user_access('switch theme')) {

    $block['subject'] = t('Previous theme');

    $block['content'] = switchtheme_display_previous_block();

    return $block;

  }

 

然后再创建一个switchtheme_display_previous_block()函数。让这个函数返回一个静态的$output;这样,就可以启用这个区块了,而且在上面可以看到这个区块中的内容了。由于开始的时候,这里是静态的,所以接下来需要向switchtheme_display_previous_block(函数中添加逻辑代码。list_themes()函数返回来的是一个数组。这里需要对php的数组进行处理,我对这方面不熟,以前有一本很好的参考书,后来留到了原公司了。所以只好google一下。很快就找到了关于数组的php函数,里面有相关的介绍。

 

边找函数,也在边思考具体的逻辑,首先在程序中,我需要找到当前的主题,根据当前的主题,我让指针向前移动一位,就可以找到前一个主题。既然list_themes()把所有的主题都读了进来,直接进行数组操作就可以了。

 

当前的主题比较好找到,代码有现成的:

$current_theme = !empty($custom_theme) ? $custom_theme : $user->theme;

 

不过注意这里,$custom_theme是个全局变量,使用以前需要global一下。这个是我在调试的时候发现的,其实拷贝的时候,就带上了,后来又用到的时候,忘记了global,所就出了错误。很快就定位到这里了。所以提醒一下,这里的当前主题是存在session里面的。找到了两个函数,ksort(),prev()这两个就够用了。我现在有了当前的主题,有了主题数组,如何让数组的指针直接指到当前的主题之上,我觉得应该有现成的方法,但是我不会,没有用过,所以只好使用foreach()来一个一个的判断了。最初的代码如下:

 

global $custom_theme;

          $themes = list_themes();

          ksort($themes);

          $current_theme = !empty($custom_theme) ? $custom_theme : $user->theme;

     foreach ($themes as $key => $theme) {

       if($key==$current_theme){

         break;

       }

     }

          $previous_theme = prev($themes);

 

        后来debug,发现指向了当前的主题,原来php的数组找到了当前的主题以后,会把指针向下移动一位,所以我又加了一句$previous_theme = prev($themes);

 

这样就找到了前一个主题,然后对其进行输出:

          if($previous_theme){

                 $previous_theme->screenshot = dirname($previous_theme->filename) .'/screenshot.png';

                 $output = l($previous_theme->name, $_GET['q'], array('query' => 'theme='. $previous_theme->name, 'html' => TRUE));

                 $output .="</br>";

                      $output .= l("<img src=\"". base_path() ."$previous_theme->screenshot\" alt=\"preview of $previous_theme->name\"/>", $_GET['q'], array('query' => 'theme='. $previous_theme->name, 'html' => TRUE));

          }else{

            $output =t('这个主题是第一个,前面没有主题了^_^,你可以选择下一个主题');

          }

      return $output;

 

最初这里也是没有if判断的,只有前面的逻辑代码,后来发现,当跑到边界的时候会出乱子,所以加了一个if语句用来判断边界条件。简单的if语句我还是会的。

 

再后来,在边界附近有发现了问题,把前面的两个prev改为了:

$previous_theme = prev($themes);

          if(!$previous_theme ){

            end($themes);

          }

  $previous_theme = prev($themes);

这里面又加了一个判断,终于搞定了。

 

上面的这些代码都是从这里,还有从那里拷贝过来的。包括拼凑的字符串。

 

接下来,一口气,把这里的逻辑写完了,花了4个小时,就把这个网站的难点给搞定了。当然这样的代码,没有注释,效率也不是很高,不过这个网站,这些代码,对于他人也没有什么大用,仅仅用于教学,以及方便大家预览drupal主题使用。

 

我是把逻辑直接放到了switchtheme模块中,后来功能实现以后,自己就把它独立了出来。当然,里面的字符串也都直接替换成了中文的。令我惊讶的是,拷贝出来以后,改了改名字以后,就可以正常工作了。

 

当然,能够这样的解决这个问题,我还是有些基础的,比如两年的时间自己读过各种各样的代码,就拿drupal来说,内核的代码,我是读过一遍的,还有项目中的各种php代码,虽然自己遇到问题,不能将函数直接写书来,但是,知道类似的函数,在那里可以找到。也知道如何修改一个函数。

 

在项目中,大多数时候,都是在抄袭别人的代码,自己仅仅是一个IT民工,谈不上任何的创造性

相关链接: Think in Drupal

Drupal版本:

评论