第十八天:滤镜
symfony前情提要欧宝娱乐app下载地址
昨天我们看到了如何通过XML API使askeket服务可用。今天的课程将关注过滤器,我们将通过创建askeet的子域来说明它们的使用。例如,'php.askeet.com'将只显示带有PHP标记的问题,并且在此域中发布的任何新问题都将标记为' PHP '。让我们将这个新功能称为“askeet universe”,并立即开发它。
可配置的特性
首先,这个新功能必须是可选的。Askeet应该是一个可以安装在任何配置上的软件,您可能不希望允许在企业内部网中安装子域。
因此,我们将在应用程序配置中添加一个新参数。要启用宇宙特性,必须将其设置为在
.要添加自定义参数,请打开使用/应用程序/前端/ config / app.yml
文件和添加:
All: .global: universe: on
这个参数现在对应用程序的所有操作都可用。要获得其值,请使用sfConfig: get(“app_universe”)
调用。
自定义设置的详细信息请参见配置章交响乐书的。欧宝娱乐app下载地址
创建一个过滤器
过滤器是在每个操作之前执行的一段代码。这就是我们在所有操作之前检查主机名所需要的,在域中搜索标记名。
过滤器必须在要执行的特殊配置文件中声明使用/应用程序/前端/ config / filters.yml
文件。该文件在初始化应用程序时默认创建,为空。打开并添加:
myTagFilter类:myTagFilter
这声明了一个新的myTagFilter
过滤器。我们将创建一个myTagFilter.class.php
类文件中的使用/应用程序/前端/ lib /
目录,使其可用于整个前端
应用程序:
<?php类myTagFilter扩展sfFilter{公共函数执行(filterChain美元){//只执行一次过滤器如果(sfConfig::得到(“app_universe”)& &这个美元->isFirstCall()){//做事情}//执行下一个过滤器filterChain美元->执行();}}? >
这是滤波器的一般结构。如果app_universe
参数未设置为在
,过滤器不会执行。因为我们希望每个请求只执行一次过滤器(尽管每个请求可能有多个动作,因为我们使用转发),所以我们检查- > isFirstCall ()
方法。它是真正的
仅在给定请求中第一次执行筛选器。
简单说一下filterChain
object:执行请求的所有步骤(配置、前端控制器、动作、视图)都是一个过滤器链。自定义过滤器只是在这个链的早期出现(在一个动作执行之前),它不能中断链过滤器其他步骤的执行。这就是为什么自定义过滤器必须总是以filterChain - > execute ();
.
请注意
的sfFilter
类有一个初始化()
方法,在创建筛选器对象时执行。如果需要以自己的方式处理筛选器参数,可以在自定义筛选器中覆盖它。
从域名中获取永久标记
我们希望检查主机名,以检查它是否包含可能是标记的子域。像“www”或“askeet”这样的标签必须被忽略。此外,我们希望能够修改子域的规则来忽略,例如,如果我们使用负载平衡技术来替代域名,如'www1', 'www2'等。这就是为什么我们决定在的参数中加入忽略规则(正则表达式)filters.yml
配置文件:
myTagFilter: class: myTagFilter参数:host_exclude_regex: /^(www|askeet)/
现在是时候看看内容了execute ()
过滤器的动作(替换//做事情
评论):
//主机名中有标记吗?美元的主机名=这个美元->getContext()->getRequest()->getHost();如果(!preg_match(这个美元->getParameter(“host_exclude_regex”),美元的主机名)& &pos美元=大小写敏感(美元的主机名,“。”)){美元的标记=标签::正常化(字符串的子串(美元的主机名,0,pos美元));//添加一个永久标签自定义配置参数sfConfig::集(“app_permanent_tag”,美元的标记);//添加自定义样式表这个美元->getContext()->getResponse()->addStylesheet(美元的标记);}
过滤器在URI中寻找可能的永久标记。如果找到一个,则将其作为自定义参数添加,并将自定义样式表添加到视图中。例如:
//调用这个URI来显示PHP宇宙http://php.askeet.com //将创建一个常量sfConfig::set('app_permanent_tag', ' PHP ');//在视图中包含一个自定义样式表
请注意
由于自定义过滤器的执行发生在过滤器链的非常早期,甚至早于视图配置解析,因此自定义样式表将出现在输出HTML文件中之前其他样式表。因此,如果您必须在自定义样式表中覆盖主askeet站点的样式设置,则需要声明这些设置重要的!
.
模型修改
现在,我们需要修改动作和模型方法,以将永久标记考虑在内。由于我们喜欢将模型逻辑保持在model层中,并且因为重构变得非常必要,所以我们利用永久标记修改将Propel请求从操作中取出,并将它们放入模型中。如果你看一下今天发布的修改列表askeet trac,您将看到一些新的模型方法被创建,并且操作调用这些方法而不是执行doSelect ()
自己:
回答- - - - - - >getRecent()问题——>getPopularAnswers()QuestionPeer::getPopular()QuestionPeer::getRecent()QuestionTagPeer::getForUserLike()
根据永久标记筛选列表
当在askeet宇宙中显示问题、标签或答案列表时,所有请求都必须考虑一个新的搜索参数。在sy欧宝娱乐app下载地址mfony中,搜索参数调用- > add ()
方法标准
对象。
因此,将以下方法添加到QuestionPeer
而且AnswerPeer
类:
私人静态函数addPermanentTagToCriteria(美元标准){如果(sfConfig::得到(“app_permanent_tag”)){美元标准->addJoin(自我::ID, QuestionTagPeer::QUESTION_ID标准::LEFT_JOIN);美元标准->添加(QuestionTagPeer::NORMALIZED_TAG, sfConfig::得到(“app_permanent_tag”));美元标准->setDistinct();}返回美元标准;}
我们现在需要寻找所有返回一个列表的模型方法,该列表必须在一个宇宙中进行筛选,并添加到标准
定义如下一行:
$ c= self::addPermanentTagToCriteria($ c);
例如,QuestionPeer: getHomepagePager ()
必须修改成这样:
公共静态函数getHomepagePager(美元的页面){美元寻呼机=新sfPropelPager(“问题”, sfConfig::得到(“app_pager_homepage_max”));$ c=新标准();$ c->addDescendingOrderByColumn(自我::INTERESTED_USERS);//添加此行$ c= self::addPermanentTagToCriteria($ c);美元寻呼机->setCriteria($ c);美元寻呼机->setPage(美元的页面);美元寻呼机->setPeerMethod(“doSelectJoinUser”);美元寻呼机->初始化();返回美元寻呼机;}
同样的修改必须重复很多次,方法如下:
QuestionPeer::getHomepagePager()QuestionPeer::getPopular()QuestionPeer::getPopular()QuestionPeer::getRecentPager()QuestionPeer::getRecent()AnswerPeer::getPager()AnswerPeer::getRecentPager()AnswerPeer::getRecent()
的复杂请求标准
对象时,我们需要将永久标记添加为在哪里
语句。看看我们是怎么做的QuestionTagPeer: getPopularTags ()
而且QuestionTagPeer: getPopularTagsFor ()
方法askeet trac或者在SVN储存库.
问题或用户的标记列表
“PHP”领域的所有问题都被标记为“PHP”。但是,如果用户在“PHP”领域中浏览问题,则“PHP”标记不能显示在标记列表中,因为它是隐含的。当为某个问题或某个宇宙中的用户输出一组标记时,必须省略永久标记。这可以通过在循环中绕过它来轻松完成,例如问题——> getTags ()
方法:
公共函数getTags(){$ c=新标准();$ c->添加(QuestionTagPeer::QUESTION_ID,这个美元->getId());$ c->addGroupByColumn(QuestionTagPeer::NORMALIZED_TAG);$ c->setDistinct();$ c->addAscendingOrderByColumn(QuestionTagPeer::NORMALIZED_TAG);美元的标记=数组();foreach(QuestionTagPeer::doSelect($ c)作为美元的标记){如果(sfConfig::得到(“app_permanent_tag”)= =美元的标记){继续;}美元的标记[]=美元的标记->getNormalizedTag();}返回美元的标记;}
同样的技术将用于以下方法:
问题——>getTags()问题——>getPopularTags()用户- >getTagsFor()用户- >getPopularTags()
将永久标签附加到新问题
在askeet宇宙中创建问题时,除了用户输入的标签外,还必须使用永久标签对其进行标记。作为提醒,在问题/添加
方法,问题——> addTagsForUser ()
方法调用:
美元问题->addTagsForUser(这个美元->getRequestParameter(“标签”),sf_user美元->getId());
...在哪里标签
请求参数包含用户输入的标签,用空格分隔(我们称之为“短语”)。的第一行中的短语附加永久标记addTagsForUser
方法:
公共函数addTagsForUser(美元的短语,userId美元){//将短语拆分为单独的标签美元的标记=标签::splitPhrase(美元的短语.(sfConfig::得到(“app_permanent_tag”)?' '.sfConfig::得到(“app_permanent_tag”):”));//添加标签foreach(美元的标记作为美元的标记){questionTag美元=新QuestionTag();questionTag美元->setQuestionId(这个美元->getId());questionTag美元->setUserId(userId美元);questionTag美元->setTag(美元的标记);questionTag美元->保存();}}
就是这样:如果用户还没有包含永久标记,那么它将被添加到新问题的标记列表中。
服务器配置
为了使新的域名可用,你必须修改你的web服务器配置。
在本地,即如果您不控制askeet站点的DNS,则为您想要添加的每个新宇宙添加一个新主机设置
文件,或者在C:\WINDOWS\system32\drivers\etc\hosts
Windows系统中的文件):
127.0.0.1 php。作为keet 127.0.0.1 senseoflife.askeet 127.0.0.1 women.askeet
请注意
您需要管理员权限才能执行此操作。
在所有情况下,都必须在虚拟主机配置中添加服务器别名httpd . conf
Apache文件):
ServerName askeet ServerAlias *。作为keet DocumentRoot "/home/sfprojects/askeet/web" DirectoryIndex index.php Alias /sf /usr/local/lib/php/data/symfony/web/sf AllowOverride All
重新启动web服务器后,你可以通过请求来测试其中一个宇宙,例如:
http://php.askeet/
明天见
过滤器功能强大,可以用于各种各样的事情。标签允许我们根据特定的主题定制内容。结合标签和过滤器帮助我们将askeet划分为几个领域,专门的askeet网站(想想music.askeet.com、programming.askeet.com或doityourself.askeet.com)的可能性是无限的。由于所有这些站点都可以以不同的方式蒙皮,并且由于专门站点的内容仍然出现在全局askeet站点中,askeet获得了基于社区的web应用程序的最佳效果。欧宝下载链接宇宙很小,可以建立一个社区,而全球站点可以成为寻找任何问题答案的最佳场所。欧宝下载链接
明天,我们将重点讨论性能,看看HTML缓存如何提高复杂页面的交付时间。三天之后,神秘的功能就会出现,你还有时间投票选出最好的创意。你仍然可以去参观使用论坛看看askeet网站是如何运作的在线.
本作品采用创作共用署名-非商业性-禁止派生作品3.0未移植许可协议授权。