<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[]]></ac:plain-text-body></ac:macro> <ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[
This proposition covers several classes dedicated to the client browser/device detection and the available associated features and capabilities.
<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[
Zend Framework: Zend_Http_UserAgent (was Zend_Browser) Component Proposal
Proposed Component Name
Zend_Http_UserAgent (was Zend_Browser)
Developer Notes
http://framework.zend.com/wiki/display/ZFDEV/Zend_Http_UserAgent (was Zend_Browser)
Proposers
Raphaël Carles
Zend Liaison
Revision
1.0 - 03 August 2010: Initial Draft. (wiki revision: 13)
Table of Contents
1. Overview
Its aim is to provide an interface to devices identification libraries like WURFL or DeviceAtlas and ease browsers differences handling, including mobile browsers.
This normalization of client environment detection can ease the management of multi-support development.2. References
3. Component Requirements, Constraints, and Acceptance Criteria
4. Dependencies on Other Framework Components
- Zend_Session (optional)
5. Theory of Operation
The UserAgent component should be seen as an information provider to Zend Framework applications at any level (helpers, controllers...)
Detection relies on declared or forced user agent information from server vars. It allows to have a standard behavior in the case that user agent string is present, a default one otherwise, and a forced mode where user agent is given at call time.
The identification class has a declared list of browsers types, ordered by priority.
Priorities can be changed to reflect application orientation (eg. a mobile-oriented website should have a faster identification of mobile devices than desktop ones).
New browser types can be developed and added to the priority list (or to extend an existing one), allowing wider recognition (probes, text browsers, ...) for the application that uses it.
The identification function is not called directly, although this is also possible.
All calls should be done to the getInstance method to execute the full identification process only one time per-request, or if session is activated, one time per-session and user agent.
After a quick detection of browser type, Zend_UserAgent can populate features by two ways :
- by responding directly to features checks (eg. return false to every request for a text browser, return true to every request for a desktop browser)
- by delegating to a Zend_UserAgent_Features_Adapter that will retrieve features.
The result is then stored as mentioned to bypass identification at next call (unless another user agent is forced).
6. Milestones / Tasks
Component already done for specific developments without ZF.
- Milestone 1: refactoring of existing code and adpatations to ZF design standards
- Milestone 2: Working prototype checked into the incubator supporting use cases #1, #2, ...
- Milestone 3: Working prototype checked into the incubator supporting use cases #3 and #4.
- Milestone 4: Unit tests exist, work, and are checked into SVN.
- Milestone 5: Initial documentation exists.
7. Class Index
- Zend_UserAgent
- Zend_UserAgent_AbstractUserAgent
- Zend_UserAgent_Mobile
- Zend_UserAgent_Tablet
- Zend_UserAgent_Desktop (by default)
- Zend_UserAgent_Bot
- Zend_UserAgent_Text
- Zend_UserAgent_Features_Adapter
- Zend_UserAgent_Features_Adapter_WurflPhpApi (the first adapter to be provided)
- Zend_UserAgent_Features_Adapter_Wurfl
- Zend_UserAgent_Features_Adapter_TeraWurfl
- Zend_UserAgent_Features_Adapter_DeviceAtlas
- Zend_UserAgent_Storage
- Zend_UserAgent_Storage_NonPersistent
- Zend_UserAgent_Storage_Session
The first adapter provided will be Zend_UserAgent_Features_Adapter_WurflPhpApi http://wurfl.sourceforge.net/nphp/
15 Comments
comments.show.hideAug 03, 2010
Dolf Schimmel (Freeaqingme)
<p>Wouldn't it be better to implement this as a viewhelper?</p>
Aug 09, 2010
Matthew Weier O'Phinney
<p>Not necessarily. It's often good to get the browser capability detection <em>before</em> any views or layouts are rendered, as it allows you to choose which ones you want to use. (Think ContextSwitch here – browser detection can be used instead of an XHR header or a "format" query parameter.)</p>
Aug 18, 2010
Business&Decision / Interakting
<p>The aim of this component is to provide the necessary informations to make conditional code for multi support display (and of course for the mobile support which is the most relevant target). </p>
<p>This adaptation can be done before or after the view rendering.</p>
<p>As a standalone component it can be anyway used as a viewhelper.</p>
Aug 04, 2010
Martin Keckeis
<p>Hello,</p>
<p>i wanted to start also this proposal today, but it seems that u we're faster <ac:emoticon ac:name="smile" /></p>
<p>I think the name of the class is "wrong", it thould be "Zend_User" or something like that, because the information is not only from the browser:</p>
<ul>
<li>OS</li>
<li>Resolution</li>
<li>...</li>
</ul>
Aug 05, 2010
Boris Guéry
<p>Hi,</p>
<p>I agree with Martin Keckeis.<br />
By the way, as the extending class are not only browser, UserAgent could be appropriate.</p>
Aug 09, 2010
Matthew Weier O'Phinney
<p>UserAgent makes sense as a name to me. "User" is too short and ambiguous; browser is perhaps too narrow.</p>
Aug 18, 2010
Business&Decision / Interakting
<p>Everyone seems to agree for "Zend_UserAgent".</p>
<p>I will update the Class Index to :</p>
<p>•Zend_UserAgent</p>
<p>•Zend_UserAgent_Abstract<br />
•Zend_UserAgent_Bot<br />
•Zend_UserAgent_Checker<br />
•Zend_UserAgent_Console<br />
•Zend_UserAgent_Desktop (by default)<br />
•Zend_UserAgent_Email<br />
•Zend_UserAgent_Feed<br />
•Zend_UserAgent_Mobile<br />
•Zend_UserAgent_Offline<br />
•Zend_UserAgent_Spam<br />
•Zend_UserAgent_Tablet<br />
•Zend_UserAgent_Text<br />
•Zend_UserAgent_Validator<br />
(inspired by the lists provided by <a class="external-link" href="http://www.useragentstring.com/pages/useragentstring.php">http://www.useragentstring.com/pages/useragentstring.php</a> and <a class="external-link" href="http://user-agent-string.info/list-of-ua">http://user-agent-string.info/list-of-ua</a>)</p>
<p>•Zend_UserAgent_Features_Adapter_WurflApi (the first adapter to be provided)<br />
•Zend_UserAgent_Features_Adapter_DeviceAtlas<br />
•Zend_UserAgent_Features_Adapter_Interface<br />
•Zend_UserAgent_Features_Adapter_TeraWurfl<br />
•Zend_UserAgent_Features_Adapter_Wurfl</p>
<p>NOTE : the "Features" classes must be independant on user-agent's type because, for example, the Wurfl API can provide capabilities for mobile/desktop/bot and spider browsers (see <a class="external-link" href="http://dev.wurflpro.com/projects/wurfl-api/browser/php/core/trunk/examples/resources/web_browsers_patch.xml">http://dev.wurflpro.com/projects/wurfl-api/browser/php/core/trunk/examples/resources/web_browsers_patch.xml</a> and <a class="external-link" href="http://dev.wurflpro.com/projects/wurfl-api/browser/php/core/trunk/examples/resources/bots_and_spider.xml">http://dev.wurflpro.com/projects/wurfl-api/browser/php/core/trunk/examples/resources/bots_and_spider.xml</a>).</p>
Aug 19, 2010
Pádraic Brady
<p>The proposer should note that all future proposals should target Zend Framework 2.0 since ZF 1.11 will be the final release accepting new features in the 1.x branch. ZF 1.x proposals cannot be reviewed until they are updated accordingly. For your information, Zend Framework 2.0 is written for PHP 5.3 and utilises namespaces - updating code for this is not as hard as it seems <ac:emoticon ac:name="wink" />.</p>
<p>Paddy</p>
<p>Community Review (CR) Team </p>
Aug 19, 2010
Matthew Weier O'Phinney
<p>Actually, Paddy – this is a Zend partner, and they have agreed to be able to prepare the proposal and code in time for 1.11. I'd like to discuss this with the CR-Team today, if possible.</p>
Aug 20, 2010
Ben Scholzen
<p>I'd suggest to rename the component to Zend_Http_UserAgent.</p>
Aug 24, 2010
Dolf Schimmel (Freeaqingme)
<ac:macro ac:name="note"><ac:rich-text-body><p><strong>Community Review Team Recommendation</strong></p>
<p>The CR Team recommends this component be included into versions 1.11 and 2.0 of the Zend Framework with the following requirements:</p>
<ul>
<li>The component be put in the Zend_Http_UserAgent namespace</li>
<li>The component should not be a singleton, instead it should be accompanied with a Zend_Application Resource Plugin that instantiates it and stores it inside Zend_Application's DI-container, and then can be retrieved from there using a viewhelper.</li>
<li>The component should be accompanied with a method to clear its session (to assist in testing).</li>
<li>If the component is dependent on external libraries their license should be compatible with the one ZF is shipped with.</li>
</ul>
</ac:rich-text-body></ac:macro>
Sep 17, 2010
Kazusuke Sasezaki
<p>Hi, CR-Team.</p>
<p>Is there any reason which should be renaming to Zend_Http_UserAgent?</p>
<p>Currently, Zend_Http_* is a side where sending request.Zend_Http_* should be no where request is received?</p>
Sep 18, 2010
Matthew Weier O'Phinney
<p>This functionality of the proposed component is not restricted to use in the MVC, but falls under the HTTP protocol (as a combination of HTTP request headers are inspected). </p>
<p>Zend_Http has primarily been an area of the Client in the past. However, it was never intended to be <em>only</em> for HTTP client purposes; at one point, a Server was considered. As such, this is a perfect location for this new component.</p>
Sep 17, 2010
Kazusuke Sasezaki
<p>I think that these classes should be written to be cooperate with the Zend_Controller_Request_Http and User's Controller_Request_HttpTestCase. </p>
<p>So, I propose a defining proxy-class, instead of $_SERVER. as follows.</p>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
abstract class Zend_Http_UserAgent_AbstractUserAgent
{
private $_serverVar;
//@return Zend_Http_UserAgent_ServerVar
public function getServer()
{
if (!$this->_server)
return $_server;
}
public function setServer(Zend_Http_UserAgent_ServerVar $serverVar)
}
]]></ac:plain-text-body></ac:macro>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class Zend_Http_UserAgent_ServerVar implements ArrayAccess
{
private $_server;
public function __construct($request = null)
{
if ($request instanceof Zend_Controller_Request_Http)
elseif (is_array($request))
else
}
}
]]></ac:plain-text-body></ac:macro>
<p>current code will be change as follows?<br />
if (isset ( $_SERVER <ac:link><ri:page ri:content-title=""REMOTE_ADDR"" /></ac:link> )) {<br />
?<br />
$server = $this->getServer();<br />
if (isset ( $server<ac:link><ri:page ri:content-title=""REMOTE_ADDR"" /></ac:link> )) {</p>
Sep 18, 2010
Matthew Weier O'Phinney
<p>There's no reason to tie it to Zend_Controller_Request_Http at all. That class has a getServer() method already, and the return of that may be passed in to Zend_Http_UserAgent to introspect.</p>