EMwI插件启用失败的问题

有几名External Media without Import的用户向我反馈说插件启用失败,提示语法错误。其中还有一名用户就此问题在github上向我提了一个issue。具体的错误提示是Parse error: syntax error, unexpected T_STRING in …….external-media-without-import.php on line 25。

然而external-media-without-import.php的第25行仅仅是一个名字空间定义:

经过调查与沟通,发现原因是用户使用的PHP版本低于5.3.0,而PHP到了5.3.0才引入名字空间的特性,见PHP 5.3.0 Release Announcement。起初用户以为自己的PHP版本是5.6.30,但依据经验我猜测对方机器上可能有多个PHP版本,并且WordPress使用了较老的PHP。后来用户在自己的WordPress上安装了Display PHP Vesion插件,果然发现WordPress用的是PHP 5.2.17。

因此各位用户如果遇到这个启用失败的问题的话,请用Display PHP Vesion插件查看一下WordPress所用的PHP版本,确保PHP是5.3.0或更高的版本。

想不到那么老的PHP版本都还是有很多国内外用户在用啊。

用UGUI Slider做血条时遇到的一个小问题

前段时间想在小游戏中做一个血条UI,自然而然地想到了用UGUI的Slider。

在Unity中可以通过编辑器菜单一键创建一个Slider。这样的一个Slider里会包含Background、Fill Area和Handle Slide Area三个部分。其中Handle Slide Area就是滑块。血条不需要滑块,因此要将它删掉。

刚用编辑器菜单创建的Slider。需要将Handle Slide Area也就是滑块删掉。

我以为将滑块删掉就万事大吉不用改了,谁知却遇到一个问题。Value为0的时候,血条在表现上还有残留的血量:

Value为1的时候,血量却还没填满整个血条:

后来发现要将Fill Area及其孩子Fill的Left和Right都调成0才行。这样问题就解决了。

这里Left是指UI控件的左边缘相对于Anchors Min X的距离,Right是右边缘相对于Anchors Max X的距离。

EMwI更新:版本1.0.2 防XSS攻击

8月底的时候External Media without Import插件在github上收到一个pull request。对方指出我的代码存在XSS漏洞。惭愧,直到最近才腾出时间仔细研究他说的问题。插件的1.0.2版本合并了对方的pull request,修复了该漏洞。

在修复之前,我的插件中有如下代码(点击查看源文件):

这个函数将width 、height 和mime-type等信息通过 urlencode编码后设置为url的参数,然后重定向到该url。在url的响应函数中,我调用了 urldecode读取来这些信息: 继续阅读EMwI更新:版本1.0.2 防XSS攻击

理解Blender的表面细分修改器

以前一直不太理解Blender的表面细分修改器(Subdivision Surface Modifier,简称Subsurf)究竟是按什么规则来切割模型上的面。直到前段时间看了上篇文章提到Andrew Price的视频才理解。表面细分的规则是:给定三个顶点组成的两条相交线段,subsurf会构造一条曲线,使曲线和两条线段的中点相切,如下图所示。

不过因为模型中的线都是直线,所以Blender只能是用多条直线逼近这条曲线。细分次数越多,就越能逼近这条曲线。我们以一个四个顶点组成的平面模型为例,给这个平面添加一个表面细分修改器。细分次数为1是如下样子:

继续阅读理解Blender的表面细分修改器

Blender中的3D杯子

在画室刚开始学画静物,临摹一个杯子的时候,我卡在了杯子的把手上。当时我曾想着要在Blender中做一个杯子,好好观察解析一下把手的结构。但是直到最近我才有时间把这杯子做出来:

这杯子是我参考一个YouTube视频做出来的:Blender Beginner Tutorial – Part 5: Modelling

通过这个视频我还理解了Subdivision Modifier的原理,并学会了用Loop Cut和Inset Faces将subdivision构造的曲面局限在某个区域,并消除subdivision带来的一些artifact。

来张素描原画和3D模型的对比,附上3D模型的结构解析:

继续阅读Blender中的3D杯子

如何将图片中不想要的部分P掉

以前一直不知道那些玩PS的人是如何将图片中不想要的部分P掉的。偶尔遇到这种需求的时候,我都是手工选中并复制需要抹掉的部分周围的区域,然后粘贴覆盖要抹掉的区域,不断重复这个过程直到不想要的部分全部被覆盖;最后为了避免粘贴的像素和四周形成明显的交界,我会使用虚化或喷漆之类的工具涂抹交界区域,尽量使被抹掉的区域和四周的区域融合在一起。这种方法在处理背景比较简单(比如接近纯色且没什么花纹)的图片时还能凑合用,但只要背景稍微有点复杂就不能胜任了,因为无法让粘贴的像素和四周区域自然融合;而且这种方法费时费力,有时候还要一个像素一个像素地操作,直觉上感觉就不是正确的方法,至少不是最佳实践。

前段时间偶然在一节Photoshop课程上得知了一个方法,就是Photoshop的内容识别填充功能(Content Aware Fill)。只要用选择工具将想要去掉的部分圈中,然后点几下鼠标就可以将不想要的部分P掉了。

GIMP也有类似的功能。在菜单栏中的 工具 -> 涂画工具 中有一个GIMP自带的“复原”(Heal)工具,在工具栏上是一个止血贴图标:

继续阅读如何将图片中不想要的部分P掉

WordPress官方的代码审查意见

在向WordPress官方首次提交插件代码的时候,我收到了对方的反馈邮件。WordPress官方在邮件中对我的代码提出了一些审查意见,其中的内容挺值得学习的,因此在这里分享一下。其实大致意思就两点:一是后端不要信任前端发来的数据,要多做检查和处理,这是做后端的常识;二是尽量使用WordPress已有的API而不要自己直接调用curl。

原文如下:

There are issues with your plugin code.

Please read this ENTIRE email, address all listed issues, and reply to this email with your corrected code attached. It is required for you to read and reply to these emails, and failure to do so will result in significant delays with your plugin being accepted.

Also please remember in addition to code quality, security and functionality, we require all plugins adhere to our guidelines. If you have not yet, please read them:

* https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/

## Please sanitize, escape, and validate your POST calls

When you include POST/GET/REQUEST calls in your plugin, it’s important to sanitize, validate, and escape them. The goal here is to prevent a user from accidentally sending trash data through the system, as well as protecting them from potential security issues.

SANITIZE: All instances where generated content is inserted into the database, or into a file, or being otherwise processed by WordPress, the data MUST be properly sanitized for security. By sanitizing your POST data when used to make action calls or URL redirects, you will lessen the possibility of XSS vulnerabilities. You should never have a raw data inserted into the database, even by a update function, and even with a prepare()  call.

VALIDATE: In addition to sanitization, you should validate all your calls. If a $_POST  call should only be a number, ensure it’s an int()  before you pass it through anything. Even if you’re sanitizing or using WordPress functions to ensure things are safe, we ask you please validate for sanity’s sake. Any time you are adding data to the database, it should be the right data.

ESCAPE: Similarly, when you’re outputting data, make sure to escape it properly, so it can’t hijack admin screens. There are many esc_*()  functions you can use to make sure you don’t show people the wrong data.

In all cases, using stripslashes  or strip_tags  is not enough. You need to use the most appropriate method associated with the type of content you’re processing. Check that a URL is a URL and don’t just be lazy and use sanitize_text  please. The ultimate goal is that you should ensure that invalid and unsafe data is NEVER processed or displayed. Clean everything, check everything, escape everything, and never trust the users to always have input sane data.

Please review this document and update your code accordingly: http://codex.wordpress.org/Validating_Sanitizing_and_Escaping_User_Data

Example:

WordPress comes with an extensive HTTP API that should be used instead of creating your own curl calls. It’s both faster and more extensive. It’ll fall back to curl if it has to, but it’ll use a lot of WordPress’ native functionality first.

https://developer.wordpress.org/plugins/http-api/

—-

Please make sure you’ve addressed ALL issues brought up in this email.

译文:

继续阅读WordPress官方的代码审查意见

对一个项目同时使用svn和git两个远程仓库

以前曾经和朋友讨论过在一个项目中同时使用svn和git两个远程仓库的可能,如今真的遇到了这样的实际需求。

在开发WordPress插件External Media without Import的时候,因为希望插件能在WordPress官方渠道发布,所以需要在WordPress官方提供的svn远程仓库上托管这个项目。WordPress官方给我提供的svn仓库的地址是https://plugins.svn.wordpress.org/external-media-without-import/

但另一方面,考虑到github作为开源社区的人气,以及fork、pull request等代码贡献的便利性,我也想在github上托管这个项目。因此我在github上也创建了一个仓库:https://github.com/zzxiang/external-media-without-import.git

与此同时,我希望本地只需要维护一个项目文件夹,或者绝大部分操作只需要在一个文件夹中执行。这个文件夹由git管理,并可以方便地与WordPress的svn和github双方同步。不过后来经过一段时间摸索,我似乎只能做到让git和svn仓库的trunk分支同步,但这也足够了。

也就是说,我希望实现的应用场景如下图所示:

继续阅读对一个项目同时使用svn和git两个远程仓库

搭建本地WordPress开发调试环境

WordPress的运行环境是很传统的Apache + MySQL + PHP,其中PHP用的是PHP5,因此部署过程中应该不会有很难解决的问题,只不过步骤可能会比较繁琐。除此以外就是调试的配置需要摸索一阵子。

一开始我曾想过花钱买MAMP PRO来搭建WordPress的本地开发环境(MAMP免费版本只支持PHP7),图省事。但后来还是决定自己折腾,省下这笔钱。于是花了那么几天自己搭建了一套本地WordPress编码、运行和调试环境。除了Apache + MySQL + PHP之外,为了能在编辑器中单步调试,我还给PHP加装了Xdebug扩展,并给Vim编辑器加装了Vdebug插件。最终我将自己的WordPress站点从云主机拷贝到了本地,并在Vim中愉快地编写和调试里面的PHP代码:

让我哭笑不得的是,在我把环境搭建好一个月后写这篇文章的过程中,才发现其实Mac本身已经自带了Apache和PHP,并不用我自己去下载源代码再安装。

继续阅读搭建本地WordPress开发调试环境

让WordPress媒体库支持外链图片

最近有一个月左右没更新了,因为这个月的业余时间都在忙于一个WordPress插件:External Media without Import。

其实只是很小很简单的一个插件,代码不过短短几百行。不过这东西一旦被当成产品认真做起来,依然让我感到——每天在上班时间以外,应对完工作上的需求和bug之后,接着还要在业余时间认真做好另一个产品是多么劳心劳力。这是我正式发布并打算认真维护的第一个个人项目。为此我还自己设计制作了用于WordPress官方渠道的插件图标和Banner:

闲话少说,还是来介绍一下这个插件。先列出插件地址。

插件的WordPress官方渠道地址:

https://wordpress.org/plugins/external-media-without-import/

插件的Github地址:

https://github.com/zzxiang/external-media-without-import

继续阅读让WordPress媒体库支持外链图片