Drupal 7 Form Token

表单的Token 是为了防欺骗的验证.
Drupal 表单Token的生成是 $form['token'] 加上 一个私有的key, 这个key是由以下函数生成

$key = drupal_get_private_key();

Form Token生成函数生成.

$token = drupal_get_token();

Token的验证函数:

drupal_valid_token(token_value, token_id);

// Examples:
  if (isset($form['#token'])) {
    if (!drupal_valid_token($form_state['values']['form_token'], $form['#token'])) {
      // Setting this error will cause the form to fail validation.
      form_set_error('form_token', t('Validation error, please try again. If this error persists, please contact the site administrator.'));
    }
  }
发表在 Drupal | 留下评论

PHP 使用file_get_contents 模拟POST抓取数据

  1. // POST数据.
  2. $data = array(
  3.   'name' => 'xiukun',
  4.   'pass' => 'password123',
  5. );
  6. $data = http_build_query($data);
  7.  
  8. // 模拟浏览器的header头信息.
  9. $headers = array(
  10.   'Content-type: application/x-www-form-urlencoded',
  11.   'Content-Length: ' . strlen($data),
  12.   'Cookie: PHPSESSID = '. session_id(),
  13.   'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36',
  14.   'Referer: http://www.drupalmodule.cn/index.php',
  15.  );
  16. $opts = array(
  17.   'http'=>array(
  18.     'method'=>'POST',
  19.     'header'=> implode("\r\n", $headers),
  20.     'content' => $data
  21.   )
  22. );
  23.  
  24. // 创建资源流.
  25. $context = stream_context_create($opts);
  26. $html = file_get_contents('http://www.drupalmodule.cn/push.php', false, $context);
  27. echo ($html);
发表在 PHP | 留下评论

HTML 5 Video

http://blog.denivip.ru/index.php/2012/06/html5-player-development/?lang=en

获取Video

  1. // 原生方法获取
  2. document.getElementById("player")
  3.  
  4. // JQuery
  5. var player = $ ('#player')[0];

当前播放时间

  1. // 获取当前播放时间.
  2. var currentTime = player.currentTime;
  3.  
  4. // 设置当前播放时间.
  5. player.currentTime = 60;

声音控制

  1. // 静音0
  2. player.volume = 0;
  3.  
  4. player.volume = 1;

事件绑定和移除

  1. // 绑定一个事件.
  2. player.addEventListener('ended', onEndFunc);
  3.  
  4. // 移出一个事件.
  5. player.removeEventListener('ended', onEndFunc);
  6.  
  7. var onEndFunc = function() {
  8. }

事件列表

  • onabort – 播放中断事件
  • oncanplay – 可以播放时触发的事件, 视频已加载有足够的部分
  • oncanplaythrough – 可以播放时触发的事件, 内容已经完全缓冲
  • ondurationchange – 内容的时间发生变化事件
  • onemptied – 当断开链接的时候产生的事件
  • onended – 播放结束事件.
  • onerror – 视频文件下载错误事件.
  • onloadeddata – 事件文件下载事件
  • onloadedmetadata – 元数据加载事件(metada).
  • onloadstart – 视频文件开始下载事件
  • onpause – 暂停事件
  • onplay – 开始播放事件
  • onplaying – playback event (to be run until the video stops)
  • onprogress – 视频下载进度事件(将运行直到整个内容下载)
  • onratechange – playback rate change event
  • onreadystatechange – 视频“播放器”准备状态更改事件
  • onseeked – 视频寻求结束事件
  • onseeking – an event raised at content seek
  • onstalled – 浏览器未能获得内容引发的事件
  • onsuspend – 当浏览器停止获取数据事件
  • ontimeupdate – 当播放时间发生变化时事件,能时时监控当前播放的时间
  • onvolumechange – 声音发生变化事件
  • onwaiting – 当播放停止因为下一帧的视频资源不可用触发的事件
  1. </pre>
  2.  
  3. <pre lang="javascript">

							
发表在 HTML5 | 评论关闭

PHP 时间计算

此代码取自Drupal, 分享给广大PHP爱好者

https://api.drupal.org/api/drupal/includes!common.inc/function/format_interval/7

  1. function format_interval($interval, $granularity = 2) {
  2.   $units = array(
  3.     '@count年' => 31536000,
  4.     '@count月' => 2592000,
  5.     '@count星期' => 604800,
  6.     '@count天' => 86400,
  7.     '@count小时' => 3600,
  8.     '@count分钟' => 60,
  9.     '@count秒' => 1
  10.   );
  11.   $output = '';
  12.   foreach ($units as $key => $value) {
  13.     if ($interval >= $value) {
  14.       $output .= str_replace('@count', floor($interval / $value), $key);
  15.       $interval %= $value;
  16.       $granularity–;
  17.     }
  18.  
  19.     if ($granularity == 0) {
  20.       break;
  21.     }
  22.   }
  23.   return $output ? $output : '刚刚';
  24. }
  25.  
  26. // 传入的时候是两个时间的比较结果.
  27. var_dump(format_interval(500));
  28.  
  29. // 输出
  30. 8分钟20
  31.  
  32. 当然你还可以这样.
  33. var_dump(format_interval(511100, 4));
  34.  
  35. // 输出
  36. 521小时58分钟20
发表在 PHP | 评论关闭

Drupal Views Filter

过滤Query(hook_views_query_alter())

过滤字段类型为DatabaseCondition

通常我们可以使用以下来进行条件的重写

  1. foreach ($query->where[1]['conditions'] as $key => &$conditions) {
  2.     if (is_object($conditions['field'])) {
  3.         $conditions = &$conditions['field']->conditions();
  4.         if ($conditions[0]['field'] == 'myfield') {
  5.            $conditions[0]['value'] = 'myvalue';
  6.        }
  7.         continue;
  8.     }
  9. }

给过滤条件加默认的

默认情况下并不能对不存在的字段进行过滤.
方法1

  1. /**
  2.  * Implements hook_views_pre_build().
  3.  *
  4.  * @param object $view
  5.  * @return object
  6.  */
  7. function mymodule_views_pre_build($view) {
  8.   if ($view->name == 'myview' && $view->current_display == 'page') {
  9.     $view->display['page_2']->handler->handlers['filter']['myfield']->value = 'test';
  10.     return $view;
  11.   }
  12. }

方法2: 使用hook_views_query_alter();
如果不字段名和表名怎么写, 可以先进行一次有值的过滤,然后打印出$condition['field']名来参考

  1. if ($view->name == 'myview' && $view->current_display == 'page') {
  2.   $query->add_field('mytable', 'myfield', 'mytable.myfield');
  3.   $query->add_where(1, 'mytable.myfield', array(8099), 'IN');
  4. }
发表在 Drupal | 评论关闭

PHP 中的内存引址&

在PHP一般有函数引址和变量引址
变量引址

$var = 998;
$c = &$var;  // 变量$c引用了$var的内存地址. 这时变量$c和变量$var使用的就是同一个内存地址. 他们值会一起变
$c = 100;   // 当我改变了变量$c的值以后$var也会跟着变
var_dump($var);

//返回结果
100

函数引址
函数地址引用可以改变函数的返回值. 适用于跨函数的值保存.

class ref {
  public $var = 100;
  function &getvar() {
    return $this->var;
  }
}

$demo = new ref();
$var = &$demo->getvar();
$var = 300; // 改变函数的返回值.
echo $demo->getvar();

//结果
300

发表在 PHP | 评论关闭

Drupal node克隆/复制

此代码将一个已经存在的node覆盖成一个新node.

  1. $nid = 14; //想要复制node id
  2. $node = node_load(14);
  3. $node->nid = 0;
  4. $node->is_new = true;
  5. $node->vid = 0;
  6.  
  7. // 可以修改新node 标题,也可以注释掉.
  8. $node->title = "我的新nodeTitle";
  9.  
  10. // 保存.
  11. node_save($node);
发表在 Drupal | 评论关闭

Apache 压力测试工具

ab -c 100 -n 100 http://www.baidu.com

发表在 apache | 评论关闭

Mac 安装LAMP

Mac 集成环境MAMP.

http://www.mamp.info/en/downloads/

发表在 其它 | 评论关闭

我的Drupal之路

之前的我

10年刚刚毕业出来以后学校将我分配到慈溪的一家网站公司,主要负责扣图,拍照片. 上传图片等打杂工作,在一次机会看到公司有同事在使用PHP编程觉得蛮有意思(其实是蛮牛B的, 学了可以装一下),于是就开始我的PHP之路,当时我任何东西都是自己手写,爱好各种牛X的技术。比如那时jQuery比较流行,于是就用JQuery做了很多的效果,这是我第一个网站: http://www.cxlxtx.com/. 纯手工开发的网站,任何一段代码函数, 可以说是我学习PHP的一个结晶。

之后工作换到了宁波,在宁波的公司里面学了不少东西(GIT, Linux, Codeigniter. OOP.. 等强大又装B的东西). 公司里面都是技术狂,跟着技术狂一起工作你懂的,不努力都难。我读过Codeigniter源代码,这是一个简单又是当时MVC框架的一个代表作之一,从中我的PHP功底提升得非常大。

来到上海

12年8月后, 我离开了那家公司第一次来上海这边找工作,上海是个好城市, 来到上海这边我最希望能在这边先找份工作稳定下来, 信心满满的我面试了很多家基本都过了. 我完全就是想先稳定一下。在找工作的第三天,也是我快做选择的时候. 我决定再去某某招聘网站上看看工作。很熟悉的输入了PHP招聘,又一页一页的往后面翻。突然看到有公司招Drupal(由于上家公司两位比较大牛的师傅一直提起这个东西很了不起,所以早在思想里面根深蒂固). 无意识下就点了过去。简直亮瞎了我的双眼。招Drupal研发工程师, 你可以不会Drupal. 我们公司提供免费培训。这么好的事怎么就落在了我的身上,就这样我接到了这家公司的面试通知.

关于面试

刚进公司准备面试,客服人员告诉我老板正在开会需要我等一下。操! 我看到了什么。老板是老外! 我当时吓尿了. 我当时英语真的极差跟没学过似的。我怕太尴尬当时本来就打算走了. 一系列的心理斗争以后老板开完会了。老板在和我说中文,我当时惊呆了。当然以我强厚的PHP功底面试是非常成功的,给我出的几个PHP面试题我都做得很棒,为了能得到这份工作我要了一份最低的工资。 就这样我成功面试上了这份工作,就这样我认识我的Drupal导师大卫 – 法国人

培训

面试时老板告诉我叫我第二天10点准时来公司(第二天还是周末),我们要培训, 第二天我来得很早, 9点就来到公司了, 大卫10半才到公司(后来才了解到法国人拖延症比较严重, 经过多次这样的事, 我吸取教训,知道大卫说的10点就是10点半。以此类推 + 半个小时)。

我的第一天培训开始了,大卫先是给我讲了核心模块的介绍还有关于Drupal内容的添加和使用还有内容类型的基本使用, 我只能说头晕眼花,由于我英文不好。而大卫又是一半中文一半英文,跳得比较严重. 不大容易适应. 幸运的是我坚持下来了. 接下来的时间就是正常上班,周6培训Examples模块, hook的使用, Menu、Form、Field、Entity、Rules、Views、Theme等模块的学习和扩展的开发。每学一样东西大卫都会叫我们写一个案例. 基础学完了以后, 就是去学习一些简单模块的。大卫希望我们只要看一下源代码就知道这个模块是做什么的. 大概是3个月的左右的时间吧。 我觉得终于算是一个真正的Drupal开发者了。

第一个模块(Baidu map)

http://drupal.org/project/baidu_map

一次机会了解到官方竟然还没有百度地图这个模块, 于是决定开发这个模块, 当然此模块不是我可以凭空想出要怎么开发的。 任何一件好的作品都会先有一个beta版(来自黑客与画家),这次我参考的模块是alimap(作者希望之翼)当时这个模块还没有提交。我参考了他的功能和实现,采用了强大的Copy和Paste后,再将所有的文件名从alimap改成了baidu_map, 然后参考官方baidu_map的API。开始修改每一个接口的代码使其符合百度地图的标准, 此模块的算是可以正常运行了。到现在为止我只花了一个星期,总算心花怒放。还来了一次小小的自虐(我总算开发出我的第一个模块了)。接着大卫替我审核,然后我们就一起修改这个模块,后来发现开发一个模块最麻烦的不是写代码,而是:

  1. 注释、代码标准和Drupal的标准. 只要这样才能过大卫的关
  2. 官方的审核代码(此处最少需要一个月), 流程非常复杂

大卫在审核我代码的时候他会问我每一段代码为什么要这样写?是否符合标准, 比如一段百度地图官方提供的APP KEY. 在我的眼里就是一段字符串。但是我们有准备写正则表达式来验证此App Key是否符合标准,此时大卫就问我: 这段App key只有小写字母吗? 会不会只有A-D或者a-d? 或者只是只有大写字母(连官方都没有给出这样的文档)。一切的一切. 通过了后才会进行下一步。加上大卫的拖延者和工作上的事此模块总共用了三个月才提到到官方。

此模块只是有感悟比较深的作品之一,我还开发过其它的模块比如(Views Number Field Calc). 此模块是用于计算Views 两个字段的结果,并其结果支持排序和过滤。

我还成为了Nice menus的管理员,这是大卫为我申请的,后来由于Nice menus作者好像不干了。官方的人就直接把作者改成了我的名字. 通过这个模块的维护我也算是彻底了解了开源精神和Drupal这么强大的作品是怎么来的。

之后又成为了Views Slideshow的管理员

关于Drupal模块中文社区

www.drupalmodule.cn
当时作为一个像我这样的新手,遇到一个新的模块我觉得我最需要的就是一段简单的文字告诉这个模块是做什么,好让我开始去研究模块。但是我觉得好的中文资料实在不怎么样, 或者就是乱成一团。此网站开始的目的就是可以让新手们能够快速了解和使用一个新模块, 自己弄了足足3天才把这个网站做完和上线。经过自己的努力上面已经有了快拉近200个模块的使用和介绍。

关于Drupal聚会

在圈子里面还有一个最好的就是聚会,每隔一段时间都会有一次聚会,在聚会中我认识了龙马、希望之翼这样的大神。当然我更愿意叫他们大哥,每次聚会都会有人来分享东西(我也参加过多次分享)。 聚会我觉得最重要的是结交朋友,每次都能认识很多不同的新朋友。

关于工作

工作是很严谨的,在工作中的大忌不到万不得已不得修改核心代码和第三方模块的代码,一切都得按照官方的标准来,比如你遇到一个问题,你需要去官方找一下这个问题有没有解决,找一下有没有相应的Patch. 如果这个问题还不存在那么你需要给官方提出这个问题。然后跟进.必要的时候你需要去阅读核心代码来解决一个问题,有时只是一个小问题。但是大卫需要你用正确的方法来做, 我只有说跟着大卫在一起工作是非常开心的事, 那种做事的态度, 你会找到真正做程序员的乐趣。

关于大卫

他是我最尊敬的人,也是我的导师,是一位非常好的导师。大卫的拖延症比较严重,做事非常认真仔细,他很在乎一个符号要怎么写更好? 或者这里的字体可以要加粗一下会更好, 每一件我们看起来非常的事在他眼里面却是很重要. 要达到非常标准他才满意。 就拿一件普通的事来说吧,如果他叫你做一个功能。你使用下三烂的手段快速实现,他会直接你骂一顿.就是因为如此我刚刚开始的时候还抱怨过他怎么这么罗嗦,后来我才知道他是对的. 这也是我最欣赏他的地方,能学到很多东西. 不仅仅是技术。还有想问题的方法和思想。

发表在 Drupal | 评论关闭